Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I am trying to compress videos of 10 seconds at different bitrates with ffmpeg. My aim is to obtain the same video at different qualities (from very low to very high). I don't want to touch audio part and I am using H264 as a video codec. I am using the following CLI:

ffmpeg -i input.mkv -c:v libx264 -b:v $j'k' -c:a copy output.mkv

Where $j vary from 150 to 4000.

My problem is that I get 10s videos compressed but the quality is not constant at all through the time. Here is an example: With a very low bitrate ($j = 150), at the beginning (between 0 and 3s), the video is really poor but at the end (between 8 and 10s), the quality is proper! Besides, while watching the video, one can see this increasing of quality through the time. Can someone explain me this phenomenon? How to get a constant quality?

Thanks'

share|improve this question
1  
See the FFmpeg and x264 Encoding Guide and CRF Guide. – LordNeckbeard Jul 5 '13 at 1:52
    
Thank you for advice. – MarAja Jul 9 '13 at 7:55
    
Please note this question below (I just posted it): I think I have found a problem in the Linux version where it overdoes the bitrate in the first...get this...THREE SECONDS of the video. superuser.com/questions/963424/… – Mark Gerolimatos Aug 27 '15 at 5:55
up vote 2 down vote accepted

As @LordNeckbeard already points out, constant bitrate is not the same as constant quality. In fact, it's quite the opposite. Certain parts of video sequences are easier to encode than others (easier in the sense of requiring less bits), and others are not. If you spend all your bits on the easy parts, you're going to lack them for the harder parts.

That's where constant quality comes into play. In x264 there is the Constant Rate Factor, which does exactly that. I suggest you read the linked article if you want more background info. Basically, the CRF ranges from 0 (lossless, best) to 51 (worst). Steps of ±6 roughly egal double or half the bitrate.

So, to adapt your script, simply do something like the following:

for i in $(seq 0 5 51); do 
  ffmpeg -i input.mkv -c:v libx264 -crf $i -c:a copy output-$i.mkv
done

The scale itself is—unless I'm mistaken—close to logarithmic in terms of quality, so you can calculate your steps based on that instead of the seq call.


With a very low bitrate ($j = 150), at the beginning (between 0 and 3s), the video is really poor but at the end (between 8 and 10s), the quality is proper! Besides, while watching the video, one can see this increasing of quality through the time. Can someone explain me this phenomenon?

Doing constant bit rate is not an easy task for an encoder. You give it a certain value to work with, e.g. tell it "give me 150 kBit per second", but the encoder does not even know what it's going to encode at the next frame.

So, how much should it spend on this frame? How much on the next? Some frames—like I mentioned above—are easy to encode and just take a few kilobits, while others may take much more. But the encoder can really only look at what it's encoded in the past in order to scale for future pictures. Also take into account the different picture types.

Algorithmically, doing constant bitrate is really hard, and it's also the worst of the rate control modes x264 has to offer. Especially for short clips, since the encoder won't know what it can expect without doing a 2-pass encoding, you might notice this in the way you describe: the quality drastically changes throughout the ten seconds. But 150 kBit/s is really not enough for video of somewhat decent dimensions anyway.

share|improve this answer
    
Thank you for this detailled answer! It was exactly what I was expecting for. – MarAja Jul 9 '13 at 7:53

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.