FFmpeg libx264 AVCodecContext设置

5

我正在使用最新的Windows (2011年1月) ffmpeg编译,并尝试录制H264视频。使用以下设置可以成功录制MPEG4:

c->codec_id = CODEC_ID_MPEG4;
c->codec_type = AVMEDIA_TYPE_VIDEO;
c->width = VIDEO_WIDTH;
c->height = VIDEO_HEIGHT;
c->bit_rate = c->width * c->height * 4;
c->time_base.den = FRAME_RATE;
c->time_base.num = 1;
c->gop_size = 12;
c->pix_fmt = PIX_FMT_YUV420P;

仅仅将CODEC Id更改为H264会导致avcodec_open()失败(-1)。我在这里找到了一个可能的设置列表如何使用libavcodec/x264编码h.264?。我尝试过这些设置,没有设置pix_fmt,即使我另外设置了c->pix_fmt = PIX_FMT_YUV420P; avcodec_open()仍然失败,而且我得到了一个除以零异常。
然后我看到了一些帖子说我不应该设置任何东西(除了code_id、codec_type、width、height和也许bit_rate和pix_fmt),因为库现在会自动选择最佳设置。我尝试了各种组合,但avcode_open()仍然失败。
有人能给我一些建议或者当前的某些设置吗?
谢谢。
以下是导致我描述问题的一组H264设置:
static AVStream* AddVideoStream(AVFormatContext *pOutputFmtCtx, 
int frameWidth, int frameHeight, int fps)
{
AVCodecContext* ctx;
AVStream* stream;

stream = av_new_stream(pOutputFmtCtx, 0);
if (!stream) 
{
    return NULL;
}

ctx = stream->codec;

ctx->codec_id = pOutputFmtCtx->oformat->video_codec; //CODEC_ID_H264
ctx->codec_type = AVMEDIA_TYPE_VIDEO;
ctx->width = frameWidth;             //704
ctx->height = frameHeight;           //576
ctx->bit_rate = frameWidth * frameHeight * 4;

ctx->coder_type = 1;  // coder = 1
ctx->flags|=CODEC_FLAG_LOOP_FILTER;   // flags=+loop
ctx->me_cmp|= 1;  // cmp=+chroma, where CHROMA = 1
ctx->partitions|=X264_PART_I8X8+X264_PART_I4X4+X264_PART_P8X8+X264_PART_B8X8; // partitions=+parti8x8+parti4x4+partp8x8+partb8x8
ctx->me_method=ME_HEX;    // me_method=hex
ctx->me_subpel_quality = 7;   // subq=7
ctx->me_range = 16;   // me_range=16
ctx->gop_size = 250;  // g=250
ctx->keyint_min = 25; // keyint_min=25
ctx->scenechange_threshold = 40;  // sc_threshold=40
ctx->i_quant_factor = 0.71; // i_qfactor=0.71
ctx->b_frame_strategy = 1;  // b_strategy=1
ctx->qcompress = 0.6; // qcomp=0.6
ctx->qmin = 10;   // qmin=10
ctx->qmax = 51;   // qmax=51
ctx->max_qdiff = 4;   // qdiff=4
ctx->max_b_frames = 3;    // bf=3
ctx->refs = 3;    // refs=3
ctx->directpred = 1;  // directpred=1
ctx->trellis = 1; // trellis=1
       ctx->flags2|=CODEC_FLAG2_BPYRAMID+CODEC_FLAG2_MIXED_REFS+CODEC_FLAG2_WPRED+CODEC_FLAG2_8X8DCT+CODEC_FLAG2_FASTPSKIP;  // flags2=+bpyramid+mixed_refs+wpred+dct8x8+fastpskip
ctx->weighted_p_pred = 2; // wpredp=2
// libx264-main.ffpreset preset
ctx->flags2|=CODEC_FLAG2_8X8DCT;
ctx->flags2^=CODEC_FLAG2_8X8DCT;    // flags2=-dct8x8

// if set this get divide by 0 error on avcodec_open()
// if don't set it get -1 error on avcodec_open()
//ctx->pix_fmt = PIX_FMT_YUV420P; 

return stream;

}


你确定在ffmpeg构建中包含了h.264编解码器吗? - ciphor
我正在使用 http://ffmpeg.zeranoe.com/builds/ 构建版本。它们声称该版本是使用 --enable-libx264 参数构建的。 - integra753
请张贴CODEC_ID_H264的代码。 - ciphor
将avcodeccontext的avrational设置为正确的值。 - Sureshkumar Menon
我有完全相同的问题:
  • 从http://ffmpeg.zeranoe.com/builds/下载源代码
  • avcodec_open()对于CODEC_ID_H264返回-1
  • avcodec_open()对于CODEC_ID_MPEG2VIDEO完美工作
  • ffmpeg.zeranoe.com/builds表明库是使用--enable-libx264构建的。那么,你找到解决方案了吗?
- user1733237
@integra753 请发布您的H264 payloadType。我的意思是像这样:{34,“H263”,AVMEDIA_TYPE_VIDEO,CODEC_ID_H263,90000,-1} - Dr.jacky
1个回答

3

根据我的经验,初始化编解码器时应该尽可能地减少向FFMPEG提供的信息。这似乎是违反直觉的,但这意味着FFMPEG将使用其默认设置,这些设置比您自己的猜测更有可能起作用。请查看下面我将包括哪些内容:

AVStream *stream;
m_video_codec = avcodec_find_encoder(AV_CODEC_ID_H264);
stream = avformat_new_stream(_outputCodec, m_video_codec);
ctx = stream->codec;
ctx->codec_id = m_fmt->video_codec;
ctx->bit_rate = m_AVIMOV_BPS;           //Bits Per Second 
ctx->width    = m_AVIMOV_WIDTH;         //Note Resolution must be a multiple of 2!!
ctx->height   = m_AVIMOV_HEIGHT;        //Note Resolution must be a multiple of 2!!
ctx->time_base.den = m_AVIMOV_FPS;      //Frames per second
ctx->time_base.num = 1;
ctx->gop_size      = m_AVIMOV_GOB;      // Intra frames per x P frames
ctx->pix_fmt       = AV_PIX_FMT_YUV420P;//Do not change this, H264 needs YUV format not RGB

如之前的回答一样,这里有一个可行的FFMPEG库将RGB帧编码成H264视频的工作示例:

http://www.imc-store.com.au/Articles.asp?ID=276

对于您的代码还有一个额外的想法:

  • 您是否调用了以下注册函数?

    avcodec_register_all();

    av_register_all();

    如果您没有在代码开头附近调用这两个函数,那么随后对FFMPEG的调用会失败,您很可能会遇到段错误。

请查看链接的示例,我在VC++2010上测试过,它完美地工作。


1
您提供的链接是404错误页面,我想知道您是否还有那个示例? - phdfong - Kenneth Fong

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接