mux/codec/mpegaudio: keep free-format frames

Free-format MPEG-audio (bitrate_index 0) is a legal, decodable mode — the
decoder derives the frame size from the sync spacing. Dropping it was a
false positive on a clean stream, so it now passes the gate.
This commit is contained in:
Matthew Jackson
2026-07-19 14:23:04 -07:00
parent b2bd5f8b3e
commit 2ccb5c9d01
+11 -9
View File
@@ -46,11 +46,10 @@ fn mpa_verdict(data: &[u8]) -> MpaVerdict {
{ {
return MpaVerdict::Invalid; return MpaVerdict::Invalid;
} }
// Free format (bitrate_index == 0): ff_mpa_decode_header returns 1, which the // NOTE: bitrate_index == 0 (free format) is NOT rejected. It is a legal,
// framing wrapper treats as failure. Reject for consistency. // decodable MPEG-audio mode (ffmpeg's ff_mpa_check_header accepts it and the
if (h >> 12) & 0xf == 0 { // decoder derives the frame size from the sync spacing). Dropping it would be
return MpaVerdict::Invalid; // a false positive on a clean stream, so it passes the gate.
}
MpaVerdict::Valid MpaVerdict::Valid
} }
@@ -188,12 +187,15 @@ mod tests {
} }
#[test] #[test]
fn free_format_bitrate_zero_is_dropped() { fn free_format_bitrate_zero_is_kept() {
// Free format (bitrate_index == 0) is legal and decodable — it must NOT
// be dropped (that would be a false positive on a clean stream).
let mut p = MpegAudioParser::new(); let mut p = MpegAudioParser::new();
let mut frame = mp3_frame(400); let mut frame = mp3_frame(400);
frame[2] = 0x00; // bitrate_index = 0000 (free format) frame[2] = 0x00; // bitrate_index = 0000 (free format); sync/layer/rate ok
assert!(p.parse(&make_pes(frame, Some(0))).is_empty()); let f = p.parse(&make_pes(frame, Some(0)));
assert_eq!(p.dropped_frames(), 1); assert_eq!(f.len(), 1, "free-format frame kept");
assert_eq!(p.dropped_frames(), 0);
} }
#[test] #[test]