Pass the correct size in bits to mpeg4audio_get_config and add a flag to disable parsing of the sync extension when the size is not known. Latm with AudioMuxVersion 0 does not specify the size of the audio specific config. Data after the audio specific config can be misinterpreted as sync extension resulting in random and wrong configs.
Unified · Split
| @@ -452,15 +452,17 @@ static int decode_ga_specific_config(AACContext *ac, AVCodecContext *avctx, · 451 unmodified lines | ||
| 452 | 452 | * @param ac pointer to AACContext, may be null |
| 453 | 453 | * @param avctx pointer to AVCCodecContext, used for logging |
| 454 | 454 | * @param m4ac pointer to MPEG4AudioConfig, used for parsing |
| 455 | − * @param data pointer to AVCodecContext extradata | |
| 456 | − * @param data_size size of AVCCodecContext extradata | |
| 455 | + * @param data pointer to buffer holding an audio specific config | |
| 456 | + * @param bit_size size of audio specific config or data in bits | |
| 457 | + * @param sync_extension look for an appended sync extension | |
| 457 | 458 | * |
| 458 | 459 | * @return Returns error status or number of consumed bits. <0 - error |
| 459 | 460 | */ |
| 460 | 461 | static int decode_audio_specific_config(AACContext *ac, |
| 461 | 462 | AVCodecContext *avctx, |
| 462 | 463 | MPEG4AudioConfig *m4ac, |
| 463 | − const uint8_t *data, int data_size) | |
| 464 | + const uint8_t *data, int bit_size, | |
| 465 | + int sync_extension) | |
| 464 | 466 | { |
| 465 | 467 | GetBitContext gb; |
| 466 | 468 | int i; |
| @@ -470,9 +472,9 @@ static int decode_audio_specific_config(AACContext *ac, · 3 unmodified lines | ||
| 470 | 472 | av_dlog(avctx, "%02x ", avctx->extradata[i]); |
| 471 | 473 | av_dlog(avctx, "\n"); |
| 472 | 474 | |
| 473 | − init_get_bits(&gb, data, data_size * 8); | |
| 475 | + init_get_bits(&gb, data, bit_size); | |
| 474 | 476 | |
| 475 | − if ((i = avpriv_mpeg4audio_get_config(m4ac, data, data_size)) < 0) | |
| 477 | + if ((i = avpriv_mpeg4audio_get_config(m4ac, data, bit_size, sync_extension)) < 0) | |
| 476 | 478 | return -1; |
| 477 | 479 | if (m4ac->sampling_index > 12) { |
| 478 | 480 | av_log(avctx, AV_LOG_ERROR, "invalid sampling rate index %d\n", m4ac->sampling_index); |
| @@ -572,7 +574,7 @@ static av_cold int aac_decode_init(AVCodecContext *avctx) · 93 unmodified lines | ||
| 572 | 574 | if (avctx->extradata_size > 0) { |
| 573 | 575 | if (decode_audio_specific_config(ac, ac->avctx, &ac->m4ac, |
| 574 | 576 | avctx->extradata, |
| 575 | − avctx->extradata_size) < 0) | |
| 577 | + avctx->extradata_size*8, 1) < 0) | |
| 576 | 578 | return -1; |
| 577 | 579 | } else { |
| 578 | 580 | int sr, i; |
| @@ -2315,12 +2317,19 @@ static inline uint32_t latm_get_value(GetBitContext *b) · 1736 unmodified lines | ||
| 2315 | 2317 | } |
| 2316 | 2318 | |
| 2317 | 2319 | static int latm_decode_audio_specific_config(struct LATMContext *latmctx, |
| 2318 | − GetBitContext *gb) | |
| 2320 | + GetBitContext *gb, int asclen) | |
| 2319 | 2321 | { |
| 2320 | 2322 | AVCodecContext *avctx = latmctx->aac_ctx.avctx; |
| 2321 | 2323 | MPEG4AudioConfig m4ac; |
| 2322 | − int config_start_bit = get_bits_count(gb); | |
| 2323 | − int bits_consumed, esize; | |
| 2324 | + int config_start_bit = get_bits_count(gb); | |
| 2325 | + int sync_extension = 0; | |
| 2326 | + int bits_consumed, esize; | |
| 2327 | + | |
| 2328 | + if (asclen) { | |
| 2329 | + sync_extension = 1; | |
| 2330 | + asclen = FFMIN(asclen, get_bits_left(gb)); | |
| 2331 | + } else | |
| 2332 | + asclen = get_bits_left(gb); | |
| 2324 | 2333 | |
| 2325 | 2334 | if (config_start_bit % 8) { |
| 2326 | 2335 | av_log_missing_feature(latmctx->aac_ctx.avctx, "audio specific " |
| @@ -2330,7 +2339,7 @@ static int latm_decode_audio_specific_config(struct LATMContext *latmctx, · 3 unmodified lines | ||
| 2330 | 2339 | bits_consumed = |
| 2331 | 2340 | decode_audio_specific_config(NULL, avctx, &m4ac, |
| 2332 | 2341 | gb->buffer + (config_start_bit / 8), |
| 2333 | − get_bits_left(gb) / 8); | |
| 2342 | + asclen, sync_extension); | |
| 2334 | 2343 | |
| 2335 | 2344 | if (bits_consumed < 0) |
| 2336 | 2345 | return AVERROR_INVALIDDATA; |
| @@ -2388,11 +2397,11 @@ static int read_stream_mux_config(struct LATMContext *latmctx, · 51 unmodified lines | ||
| 2388 | 2397 | |
| 2389 | 2398 | // for all but first stream: use_same_config = get_bits(gb, 1); |
| 2390 | 2399 | if (!audio_mux_version) { |
| 2391 | − if ((ret = latm_decode_audio_specific_config(latmctx, gb)) < 0) | |
| 2400 | + if ((ret = latm_decode_audio_specific_config(latmctx, gb, 0)) < 0) | |
| 2392 | 2401 | return ret; |
| 2393 | 2402 | } else { |
| 2394 | 2403 | int ascLen = latm_get_value(gb); |
| 2395 | − if ((ret = latm_decode_audio_specific_config(latmctx, gb)) < 0) | |
| 2404 | + if ((ret = latm_decode_audio_specific_config(latmctx, gb, ascLen)) < 0) | |
| 2396 | 2405 | return ret; |
| 2397 | 2406 | ascLen -= ret; |
| 2398 | 2407 | skip_bits_long(gb, ascLen); |
| @@ -2514,7 +2523,7 @@ static int latm_decode_frame(AVCodecContext *avctx, void *out, · 115 unmodified lines | ||
| 2514 | 2523 | } else { |
| 2515 | 2524 | if ((err = decode_audio_specific_config( |
| 2516 | 2525 | &latmctx->aac_ctx, avctx, &latmctx->aac_ctx.m4ac, |
| 2517 | − avctx->extradata, avctx->extradata_size)) < 0) | |
| 2526 | + avctx->extradata, avctx->extradata_size*8, 1)) < 0) | |
| 2518 | 2527 | return err; |
| 2519 | 2528 | latmctx->initialized = 1; |
| 2520 | 2529 | } |
| @@ -291,7 +291,7 @@ static av_cold int read_specific_config(ALSDecContext *ctx) · 290 unmodified lines | ||
| 291 | 291 | init_get_bits(&gb, avctx->extradata, avctx->extradata_size * 8); |
| 292 | 292 | |
| 293 | 293 | config_offset = avpriv_mpeg4audio_get_config(&m4ac, avctx->extradata, |
| 294 | − avctx->extradata_size); | |
| 294 | + avctx->extradata_size * 8, 1); | |
| 295 | 295 | |
| 296 | 296 | if (config_offset < 0) |
| 297 | 297 | return -1; |
| @@ -76,12 +76,13 @@ static inline int get_sample_rate(GetBitContext *gb, int *index) · 75 unmodified lines | ||
| 76 | 76 | avpriv_mpeg4audio_sample_rates[*index]; |
| 77 | 77 | } |
| 78 | 78 | |
| 79 | −int avpriv_mpeg4audio_get_config(MPEG4AudioConfig *c, const uint8_t *buf, int buf_size) | |
| 79 | +int avpriv_mpeg4audio_get_config(MPEG4AudioConfig *c, const uint8_t *buf, | |
| 80 | + int bit_size, int sync_extension) | |
| 80 | 81 | { |
| 81 | 82 | GetBitContext gb; |
| 82 | 83 | int specific_config_bitindex; |
| 83 | 84 | |
| 84 | − init_get_bits(&gb, buf, buf_size*8); | |
| 85 | + init_get_bits(&gb, buf, bit_size); | |
| 85 | 86 | c->object_type = get_object_type(&gb); |
| 86 | 87 | c->sample_rate = get_sample_rate(&gb, &c->sampling_index); |
| 87 | 88 | c->chan_config = get_bits(&gb, 4); |
| @@ -117,7 +118,7 @@ int avpriv_mpeg4audio_get_config(MPEG4AudioConfig *c, const uint8_t *buf, int bu · 29 unmodified lines | ||
| 117 | 118 | return -1; |
| 118 | 119 | } |
| 119 | 120 | |
| 120 | − if (c->ext_object_type != AOT_SBR) { | |
| 121 | + if (c->ext_object_type != AOT_SBR && sync_extension) { | |
| 121 | 122 | while (get_bits_left(&gb) > 15) { |
| 122 | 123 | if (show_bits(&gb, 11) == 0x2b7) { // sync extension |
| 123 | 124 | get_bits(&gb, 11); |
| @@ -42,14 +42,17 @@ typedef struct { · 41 unmodified lines | ||
| 42 | 42 | |
| 43 | 43 | extern const int avpriv_mpeg4audio_sample_rates[16]; |
| 44 | 44 | extern const uint8_t ff_mpeg4audio_channels[8]; |
| 45 | + | |
| 45 | 46 | /** |
| 46 | 47 | * Parse MPEG-4 systems extradata to retrieve audio configuration. |
| 47 | 48 | * @param[in] c MPEG4AudioConfig structure to fill. |
| 48 | 49 | * @param[in] buf Extradata from container. |
| 49 | − * @param[in] buf_size Extradata size. | |
| 50 | + * @param[in] bit_size Extradata size in bits. | |
| 51 | + * @param[in] sync_extension look for a sync extension after config if true. | |
| 50 | 52 | * @return On error -1 is returned, on success AudioSpecificConfig bit index in extradata. |
| 51 | 53 | */ |
| 52 | −int avpriv_mpeg4audio_get_config(MPEG4AudioConfig *c, const uint8_t *buf, int buf_size); | |
| 54 | +int avpriv_mpeg4audio_get_config(MPEG4AudioConfig *c, const uint8_t *buf, | |
| 55 | + int bit_size, int sync_extension); | |
| 53 | 56 | |
| 54 | 57 | enum AudioObjectType { |
| 55 | 58 | AOT_NULL, |
| @@ -1966,7 +1966,8 @@ static int decode_init_mp3on4(AVCodecContext * avctx) · 1965 unmodified lines | ||
| 1966 | 1966 | return AVERROR_INVALIDDATA; |
| 1967 | 1967 | } |
| 1968 | 1968 | |
| 1969 | − avpriv_mpeg4audio_get_config(&cfg, avctx->extradata, avctx->extradata_size); | |
| 1969 | + avpriv_mpeg4audio_get_config(&cfg, avctx->extradata, | |
| 1970 | + avctx->extradata_size * 8, 1); | |
| 1970 | 1971 | if (!cfg.chan_config || cfg.chan_config > 7) { |
| 1971 | 1972 | av_log(avctx, AV_LOG_ERROR, "Invalid channel config number.\n"); |
| 1972 | 1973 | return AVERROR_INVALIDDATA; |
| @@ -37,7 +37,7 @@ int ff_adts_decode_extradata(AVFormatContext *s, ADTSContext *adts, uint8_t *buf · 36 unmodified lines | ||
| 37 | 37 | int off; |
| 38 | 38 | |
| 39 | 39 | init_get_bits(&gb, buf, size * 8); |
| 40 | − off = avpriv_mpeg4audio_get_config(&m4ac, buf, size); | |
| 40 | + off = avpriv_mpeg4audio_get_config(&m4ac, buf, size * 8, 1); | |
| 41 | 41 | if (off < 0) |
| 42 | 42 | return off; |
| 43 | 43 | skip_bits_long(&gb, off); |
| @@ -534,7 +534,7 @@ static int flv_read_packet(AVFormatContext *s, AVPacket *pkt) · 533 unmodified lines | ||
| 534 | 534 | if (st->codec->codec_id == CODEC_ID_AAC) { |
| 535 | 535 | MPEG4AudioConfig cfg; |
| 536 | 536 | avpriv_mpeg4audio_get_config(&cfg, st->codec->extradata, |
| 537 | − st->codec->extradata_size); | |
| 537 | + st->codec->extradata_size * 8, 1); | |
| 538 | 538 | st->codec->channels = cfg.channels; |
| 539 | 539 | if (cfg.ext_sample_rate) |
| 540 | 540 | st->codec->sample_rate = cfg.ext_sample_rate; |
| @@ -436,7 +436,7 @@ int ff_mp4_read_dec_config_descr(AVFormatContext *fc, AVStream *st, AVIOContext · 435 unmodified lines | ||
| 436 | 436 | if (st->codec->codec_id == CODEC_ID_AAC) { |
| 437 | 437 | MPEG4AudioConfig cfg; |
| 438 | 438 | avpriv_mpeg4audio_get_config(&cfg, st->codec->extradata, |
| 439 | − st->codec->extradata_size); | |
| 439 | + st->codec->extradata_size * 8, 1); | |
| 440 | 440 | st->codec->channels = cfg.channels; |
| 441 | 441 | if (cfg.object_type == 29 && cfg.sampling_index < 3) // old mp3on4 |
| 442 | 442 | st->codec->sample_rate = avpriv_mpa_freq_tab[cfg.sampling_index]; |
| @@ -54,7 +54,7 @@ static int latm_decode_extradata(LATMContext *ctx, uint8_t *buf, int size) · 53 unmodified lines | ||
| 54 | 54 | MPEG4AudioConfig m4ac; |
| 55 | 55 | |
| 56 | 56 | init_get_bits(&gb, buf, size * 8); |
| 57 | − ctx->off = avpriv_mpeg4audio_get_config(&m4ac, buf, size); | |
| 57 | + ctx->off = avpriv_mpeg4audio_get_config(&m4ac, buf, size * 8, 1); | |
| 58 | 58 | if (ctx->off < 0) |
| 59 | 59 | return ctx->off; |
| 60 | 60 | skip_bits_long(&gb, ctx->off); |
| @@ -448,7 +448,8 @@ static void get_aac_sample_rates(AVFormatContext *s, AVCodecContext *codec, int · 447 unmodified lines | ||
| 448 | 448 | { |
| 449 | 449 | MPEG4AudioConfig mp4ac; |
| 450 | 450 | |
| 451 | − if (avpriv_mpeg4audio_get_config(&mp4ac, codec->extradata, codec->extradata_size) < 0) { | |
| 451 | + if (avpriv_mpeg4audio_get_config(&mp4ac, codec->extradata, | |
| 452 | + codec->extradata_size * 8, 1) < 0) { | |
| 452 | 453 | av_log(s, AV_LOG_WARNING, "Error parsing AAC extradata, unable to determine samplerate.\n"); |
| 453 | 454 | return; |
| 454 | 455 | } |