symphonia_bundle_mp3/
header.rs

1// Symphonia
2// Copyright (c) 2019-2022 The Project Symphonia Developers.
3//
4// This Source Code Form is subject to the terms of the Mozilla Public
5// License, v. 2.0. If a copy of the MPL was not distributed with this
6// file, You can obtain one at https://mozilla.org/MPL/2.0/.
7
8use symphonia_core::errors::{decode_error, unsupported_error, Result};
9use symphonia_core::io::ReadBytes;
10
11use crate::common::*;
12
13/// The length in bytes of a MPEG frame header word.
14pub const MPEG_HEADER_LEN: usize = 4;
15
16/// The maximum length in bytes of a MPEG audio frame including the header.
17pub const MAX_MPEG_FRAME_SIZE: u64 = 2881;
18
19/// Bit-rate lookup table for MPEG version 1 layer 1.
20const BIT_RATES_MPEG1_L1: [u32; 15] = [
21    0, 32_000, 64_000, 96_000, 128_000, 160_000, 192_000, 224_000, 256_000, 288_000, 320_000,
22    352_000, 384_000, 416_000, 448_000,
23];
24
25/// Bit-rate lookup table for MPEG version 1 layer 2.
26const BIT_RATES_MPEG1_L2: [u32; 15] = [
27    0, 32_000, 48_000, 56_000, 64_000, 80_000, 96_000, 112_000, 128_000, 160_000, 192_000, 224_000,
28    256_000, 320_000, 384_000,
29];
30
31/// Bit-rate lookup table for MPEG version 1 layer 3.
32const BIT_RATES_MPEG1_L3: [u32; 15] = [
33    0, 32_000, 40_000, 48_000, 56_000, 64_000, 80_000, 96_000, 112_000, 128_000, 160_000, 192_000,
34    224_000, 256_000, 320_000,
35];
36
37/// Bit-rate lookup table for MPEG version 2 & 2.5 audio layer 1.
38const BIT_RATES_MPEG2_L1: [u32; 15] = [
39    0, 32_000, 48_000, 56_000, 64_000, 80_000, 96_000, 112_000, 128_000, 144_000, 160_000, 176_000,
40    192_000, 224_000, 256_000,
41];
42
43/// Bit-rate lookup table for MPEG version 2 & 2.5 audio layers 2 & 3.
44const BIT_RATES_MPEG2_L23: [u32; 15] = [
45    0, 8_000, 16_000, 24_000, 32_000, 40_000, 48_000, 56_000, 64_000, 80_000, 96_000, 112_000,
46    128_000, 144_000, 160_000,
47];
48
49/// Quickly check if a header sync word may be valid.
50#[inline]
51pub fn check_header(header: u32) -> bool {
52    // Version (0x1 is not allowed).
53    if (header >> 19) & 0x3 == 0x1 {
54        return false;
55    }
56    // Layer (0x0 is not allowed).
57    if (header >> 17) & 0x3 == 0x0 {
58        return false;
59    }
60    // Bitrate (0xf is not allowed).
61    if (header >> 12) & 0xf == 0xf {
62        return false;
63    }
64    // Sample rate (0x3 is not allowed).
65    if (header >> 10) & 0x3 == 0x3 {
66        return false;
67    }
68    true
69}
70
71/// Returns true if the provided frame header word is synced.
72#[inline(always)]
73pub fn is_frame_header_word_synced(sync: u32) -> bool {
74    (sync & 0xffe0_0000) == 0xffe0_0000
75}
76
77/// Synchronize the provided reader to the end of the frame header, and return the frame header as
78/// as `u32`.
79pub fn sync_frame<B: ReadBytes>(reader: &mut B) -> Result<u32> {
80    let mut sync = 0u32;
81
82    loop {
83        // Synchronize stream to the next frame using the sync word. The MPEG audio frame header
84        // always starts at a byte boundary with 0xffe (11 consecutive 1 bits.) if supporting up to
85        // MPEG version 2.5.
86        while !is_frame_header_word_synced(sync) {
87            sync = (sync << 8) | u32::from(reader.read_u8()?);
88        }
89
90        // Random data can look like a sync word. Do a quick check to increase confidence that
91        // this is may be the start of a frame.
92        if check_header(sync) {
93            break;
94        }
95
96        sync = (sync << 8) | u32::from(reader.read_u8()?);
97    }
98
99    Ok(sync)
100}
101
102pub fn parse_frame_header(header: u32) -> Result<FrameHeader> {
103    // The MPEG audio header is structured as follows:
104    //
105    // 0b1111_1111 0b111v_vlly 0brrrr_hhpx 0bmmmm_coee
106    // where:
107    //     vv   = version, ll = layer      , y = crc
108    //     rrrr = bitrate, hh = sample rate, p = padding , x  = private bit
109    //     mmmm = mode   , c  = copyright  , o = original, ee = emphasis
110
111    let version = match (header & 0x18_0000) >> 19 {
112        0b00 => MpegVersion::Mpeg2p5,
113        0b10 => MpegVersion::Mpeg2,
114        0b11 => MpegVersion::Mpeg1,
115        _ => return decode_error("mpa: invalid MPEG version"),
116    };
117
118    let layer = match (header & 0x6_0000) >> 17 {
119        0b01 => MpegLayer::Layer3,
120        0b10 => MpegLayer::Layer2,
121        0b11 => MpegLayer::Layer1,
122        _ => return decode_error("mpa: invalid MPEG layer"),
123    };
124
125    let bitrate = match ((header & 0xf000) >> 12, version, layer) {
126        // "Free" bit-rate. Note, this is NOT variable bit-rate and is not a mandatory feature of
127        // MP3 decoders.
128        (0b0000, _, _) => return unsupported_error("mpa: free bit-rate is not supported"),
129        // Invalid bit-rate.
130        (0b1111, _, _) => return decode_error("mpa: invalid bit-rate"),
131        // MPEG 1 bit-rates.
132        (i, MpegVersion::Mpeg1, MpegLayer::Layer1) => BIT_RATES_MPEG1_L1[i as usize],
133        (i, MpegVersion::Mpeg1, MpegLayer::Layer2) => BIT_RATES_MPEG1_L2[i as usize],
134        (i, MpegVersion::Mpeg1, MpegLayer::Layer3) => BIT_RATES_MPEG1_L3[i as usize],
135        // MPEG 2 bit-rates.
136        (i, _, MpegLayer::Layer1) => BIT_RATES_MPEG2_L1[i as usize],
137        (i, _, _) => BIT_RATES_MPEG2_L23[i as usize],
138    };
139
140    let (sample_rate, sample_rate_idx) = match ((header & 0xc00) >> 10, version) {
141        (0b00, MpegVersion::Mpeg1) => (44_100, 0),
142        (0b01, MpegVersion::Mpeg1) => (48_000, 1),
143        (0b10, MpegVersion::Mpeg1) => (32_000, 2),
144        (0b00, MpegVersion::Mpeg2) => (22_050, 3),
145        (0b01, MpegVersion::Mpeg2) => (24_000, 4),
146        (0b10, MpegVersion::Mpeg2) => (16_000, 5),
147        (0b00, MpegVersion::Mpeg2p5) => (11_025, 6),
148        (0b01, MpegVersion::Mpeg2p5) => (12_000, 7),
149        (0b10, MpegVersion::Mpeg2p5) => (8_000, 8),
150        _ => return decode_error("mpa: invalid sample rate"),
151    };
152
153    let channel_mode = match ((header & 0xc0) >> 6, layer) {
154        // Stereo, for layers 1, 2, and 3.
155        (0b00, _) => ChannelMode::Stereo,
156        // Dual mono, for layers 1, 2, and 3.
157        (0b10, _) => ChannelMode::DualMono,
158        // Mono, for layers 1, 2, and 3.
159        (0b11, _) => ChannelMode::Mono,
160        // Joint stereo mode for layer 3 supports a combination of Mid-Side and Intensity Stereo
161        // depending on the mode extension bits.
162        (0b01, MpegLayer::Layer3) => ChannelMode::JointStereo(Mode::Layer3 {
163            mid_side: header & 0x20 != 0x0,
164            intensity: header & 0x10 != 0x0,
165        }),
166        // Joint stereo mode for layers 1 and 2 only supports Intensity Stereo. The mode extension
167        // bits indicate for which sub-bands intensity stereo coding is applied.
168        (0b01, _) => {
169            ChannelMode::JointStereo(Mode::Intensity { bound: (1 + ((header & 0x30) >> 4)) << 2 })
170        }
171        _ => unreachable!(),
172    };
173
174    // Some layer 2 channel and bit-rate combinations are not allowed. Check that the frame does not
175    // use them.
176    if layer == MpegLayer::Layer2 {
177        if channel_mode == ChannelMode::Mono {
178            if bitrate == 224_000 || bitrate == 256_000 || bitrate == 320_000 || bitrate == 384_000
179            {
180                return decode_error("mpa: invalid Layer 2 bitrate for mono channel mode");
181            }
182        }
183        else if bitrate == 32_000 || bitrate == 48_000 || bitrate == 56_000 || bitrate == 80_000 {
184            return decode_error("mpa: invalid Layer 2 bitrate for non-mono channel mode");
185        }
186    }
187
188    let emphasis = match header & 0x3 {
189        0b01 => Emphasis::Fifty15,
190        0b11 => Emphasis::CcitJ17,
191        _ => Emphasis::None,
192    };
193
194    let is_copyrighted = header & 0x8 != 0x0;
195    let is_original = header & 0x4 != 0x0;
196    let has_padding = header & 0x200 != 0;
197
198    let has_crc = header & 0x1_0000 == 0;
199
200    // Constants provided for size calculation in section ISO-11172 section 2.4.3.1.
201    let factor = match layer {
202        MpegLayer::Layer1 => 12,
203        MpegLayer::Layer2 => 144,
204        MpegLayer::Layer3 if version == MpegVersion::Mpeg1 => 144,
205        MpegLayer::Layer3 => 72,
206    };
207
208    // The header specifies the total frame size in "slots". For layers 2 & 3 a slot is 1 byte,
209    // however for layer 1 a slot is 4 bytes.
210    let slot_size = match layer {
211        MpegLayer::Layer1 => 4,
212        _ => 1,
213    };
214
215    // Calculate the total frame size in number of slots.
216    let frame_size_slots = (factor * bitrate / sample_rate) as usize + usize::from(has_padding);
217
218    // Calculate the frame size in bytes, excluding the header.
219    let frame_size = (frame_size_slots * slot_size) - 4;
220
221    Ok(FrameHeader {
222        version,
223        layer,
224        bitrate,
225        sample_rate,
226        sample_rate_idx,
227        channel_mode,
228        emphasis,
229        is_copyrighted,
230        is_original,
231        has_padding,
232        has_crc,
233        frame_size,
234    })
235}
236
237/// Synchronize the stream to the start of the next MPEG audio frame header, then read and return
238/// the frame header or an error.
239#[inline]
240#[allow(dead_code)]
241pub fn read_frame_header<B: ReadBytes>(reader: &mut B) -> Result<FrameHeader> {
242    // Synchronize and parse the frame header.
243    parse_frame_header(sync_frame(reader)?)
244}
245
246/// Read a MPEG audio frame header word from the current location in the stream without any frame
247/// synchronization.
248#[inline]
249pub fn read_frame_header_word_no_sync<B: ReadBytes>(reader: &mut B) -> Result<u32> {
250    Ok(reader.read_be_u32()?)
251}