使用散布在互联网上的各种帖子,包括SO 上的这个帖子,我已经能够理解如何使用 FFmpeg cli 使用 x264 编解码器(包装在 MPEG-2 传输流中)生成 CBR 视频比特率。注意:我关心的是视频比特率——没有别的。
ffmpeg -i cbr_test_file_input.mp4 -c:v libx264 -pix_fmt yuv420p -b:v 6000000 -preset fast -tune film -g 25 -x264-params vbv-maxrate=6000:vbv-bufsize=6000:force-cfr=1:nal-hrd=cbr -flags +ildct+ilme x264_cbr_test_output.ts
Run Code Online (Sandbox Code Playgroud)
但是,我试图从 FFmpeg C-API 的角度来解决这个问题。我有问题。我已经拼凑了一些代码来尝试做一些与 FFmpeg CLI 中所做的非常相似的事情。我可以生成一个我认为应该是 CBR的传输流,但是视频比特率的配置文件与我认为的 FFmpeg cli 等效文件非常不同:
AVCodecContext 的初始化看起来像:
av_dict_set(&pDict, "preset", "faster", 0);
av_dict_set(&pDict, "tune", "film", 0);
av_dict_set_int(&pDict, "rc-lookahead", 25, 0);
pCdcCtxOut->width = pCdcCtxIn->width;
pCdcCtxOut->height = pCdcCtxIn->height;
pCdcCtxOut->pix_fmt = AV_PIX_FMT_YUV420P;
pCdcCtxOut->gop_size = 25;
// Going for 6Mbit/s
pCdcCtxOut->bit_rate = 6000000;
//pCdcCtxOut->rc_min_rate = pCdcCtxOut->bit_rate;
pCdcCtxOut->rc_max_rate = pCdcCtxOut->bit_rate;
pCdcCtxOut->rc_buffer_size = pCdcCtxOut->bit_rate;
pCdcCtxOut->rc_initial_buffer_occupancy = static_cast<int>((pCdcCtxOut->bit_rate * 9) / 10);
std::string strParams = "vbv-maxrate="
+ std::to_string(pCdcCtxOut->bit_rate / 1000)
+ ":vbv-bufsize="
+ std::to_string(pCdcCtxOut->bit_rate / 1000)
+ ":force-cfr=1:nal-hrd=cbr";
av_dict_set(&pDict, "x264-params", strParams.c_str(), 0);
pCdcCtxOut->field_order = AV_FIELD_TT;
pCdcCtxOut->flags = (AV_CODEC_FLAG_INTERLACED_DCT | AV_CODEC_FLAG_INTERLACED_ME | AV_CODEC_FLAG_CLOSED_GOP);
// WARN: Make some assumptions here!
pCdcCtxOut->time_base = AVRational{1,25};
pCdcCtxOut->framerate = AVRational{25,1};
pCdcCtxOut->sample_aspect_ratio = AVRational{64,45};
Run Code Online (Sandbox Code Playgroud)
输出图看起来非常不同:
以上是 FFmpeg CLI 输出 - 视频比特率保持相当稳定。
以上是我的示例应用程序的输出 - 视频比特率的一些显着下降。
我更进一步,创建了一个git repo,其中包括:
| 归档时间: |
|
| 查看次数: |
460 次 |
| 最近记录: |