saneSAR bounds each SAR component to 256, which catches the pathological values (the 1088:1 the comment mentions) but still admits small-but-wrong ratios that stretch the picture into an unwatchable strip.
Observed on a live 1080p H.264 IPTV channel that declared SAR 3:1, then 2:1 on a later run — both well inside the existing gate. 3:1 applied to 1920x1080 yields a 5.33:1 display aspect; 2:1 yields 3.55:1. The picture renders as a horizontally smeared band. The user-visible workaround is switching the aspect mode to Fill, which is a real tell that the ratio itself is wrong rather than the content being unusual.
The magnitude gate can't distinguish these, because the problem isn't the size of the numbers — it's the aspect they produce.
What we do locally
Bound the resulting display aspect rather than the component magnitudes, in the same helper:
static func saneSAR(_ sar: AVRational) -> AVRational? {
guard sar.num > 0, sar.den > 0, sar.num <= 256, sar.den <= 256 else { return nil }
// Reject an implausibly extreme pixel aspect (e.g. a bogus 3:1 that stretches 1920x1080 into a
// 5760x1080 strip). No real PAR stretches a frame more than ~2.5x on either axis.
let ratio = Double(sar.num) / Double(sar.den)
guard ratio <= 2.5, ratio >= 1.0 / 2.5 else { return nil }
return sar
}
Rejecting returns nil, which falls back to square pixels — for a stream lying about its SAR that is the correct picture, and for a stream telling the truth it's never reached, since no legitimate PAR is that extreme.
On the threshold
2.5 is a judgement call and I'd expect you to want a different one. The widest genuine PARs in circulation are the anamorphic DVD/broadcast set — 16:11 (~1.45), 12:11, 64:45, and the 4:3-into-16:9 cases around 1.8 — so 2.5 leaves a lot of headroom above anything real while still rejecting the 3:1 above. Verified on our side that legitimate anamorphic content is unaffected: a 720x576 PAL source at 16:11 still resolves to ~16:9 and renders correctly.
This refines the gate you added in #177 rather than replacing it — both checks are useful, they just catch different failures. Raising as an issue rather than a PR since the bound is a policy choice; happy to send it either way.
This issue was auto-generated by Claude on behalf of @kskchaitanya1993.
saneSARbounds each SAR component to 256, which catches the pathological values (the1088:1the comment mentions) but still admits small-but-wrong ratios that stretch the picture into an unwatchable strip.Observed on a live 1080p H.264 IPTV channel that declared SAR
3:1, then2:1on a later run — both well inside the existing gate.3:1applied to 1920x1080 yields a 5.33:1 display aspect;2:1yields 3.55:1. The picture renders as a horizontally smeared band. The user-visible workaround is switching the aspect mode to Fill, which is a real tell that the ratio itself is wrong rather than the content being unusual.The magnitude gate can't distinguish these, because the problem isn't the size of the numbers — it's the aspect they produce.
What we do locally
Bound the resulting display aspect rather than the component magnitudes, in the same helper:
Rejecting returns
nil, which falls back to square pixels — for a stream lying about its SAR that is the correct picture, and for a stream telling the truth it's never reached, since no legitimate PAR is that extreme.On the threshold
2.5 is a judgement call and I'd expect you to want a different one. The widest genuine PARs in circulation are the anamorphic DVD/broadcast set — 16:11 (~1.45), 12:11, 64:45, and the 4:3-into-16:9 cases around 1.8 — so 2.5 leaves a lot of headroom above anything real while still rejecting the 3:1 above. Verified on our side that legitimate anamorphic content is unaffected: a 720x576 PAL source at 16:11 still resolves to ~16:9 and renders correctly.
This refines the gate you added in #177 rather than replacing it — both checks are useful, they just catch different failures. Raising as an issue rather than a PR since the bound is a policy choice; happy to send it either way.
This issue was auto-generated by Claude on behalf of @kskchaitanya1993.