50 .MatchSyncWord = [](
const uint8_t* data) ->
bool {
51 constexpr uint32_t MPEG_AUDIO_SYNC_WORD = 0xFF'E000;
52 constexpr uint32_t MPEG_AUDIO_VERSION_FORBIDDEN_VALUE = 0x00'0800;
53 constexpr uint32_t MPEG_AUDIO_LAYER_DESCRIPTION_FORBIDDEN_VALUE = 0x00'0000;
54 constexpr uint32_t MPEG_AUDIO_BITRATE_INDEX_FORBIDDEN_VALUE = 0x00'00F0;
57 return (syncWord & 0b1111'1111'1110'0000'0000'0000) == MPEG_AUDIO_SYNC_WORD &&
58 (syncWord & 0b0000'0000'0001'1000'0000'0000) != MPEG_AUDIO_VERSION_FORBIDDEN_VALUE &&
59 (syncWord & 0b0000'0000'0000'0110'0000'0000) != MPEG_AUDIO_LAYER_DESCRIPTION_FORBIDDEN_VALUE &&
60 (syncWord & 0b0000'0000'0000'0000'1111'0000) != MPEG_AUDIO_BITRATE_INDEX_FORBIDDEN_VALUE;
62 .GetFrameSize = [](
const uint8_t* data) ->
int {
63 constexpr uint16_t BitRateTable[2][4][16] = {
66 {0, 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448, 0},
67 {0, 32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384, 0},
68 {0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 0}},
71 {0, 32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256, 0},
72 {0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, 0},
73 {0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, 0}
76 constexpr uint16_t SampleRateTable[4] = {44100, 48000, 32000, 0};
78 int mpeg2 = !(data[1] & 0x08) && (data[1] & 0x10);
79 int mpeg25 = !(data[1] & 0x08) && !(data[1] & 0x10);
80 int layer = 4 - ((data[1] >> 1) & 0x03);
81 int bitRateIndex = (data[2] >> 4) & 0x0F;
82 int sampleRateIndex = (data[2] >> 2) & 0x03;
83 int padding = (data[2] >> 1) & 0x01;
85 int sampleRate = SampleRateTable[sampleRateIndex];
87 throw std::invalid_argument(
"MPEG: invalid sample rate");
90 sampleRate >>= mpeg25;
92 int bitRate = BitRateTable[mpeg2 | mpeg25][layer][bitRateIndex];
94 throw std::invalid_argument(
"MPEG: invalid bit rate");
100 frameSize = (12 * bitRate) / sampleRate;
101 frameSize = (frameSize + padding) * 4;
106 frameSize = (144 * bitRate) / sampleRate;
107 frameSize = frameSize + padding;
113 {AV_CODEC_ID_AAC_LATM, {
115 .MatchSyncWord = [](
const uint8_t* data) ->
bool {
116 constexpr uint32_t LAOS_SYNC_WORD_MASK = 0xFFE000;
117 constexpr uint32_t LAOS_SYNC_WORD = 0x2B7 << (24-11);
120 return (syncWord & LAOS_SYNC_WORD_MASK) == LAOS_SYNC_WORD;
122 .GetFrameSize = [](
const uint8_t* data) ->
int {
123 return ((data[1] & 0x1F) << 8) + data[2] + 3;
128 .MatchSyncWord = [](
const uint8_t* data) ->
bool {
129 constexpr uint32_t AC3_SYNC_WORD_MASK = 0xFFFF00;
130 constexpr uint32_t AC3_SYNC_WORD = 0x0B77 << (24-16);
133 return (syncWord & AC3_SYNC_WORD_MASK) == AC3_SYNC_WORD &&
134 data[5] <= (10 << 3);
136 .GetFrameSize = [](
const uint8_t* data) ->
int {
137 constexpr uint16_t Ac3FrameSizeTable[38][3] = {
138 {64, 69, 96}, {64, 70, 96}, {80, 87, 120}, {80, 88, 120},
139 {96, 104, 144}, {96, 105, 144}, {112, 121, 168}, {112, 122, 168},
140 {128, 139, 192}, {128, 140, 192}, {160, 174, 240}, {160, 175, 240},
141 {192, 208, 288}, {192, 209, 288}, {224, 243, 336}, {224, 244, 336},
142 {256, 278, 384}, {256, 279, 384}, {320, 348, 480}, {320, 349, 480},
143 {384, 417, 576}, {384, 418, 576}, {448, 487, 672}, {448, 488, 672},
144 {512, 557, 768}, {512, 558, 768}, {640, 696, 960}, {640, 697, 960},
145 {768, 835, 1152}, {768, 836, 1152}, {896, 975, 1344}, {896, 976, 1344},
146 {1024, 1114, 1536}, {1024, 1115, 1536}, {1152, 1253, 1728},
147 {1152, 1254, 1728}, {1280, 1393, 1920}, {1280, 1394, 1920},
150 int fscod = data[4] >> 6;
152 throw std::invalid_argument(
"AC3: invalid sample rate");
154 int frmsizcod = data[4] & 0x3F;
156 throw std::invalid_argument(
"AC3: invalid frame size");
158 return Ac3FrameSizeTable[frmsizcod][fscod] * 2;
163 .MatchSyncWord = [](
const uint8_t* data) ->
bool {
164 constexpr uint32_t AC3_SYNC_WORD = 0x0B77 << (24-16);
167 return (syncWord & 0xFFFF00) == AC3_SYNC_WORD && data[5] > (10 << 3);
169 .GetFrameSize = [](
const uint8_t* data) ->
int {
170 if ((data[4] & 0xF0) == 0xF0)
171 throw std::invalid_argument(
"AC3: invalid fscod fscod2");
173 return (((data[2] & 0x07) << 8) + data[3] + 1) * 2;
178 .MatchSyncWord = [](
const uint8_t* data) ->
bool {
179 constexpr uint32_t ADTS_SYNC_WORD = 0xFFF000;
180 constexpr uint32_t ADTS_LAYER = 0x000000;
181 constexpr uint32_t ADTS_SAMPLING_FREQUENCY_FORBIDDEN_VALUE = 15 << 6;
184 return (syncWord & 0b1111'1111'1111'0000'0000'0000) == ADTS_SYNC_WORD &&
185 (syncWord & 0b0000'0000'0000'0110'0000'0000) == ADTS_LAYER &&
186 (syncWord & 0b0000'0000'0000'0011'1100'0000) != ADTS_SAMPLING_FREQUENCY_FORBIDDEN_VALUE;
188 .GetFrameSize = [](
const uint8_t* data) ->
int {
189 return ((data[3] & 0x03) << 11) | ((data[4] & 0xFF) << 3) | ((data[5] & 0xE0) >> 5);