commit adc30c93d80374a2670fd6b3fa086bba9c0aaca2
parent e4d5b2294c324f34022e2727b932e551997c3fd0
Author: Alastor Wu <alwu@mozilla.com>
Date: Fri, 17 Oct 2025 18:28:12 +0000
Bug 1967475 - part3 : treat certain Recovery Point SEI frames as IDR frames r=media-playback-reviewers,jolin
There are two attributes, `recovery_frame_cnt` and `exact_match_flag`, that can
be used to determine whether a Recovery Point SEI can be treated as an IDR frame.
When `recovery_frame_cnt = 0` and `exact_match_flag = 1`, it means that after
zero frames, the decoded frame will be identical to decoding from an IDR frame.
If only one condition is met, it can still be used as an IDR substitute, but may
cause minor visual artifacts depending on the decoder implementation.
In practice, not all video streams set these attributes correctly. Instead of
failing to play such streams, it is preferable to allow playback even with minor
visual imperfections.
Differential Revision: https://phabricator.services.mozilla.com/D268214
Diffstat:
1 file changed, 10 insertions(+), 1 deletion(-)
diff --git a/dom/media/platforms/agnostic/bytestreams/H264.cpp b/dom/media/platforms/agnostic/bytestreams/H264.cpp
@@ -965,7 +965,16 @@ uint32_t H264::ComputeMaxRefFrames(const mozilla::MediaByteBuffer* aExtraData) {
RefPtr<mozilla::MediaByteBuffer> decodedNAL = DecodeNALUnit(p, nalLen);
SEIRecoveryData data;
if (DecodeRecoverySEI(decodedNAL, data)) {
- return FrameType::I_FRAME_OTHER;
+ // When both conditions are true, it means that starting decoding from
+ // an SEI frame will produce the same result as starting from an IDR
+ // frame, with no frame difference. If only one condition is true, it is
+ // not a true IDR substitute and may cause minor visual artifacts.
+ // However, since some video streams are incorrectly muxed without
+ // proper attributes, allowing playback with a few visual imperfections
+ // is preferable to failing to play them at all.
+ return (data.recovery_frame_cnt == 0 || data.exact_match_flag == 0)
+ ? FrameType::I_FRAME_IDR
+ : FrameType::I_FRAME_OTHER;
}
} else if (nalType == H264_NAL_SLICE) {
RefPtr<mozilla::MediaByteBuffer> decodedNAL = DecodeNALUnit(p, nalLen);