ffmpeginteropx / FFmpegInteropX

FFmpeg decoding library for Windows 10 UWP and WinUI 3 Apps
Apache License 2.0
210 stars 53 forks source link

Wrong aspect ratio #340

Closed lukasf closed 1 year ago

lukasf commented 1 year ago

I recently ran across a video file which shows with a wrong aspect ratio when using our lib. It is supposed to be 4:3, but we display it at 16:9. The pixel resolution truly is 4:3, but when we open the file, it reports sample_aspect_ratio 4:3. This means that it does not have square pixel but wide pixels (4:3). We correctly forward this, so the output gets stretched from 4:3 to 16:9 (4/3 * 4/3 = 16/9). The question is, why does this file report non-square pixels, when in fact the pixels must be shown as square 1:1 pixels. And why do other players show it correctly.

Interesting output from ffprobe:

Stream #0:0: Video: h264 (High), yuv420p(progressive), 1440x1080 [SAR 4:3 DAR 16:9], SAR 1:1 DAR 4:3, 23.98 fps, 23.98 tbr, 1k tbn, 47.95 tbc (default)

So it shows both [SAR 4:3 DAR 16:9] and SAR 1:1 DAR 4:3. Why are there two different sample aspect ratio and display aspect ratio values? Where can we get the "true" aspect ratio? We must forward SAR, otherwise a lot of other files will be incorrectly stretched. But we must forward the "right" SAR value, whatever that means. Currently, we use the first set, which results in wrong output. We must find the other set. But I have not found any other SAR on the codec context.

Sample file

brabebhin commented 1 year ago

I will take a look next week. If i understand correctly, the second set of metadata is the correct one?

I tried playing it with Firefox on android and it failed. It may be that not all players actually support it

brabebhin commented 1 year ago

I checked a few videos from various sources with ffprobe, and this sample is the only file that has 2 sets. All others just show something along the lines of this

yuv420p10le(tv), 3840x2160 [SAR 1:1 DAR 16:9] I am going to hazard a guess and we should use the 2nd pair every time it exists.

For this file specifically:

The sample aspect ratio in AVStream is {num=1 den=1 } However, the sample aspect ratio in avStream->codecpar->sample_aspect_ratio = {num=4 den=3 }

some other files I tried have matching values there. So I guess if values do not match, we should use the one from AVStream.

No idea how yet.

lukasf commented 1 year ago

Thanks for the hint, I did not see that AVStream has a SAR as well. I tested lots of non-square SAR files today and none of them had SAR on AVStream level. This is the only file that has it. And all players give AVStream SAR preference over codec SAR, so this is what we should do as well. I will make a PR for this.

brabebhin commented 1 year ago

Cool. I was going to hack something together but didn't have the time. Nice work.