6

Using various posts sprinkled around the Internet, including this one here on SO, I've been able to understand how to use the FFmpeg cli to generate a CBR video bitrate using the x264 codec (wrapped in an MPEG-2 transport stream). Note: I'm concerned with the video bitrate - nothing else.

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

However, I'm trying to approach this from an FFmpeg C-API point of view. I'm having issues. I've knocked together some code to try do something very similar to what is being done in the FFmpeg CLI. I can generate a transport stream of what I think should be CBR, but the profile of the video bitrate is very different from what I thought was the FFmpeg cli equivalent:

The initialisation of the AVCodecContext looks something like:

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

The output graphs appear very different:

FFmpeg CLI output

Above is the FFmpeg CLI output - video bitrate holds fairly steady.

enter image description here

Above is the output of my sample application - some significant dips in the video bitrate.

I've taken this a step further and created a git repo consisting of:

  • Code of sample application
  • Test input file (.mp4)
  • Outputs (.ts file) of tests
  • Graphs of output bitrates.
ZeroDefect
  • 663
  • 1
  • 8
  • 27

0 Answers0