Конвертировать вывод OpenGL в H264 с x264

Я хочу конвертировать вывод программы OpenGL в h264 и выводить поток. Я где-то собрал большую часть кода и получил выходной файл, но понятия не имею, что с ним делать или если он действителен. В настоящее время вывод просто сохраняется в файле .h264.

Изменить: «Глобальные» переменные

    x264_param_t param;
x264_t* encoder;
x264_picture_t pic_in;
x264_picture_t pic_out;

x264_nal_t *headers;
int i_nal;
FILE* pFile;

Моя функция инициализации:

initX264() {
pFile = fopen("file.h264", "wb");

x264_param_t param;
x264_param_default_preset(&param, "veryfast", "zerolatency");
param.i_threads = 1;
param.i_width = 1024;
param.i_height = 768;
param.i_fps_num = 30;
param.i_fps_den = 1;

param.i_keyint_max = 30;
param.b_intra_refresh = 1;

param.rc.i_rc_method = X264_RC_CRF;
param.rc.f_rf_constant = 25;
param.rc.f_rf_constant_max = 35;

param.b_annexb = 0;
param.b_repeat_headers = 0;

param.i_log_level = X264_LOG_DEBUG;

x264_param_apply_profile(&param, "baseline");

encoder = x264_encoder_open(&param);
x264_picture_alloc(&pic_in, X264_CSP_I420, 1024, 768);

x264_encoder_parameters( encoder, &param );

x264_encoder_headers( encoder, &headers, &i_nal );

int size = headers[0].i_payload + headers[1].i_payload + headers[2].i_payload;
fwrite( headers[0].p_payload, 1, size, pFile);
}

Это происходит в функции Render и выполняется около 30 раз в секунду:

    GLubyte *data = new GLubyte[3 * 1024 * 768];
GLubyte *PixelYUV = new GLubyte[3 * 1024 * 768];

glReadPixels(0, 0, 1024, 768, GL_RGB, GL_UNSIGNED_BYTE, data);
RGB2YUV(1024, 768, data, PixelYUV, PixelYUV + 1024 * 768, PixelYUV + 1024 * 768 + (1024 * 768) / 4, true);
pic_in.img.plane[0] = PixelYUV;
pic_in.img.plane[1] = PixelYUV + 1024 * 768;
pic_in.img.plane[2] = PixelYUV + 1024 * 768 + (1024 * 768) / 4;

x264_nal_t* nals;
int i_nals;
int frame_size = x264_encoder_encode(encoder, &nals, &i_nals, &pic_in, &pic_out);

if( frame_size )
{
fwrite( (char*)nals[0].p_payload, frame_size, 1, pFile );

}

Я получил функцию GRB2YUV от http://svn.gnumonks.org/trunk/21c3-video/cutting_tagging/tools/mpeg4ip-1.2/server/util/rgb2yuv/rgb2yuv.c

Выход выглядит как

x264 [debug]: frame=   0 QP=11.14 NAL=3 Slice:I Poc:0   I:3072 P:0    SKIP:0    size=21133 bytes
x264 [debug]: frame=   1 QP=20.08 NAL=2 Slice:P Poc:2   I:0    P:14   SKIP:3058 size=72 bytes
x264 [debug]: frame=   2 QP=18.66 NAL=2 Slice:P Poc:4   I:0    P:48   SKIP:3024 size=161 bytes
x264 [debug]: frame=   3 QP=18.23 NAL=2 Slice:P Poc:6   I:0    P:84   SKIP:2988 size=293 bytes

В файле Linux файл .h264 возвращает данные.

3

Решение

Ваш формат файла плохой. Ничто не сможет прочитать это. .264 использует annexB с заголовками, добавленными к кадрам IDR.

изменить эти параметры,

param.b_annexb = 1;
param.b_repeat_headers = 1;

И удалить

x264_encoder_headers( encoder, &headers, &i_nal );
int size = headers[0].i_payload + headers[1].i_payload + headers[2].i_payload;
fwrite( headers[0].p_payload, 1, size, pFile);

Наконец, вы должны быть в состоянии взять ваш вывод и преобразовать его в mp4.

ffmpeg -i file.264 -vcodec copy -an file.mp4
3

Другие решения

 X264 expects YUV420P data (I guess some others also, but that's the common one). You can use libswscale (from ffmpeg) to convert images to the right format. Initializing this is like this (i assume RGB data with 24bpp).

Скорее всего, поэтому вы не получаете полезного видео. Вы можете найти больше о том, что делать здесь: Как можно закодировать серию изображений в H264 с помощью x264 C API?

В масштабе:

 sws_scale(convertCtx, &data, &srcstride, 0, h, pic_in.img.plane, pic_in.img.stride);
//pic_in is your RGB data getting fed to scale.
0

По вопросам рекламы [email protected]