FFmpeg - 使用 C-API 生成 x264 CBR 视频传输流

Zer*_*ect 6 ffmpeg libx264

使用散布在互联网上的各种帖子,包括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 输出

以上是 FFmpeg CLI 输出 - 视频比特率保持相当稳定。

在此处输入图片说明

以上是我的示例应用程序的输出 - 视频比特率的一些显着下降。

我更进一步,创建了一个git repo,其中包括:

  • 示例应用程序代码
  • 测试输入文件 (.mp4)
  • 测试的输出(.ts 文件)
  • 输出比特率图表。