Often, I've seen FFmpeg commands using the sameq
option, for example
ffmpeg -i input.mp4 -sameq output.avi
What does this mean? Does it mean "same quality"? If not, what should I use instead?
Often, I've seen FFmpeg commands using the sameq
option, for example
ffmpeg -i input.mp4 -sameq output.avi
What does this mean? Does it mean "same quality"? If not, what should I use instead?
sameq
does not mean "same quality"Several resources on the web promote the use of the sameq
or same_quant
option, but in essence, they're wrong. Using sameq
does not give you a result with the same quality as the input.
Do not use it, ever.
The source of the confusion was poorly written documentation that implied that using this option will provide the same quality. Fortunately, the option has been removed.
Here's what the FFmpeg documentation said:
Note that this is NOT SAME QUALITY. Do not use this option unless you know you need it.
In fact the FFmpeg developers had changed the name from sameq
to same_quant
just to make sure, and then removed sameq
/same_quant
altogether; meaning that this option does not exist in recent FFmpeg, but this article is still useful for those using older FFmpeg builds.
Now that we've cleared this up, let's go into some technical details.
To understand why it doesn't work reliably, we need to grasp the concept of what "quality" means for a common video encoder and what influences quality. Why does one video look better than the other when compressed with different bit rates? What makes a conversion lossy, and why is the video smaller than the original after encoding?
When you encode video, your input data is converted into a different dimension by first applying a mathematical transformation to blocks of pixels. This transformation, mostly a Discrete Cosine Transform, produces a matrix of numbers that describe, let's say, a field of 8×8 pixels in the video.
So, your 8×8 pixels and the corresponding matrix initially would look like this:^{1}
But this is too much data! If we want to compress video, we can actually get rid of the numbers towards the bottom right. I won't explain why this is exactly, but let's just say that the numbers in the top left are more important when describing such a block. The whole idea of the transformation basically is to put the important stuff top left.
To remove the numbers in the bottom right we can make them zeroes. If something is "nothing", or just repeating as 0
s, we won't have to store it, and that way we'll save space. Mathematically, we need to quantize this first matrix by applying another matrix, a "quantization matrix".
This will result in a matrix that now has considerably less numbers in it, and lots of zeroes:
The result of this is that we turned the first, high quality matrix with lots of numbers into a matrix that still resembles the same 8×8 pixels, but with less quality because it has less numbers to describe those pixels. If you compare the block visually, they're similar, but not quite the same anymore.
Here, the quantization matrix determines the quality. This is important. We can use different quantiization matrices for different quality. Some quantization matrices leave the original matrix almost intact, others don't. The more numbers we remove, the worse the quality will get, but the more we can compress the video, because we can basically "throw away" the zeroes here.
sameq
?Let's assume you encode a video and you want to set a certain quality. As we already learned, different quantization matrices lead to different quality, so when we tell our encoder to use quality x
, it will select the appropriate quantization matrix y
to get that quality, whatever it is. The result is a video that was compressed using the y
matrix.^{2}
And here's the interesting part: sameq
means "same quantizer". Not "same quality". If you have a non-recent version of FFmpeg, you can still find it in ffmpeg --help
:
ffmpeg --help 2>&1 | grep sameq
So, when you now take that converted video and encode it again, and you apply the sameq
option, FFmpeg will, simply speaking, select the same quantization matrices that were used for the input video.
This somewhat works when you use exactly the same codec for input and output, e.g. when converting from an XviD video to an XviD video, but you will still end up with worse quality.^{3} This is becaue encoding something that is already encoded will throw away even more information. In the example above, we'll create even more zeroes in our matrix and the result will look worse.
It does not work across different video codecs at all. Say you're converting an XviD-encoded video with x264.^{4} For these two codecs, the quantization matrices used internally are different — they don't have the same coefficients. So this option does not even make sense! Unfortunately, FFmpeg still allows you to use it.
Bottom line: Please don't use that option unless you specifically know what you're doing. If you want to encode your video with a different codec, but retain the quality, then you will have to experiment and just set the quality yourself. See if the result is satisfying, and if not, set a higher quality. That's about as much as you can do.
Finally, if you want to read up on how to keep your quality when re-encoding, check out these posts:
_{1) The matrix does not correspond to the image here, really. This is just an example.}
_{2) Actually, these days, most encoding processes don't just use one matrix. When you set a certain bit rate, the encoder will use different matrices to get an average bit rate per second. Similarly, when setting a certain quality, modern encoders employ different matrices depending on the content. This is because some contents are "easier" to compress than others and require less quantization to get the same compression factor.}
_{3) Example: ffmpeg -i input.avi -sameq -c:v libxvid output.avi. Do not use this. Please.}
_{4) Example: ffmpeg -i input.avi -sameq -c:v libx264 output.mp4. Do not use this either. I'm serious.}