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
452452 * @param ac pointer to AACContext, may be null
453453 * @param avctx pointer to AVCCodecContext, used for logging
454454 * @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
457458 *
458459 * @return Returns error status or number of consumed bits. <0 - error
459460 */
460461 static int decode_audio_specific_config(AACContext *ac,
461462 AVCodecContext *avctx,
462463 MPEG4AudioConfig *m4ac,
463− const uint8_t *data, int data_size)
464+ const uint8_t *data, int bit_size,
465+ int sync_extension)
464466 {
465467 GetBitContext gb;
466468 int i;
@@ -470,9 +472,9 @@ static int decode_audio_specific_config(AACContext *ac, · 3 unmodified lines
470472 av_dlog(avctx, "%02x ", avctx->extradata[i]);
471473 av_dlog(avctx, "\n");
472474
473− init_get_bits(&gb, data, data_size * 8);
475+ init_get_bits(&gb, data, bit_size);
474476
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)
476478 return -1;
477479 if (m4ac->sampling_index > 12) {
478480 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
572574 if (avctx->extradata_size > 0) {
573575 if (decode_audio_specific_config(ac, ac->avctx, &ac->m4ac,
574576 avctx->extradata,
575− avctx->extradata_size) < 0)
577+ avctx->extradata_size*8, 1) < 0)
576578 return -1;
577579 } else {
578580 int sr, i;
@@ -2315,12 +2317,19 @@ static inline uint32_t latm_get_value(GetBitContext *b) · 1736 unmodified lines
23152317 }
23162318
23172319 static int latm_decode_audio_specific_config(struct LATMContext *latmctx,
2318− GetBitContext *gb)
2320+ GetBitContext *gb, int asclen)
23192321 {
23202322 AVCodecContext *avctx = latmctx->aac_ctx.avctx;
23212323 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);
23242333
23252334 if (config_start_bit % 8) {
23262335 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
23302339 bits_consumed =
23312340 decode_audio_specific_config(NULL, avctx, &m4ac,
23322341 gb->buffer + (config_start_bit / 8),
2333− get_bits_left(gb) / 8);
2342+ asclen, sync_extension);
23342343
23352344 if (bits_consumed < 0)
23362345 return AVERROR_INVALIDDATA;
@@ -2388,11 +2397,11 @@ static int read_stream_mux_config(struct LATMContext *latmctx, · 51 unmodified lines
23882397
23892398 // for all but first stream: use_same_config = get_bits(gb, 1);
23902399 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)
23922401 return ret;
23932402 } else {
23942403 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)
23962405 return ret;
23972406 ascLen -= ret;
23982407 skip_bits_long(gb, ascLen);
@@ -2514,7 +2523,7 @@ static int latm_decode_frame(AVCodecContext *avctx, void *out, · 115 unmodified lines
25142523 } else {
25152524 if ((err = decode_audio_specific_config(
25162525 &latmctx->aac_ctx, avctx, &latmctx->aac_ctx.m4ac,
2517− avctx->extradata, avctx->extradata_size)) < 0)
2526+ avctx->extradata, avctx->extradata_size*8, 1)) < 0)
25182527 return err;
25192528 latmctx->initialized = 1;
25202529 }
libavcodec/alsdec.c+1−1
@@ -291,7 +291,7 @@ static av_cold int read_specific_config(ALSDecContext *ctx) · 290 unmodified lines
291291 init_get_bits(&gb, avctx->extradata, avctx->extradata_size * 8);
292292
293293 config_offset = avpriv_mpeg4audio_get_config(&m4ac, avctx->extradata,
294− avctx->extradata_size);
294+ avctx->extradata_size * 8, 1);
295295
296296 if (config_offset < 0)
297297 return -1;
libavcodec/mpeg4audio.c+4−3
@@ -76,12 +76,13 @@ static inline int get_sample_rate(GetBitContext *gb, int *index) · 75 unmodified lines
7676 avpriv_mpeg4audio_sample_rates[*index];
7777 }
7878
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)
8081 {
8182 GetBitContext gb;
8283 int specific_config_bitindex;
8384
84− init_get_bits(&gb, buf, buf_size*8);
85+ init_get_bits(&gb, buf, bit_size);
8586 c->object_type = get_object_type(&gb);
8687 c->sample_rate = get_sample_rate(&gb, &c->sampling_index);
8788 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
117118 return -1;
118119 }
119120
120− if (c->ext_object_type != AOT_SBR) {
121+ if (c->ext_object_type != AOT_SBR && sync_extension) {
121122 while (get_bits_left(&gb) > 15) {
122123 if (show_bits(&gb, 11) == 0x2b7) { // sync extension
123124 get_bits(&gb, 11);
libavcodec/mpeg4audio.h+5−2
@@ -42,14 +42,17 @@ typedef struct { · 41 unmodified lines
4242
4343 extern const int avpriv_mpeg4audio_sample_rates[16];
4444 extern const uint8_t ff_mpeg4audio_channels[8];
45+
4546 /**
4647 * Parse MPEG-4 systems extradata to retrieve audio configuration.
4748 * @param[in] c MPEG4AudioConfig structure to fill.
4849 * @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.
5052 * @return On error -1 is returned, on success AudioSpecificConfig bit index in extradata.
5153 */
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);
5356
5457 enum AudioObjectType {
5558 AOT_NULL,
libavcodec/mpegaudiodec.c+2−1
@@ -1966,7 +1966,8 @@ static int decode_init_mp3on4(AVCodecContext * avctx) · 1965 unmodified lines
19661966 return AVERROR_INVALIDDATA;
19671967 }
19681968
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);
19701971 if (!cfg.chan_config || cfg.chan_config > 7) {
19711972 av_log(avctx, AV_LOG_ERROR, "Invalid channel config number.\n");
19721973 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
3737 int off;
3838
3939 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);
4141 if (off < 0)
4242 return off;
4343 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
534534 if (st->codec->codec_id == CODEC_ID_AAC) {
535535 MPEG4AudioConfig cfg;
536536 avpriv_mpeg4audio_get_config(&cfg, st->codec->extradata,
537− st->codec->extradata_size);
537+ st->codec->extradata_size * 8, 1);
538538 st->codec->channels = cfg.channels;
539539 if (cfg.ext_sample_rate)
540540 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
436436 if (st->codec->codec_id == CODEC_ID_AAC) {
437437 MPEG4AudioConfig cfg;
438438 avpriv_mpeg4audio_get_config(&cfg, st->codec->extradata,
439− st->codec->extradata_size);
439+ st->codec->extradata_size * 8, 1);
440440 st->codec->channels = cfg.channels;
441441 if (cfg.object_type == 29 && cfg.sampling_index < 3) // old mp3on4
442442 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
5454 MPEG4AudioConfig m4ac;
5555
5656 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);
5858 if (ctx->off < 0)
5959 return ctx->off;
6060 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
448448 {
449449 MPEG4AudioConfig mp4ac;
450450
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) {
452453 av_log(s, AV_LOG_WARNING, "Error parsing AAC extradata, unable to determine samplerate.\n");
453454 return;
454455 }

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