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 | * @param ac pointer to AACContext, may be null | 452 | * @param ac pointer to AACContext, may be null |
| 453 | * @param avctx pointer to AVCCodecContext, used for logging | 453 | * @param avctx pointer to AVCCodecContext, used for logging |
| 454 | * @param m4ac pointer to MPEG4AudioConfig, used for parsing | 454 | * @param m4ac pointer to MPEG4AudioConfig, used for parsing |
| 455 | * @param data pointer to AVCodecContext extradata | 455 | * @param data pointer to buffer holding an audio specific config |
| 456 | * @param data_size size of AVCCodecContext extradata | 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 | * @return Returns error status or number of consumed bits. <0 - error | 459 | * @return Returns error status or number of consumed bits. <0 - error |
| 459 | */ | 460 | */ |
| 460 | static int decode_audio_specific_config(AACContext *ac, | 461 | static int decode_audio_specific_config(AACContext *ac, |
| 461 | AVCodecContext *avctx, | 462 | AVCodecContext *avctx, |
| 462 | MPEG4AudioConfig *m4ac, | 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 | GetBitContext gb; | 467 | GetBitContext gb; |
| 466 | int i; | 468 | int i; |
| @@ -470,9 +472,9 @@ static int decode_audio_specific_config(AACContext *ac, · 3 unmodified lines | |||
| 470 | av_dlog(avctx, "%02x ", avctx->extradata[i]); | 472 | av_dlog(avctx, "%02x ", avctx->extradata[i]); |
| 471 | av_dlog(avctx, "\n"); | 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 | return -1; | 478 | return -1; |
| 477 | if (m4ac->sampling_index > 12) { | 479 | if (m4ac->sampling_index > 12) { |
| 478 | av_log(avctx, AV_LOG_ERROR, "invalid sampling rate index %d\n", m4ac->sampling_index); | 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 | if (avctx->extradata_size > 0) { | 574 | if (avctx->extradata_size > 0) { |
| 573 | if (decode_audio_specific_config(ac, ac->avctx, &ac->m4ac, | 575 | if (decode_audio_specific_config(ac, ac->avctx, &ac->m4ac, |
| 574 | avctx->extradata, | 576 | avctx->extradata, |
| 575 | avctx->extradata_size) < 0) | 577 | avctx->extradata_size*8, 1) < 0) |
| 576 | return -1; | 578 | return -1; |
| 577 | } else { | 579 | } else { |
| 578 | int sr, i; | 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 | static int latm_decode_audio_specific_config(struct LATMContext *latmctx, | 2319 | static int latm_decode_audio_specific_config(struct LATMContext *latmctx, |
| 2318 | GetBitContext *gb) | 2320 | GetBitContext *gb, int asclen) |
| 2319 | { | 2321 | { |
| 2320 | AVCodecContext *avctx = latmctx->aac_ctx.avctx; | 2322 | AVCodecContext *avctx = latmctx->aac_ctx.avctx; |
| 2321 | MPEG4AudioConfig m4ac; | 2323 | MPEG4AudioConfig m4ac; |
| 2322 | int config_start_bit = get_bits_count(gb); | 2324 | int config_start_bit = get_bits_count(gb); |
| 2323 | int bits_consumed, esize; | 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 | if (config_start_bit % 8) { | 2334 | if (config_start_bit % 8) { |
| 2326 | av_log_missing_feature(latmctx->aac_ctx.avctx, "audio specific " | 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 | bits_consumed = | 2339 | bits_consumed = |
| 2331 | decode_audio_specific_config(NULL, avctx, &m4ac, | 2340 | decode_audio_specific_config(NULL, avctx, &m4ac, |
| 2332 | gb->buffer + (config_start_bit / 8), | 2341 | gb->buffer + (config_start_bit / 8), |
| 2333 | get_bits_left(gb) / 8); | 2342 | asclen, sync_extension); |
| 2334 | 2343 | ||
| 2335 | if (bits_consumed < 0) | 2344 | if (bits_consumed < 0) |
| 2336 | return AVERROR_INVALIDDATA; | 2345 | return AVERROR_INVALIDDATA; |
| @@ -2388,11 +2397,11 @@ static int read_stream_mux_config(struct LATMContext *latmctx, · 51 unmodified lines | |||
| 2388 | 2397 | ||
| 2389 | // for all but first stream: use_same_config = get_bits(gb, 1); | 2398 | // for all but first stream: use_same_config = get_bits(gb, 1); |
| 2390 | if (!audio_mux_version) { | 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 | return ret; | 2401 | return ret; |
| 2393 | } else { | 2402 | } else { |
| 2394 | int ascLen = latm_get_value(gb); | 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 | return ret; | 2405 | return ret; |
| 2397 | ascLen -= ret; | 2406 | ascLen -= ret; |
| 2398 | skip_bits_long(gb, ascLen); | 2407 | skip_bits_long(gb, ascLen); |
| @@ -2514,7 +2523,7 @@ static int latm_decode_frame(AVCodecContext *avctx, void *out, · 115 unmodified lines | |||
| 2514 | } else { | 2523 | } else { |
| 2515 | if ((err = decode_audio_specific_config( | 2524 | if ((err = decode_audio_specific_config( |
| 2516 | &latmctx->aac_ctx, avctx, &latmctx->aac_ctx.m4ac, | 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 | return err; | 2527 | return err; |
| 2519 | latmctx->initialized = 1; | 2528 | latmctx->initialized = 1; |
| 2520 | } | 2529 | } |
| @@ -291,7 +291,7 @@ static av_cold int read_specific_config(ALSDecContext *ctx) · 290 unmodified lines | |||
| 291 | init_get_bits(&gb, avctx->extradata, avctx->extradata_size * 8); | 291 | init_get_bits(&gb, avctx->extradata, avctx->extradata_size * 8); |
| 292 | 292 | ||
| 293 | config_offset = avpriv_mpeg4audio_get_config(&m4ac, avctx->extradata, | 293 | config_offset = avpriv_mpeg4audio_get_config(&m4ac, avctx->extradata, |
| 294 | avctx->extradata_size); | 294 | avctx->extradata_size * 8, 1); |
| 295 | 295 | ||
| 296 | if (config_offset < 0) | 296 | if (config_offset < 0) |
| 297 | return -1; | 297 | return -1; |
| @@ -76,12 +76,13 @@ static inline int get_sample_rate(GetBitContext *gb, int *index) · 75 unmodified lines | |||
| 76 | avpriv_mpeg4audio_sample_rates[*index]; | 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 | GetBitContext gb; | 82 | GetBitContext gb; |
| 82 | int specific_config_bitindex; | 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 | c->object_type = get_object_type(&gb); | 86 | c->object_type = get_object_type(&gb); |
| 86 | c->sample_rate = get_sample_rate(&gb, &c->sampling_index); | 87 | c->sample_rate = get_sample_rate(&gb, &c->sampling_index); |
| 87 | c->chan_config = get_bits(&gb, 4); | 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 | return -1; | 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 | while (get_bits_left(&gb) > 15) { | 122 | while (get_bits_left(&gb) > 15) { |
| 122 | if (show_bits(&gb, 11) == 0x2b7) { // sync extension | 123 | if (show_bits(&gb, 11) == 0x2b7) { // sync extension |
| 123 | get_bits(&gb, 11); | 124 | get_bits(&gb, 11); |
| @@ -42,14 +42,17 @@ typedef struct { · 41 unmodified lines | |||
| 42 | 42 | ||
| 43 | extern const int avpriv_mpeg4audio_sample_rates[16]; | 43 | extern const int avpriv_mpeg4audio_sample_rates[16]; |
| 44 | extern const uint8_t ff_mpeg4audio_channels[8]; | 44 | extern const uint8_t ff_mpeg4audio_channels[8]; |
| 45 | |||
| 45 | /** | 46 | /** |
| 46 | * Parse MPEG-4 systems extradata to retrieve audio configuration. | 47 | * Parse MPEG-4 systems extradata to retrieve audio configuration. |
| 47 | * @param[in] c MPEG4AudioConfig structure to fill. | 48 | * @param[in] c MPEG4AudioConfig structure to fill. |
| 48 | * @param[in] buf Extradata from container. | 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 | * @return On error -1 is returned, on success AudioSpecificConfig bit index in extradata. | 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 | enum AudioObjectType { | 57 | enum AudioObjectType { |
| 55 | AOT_NULL, | 58 | AOT_NULL, |
| @@ -1966,7 +1966,8 @@ static int decode_init_mp3on4(AVCodecContext * avctx) · 1965 unmodified lines | |||
| 1966 | return AVERROR_INVALIDDATA; | 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 | if (!cfg.chan_config || cfg.chan_config > 7) { | 1971 | if (!cfg.chan_config || cfg.chan_config > 7) { |
| 1971 | av_log(avctx, AV_LOG_ERROR, "Invalid channel config number.\n"); | 1972 | av_log(avctx, AV_LOG_ERROR, "Invalid channel config number.\n"); |
| 1972 | return AVERROR_INVALIDDATA; | 1973 | return AVERROR_INVALIDDATA; |
| @@ -37,7 +37,7 @@ int ff_adts_decode_extradata(AVFormatContext *s, ADTSContext *adts, uint8_t *buf · 36 unmodified lines | |||
| 37 | int off; | 37 | int off; |
| 38 | 38 | ||
| 39 | init_get_bits(&gb, buf, size * 8); | 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 | if (off < 0) | 41 | if (off < 0) |
| 42 | return off; | 42 | return off; |
| 43 | skip_bits_long(&gb, off); | 43 | skip_bits_long(&gb, off); |
| @@ -534,7 +534,7 @@ static int flv_read_packet(AVFormatContext *s, AVPacket *pkt) · 533 unmodified lines | |||
| 534 | if (st->codec->codec_id == CODEC_ID_AAC) { | 534 | if (st->codec->codec_id == CODEC_ID_AAC) { |
| 535 | MPEG4AudioConfig cfg; | 535 | MPEG4AudioConfig cfg; |
| 536 | avpriv_mpeg4audio_get_config(&cfg, st->codec->extradata, | 536 | avpriv_mpeg4audio_get_config(&cfg, st->codec->extradata, |
| 537 | st->codec->extradata_size); | 537 | st->codec->extradata_size * 8, 1); |
| 538 | st->codec->channels = cfg.channels; | 538 | st->codec->channels = cfg.channels; |
| 539 | if (cfg.ext_sample_rate) | 539 | if (cfg.ext_sample_rate) |
| 540 | st->codec->sample_rate = cfg.ext_sample_rate; | 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 | if (st->codec->codec_id == CODEC_ID_AAC) { | 436 | if (st->codec->codec_id == CODEC_ID_AAC) { |
| 437 | MPEG4AudioConfig cfg; | 437 | MPEG4AudioConfig cfg; |
| 438 | avpriv_mpeg4audio_get_config(&cfg, st->codec->extradata, | 438 | avpriv_mpeg4audio_get_config(&cfg, st->codec->extradata, |
| 439 | st->codec->extradata_size); | 439 | st->codec->extradata_size * 8, 1); |
| 440 | st->codec->channels = cfg.channels; | 440 | st->codec->channels = cfg.channels; |
| 441 | if (cfg.object_type == 29 && cfg.sampling_index < 3) // old mp3on4 | 441 | if (cfg.object_type == 29 && cfg.sampling_index < 3) // old mp3on4 |
| 442 | st->codec->sample_rate = avpriv_mpa_freq_tab[cfg.sampling_index]; | 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 | MPEG4AudioConfig m4ac; | 54 | MPEG4AudioConfig m4ac; |
| 55 | 55 | ||
| 56 | init_get_bits(&gb, buf, size * 8); | 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 | if (ctx->off < 0) | 58 | if (ctx->off < 0) |
| 59 | return ctx->off; | 59 | return ctx->off; |
| 60 | skip_bits_long(&gb, ctx->off); | 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 | MPEG4AudioConfig mp4ac; | 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 | av_log(s, AV_LOG_WARNING, "Error parsing AAC extradata, unable to determine samplerate.\n"); | 453 | av_log(s, AV_LOG_WARNING, "Error parsing AAC extradata, unable to determine samplerate.\n"); |
| 453 | return; | 454 | return; |
| 454 | } | 455 | } |