2014-09-27 3 views
0

Я пытаюсь создать видеофайл из анимации, которую я имею в OpenGL. Я читал о том, как сделать это, и мое понимание есть два варианта:Создайте видео с открытыми кадрами OpenGL

  1. Сохранить каждый визуализацию кадра в OpenGL в файл изображения, а затем создать видеофайл из тех
  2. Получить данные кадра используя glReadPixels() и на лету писать те, в видеофайл

второй подход является то, что я считаю, будет работать лучше для меня, однако, я не могу найти информацию о том, как достичь вторую часть (запись в видеофайл).

Может ли кто-нибудь указать мне на некоторые веб-сайты, где я узнаю, как это сделать? Какие библиотеки существуют там, которые я могу использовать для кодирования (?) Видео из фреймов, которые я рендеринга в OpenGL?

EDIT

После поиска немного больше об этом, я считаю, FFmpeg это путь. Я нашел this blog, у которого есть код, который, по-видимому, работает на окнах.

Я загрузил ffmpeg с веб-сайта, чтобы выполнить команду так же, как в примере. К сожалению, мое приложение отключается, и видео не создается. Я проверил, чтобы указатель файла был действительным, но это не так, поэтому я считаю, что ошибка возникает из-за выполнения функции popen.

Я передаю те же аргументы, что и команда, но все еще не имеет действительного указателя на файл, любая идея о том, что может произойти?

Дело в том, что я не хочу тратить много времени на кодирование кодировки видео, так как у меня есть другие проекты, над которыми нужно работать.

+0

Я не очень разбираюсь в кодировании/декодировании видеофайлов, но я думаю, что лучше всего будет искать библиотеку, которая сделает это за вас, и вы просто передадите ей данные. Если его какая-то часть такая же, как и звук (который), я думаю, что это так, это не будет тривиально. К сожалению, я не знаю никаких библиотек. – Daniel

+0

Проблема в том, что вы не просите о конкретной помощи. Существует множество библиотек, которые могут кодировать серию изображений RGB в видеопоток (ffmpeg, gstreamer, я уверен, что у OSX есть что-то родное). Если вы не попросите что-то конкретное об этих библиотеках, этот вопрос не имеет смысла. – peppe

ответ

1

Поскольку я не мог использовать ffmpeg непосредственно из моего кода на C++, возможно решение следующего. В Qt5 у вас есть функция paintGL, где вы обновляете фрейм, который нужно визуализировать. После этого, получить пикселы с glReadPixels, а затем просто сохранить кадр как PNG изображения с помощью 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"); 
} 

Это оставит кучу изображений в вашем рабочем каталоге, вы можете закодировать в видео, используя следующую команду консоль

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

Я до сих пор, чтобы проверить, почему цвета инвертируются, но сейчас это работает отлично, так как анимация главное, а не цвет.

0

Вы можете сделать в этом случае после установки Libpng: uint8_t пикселей = новый uint8_t [ш ч * 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); если (!png) return 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 Frame% d.png -vcodec mpeg4 -vf vflip test.avi – user3059007

Смежные вопросы