首页 文章

使用x264将OpenGL输出转换为H264

提问于
浏览
3

我想将OpenGL程序的输出转换为h264并输出流 . 我收集了大部分代码并得到了一个输出文件,但我不知道如何处理它,或者它是否有效 . 目前输出只保存在file.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;

我的init函数:

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 );

    }

我从http://svn.gnumonks.org/trunk/21c3-video/cutting_tagging/tools/mpeg4ip-1.2/server/util/rgb2yuv/rgb2yuv.c获得了GRB2YUV的功能

输出看起来像

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文件中,file.h264返回数据 .

2 回答

  • 0

    你的文件格式不好 . 没有什么能够读到这一点 . .264使用附件B,前缀为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).
    

    那个's most likely why you'没有得到任何可用的视频 . 您可以在此处找到有关该做什么的更多信息:How does one encode a series of images into H264 using the 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.
    

相关问题