[FFmpeg-user] Automatic Aspect Ratio Conversion
Dan Flett
dflett at bigpond.net.au
Tue Jul 26 06:51:39 CEST 2011
Hi all,
For a while I'd been wondering if ffmpeg could correctly aspect ratio
convert (ARC) a video to a specified width/height/Display Aspect Ratio(DAR),
without needing to know the width/height/Display Aspect Ratio of the source
file.
I wanted to have the choice of padding (pillar or letterboxing) or cropping
(centre cut). After reading the libavfilter documentation closely I found
the answer under my nose.
http://ffmpeg.org/libavfilter.html
There is an example under the "pad" section:
# pad the input to get a final w/h ratio of 16:9
pad="ih*16/9:ih:(ow-iw)/2:(oh-ih)/2"
This example assumes that the input is thinner/taller than 16:9 - if the
input video is wider/shorter than 16:9 it will fail with error - because the
input width will be wider than ih*16/9 and pad doesn't allow an output width
thinner than the input video.
Another example is:
# pad the input to get a squared output with size equal to the maximum
# value between the input width and height, and put the input video at
# the center of the padded area
pad="max(iw\,ih):ow:(ow-iw)/2:(oh-ih)/2"
This gives an output that is always padded square, regardless of the input
video dimensions.
To get the best of both examples (output 16:9 but works with any input
dimensions) I did this:
"pad=max(iw\,ih*(16/9)):ow/(16/9):(ow-iw)/2:(oh-ih)/2" -aspect 16:9
This example selects the maximum of either the input width as-is, or the
input height * 16/9. The output height is the output width * 16/9.
This gives an output that is always 16:9, padding either the sides or
top/bottom, as appropriate. The video is always centred.
However I found that if the input video is anamorphic (i.e. non-square
pixel), the output is also anamorphic, and the DAR / SAR information is
lost.
To fix this, I did this:
"scale=iw*sar:ih , pad=max(iw\,ih*(16/9)):ow/(16/9):(ow-iw)/2:(oh-ih)/2"
-aspect 16:9
This scales the input width to make the pixels square. This means that
subsequent padding/cropping/scaling operations are done on square-pixel
video frames.
To crop the input video to 16:9 instead of padding, I do this:
"scale=iw*sar:ih , crop=min(iw\,ih*(16/9)):ow/(16/9)" -aspect 16:9
This chops off the sides or top/bottom, as appropriate to get a 16/9 output.
Dan
More information about the ffmpeg-user
mailing list