FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavcodec/aac/aacdec_latm.h
Date: 2026-09-28 11:37:26
Exec Total Coverage
Lines: 102 165 61.8%
Functions: 6 7 85.7%
Branches: 56 109 51.4%

Line Branch Exec Source
1 /*
2 * AAC decoder
3 * Copyright (c) 2005-2006 Oded Shimon ( ods15 ods15 dyndns org )
4 * Copyright (c) 2006-2007 Maxim Gavrilov ( maxim.gavrilov gmail com )
5 * Copyright (c) 2008-2013 Alex Converse <alex.converse@gmail.com>
6 *
7 * AAC LATM decoder
8 * Copyright (c) 2008-2010 Paul Kendall <paul@kcbbs.gen.nz>
9 * Copyright (c) 2010 Janne Grunau <janne-libav@jannau.net>
10 *
11 * AAC decoder fixed-point implementation
12 * Copyright (c) 2013
13 * MIPS Technologies, Inc., California.
14 *
15 * This file is part of FFmpeg.
16 *
17 * FFmpeg is free software; you can redistribute it and/or
18 * modify it under the terms of the GNU Lesser General Public
19 * License as published by the Free Software Foundation; either
20 * version 2.1 of the License, or (at your option) any later version.
21 *
22 * FFmpeg is distributed in the hope that it will be useful,
23 * but WITHOUT ANY WARRANTY; without even the implied warranty of
24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
25 * Lesser General Public License for more details.
26 *
27 * You should have received a copy of the GNU Lesser General Public
28 * License along with FFmpeg; if not, write to the Free Software
29 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
30 */
31
32 #ifndef AVCODEC_AAC_AACDEC_LATM_H
33 #define AVCODEC_AAC_AACDEC_LATM_H
34
35 #define LOAS_SYNC_WORD 0x2b7 ///< 11 bits LOAS sync word
36
37 struct LATMContext {
38 AACDecContext aac_ctx; ///< containing AACContext
39 int initialized; ///< initialized after a valid extradata was seen
40
41 // parser data
42 int audio_mux_version_A; ///< LATM syntax version
43 int frame_length_type; ///< 0/1 variable/fixed frame length
44 int frame_length; ///< frame length for fixed frame length
45 };
46
47 ✗ static inline uint32_t latm_get_value(GetBitContext *b)
48 {
49 ✗ int length = get_bits(b, 2);
50
51 ✗ return get_bits_long(b, (length+1)*8);
52 }
53
54 324 static int latm_decode_audio_specific_config(struct LATMContext *latmctx,
55 GetBitContext *gb, int asclen)
56 {
57 324 AACDecContext *ac = &latmctx->aac_ctx;
58 324 AVCodecContext *avctx = ac->avctx;
59 324 OutputConfiguration oc = { 0 };
60 324 MPEG4AudioConfig *m4ac = &oc.m4ac;
61 GetBitContext gbc;
62 324 int config_start_bit = get_bits_count(gb);
63 324 int sync_extension = 0;
64 int bits_consumed, esize, i;
65
66
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 324 times.
324 if (asclen > 0) {
67 ✗ sync_extension = 1;
68 ✗ asclen = FFMIN(asclen, get_bits_left(gb));
69 ✗ init_get_bits(&gbc, gb->buffer, config_start_bit + asclen);
70 ✗ skip_bits_long(&gbc, config_start_bit);
71
1/2
✓ Branch 0 taken 324 times.
✗ Branch 1 not taken.
324 } else if (asclen == 0) {
72 324 gbc = *gb;
73 } else {
74 ✗ return AVERROR_INVALIDDATA;
75 }
76
77
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 324 times.
324 if (get_bits_left(gb) <= 0)
78 ✗ return AVERROR_INVALIDDATA;
79
80 324 bits_consumed = decode_audio_specific_config_gb(NULL, avctx, &oc,
81 &gbc, config_start_bit,
82 sync_extension);
83
84
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 324 times.
324 if (bits_consumed < config_start_bit)
85 ✗ return AVERROR_INVALIDDATA;
86 324 bits_consumed -= config_start_bit;
87
88
1/2
✓ Branch 0 taken 324 times.
✗ Branch 1 not taken.
324 if (asclen == 0)
89 324 asclen = bits_consumed;
90
91
2/2
✓ Branch 0 taken 316 times.
✓ Branch 1 taken 8 times.
324 if (!latmctx->initialized ||
92
1/2
✓ Branch 0 taken 316 times.
✗ Branch 1 not taken.
316 ac->oc[1].m4ac.sample_rate != m4ac->sample_rate ||
93
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 315 times.
316 ac->oc[1].m4ac.chan_config != m4ac->chan_config) {
94
95
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 8 times.
9 if (latmctx->initialized) {
96 1 av_log(avctx, AV_LOG_INFO, "audio config changed (sample_rate=%d, chan_config=%d)\n",
97 m4ac->sample_rate, m4ac->chan_config);
98 } else {
99 8 av_log(avctx, AV_LOG_DEBUG, "initializing latmctx\n");
100 }
101 9 latmctx->initialized = 0;
102
103 9 esize = (asclen + 7) / 8;
104
105
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 1 times.
9 if (avctx->extradata_size < esize) {
106 8 av_free(avctx->extradata);
107 8 avctx->extradata = av_malloc(esize + AV_INPUT_BUFFER_PADDING_SIZE);
108
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
8 if (!avctx->extradata)
109 ✗ return AVERROR(ENOMEM);
110 }
111
112 9 avctx->extradata_size = esize;
113 9 gbc = *gb;
114
2/2
✓ Branch 0 taken 25 times.
✓ Branch 1 taken 9 times.
34 for (i = 0; i < esize; i++) {
115 25 avctx->extradata[i] = get_bits(&gbc, 8);
116 }
117 9 memset(avctx->extradata+esize, 0, AV_INPUT_BUFFER_PADDING_SIZE);
118 }
119 324 skip_bits_long(gb, asclen);
120
121 324 return 0;
122 }
123
124 324 static int read_stream_mux_config(struct LATMContext *latmctx,
125 GetBitContext *gb)
126 {
127 324 int ret, audio_mux_version = get_bits(gb, 1);
128
129 324 latmctx->audio_mux_version_A = 0;
130
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 324 times.
324 if (audio_mux_version)
131 ✗ latmctx->audio_mux_version_A = get_bits(gb, 1);
132
133
1/2
✓ Branch 0 taken 324 times.
✗ Branch 1 not taken.
324 if (!latmctx->audio_mux_version_A) {
134
135
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 324 times.
324 if (audio_mux_version)
136 ✗ latm_get_value(gb); // taraFullness
137
138 324 skip_bits(gb, 1); // allStreamSameTimeFraming
139 324 skip_bits(gb, 6); // numSubFrames
140 // numPrograms
141
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 324 times.
324 if (get_bits(gb, 4)) { // numPrograms
142 ✗ avpriv_request_sample(latmctx->aac_ctx.avctx, "Multiple programs");
143 ✗ return AVERROR_PATCHWELCOME;
144 }
145
146 // for each program (which there is only one in DVB)
147
148 // for each layer (which there is only one in DVB)
149
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 324 times.
324 if (get_bits(gb, 3)) { // numLayer
150 ✗ avpriv_request_sample(latmctx->aac_ctx.avctx, "Multiple layers");
151 ✗ return AVERROR_PATCHWELCOME;
152 }
153
154 // for all but first stream: use_same_config = get_bits(gb, 1);
155
1/2
✓ Branch 0 taken 324 times.
✗ Branch 1 not taken.
324 if (!audio_mux_version) {
156
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 324 times.
324 if ((ret = latm_decode_audio_specific_config(latmctx, gb, 0)) < 0)
157 ✗ return ret;
158 } else {
159 ✗ int ascLen = latm_get_value(gb);
160 ✗ if ((ret = latm_decode_audio_specific_config(latmctx, gb, ascLen)) < 0)
161 ✗ return ret;
162 }
163
164 324 latmctx->frame_length_type = get_bits(gb, 3);
165
1/5
✓ Branch 0 taken 324 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
324 switch (latmctx->frame_length_type) {
166 324 case 0:
167 324 skip_bits(gb, 8); // latmBufferFullness
168 324 break;
169 ✗ case 1:
170 ✗ latmctx->frame_length = get_bits(gb, 9);
171 ✗ break;
172 ✗ case 3:
173 case 4:
174 case 5:
175 ✗ skip_bits(gb, 6); // CELP frame length table index
176 ✗ break;
177 ✗ case 6:
178 case 7:
179 ✗ skip_bits(gb, 1); // HVXC frame length table index
180 ✗ break;
181 }
182
183
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 324 times.
324 if (get_bits(gb, 1)) { // other data
184 ✗ if (audio_mux_version) {
185 ✗ latm_get_value(gb); // other_data_bits
186 } else {
187 int esc;
188 do {
189 ✗ if (get_bits_left(gb) < 9)
190 ✗ return AVERROR_INVALIDDATA;
191 ✗ esc = get_bits(gb, 1);
192 ✗ skip_bits(gb, 8);
193 ✗ } while (esc);
194 }
195 }
196
197
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 324 times.
324 if (get_bits(gb, 1)) // crc present
198 ✗ skip_bits(gb, 8); // config_crc
199 }
200
201 324 return 0;
202 }
203
204 517 static int read_payload_length_info(struct LATMContext *ctx, GetBitContext *gb)
205 {
206 uint8_t tmp;
207
208
1/2
✓ Branch 0 taken 517 times.
✗ Branch 1 not taken.
517 if (ctx->frame_length_type == 0) {
209 517 int mux_slot_length = 0;
210 do {
211
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1510 times.
1510 if (get_bits_left(gb) < 8)
212 ✗ return AVERROR_INVALIDDATA;
213 1510 tmp = get_bits(gb, 8);
214 1510 mux_slot_length += tmp;
215
2/2
✓ Branch 0 taken 993 times.
✓ Branch 1 taken 517 times.
1510 } while (tmp == 255);
216 517 return mux_slot_length;
217 ✗ } else if (ctx->frame_length_type == 1) {
218 ✗ return ctx->frame_length;
219 ✗ } else if (ctx->frame_length_type == 3 ||
220 ✗ ctx->frame_length_type == 5 ||
221 ✗ ctx->frame_length_type == 7) {
222 ✗ skip_bits(gb, 2); // mux_slot_length_coded
223 }
224 ✗ return 0;
225 }
226
227 527 static int read_audio_mux_element(struct LATMContext *latmctx,
228 GetBitContext *gb)
229 {
230 int err;
231 527 uint8_t use_same_mux = get_bits(gb, 1);
232
2/2
✓ Branch 0 taken 324 times.
✓ Branch 1 taken 203 times.
527 if (!use_same_mux) {
233
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 324 times.
324 if ((err = read_stream_mux_config(latmctx, gb)) < 0)
234 ✗ return err;
235
2/2
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 193 times.
203 } else if (!latmctx->aac_ctx.avctx->extradata) {
236 10 av_log(latmctx->aac_ctx.avctx, AV_LOG_DEBUG,
237 "no decoder config found\n");
238 10 return 1;
239 }
240
1/2
✓ Branch 0 taken 517 times.
✗ Branch 1 not taken.
517 if (latmctx->audio_mux_version_A == 0) {
241 517 int mux_slot_length_bytes = read_payload_length_info(latmctx, gb);
242
2/4
✓ Branch 0 taken 517 times.
✗ Branch 1 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 517 times.
517 if (mux_slot_length_bytes < 0 || mux_slot_length_bytes * 8LL > get_bits_left(gb)) {
243 ✗ av_log(latmctx->aac_ctx.avctx, AV_LOG_ERROR, "incomplete frame\n");
244 ✗ return AVERROR_INVALIDDATA;
245
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 517 times.
517 } else if (mux_slot_length_bytes * 8 + 256 < get_bits_left(gb)) {
246 ✗ av_log(latmctx->aac_ctx.avctx, AV_LOG_ERROR,
247 "frame length mismatch %d << %d\n",
248 mux_slot_length_bytes * 8, get_bits_left(gb));
249 ✗ return AVERROR_INVALIDDATA;
250 }
251 }
252 517 return 0;
253 }
254
255
256 529 static int latm_decode_frame(AVCodecContext *avctx, AVFrame *out,
257 int *got_frame_ptr, AVPacket *avpkt)
258 {
259 529 struct LATMContext *latmctx = avctx->priv_data;
260 int muxlength, err;
261 GetBitContext gb;
262
263
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 529 times.
529 if ((err = init_get_bits8(&gb, avpkt->data, avpkt->size)) < 0)
264 ✗ return err;
265
266 // check for LOAS sync word
267
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 529 times.
529 if (get_bits(&gb, 11) != LOAS_SYNC_WORD)
268 ✗ return AVERROR_INVALIDDATA;
269
270 529 muxlength = get_bits(&gb, 13) + 3;
271 // not enough data, the parser should have sorted this out
272
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 527 times.
529 if (muxlength > avpkt->size)
273 2 return AVERROR_INVALIDDATA;
274
275
2/2
✓ Branch 1 taken 10 times.
✓ Branch 2 taken 517 times.
527 if ((err = read_audio_mux_element(latmctx, &gb)))
276
1/2
✓ Branch 0 taken 10 times.
✗ Branch 1 not taken.
10 return (err < 0) ? err : avpkt->size;
277
278
2/2
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 508 times.
517 if (!latmctx->initialized) {
279
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 9 times.
9 if (!avctx->extradata) {
280 ✗ *got_frame_ptr = 0;
281 ✗ return avpkt->size;
282 } else {
283 9 push_output_configuration(&latmctx->aac_ctx);
284
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 9 times.
9 if ((err = decode_audio_specific_config(
285 &latmctx->aac_ctx, avctx, &latmctx->aac_ctx.oc[1],
286 9 avctx->extradata, avctx->extradata_size*8LL, 1)) < 0) {
287 ✗ pop_output_configuration(&latmctx->aac_ctx);
288 ✗ return err;
289 }
290 9 latmctx->initialized = 1;
291 }
292 }
293
294
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 517 times.
517 if (show_bits(&gb, 12) == 0xfff) {
295 ✗ av_log(latmctx->aac_ctx.avctx, AV_LOG_ERROR,
296 "ADTS header detected, probably as result of configuration "
297 "misparsing\n");
298 ✗ return AVERROR_INVALIDDATA;
299 }
300
301
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 517 times.
517 switch (latmctx->aac_ctx.oc[1].m4ac.object_type) {
302 ✗ case AOT_ER_AAC_LC:
303 case AOT_ER_AAC_LTP:
304 case AOT_ER_AAC_LD:
305 case AOT_ER_AAC_ELD:
306 ✗ err = aac_decode_er_frame(avctx, out, got_frame_ptr, &gb);
307 ✗ break;
308 517 default:
309 517 err = aac_decode_frame_int(avctx, out, got_frame_ptr, &gb, avpkt);
310 }
311
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 517 times.
517 if (err < 0)
312 ✗ return err;
313
314 517 return muxlength;
315 }
316
317 15 static av_cold int latm_decode_init(AVCodecContext *avctx)
318 {
319 15 struct LATMContext *latmctx = avctx->priv_data;
320 15 int ret = ff_aac_decode_init_float(avctx);
321
322
2/2
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 8 times.
15 if (avctx->extradata_size > 0)
323 7 latmctx->initialized = !ret;
324
325 15 return ret;
326 }
327
328 /*
329 Note: This decoder filter is intended to decode LATM streams transferred
330 in MPEG transport streams which only contain one program.
331 To do a more complex LATM demuxing a separate LATM demuxer should be used.
332 */
333 const FFCodec ff_aac_latm_decoder = {
334 .p.name = "aac_latm",
335 CODEC_LONG_NAME("AAC LATM (Advanced Audio Coding LATM syntax)"),
336 .p.type = AVMEDIA_TYPE_AUDIO,
337 .p.id = AV_CODEC_ID_AAC_LATM,
338 .priv_data_size = sizeof(struct LATMContext),
339 .init = latm_decode_init,
340 .close = decode_close,
341 FF_CODEC_DECODE_CB(latm_decode_frame),
342 CODEC_SAMPLEFMTS(AV_SAMPLE_FMT_FLTP),
343 .p.capabilities = AV_CODEC_CAP_CHANNEL_CONF | AV_CODEC_CAP_DR1,
344 .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
345 CODEC_CH_LAYOUTS_ARRAY(ff_aac_ch_layout),
346 .flush = flush,
347 .p.profiles = NULL_IF_CONFIG_SMALL(ff_aac_profiles),
348 };
349
350 #endif /* AVCODEC_AAC_AACDEC_LATM_H */
351