58

I have a video stream with the following properties:

Stream #0:0: Video: mpeg4 (Advanced Simple Profile) (XVID / 0x44495658), yuv420p, 720x416 [SAR 1:1 DAR 45:26], 1908 kb/s, 25 fps, 25 tbr, 25 tbn, 25 tbc

When I run it in VLC, I have to press "A" to change aspect ratio to "4:3" to make the video show with the correct aspect ratio.

Looking at the video facts, Is the error that a) the actual video has been incorrectly stretched in the pixel data, or b) there is simply some metadata value that has been incorrectly set?

If the former, I know I can re-encode the video and change the width and height. But if the latter, what ffmpeg command to I run to fix the metadata without re-encoding the video itself?

6 Answers 6

90

There is a difference between Sample Aspect Ratio (SAR) and Display Aspect Ratio (DAR). If you want to change the video to display at 4:3, you will either need to change the actual pixels in the image (by scaling the pixels and changing SAR), or by setting a metadata flag that at the container level that tells external media players to stretch the image to your desired DAR.

You will not be able to scale the pixels and change SAR without applying a video filter. If you choose this method, you will be required to transcode the file - since you cannot "stream copy" the video stream while applying a video filter.

To scale the image and change SAR (while transcoding), try:

ffmpeg -i <INPUT_FILE> -vf scale=720:540 -c:v <Video_Codec> <OUTPUT_FILE>

On the other hand, if you just want to change the metadata flag and adjust the DAR, you will be able to stream copy the video. To do this, try:

ffmpeg -i <INPUT_FILE> -aspect 720:540 -c copy [OUTPUT_FILE]
11
  • 1
    Excellent! Changing the aspect worked straight away!
    – forthrin
    Commented Apr 30, 2015 at 18:04
  • 9
    You can't use -c copy and scale at the same time; however you can use -aspect to change the aspect ratio at the container level (but not the stream level).
    – llogan
    Commented Apr 30, 2015 at 18:56
  • 1
    As was stated above, you can't just copy the stream and expect it to work (everywhere), you're going to have to re-encode, e.g.: ffmpeg -strict -2 -i [INPUT] -aspect 720:540 -strict -2 [OUTPUT]. I added -strict -2 (note that's -2, not just 2) to get ffmpeg to stop complaining about the aac audio in the original. This re-encoded a square source into an output at 4:3. Commented May 20, 2017 at 10:47
  • 3
    @MikhailV - for MPEG-2, -aspect is useless; you need to use -bsf:v mpeg2_metadata=display_aspect_ratio=4/3 (the only valid values are 4/3, 16/9, 221/100). Even this might not work, due to Sequence Display Extension metadata in the stream, in which case you'd have to set the aspect ratio there too, perhaps by demuxing and processing with ReStream.
    – Mike Brown
    Commented Jul 5, 2020 at 3:04
  • 2
    What are the disadvantages to setting the aspect ratio at the container's metadata level? Are there any reasons it would be less reliable than doing it "properly" at the stream level? Commented Oct 19, 2021 at 21:53
14

Changing the SAR without reencoding also works with ffmpeg on .mp4 using the h264_metadata as Gyan pointed out here:

ffmpeg -i in.mp4 -c copy -bsf:v "h264_metadata=sample_aspect_ratio=4/3" out.mp4
2
  • Works great, and on .flv too, but you need a reasonably recent version of ffmpeg. The version 3.4.6 included in Linux Mint 19.3 / Ubuntu 18.04 still lacks the h264_metadata bitstream filter, I had to install 4.1.4 from a PPA. Commented May 3, 2020 at 10:50
  • 1
    Note that 4/3 will likely not be the SAR value entered to correct a source to 4:3 (unless the source is square). One will need to calculate the amount of correction and enter that instead. For example, to correct from 5:4 to 4:3, the SAR value would be 16/15 (that is, a pixel needs to be wider by 16/15). ---- Also, it appears to me that using -aspect 4:3 in addition to -bsf works best (at least, in terms of metadata reported by ffprobe [and at least one edge case, VirtualDub2, likes it better -- VLC and other players I tested don't seem to care if -aspect is corrected or not]).
    – juanitogan
    Commented May 10, 2022 at 22:12
6

Delgado's answer is correct that MP4Box can do this, but the -par option doesn't work quite as described. With an -out parameter (so as not to disturb your original file):

mp4box source.mp4 -out target.mp4 -par stream-number=width:height

When you use -par stream-number=width:height, you define the pixel aspect ratio – that is, the result of dividing the device aspect ratio by the storage aspect ratio. (Equivalently, you're describing the aspect ratio of a source pixel.) For example, suppose you have a DVD source that's 720×480, and the correct display aspect ratio is 4:3. For this case, you need:

mp4box source.mp4 -out target.mp4 -par 1=8:9

because (4/3) / (720/480) = 8/9.

If the source represents true SD NTSC pixels (in which case only the central 704×480 pixels are supposed to map to a 4×3 screen, with 8 pixels overscan on either side), the correct command would be:

mp4box source.mp4 -out target.mp4 -par 1=10:11

because (4/3) / (704/480) = 10/11 – exactly the reference pixel aspect ratio for standard definition NTSC video.

For the case given in the question, if it's really 4:3, that gives a very odd pixel aspect ratio: (4/3)/(720/416) = 104/135. It's 720 wide, which suggests a DVD source; it's a 25 fps video, suggesting PAL, but the PAR works out to less than 1, suggesting NTSC. It could be 4:5, I suppose (very close to 104:135), but I don't know of anything that produces that pixel aspect ratio; maybe try that first, and then try 3:4 if it still looks a little too stretched horizontally. If you're certain it's exactly 4:3, of course, just use 104:135.

3

ffmpeg can't change parameters of a video stream without re-encoding (edit: or let's say does it in a strange way by adding a 2nd pair of SAR/DAR, instead of overwriting them), MP4Box (part of gpac) and mkvmerge can. In case of one (edit: 16:9 stretched) video stream and a real/correct aspect ratio of 4:3, you may want to try:

MP4Box -par 1=3:4 VideoFile.mp4

    "-par" : PixelAspectRatio (adjusts DAR + SAR with respect to the video resolution)
    "1"=   : stream number
    "3:4"  : aspect ratio (lower number 1st!) (edit: 16:9 * 3:4 = 4:3)
    Changes are directly applied to "VideoFile.mp4", no copy

To verify before and after: ffmpeg -i VideoFile.mp4

5
  • The first statement is incorrect. ffmpeg can do this with the -c copy option, as described in @occvtech's previous answer. Commented May 1, 2020 at 16:12
  • You are wrong. Read occvtech's answer again, and have in mind: ffmpeg in conjunction with -c copy works on container level, not on stream level (container is the thing that combines an audio stream and a video stream to a single file and may contain meta information). The downside on not fixing the video stream's aspect ratio is that the created container file has both aspect ratios inside and it depends on the player software, which is selected for play back (see working/not working comments above).
    – Delgado
    Commented May 2, 2020 at 19:42
  • I can personally witness that ffmpeg is able to fix the stream level as well as the container level. You are right, though, that @occvtech's answer alone is insufficient. You have to factor in @drake7's answer using -bsf:v h264_metadata. Perhaps a combined answer would be appropriate. Note that you need a reasonably recent version of ffmpeg for that. The version included in Linux Mint 19.3 is too old and lacks the h264_metadata bitstream filter. I had to use a PPA. Commented May 3, 2020 at 10:42
  • Interesting. I did test runs on debian 10 and its ffmpeg (4.1.4-1): Without the -aspect switch, it conserved the original aspect ratio - regardless of other options (copy / bitstream / video filters). Using -c copy -aspect 4:3 produced a warning: "Overriding aspect ratio with stream copy may produce invalid files", and adds a 2nd pair of SAR/DAR. That confuses me and some software player. I prefer single nailed SAR/DAR values. If this works for you, great. ffmpeg produces a file that works for most cases. Doubtless.
    – Delgado
    Commented May 6, 2020 at 19:18
  • 1
    Re: "2nd pair" ... The first pair of SAR/DAR you'll note is in square brackets and comes from the video stream. The second pair is not in square brackets and comes from the container. Use -aspect to set the DAR in the container and -bsf:v h264_metadata=sample_aspect_ratio=x/y to set the SAR in the video stream.
    – Mike Brown
    Commented Jul 5, 2020 at 2:59
2

Use this command line for changing the resolution and display aspect ratio.

ffmpeg -i "input file" -vf scale=$w:$h -aspect $w:$h "output file"

or

ffmpeg -i "input file" -vf -vf scale=$w:$h -aspect x:y "output file"

$w - resolution width
$h - resolution height
x - aspect ratio width
y - aspect ratio height

Notes:

  • If you put -aspect x:y without -vf scale=$w:$h, the output will only have the change on display aspect ratio.

  • If you put -vf scale=$w:$h without -aspect x:y, the output will only have the change on the resolution.

  • The command -vf scale=$w:-1 or scale=-1:$h will not always provide the expected output so to make sure you get both change on resolution and aspect ratio, you can just use the above command line.

** I only tried this with input.mkv and output.mkv files since this is only what I am working on at the moment. Feel free to try this with the other file types.

1
  • Unless I'm mistaken, this re-encodes the video.
    – Sawtaytoes
    Commented May 13, 2023 at 7:40
0

ffmpeg 4.3.2 -bsf:v h264_metadata=sample_aspect_ratio=x/y gives an error on DNxHR coded Quicktime files while MP4Box writes a second line of PAR into the metadata.

Width : 720 pixels Height : 540 pixels Display aspect ratio : 16:9 Original display aspect ratio : 4:3

I tested multiple players and even an NLE and so far all display the correct aspect ratio.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .