History

latmdec: fix audio specific config parsing

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.

Janne Grunau committed 15 years ago

Commit fd095531 parent 0eea21210 files · +40 −25Browse files

Unified · Split

10 files
  1. libavcodec/aacdec.c +22 −13
  2. libavcodec/alsdec.c +1 −1
  3. libavcodec/mpeg4audio.c +4 −3
  4. libavcodec/mpeg4audio.h +5 −2
  5. libavcodec/mpegaudiodec.c +2 −1
  6. libavformat/adtsenc.c +1 −1
  7. libavformat/flvdec.c +1 −1
  8. libavformat/isom.c +1 −1
  9. libavformat/latmenc.c +1 −1
  10. libavformat/matroskaenc.c +2 −1
libavcodec/aacdec.c+22−13
@@ -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 null452 * @param ac pointer to AACContext, may be null
453 * @param avctx pointer to AVCCodecContext, used for logging453 * @param avctx pointer to AVCCodecContext, used for logging
454 * @param m4ac pointer to MPEG4AudioConfig, used for parsing454 * @param m4ac pointer to MPEG4AudioConfig, used for parsing
455 * @param data pointer to AVCodecContext extradata455 * @param data pointer to buffer holding an audio specific config
456 * @param data_size size of AVCCodecContext extradata456 * @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 - error459 * @return Returns error status or number of consumed bits. <0 - error
459 */460 */
460static int decode_audio_specific_config(AACContext *ac,461static 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
2317static int latm_decode_audio_specific_config(struct LATMContext *latmctx,2319static 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 }
libavcodec/alsdec.c+1−1
@@ -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;
libavcodec/mpeg4audio.c+4−3
@@ -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
79int avpriv_mpeg4audio_get_config(MPEG4AudioConfig *c, const uint8_t *buf, int buf_size)79int 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 extension123 if (show_bits(&gb, 11) == 0x2b7) { // sync extension
123 get_bits(&gb, 11);124 get_bits(&gb, 11);
libavcodec/mpeg4audio.h+5−2
@@ -42,14 +42,17 @@ typedef struct { · 41 unmodified lines
42 42
43extern const int avpriv_mpeg4audio_sample_rates[16];43extern const int avpriv_mpeg4audio_sample_rates[16];
44extern const uint8_t ff_mpeg4audio_channels[8];44extern 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 */
52int avpriv_mpeg4audio_get_config(MPEG4AudioConfig *c, const uint8_t *buf, int buf_size);54int avpriv_mpeg4audio_get_config(MPEG4AudioConfig *c, const uint8_t *buf,
55 int bit_size, int sync_extension);
53 56
54enum AudioObjectType {57enum AudioObjectType {
55 AOT_NULL,58 AOT_NULL,
libavcodec/mpegaudiodec.c+2−1
@@ -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;
libavformat/adtsenc.c+1−1
@@ -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);
libavformat/flvdec.c+1−1
@@ -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;
libavformat/isom.c+1−1
@@ -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 mp3on4441 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];
libavformat/latmenc.c+1−1
@@ -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);
libavformat/matroskaenc.c+2−1
@@ -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 }

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t