I am attempting to encode video using libavcodec/libavformat. Audio works great, but when I try to encode video I get the following errors:
我正在尝试用libavcodec/libavformat对视频进行编码。音频效果很好,但是当我尝试对视频进行编码时,我得到了以下错误:
[libx264 @ 0x10182a000]broken ffmpeg default settings detected
[libx264 @ 0x10182a000]use an encoding preset (vpre)
easy to fix using the command line ffmpeg, but I am trying to do this in C. my options are
使用命令行ffmpeg很容易修复,但是我正在尝试在c中这样做,我的选项是
AVStream *pVideoOutStream = av_new_stream(pOutFormatCtx, 0);
AVCodecContext *pVideoOutCodecCtx = pVideoOutStream->codec;
pVideoOutCodecCtx->codec_id = CODEC_ID_H264;
pVideoOutCodecCtx->codec_type = CODEC_TYPE_VIDEO;
pVideoOutCodecCtx->bit_rate = pVideoInCodecCtx->bit_rate;
pVideoOutCodecCtx->width = pVideoInCodecCtx->width;
pVideoOutCodecCtx->height = pVideoInCodecCtx->height;
pVideoOutCodecCtx->pix_fmt = pVideoInCodecCtx->pix_fmt;
pVideoOutCodecCtx->sample_rate = pVideoInCodecCtx->sample_rate;
pVideoOutCodecCtx->gop_size = 30;
but avcodec_open() fails.
但是avcodec_open()失败。
What other values do I need to set to make x264 happy?
我还需要设置哪些值才能让x264满意呢?
5 个解决方案
#1
10
Not sure whether you got it working, but the following parameters work for me.
不确定您是否使它工作,但以下参数对我有效。
ctx->bit_rate = 500*1000;
ctx->bit_rate_tolerance = 0;
ctx->rc_max_rate = 0;
ctx->rc_buffer_size = 0;
ctx->gop_size = 40;
ctx->max_b_frames = 3;
ctx->b_frame_strategy = 1;
ctx->coder_type = 1;
ctx->me_cmp = 1;
ctx->me_range = 16;
ctx->qmin = 10;
ctx->qmax = 51;
ctx->scenechange_threshold = 40;
ctx->flags |= CODEC_FLAG_LOOP_FILTER;
ctx->me_method = ME_HEX;
ctx->me_subpel_quality = 5;
ctx->i_quant_factor = 0.71;
ctx->qcompress = 0.6;
ctx->max_qdiff = 4;
ctx->directpred = 1;
ctx->flags2 |= CODEC_FLAG2_FASTPSKIP;
The error message broken ffmpeg default settings detected
is displayed in the x264 library in x264/encoder/encoder.c when too many settings are the default ffmpeg settings (e.g. qmin = 2, qmax = 31, qcompress = 0.5
), changing these three values to something else, e.g. qmin = 10, qmax = 51, qcompress = 0.6
, resolves the error.
在x264/encoder/encoder /encoder中的x264库中显示检测到的错误消息破坏了ffmpeg默认设置。c当太多的设置是默认的ffmpeg设置时(例如qmin = 2, qmax = 31, qcompress = 0.5),将这三个值改变为其他值,例如qmin = 10, qmax = 51, qcompress = 0.6,解决了这个错误。
#2
22
Don't forget to use x264 private options. You can always set a profile:
不要忘记使用x264私有选项。你可以设置一个概要:
av_dict_set(&This->opts, "vprofile", "baseline", 0)
Or set the lowest encoding latency:
或设置最低编码延迟:
av_dict_set(&This->opts, "tune", "zerolatency", 0);
Or select a preset:
或选择一个预设:
av_dict_set(&This->opts, "preset","ultrafast",0);
Before opening a codec
在打开一个编解码器
avcodec_open2(This->context, This->codec, &This->opts)
#3
15
The following is how to interpret the ffmpeg's x264 presets.
下面是如何解释ffmpeg的x264预置。
Unfortunately I don't know of an easy way to import the presets like ffmpeg does. You can lookup the x264 preset values which are all stored in /usr/local/share/ffmpeg/libx264-{name}.ffpreset, where {name} is specified for ffmpeg as the -vpre {name} command-line argument. So typically ffmpeg would include libx264-medium.ffpreset and then libx264-main.ffpreset, specified as ffmpeg -vpre medium -vpre main
不幸的是,我不知道像ffmpeg那样导入预置的简单方法。您可以查找所有存储在/usr/local/share/ffmpeg/libx264-{name}中的x264预置值。ffpreset,其中为ffmpeg指定{name}为-vpre {name}命令行参数。所以ffmpeg通常包括libx264-medium。ffpreset然后libx264-main。ffpreset,指定为ffmpeg -vpre媒体-vpre main
You can lookup all the options (as defined in the libx264-{name}.ffpreset files) to get their structure names by looking in the libavcodec/options.c file, which can be found in the ffmpeg SVN repositories.
您可以查找所有选项(如libx264-{name}中定义的那样)。通过查找libavcodec/options,获得它们的结构名称。c文件,可以在ffmpeg SVN存储库中找到。
Here's how the medium and main presets would be translated into C code:
下面是如何将媒体和主预置翻译成C代码的:
// libx264-medium.ffpreset preset
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;c->flags2^=CODEC_FLAG2_8X8DCT; // flags2=-dct8x8
You'll have to look at the ffmpeg source code if you want to parse those presets automatically.
如果您想要自动解析这些预置,您必须查看ffmpeg源代码。
I hope that the information I just gave would help you out a bit more :)
我希望我刚才提供的信息能对你有所帮助。
#4
3
I encode YUV420P pictures into different formats, using different codecs. CodecID I took from AVOutputFormat after using guess_format(...) function. But other codec settings are (All of them has been taken from ffmpeg examples' source code):
我用不同的解码器将YUV420P图片编码成不同的格式。在使用了guess_format(…)函数后,我从AVOutputFormat获取了CodecID。但是其他的编解码设置是(它们都是从ffmpeg示例的源代码中获得的):
c->codec_id = (CodecID)CODEC_ID_H264; //This is your codec id
c->codec_type = CODEC_TYPE_VIDEO;
c->bit_rate = 1000000;
c->width = <...>;
c->height = <...>;
c->time_base.den = 25;
c->time_base.num = 1;
c->gop_size = 12;
c->pix_fmt = PIX_FMT_YUV420P;
if (c->codec_id == CODEC_ID_MPEG1VIDEO) //It not necessary for you
c->mb_decision=2;
// some formats want stream headers to be separate
if(oc->oformat->flags & AVFMT_GLOBALHEADER)
c->flags |= CODEC_FLAG_GLOBAL_HEADER;
This setting must work to most codecs, but I had a problem with fps: not all codecs supports any fps values (and some other parameters too).
这个设置必须适用于大多数编解码器,但是我对fps有一个问题:不是所有的编解码器都支持fps值(以及其他一些参数)。
#5
0
seems that the ffmpeg version 20130302 requires something like
似乎ffmpeg版本201302需要类似的东西
c->profile = FF_PROFILE_H264_BASELINE;
#1
10
Not sure whether you got it working, but the following parameters work for me.
不确定您是否使它工作,但以下参数对我有效。
ctx->bit_rate = 500*1000;
ctx->bit_rate_tolerance = 0;
ctx->rc_max_rate = 0;
ctx->rc_buffer_size = 0;
ctx->gop_size = 40;
ctx->max_b_frames = 3;
ctx->b_frame_strategy = 1;
ctx->coder_type = 1;
ctx->me_cmp = 1;
ctx->me_range = 16;
ctx->qmin = 10;
ctx->qmax = 51;
ctx->scenechange_threshold = 40;
ctx->flags |= CODEC_FLAG_LOOP_FILTER;
ctx->me_method = ME_HEX;
ctx->me_subpel_quality = 5;
ctx->i_quant_factor = 0.71;
ctx->qcompress = 0.6;
ctx->max_qdiff = 4;
ctx->directpred = 1;
ctx->flags2 |= CODEC_FLAG2_FASTPSKIP;
The error message broken ffmpeg default settings detected
is displayed in the x264 library in x264/encoder/encoder.c when too many settings are the default ffmpeg settings (e.g. qmin = 2, qmax = 31, qcompress = 0.5
), changing these three values to something else, e.g. qmin = 10, qmax = 51, qcompress = 0.6
, resolves the error.
在x264/encoder/encoder /encoder中的x264库中显示检测到的错误消息破坏了ffmpeg默认设置。c当太多的设置是默认的ffmpeg设置时(例如qmin = 2, qmax = 31, qcompress = 0.5),将这三个值改变为其他值,例如qmin = 10, qmax = 51, qcompress = 0.6,解决了这个错误。
#2
22
Don't forget to use x264 private options. You can always set a profile:
不要忘记使用x264私有选项。你可以设置一个概要:
av_dict_set(&This->opts, "vprofile", "baseline", 0)
Or set the lowest encoding latency:
或设置最低编码延迟:
av_dict_set(&This->opts, "tune", "zerolatency", 0);
Or select a preset:
或选择一个预设:
av_dict_set(&This->opts, "preset","ultrafast",0);
Before opening a codec
在打开一个编解码器
avcodec_open2(This->context, This->codec, &This->opts)
#3
15
The following is how to interpret the ffmpeg's x264 presets.
下面是如何解释ffmpeg的x264预置。
Unfortunately I don't know of an easy way to import the presets like ffmpeg does. You can lookup the x264 preset values which are all stored in /usr/local/share/ffmpeg/libx264-{name}.ffpreset, where {name} is specified for ffmpeg as the -vpre {name} command-line argument. So typically ffmpeg would include libx264-medium.ffpreset and then libx264-main.ffpreset, specified as ffmpeg -vpre medium -vpre main
不幸的是,我不知道像ffmpeg那样导入预置的简单方法。您可以查找所有存储在/usr/local/share/ffmpeg/libx264-{name}中的x264预置值。ffpreset,其中为ffmpeg指定{name}为-vpre {name}命令行参数。所以ffmpeg通常包括libx264-medium。ffpreset然后libx264-main。ffpreset,指定为ffmpeg -vpre媒体-vpre main
You can lookup all the options (as defined in the libx264-{name}.ffpreset files) to get their structure names by looking in the libavcodec/options.c file, which can be found in the ffmpeg SVN repositories.
您可以查找所有选项(如libx264-{name}中定义的那样)。通过查找libavcodec/options,获得它们的结构名称。c文件,可以在ffmpeg SVN存储库中找到。
Here's how the medium and main presets would be translated into C code:
下面是如何将媒体和主预置翻译成C代码的:
// libx264-medium.ffpreset preset
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;c->flags2^=CODEC_FLAG2_8X8DCT; // flags2=-dct8x8
You'll have to look at the ffmpeg source code if you want to parse those presets automatically.
如果您想要自动解析这些预置,您必须查看ffmpeg源代码。
I hope that the information I just gave would help you out a bit more :)
我希望我刚才提供的信息能对你有所帮助。
#4
3
I encode YUV420P pictures into different formats, using different codecs. CodecID I took from AVOutputFormat after using guess_format(...) function. But other codec settings are (All of them has been taken from ffmpeg examples' source code):
我用不同的解码器将YUV420P图片编码成不同的格式。在使用了guess_format(…)函数后,我从AVOutputFormat获取了CodecID。但是其他的编解码设置是(它们都是从ffmpeg示例的源代码中获得的):
c->codec_id = (CodecID)CODEC_ID_H264; //This is your codec id
c->codec_type = CODEC_TYPE_VIDEO;
c->bit_rate = 1000000;
c->width = <...>;
c->height = <...>;
c->time_base.den = 25;
c->time_base.num = 1;
c->gop_size = 12;
c->pix_fmt = PIX_FMT_YUV420P;
if (c->codec_id == CODEC_ID_MPEG1VIDEO) //It not necessary for you
c->mb_decision=2;
// some formats want stream headers to be separate
if(oc->oformat->flags & AVFMT_GLOBALHEADER)
c->flags |= CODEC_FLAG_GLOBAL_HEADER;
This setting must work to most codecs, but I had a problem with fps: not all codecs supports any fps values (and some other parameters too).
这个设置必须适用于大多数编解码器,但是我对fps有一个问题:不是所有的编解码器都支持fps值(以及其他一些参数)。
#5
0
seems that the ffmpeg version 20130302 requires something like
似乎ffmpeg版本201302需要类似的东西
c->profile = FF_PROFILE_H264_BASELINE;