|
- /*
- * MPEG-4 Audio common code
- * Copyright (c) 2008 Baptiste Coudurier <baptiste.coudurier@free.fr>
- * Copyright (c) 2009 Alex Converse <alex.converse@gmail.com>
- *
- * This file is part of FFmpeg.
- *
- * FFmpeg is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * FFmpeg is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with FFmpeg; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
- #include "get_bits.h"
- #include "put_bits.h"
- #include "mpeg4audio.h"
-
- const int ff_mpeg4audio_sample_rates[16] = {
- 96000, 88200, 64000, 48000, 44100, 32000,
- 24000, 22050, 16000, 12000, 11025, 8000, 7350
- };
-
- const uint8_t ff_mpeg4audio_channels[8] = {
- 0, 1, 2, 3, 4, 5, 6, 8
- };
-
- static inline int get_object_type(GetBitContext *gb)
- {
- int object_type = get_bits(gb, 5);
- if (object_type == AOT_ESCAPE)
- object_type = 32 + get_bits(gb, 6);
- return object_type;
- }
-
- static inline int get_sample_rate(GetBitContext *gb, int *index)
- {
- *index = get_bits(gb, 4);
- return *index == 0x0f ? get_bits(gb, 24) :
- ff_mpeg4audio_sample_rates[*index];
- }
-
- int ff_mpeg4audio_get_config(MPEG4AudioConfig *c, const uint8_t *buf, int buf_size)
- {
- GetBitContext gb;
- int specific_config_bitindex;
-
- init_get_bits(&gb, buf, buf_size*8);
- c->object_type = get_object_type(&gb);
- c->sample_rate = get_sample_rate(&gb, &c->sampling_index);
- c->chan_config = get_bits(&gb, 4);
- c->sbr = -1;
- if (c->object_type == AOT_SBR) {
- c->ext_object_type = c->object_type;
- c->sbr = 1;
- c->ext_sample_rate = get_sample_rate(&gb, &c->ext_sampling_index);
- c->object_type = get_object_type(&gb);
- if (c->object_type == AOT_ER_BSAC)
- c->ext_chan_config = get_bits(&gb, 4);
- } else {
- c->ext_object_type = AOT_NULL;
- c->ext_sample_rate = 0;
- }
- specific_config_bitindex = get_bits_count(&gb);
-
- if (c->ext_object_type != AOT_SBR) {
- int bits_left = buf_size*8 - specific_config_bitindex;
- 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 == AOT_SBR && (c->sbr = get_bits1(&gb)) == 1)
- c->ext_sample_rate = get_sample_rate(&gb, &c->ext_sampling_index);
- break;
- } else
- get_bits1(&gb); // skip 1 bit
- }
- }
- 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;
- }
|