2014-09-27 2 views
0

OpenGL에있는 애니메이션에서 비디오 파일을 만들려고합니다. 나는 그 작업을 수행하는 방법에 대한 나의 이해를 읽고있다 이 두 가지 옵션이 있습니다 : 이미지 파일의 OpenGL에서OpenGL 렌더링 된 프레임에서 비디오 만들기

  1. 저장 각 렌더링 프레임과 다음 프레임 데이터를 취득하는
  2. 에서 비디오 파일을 생성 glReadPixels()를 사용하여 즉석에서 비디오 파일

두 번째 방법으로 사람들을 쓰기 것은 내가 두 번째 부분을 달성하는 방법에 대한 정보를 찾을 수없는, 내가 그러나 나에게 가장 적합한 것이 믿는 것입니다 (비디오 파일에 쓰기).

누구나 내가 어떻게하는지 배울 수있는 웹 사이트를 알려줄 수 있습니까? OpenGL에서 렌더링하는 프레임의 비디오를 인코딩 (?)하는 데 사용할 수있는 라이브러리가 있습니까?

이것에 대해 좀 더 검색 한 후 편집

, 내가는 FFmpeg이 길을 가야하는 것입니다 생각합니다. Windows에서 작동하는 코드가있는 this blog을 발견했습니다.

예에서와 같이 명령을 실행할 수 있도록 웹 사이트에서 ffmpeg를 다운로드했습니다. 불행히도, 내 응용 프로그램이 충돌하고 아무 비디오도 생성되지 않습니다. 파일 포인터가 유효한지 확인했지만 그렇지 않은 것 같습니다. 따라서 오류가 함수 popen의 실행에서 비롯된 것 같습니다.

명령과 동일한 인수를 전달하고 있지만 유효한 파일 포인터가 없습니다. 어떤 일이 벌어 질 수 있는지 생각해보십시오.

다른 프로젝트를 작업하고 있으므로 비디오 인코딩 코딩에 많은 시간을 소비하고 싶지 않습니다.

+0

저는 비디오 파일을 인코딩/디코딩하는 데별로 경험이 없지만 최선의 방법은 해당 작업을 수행하는 라이브러리를 찾는 것이고 데이터를 전달하는 것입니다. 그것의 어떤 부분이 그것이 내가 상상하는 오디오와 같은 것이라면, 그것은 사소하지 않을 것입니다. 불행히도 나는 어떤 도서관에 대해서도 모른다. – Daniel

+0

문제는 특정 도움을 요청하지 않는 것입니다. 일련의 RGB 이미지를 비디오 스트림으로 인코딩 할 수있는 많은 라이브러리가 있습니다 (ffmpeg, gstreamer, OSX에는 고유 한 것이 있습니다). 도서관에 관한 구체적인 내용을 묻지 않는 이상이 질문은 의미가 없습니다. – peppe

답변

1

내 C++ 코드에서 ffmpeg을 직접 사용할 수 없기 때문에 가능한 해결책은 다음과 같습니다. Qt5에서는 렌더링 할 프레임을 업데이트하는 paintGL 함수가 있습니다. 그 후, glReadPixels로 픽셀을 얻을 후 바로 이것은 다음과 같은 명령을 사용하면 비디오 인코딩 할 수 있습니다 작업 디렉토리에있는 이미지의 무리를 떠나 QImage

void OpenGLViewer::paintGL() 
{ 
    // Clear screen 
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 

    // Update array attached to OpenGL 

    glDrawArrays(GL_POINTS, 0, _points); 

    update(); 

    glReadPixels(0, 0, this->width(), this->height(), GL_RGBA, GL_UNSIGNED_BYTE, _buffer); 

    std::stringstream name; 
    name << "Frame" << _frame++ << ".png"; 
    QString filename(name.str().c_str()); 
    QImage imagen(_buffer, this->width(), this->height(), QImage::Format_ARGB32); 
    imagen.save(filename, "PNG"); 
} 

를 사용하여 PNG로 이미지로 프레임을 저장 애니메이션이 중요한 것은 아닌 색상 때문에 난 여전히 색상이 반전 원인을 확인하지만, 위해해야 ​​콘솔

ffmpeg -framerate 30 -start_number 0 -i Frame%d.png -vcodec mpeg4 -vf vflip test.avi

이제이 잘 작동합니다.

0

libpng을 설치 한 후 다음과 같이 할 수 있습니다. uint8_t 픽셀 = 새 uint8_t [w h * 3]; glReadPixels (0, 0, w, h, GL_RGB, GL_UNSIGNED_BYTE, (GLvoid *) 픽셀);

for (int j = 0; j * 2 < h; ++j) { 
int x = j * w * 3; 
int y = (h - 1 - j) * w * 3; 
for (int i = w * 3; i > 0; --i) { 
    uint8_t tmp = pixels[x]; 
    pixels[x] = pixels[y]; 
    pixels[y] = tmp; 
    ++x; 
    ++y; 
    } 
} 

png_structp PNG = png_create_write_struct (PNG_LIBPNG_VER_STRING, nullptr, nullptr, nullptr); if (!png) false를 반환합니다.

png_infop info = png_create_info_struct(png); 
if (!info) { 
    png_destroy_write_struct(&png, &info); 
    return false; 
} 
std::string s = "IMAGE/"+string(filename); 
FILE *fp = fopen(s.c_str(), "wb"); 
if (!fp) { 
    png_destroy_write_struct(&png, &info); 
    return false; 
} 

png_init_io(png, fp); 
png_set_IHDR(png, info, w, h, 8 , PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE, 
    PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); 
png_colorp palette = (png_colorp)png_malloc(png, PNG_MAX_PALETTE_LENGTH * sizeof(png_color)); 
if (!palette) { 
    fclose(fp); 
    png_destroy_write_struct(&png, &info); 
    return false; 
} 
png_set_PLTE(png, info, palette, PNG_MAX_PALETTE_LENGTH); 
png_write_info(png, info); 
png_set_packing(png); 

png_bytepp rows = (png_bytepp)png_malloc(png, h * sizeof(png_bytep)); 
for (int i = 0; i < h; ++i) 
    rows[i] = (png_bytep)(pixels + (h - i - 1) * w * 3); 

png_write_image(png, rows); 
png_write_end(png, info); 
png_free(png, palette); 
png_destroy_write_struct(&png, &info); 

fclose(fp); 
delete[] rows; 
+0

ffmpeg -framerate 30 -start_number 0 -i 프레임 % d.png -vcodec mpeg4 -vf vflip test.avi – user3059007

관련 문제