6.30.0 - A ratio that never reached the picture
Drop-in from 6.29.0. Two additive properties, which is why this is a minor rather than a patch, and no breaking changes. Both came in as one contributed PR, and measuring what a host would do with the first of them turned up the defect underneath it.
A square ratio is not a declaration
Anamorphic video declares its pixel aspect in one of two places, and only one of them reaches codecpar. Matroska writes its DisplayWidth quotient and MP4 its pasp box to AVStream (matroskadec.c, mov.c); the bitstream's own ratio, where it has one, arrives in codecpar. The engine preferred codecpar wherever it was set, and a bitstream that says 1:1 counted as set.
So a file whose H.264 VUI says square pixels and whose container header says 64:45, which is exactly what mkvmerge --aspect-ratio leaves behind, resolved to square and stopped one axis above the answer. av_guess_sample_aspect_ratio returns 64:45 for the same file, which is why ffprobe, VLC and mpv all disagreed with this engine about it.
Two fixtures cut from one 720x576 source make the split visible. They differ in nothing but where the ratio sits:
ffmpeg -f lavfi -i testsrc2=size=720x576:rate=25 -t 10 -c:v libx264 -vf setsar=64/45 a_vui.mkv
ffmpeg -f lavfi -i testsrc2=size=720x576:rate=25 -t 10 -c:v libx264 -vf setsar=1 sq.mkv
ffmpeg -i sq.mkv -c copy -aspect 1024:576 b_container.mkv| fixture | software display size | loopback pasp |
thumbnail |
|---|---|---|---|
| ratio in the VUI | 1024x576 | 64:45 | 320x180 |
| ratio in the container | 720x576 | 1:1 | 320x256 |
The second row is a squeezed picture, not a missing number: every one of the three consumers drew the source at its coded shape. On the native path the mechanism is one field. mov_write_pasp_tag reads track->par->sample_aspect_ratio, the muxer fills that codecpar with avcodec_parameters_copy from the source, and a container-declared ratio is never in the source's codecpar to be copied. The software path and the still extractor lost it to the same square-counts-as-declared rule, one axis earlier.
The declared ratio is resolved once now, in PixelAspectPolicy, and all three take that answer:
- The container wins where it declares a real correction. It is the later authoring layer, a remuxer that sets it deliberately leaves the bitstream alone, and it is what every ffmpeg-based player resolves to.
- A square candidate no longer ends the search on any axis.
niland1:1attach the same nothing, but only one of them lets the axes below it be read. - The loopback muxer writes the resolved ratio into the codecpar it owns, so the served
paspcarries what the decoders attach, and a ratio the #290 display-aspect gate refuses (a live channel claiming 3:1 on 1080p) is no longer one AVPlayer stretches to.
Both fixtures now present at 1024x576 on every path, and the same shape in an MP4 carrying pasp behaves identically. The [SWDecoder] SAR latched line names the axis it came from, so the case reads as frame=1:1 ctx=1:1 stream=64:45 rather than as silence.
The usual encode carries its ratio in the bitstream and was always correct, which is why this survived: only a file whose ratio a remuxer wrote into the header afterwards was affected.
The two properties
player.sourceVideoWidth // coded
player.sourceVideoPixelAspectRatio // * this = presented width
track.isNativelyRenderedSubtitle // the backend draws it; subtitleCues stays emptysourceVideoPixelAspectRatio is a number for laying out an overlay before there is a layer to measure. It reads through the same policy, so it is 1 on square pixels and 1 on a declared ratio the engine refuses, and it agrees with the pasp the item carries. Where a picture is already on screen, that picture remains the better source: softwareDisplaySize on the software path, AVPlayerLayer.videoRect on the native one.
isNativelyRenderedSubtitle marks the tracks whose cues never arrive because AVFoundation renders them itself, which is every subtitle rendition on the remote-HLS path. A host offering overlay position, delay or styling for those was offering controls that cannot act.
Contributed by Rasmusmart57 (#385), who had been carrying both as local patches across updates.
Not claimed
The measurements above are macOS, on synthetic fixtures built to carry the ratio in one place each, plus one MP4 with a real pasp. Whether a specific anamorphic library now presents at the corrected width on a device is the reporter's retest, and it is still open.