Author Topic: AVCodecContext parameters for h264 encoding with CBR  (Read 7745 times)

Offline Otacon

  • Member
  • Posts: 4
    • View Profile
AVCodecContext parameters for h264 encoding with CBR
« on: December 12, 2010, 11:00:51 AM »
Hi everybody, this is my first message, I hope I'm in the right place to ask this question: which (and how) parameters of AVCodecContext should I set to obtain a h264 video with constant bit rate?

I'm writing a program that encode a h264 video using the FFmpeg API: I've started with libavformat/output-example.c and I've modified it to have a h264 video, with the following parameters (besides the ordinary ones), that are working fine for non-CBR mode (please note that if I remove any of these i get the famous "broken ffmpeg default settings detected" error):

AVCodecContext *c;
c->qcompress = 0.6;
c->qmin = 10;
c->qmax = 30;
c->max_qdiff = 4;
c->i_quant_factor = 0.71;

Then I've tried to change values of the above parameters as:
c->qcompress = 0.0;
c->qmin = 10;
c->qmax = 10;
c->max_qdiff = 0;
c->i_quant_factor = 0.01

AND to set many values of many combinations of these parameters:
crf, bit_rate, bit_rate_tolerance, rc_buffer_size, rc_max_rate, rc_min_rate, rc_max_available_vbv_use, rc_min_vbv_overflow_use

but I'm still unable to get a video with CBR: when I run my program, at the end of the processing, when libx264 prints the informations about the video, there's "kb/s:inf" and in the property of the file created there's "Bitrate: N/A".

I've tried many different combinations of settings with these parameters and now I really don't know what else to try, so I hope you can help me. Thanks in advance.

Offline Dark Shikari

  • x264 developer
  • Administrator
  • Member
  • *****
  • Posts: 650
    • View Profile
Re: AVCodecContext parameters for h264 encoding with CBR
« Reply #1 on: December 12, 2010, 01:36:30 PM »
1.  NEVER use libavcodec for encoding with libx264.  Use libx264 directly.

2.  The way to solve the "broken defaults" is not to cheese your way through the error message, but to fix the freaking defaults.  Your defaults are still broken, you've just tricked x264 into not noticing it.

3.  You're not passing valid timestamps is my guess.

Offline Otacon

  • Member
  • Posts: 4
    • View Profile
Re: AVCodecContext parameters for h264 encoding with CBR
« Reply #2 on: December 12, 2010, 06:04:38 PM »
Thanks for the answer. I have to admit that I'm not an expert programmer and a newbie in video encoding, I'm just a student and I'm working on a project for an university exam, so sorry if I may write something stupid.

1.  NEVER use libavcodec for encoding with libx264.  Use libx264 directly.

I'm afraid this is would mean re-write all the program from scratch. The principal purpose of my project is "do something to a video" with the OpenCV library and encode the modified-video in H264: when I discovered that OpenCV can't encode in H264 I made up this "workaround" through libavcodec (converting an IplImage to an AVFrame) and it is working fine, until they (who committed to me this project) came up with the "constant bit-rate" requirement. So, if there's a way to achieve CBR via libavcodec I would be very happy.

2.  The way to solve the "broken defaults" is not to cheese your way through the error message, but to fix the freaking defaults.  Your defaults are still broken, you've just tricked x264 into not noticing it.

As the error message suggests, I've used a preset (the main one), passing its values to AVCodecContext, then I naivly removed some parameters to get a "minimal set" of them that works, but even with the full main preset I've no idea how to get CBR.

3.  You're not passing valid timestamps is my guess.

I'm not sure this is what you mean, but among the "ordinary" parameters i've mentioned, I've set:
c->time_base.num = 1;
c->time_base.den = fps; // fps of the input video, obtained via OpenCV

Thanks again for your time and help.

Offline Dark Shikari

  • x264 developer
  • Administrator
  • Member
  • *****
  • Posts: 650
    • View Profile
Re: AVCodecContext parameters for h264 encoding with CBR
« Reply #3 on: December 13, 2010, 01:22:49 AM »
I'm afraid this is would mean re-write all the program from scratch.
Changing about 10 lines is a "rewrite from scratch"?  That's not a very large program then.

As the error message suggests, I've used a preset (the main one), passing its values to AVCodecContext, then I naivly removed some parameters to get a "minimal set" of them that works
Don't do that!

, but even with the full main preset I've no idea how to get CBR.
CBR is when maxrate == bitrate and a bufsize is set.  Have you tried reading the help?  The first freaking page has a CBR example on it. :-\

I'm not sure this is what you mean, but among the "ordinary" parameters i've mentioned, I've set:
c->time_base.num = 1;
c->time_base.den = fps; // fps of the input video, obtained via OpenCV
pts are timestamps.  There is one for each frame.  You aren't setting them.

Offline Otacon

  • Member
  • Posts: 4
    • View Profile
Re: AVCodecContext parameters for h264 encoding with CBR
« Reply #4 on: December 13, 2010, 02:37:58 AM »
Changing about 10 lines is a "rewrite from scratch"?  That's not a very large program then.
The part of code that uses libavcodec is about 250 lines, and I thought I should discard all of them. If it's not the case and I've to change just 10 lines among them it's very good to know, but sadly I really have no idea how to do it.

CBR is when maxrate == bitrate and a bufsize is set.

Since AVCodecContext has these parameters, I thought (and actually still hoping) there's a way to obtain CBR using them.

Have you tried reading the help?  The first freaking page has a CBR example on it. :-\

No, simply because I have to admit I havent been able to found any! I looked for it here, on videolan.org, on your site, on Google,
in my HD, I even tried x264 --longhelp on the console, without success.

pts are timestamps.  There is one for each frame.  You aren't setting them.

That make sense to all of the "non-strictly-monotonic PTS" warnings I get at runtime, but since the video works fine I just didn't care of them.

Anyway, I return to my first question: since the focus of my project should be OpenCV, and not h264 encoding, and I think i went enough crazy to have a h264 video, if there's a way to obtain CBR using libavcodec, even if it's not the right way to encode a h264 video, and you know it (and I think you do, since you're the x264 developer) PLEASE tell me. If it's the case, I'd consult you with a contract. Thanks again.

Offline nm

  • Member
  • Posts: 358
    • View Profile
Re: AVCodecContext parameters for h264 encoding with CBR
« Reply #5 on: December 13, 2010, 02:57:19 AM »
No, simply because I have to admit I havent been able to found any! I looked for it here, on videolan.org, on your site, on Google,
in my HD, I even tried x264 --longhelp on the console, without success.

It's there:

Quote
Example usage:
[...]
      Constant bitrate at 1000kbps with a 2 second-buffer:
            x264 --vbv-bufsize 2000 --bitrate 1000 -o <output> <input>


That make sense to all of the "non-strictly-monotonic PTS" warnings I get at runtime, but since the video works fine I just didn't care of them.

Anyway, I return to my first question: since the focus of my project should be OpenCV, and not h264 encoding, and I think i went enough crazy to have a h264 video, if there's a way to obtain CBR using libavcodec, even if it's not the right way to encode a h264 video, and you know it (and I think you do, since you're the x264 developer) PLEASE tell me. If it's the case, I'd consult you with a contract. Thanks again.

Dark Shikari said that your bitrate issue is probably caused by those missing timestamps (when other settings are correct). Fix that and see if it helps.
« Last Edit: December 13, 2010, 02:59:12 AM by nm »

Offline Otacon

  • Member
  • Posts: 4
    • View Profile
Re: AVCodecContext parameters for h264 encoding with CBR
« Reply #6 on: December 13, 2010, 03:40:08 AM »
It's there:
I saw it but I ignored it since I thought I had to find a C-language example.

Dark Shikari said that your bitrate issue is probably caused by those missing timestamps (when other settings are correct). Fix that and see if it helps.
I didn't get it, thanks for the hint, I'm trying to fix it.