X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavcodec%2Fmpeg4audio.c;h=0666bbbc42d5ff815602a22e9373f65cec918d85;hb=ecc1f8c3c8875e31e7cb9b7d9229b1674e1be736;hp=91ea2b7c9b3c16bbaf282d1c0e4a4731a526d182;hpb=3d10a8904d638b10036228f439755e79a15e02d4;p=ffmpeg diff --git a/libavcodec/mpeg4audio.c b/libavcodec/mpeg4audio.c index 91ea2b7c9b3..0666bbbc42d 100644 --- a/libavcodec/mpeg4audio.c +++ b/libavcodec/mpeg4audio.c @@ -1,6 +1,7 @@ /* * MPEG-4 Audio common code * Copyright (c) 2008 Baptiste Coudurier + * Copyright (c) 2009 Alex Converse * * This file is part of FFmpeg. * @@ -20,8 +21,37 @@ */ #include "get_bits.h" +#include "put_bits.h" #include "mpeg4audio.h" +/** + * Parse MPEG-4 audio configuration for ALS object type. + * @param[in] gb bit reader context + * @param[in] c MPEG4AudioConfig structure to fill + * @return on success 0 is returned, otherwise a value < 0 + */ +static int parse_config_ALS(GetBitContext *gb, MPEG4AudioConfig *c) +{ + if (get_bits_left(gb) < 112) + return -1; + + if (get_bits_long(gb, 32) != MKBETAG('A','L','S','\0')) + return -1; + + // override AudioSpecificConfig channel configuration and sample rate + // which are buggy in old ALS conformance files + c->sample_rate = get_bits_long(gb, 32); + + // skip number of samples + skip_bits_long(gb, 32); + + // read number of channels + c->chan_config = 0; + c->channels = get_bits(gb, 16) + 1; + + return 0; +} + const int ff_mpeg4audio_sample_rates[16] = { 96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050, 16000, 12000, 11025, 8000, 7350 @@ -34,7 +64,7 @@ const uint8_t ff_mpeg4audio_channels[8] = { static inline int get_object_type(GetBitContext *gb) { int object_type = get_bits(gb, 5); - if (object_type == 31) + if (object_type == AOT_ESCAPE) object_type = 32 + get_bits(gb, 6); return object_type; } @@ -55,8 +85,12 @@ int ff_mpeg4audio_get_config(MPEG4AudioConfig *c, const uint8_t *buf, int buf_si c->object_type = get_object_type(&gb); c->sample_rate = get_sample_rate(&gb, &c->sampling_index); c->chan_config = get_bits(&gb, 4); + if (c->chan_config < FF_ARRAY_ELEMS(ff_mpeg4audio_channels)) + c->channels = ff_mpeg4audio_channels[c->chan_config]; c->sbr = -1; - if (c->object_type == 5) { + if (c->object_type == AOT_SBR || (c->object_type == AOT_PS && + // check for W6132 Annex YYYY draft MP3onMP4 + !(show_bits(&gb, 3) & 0x03 && !(show_bits(&gb, 9) & 0x3F)))) { c->ext_object_type = c->object_type; c->sbr = 1; c->ext_sample_rate = get_sample_rate(&gb, &c->ext_sampling_index); @@ -64,18 +98,29 @@ int ff_mpeg4audio_get_config(MPEG4AudioConfig *c, const uint8_t *buf, int buf_si if (c->object_type == AOT_ER_BSAC) c->ext_chan_config = get_bits(&gb, 4); } else { - c->ext_object_type = 0; + c->ext_object_type = AOT_NULL; c->ext_sample_rate = 0; } specific_config_bitindex = get_bits_count(&gb); - if (c->ext_object_type != 5) { - int bits_left = buf_size*8 - specific_config_bitindex; + if (c->object_type == AOT_ALS) { + skip_bits(&gb, 5); + if (show_bits_long(&gb, 24) != MKBETAG('\0','A','L','S')) + skip_bits_long(&gb, 24); + + specific_config_bitindex = get_bits_count(&gb); + + if (parse_config_ALS(&gb, c)) + return -1; + } + + if (c->ext_object_type != AOT_SBR) { + int bits_left = buf_size*8 - get_bits_count(&gb); for (; bits_left > 15; bits_left--) { if (show_bits(&gb, 11) == 0x2b7) { // sync extension get_bits(&gb, 11); c->ext_object_type = get_object_type(&gb); - if (c->ext_object_type == 5 && (c->sbr = get_bits1(&gb)) == 1) + if (c->ext_object_type == AOT_SBR && (c->sbr = get_bits1(&gb)) == 1) c->ext_sample_rate = get_sample_rate(&gb, &c->ext_sampling_index); break; } else @@ -84,3 +129,43 @@ int ff_mpeg4audio_get_config(MPEG4AudioConfig *c, const uint8_t *buf, int buf_si } return specific_config_bitindex; } + +static av_always_inline unsigned int copy_bits(PutBitContext *pb, + GetBitContext *gb, + int bits) +{ + unsigned int el = get_bits(gb, bits); + put_bits(pb, bits, el); + return el; +} + +int ff_copy_pce_data(PutBitContext *pb, GetBitContext *gb) +{ + int five_bit_ch, four_bit_ch, comment_size, bits; + int offset = put_bits_count(pb); + + copy_bits(pb, gb, 10); //Tag, Object Type, Frequency + five_bit_ch = copy_bits(pb, gb, 4); //Front + five_bit_ch += copy_bits(pb, gb, 4); //Side + five_bit_ch += copy_bits(pb, gb, 4); //Back + four_bit_ch = copy_bits(pb, gb, 2); //LFE + four_bit_ch += copy_bits(pb, gb, 3); //Data + five_bit_ch += copy_bits(pb, gb, 4); //Coupling + if (copy_bits(pb, gb, 1)) //Mono Mixdown + copy_bits(pb, gb, 4); + if (copy_bits(pb, gb, 1)) //Stereo Mixdown + copy_bits(pb, gb, 4); + if (copy_bits(pb, gb, 1)) //Matrix Mixdown + copy_bits(pb, gb, 3); + for (bits = five_bit_ch*5+four_bit_ch*4; bits > 16; bits -= 16) + copy_bits(pb, gb, 16); + if (bits) + copy_bits(pb, gb, bits); + align_put_bits(pb); + align_get_bits(gb); + comment_size = copy_bits(pb, gb, 8); + for (; comment_size > 0; comment_size--) + copy_bits(pb, gb, 8); + + return put_bits_count(pb) - offset; +}