FFMPEG CBR (Constant Bit Rate mode) with maintain video quality

15,023

Solution 1

I'm the author of the blog post you linked.

You should not use nal-hrd cbr with mp4 because the avcc format used in MP4 doesn't support filler data.

No filler data. Video data is naturally represented as variable bit rate in the file format and should be filled for transmission if needed. Filler Data NAL units and Filler Data SEI messages shall not be present in the file format stored stream.

(ISO/IEC 14496-15 - Carriage of network abstraction layer (NAL) unit structured video in the ISO base media file format)

As you can see in my example the output is MPEG-TS which uses Annex B. nal-hrd also requires setting vbv-bufsize.

Solution 2

Increase the bitrate.

In the source file, even though the average bitrate is the same, there will be more bits allocated to complex scenes and fewer to simpler ones. By forcing a constant bitrate of the same value as the average bitrate of the source, the encoder will wastefully use bits for the simpler scenes, but more importantly, apply greater compression to the complex scenes to keep to the CBR ceiling.

Roughly, your CBR value should be near the peak bitrate of the source video to maintain source quality (not accounting for the inevitable degradation due to lossy recompression).

Also, -preset veryfast makes x264 not as optimal in achieving the best quality for a given bitrate, so increase the bitrate even more, or drop the preset.

Finally, command syntax is

ffmpeg -i in -c:v libx264 -x264-params "nal-hrd=cbr" -b:v <sourceBitrate> -bufsize <1.5*sourceBitrate> out.mp4

x264 will assume maxrate is same as b:v.

Solution 3

you should change your video format to "mpegts" and set "-muxrate" parameter to bitrate that you want . for example ffmpeg -i in.mp4 -f mpegts -muxrate 4000K -y out.mp4 also for checking it you can use MediaInfo

MediaInfo

or use from VLC

enter image description here

Share:
15,023
HarisH Sharma
Author by

HarisH Sharma

I am a PHP developer, worked on MYSql, postgresql database, Also have knowledge of HTML, CSS, Javascript, JQuery, AngularJs, Worked on different libraries related to above mentioned technologies like JQuery UI, Highchart, Fabricjs, AWS Services, FlowJs, EvaporateJs, DocuSign, Paypal etc.

Updated on June 05, 2022

Comments

  • HarisH Sharma
    HarisH Sharma almost 2 years

    I want to convert videos in mp4 with FFMPEG, while maintain source video's bitrate (CBR mode) and quality,

    I tried some commands found here:

    https://trac.ffmpeg.org/wiki/Encode/H.264#CBRConstantBitRate

    https://superuser.com/questions/314354/ffmpeg-constant-bitrate

    https://brokenpipe.wordpress.com/2016/10/07/ffmpeg-h-264-constant-bitrate-cbr-encoding-for-iptv/

    By above links I achieved Constant Bitrate using -minrate, -maxrate and some other params,

    ffmpeg -i <source> -b <sourceBitrate> -minrate <sourceBitrate> -maxrate <sourceBitrate> 2> log.txt output.mp4

    ffmpeg -i <source> -c:v libx264 -x264-params "nal-hrd=cbr" -b:v <sourceBitrate> -minrate <sourceBitrate> -maxrate <sourceBitrate> 2> log.txt output.mp4

    ffmpeg -i <source> -c:a libmp3lame -vcodec h264 -preset veryfast -f mp4 -crf 18 "nal-hrd=cbr" -b:v <sourceBitrate> -minrate <sourceBitrate> -maxrate <sourceBitrate> 2> log.txt output.mp4

    But converted video's quality not same as source. I want to keep quality same as source. How can I achieve this?

    Am I doing something wrong?

    Thank You...

  • HarisH Sharma
    HarisH Sharma over 6 years
    Thank you @Mulvya for answer, I tried using your command, but still video quality is compromised, Please check video here, https://drive.google.com/open?id=1fQ5arAqTVMserMsH_vDs9cq47k‌​jbukR7
  • HarisH Sharma
    HarisH Sharma over 6 years
  • Gyan
    Gyan over 6 years
    What bitrate values did you try?
  • HarisH Sharma
    HarisH Sharma over 6 years
    I tried using command u suggest, please check ffmpeg -i source.mp4 -c:v libx264 -x264-params "nal-hrd=cbr" -b:v 298k -bufsize 447k out1.mp4
  • Gyan
    Gyan over 6 years
    You have to increase the bitrate!
  • HarisH Sharma
    HarisH Sharma over 6 years
    Ok, but in my existing solution user can upload any video any time, after successful upload I convert it to mp4, Can I make it automated? So that system will decide bitrate itself depend on video,
  • HarisH Sharma
    HarisH Sharma over 6 years
  • aergistal
    aergistal over 6 years
    @Mulvya Why use a bufsize of 1.5x the source bitrate? For near-CBR with x264 you must cap every frame.
  • Gyan
    Gyan over 6 years
    The OP hasn't outlined end use-case, so I assumed tol != 0, some deviation is OK. On the now rare occasion I did CBR for file output, larger bufsize would help for better I-frames.
  • aergistal
    aergistal over 6 years
    @Mulvya you can't use nal-hrd with mp4 as it enables filler which is not supported in avcc. You should change your answer to .ts otherwise it doesn't make sense.
  • Gyan
    Gyan over 6 years
    Oh, forgot about that. Corrected.
  • Gyan
    Gyan over 6 years
    @aergistal - not in spec - but filler NALs don't appear to be filtered out by the MP4 muxer.
  • aergistal
    aergistal over 6 years
    @Mulvya x264 doesn't let you do it with GPAC and L-SMASH. But since ffmpeg forwards the option directly it's quite possible... I still don't see how it's useful for file output and with such a large VBV size though, I only used it for satellite streams.
  • Gyan
    Gyan over 6 years
    I don't see the point of CBR for file output nowadays, but if we are going for fixed frame sizes, but isn't CRF + intra refresh better?
  • Gyan
    Gyan over 6 years
    I would suggest cannot --> should not, given ffmpeg's behaviour.
  • aergistal
    aergistal over 6 years