Mercurial > libavcodec.hg
diff mpeg4audio.c @ 6558:06b1e0371e90 libavcodec
mpeg4audio common code
author | bcoudurier |
---|---|
date | Tue, 01 Apr 2008 12:01:40 +0000 |
parents | |
children | 13c86fee4873 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mpeg4audio.c Tue Apr 01 12:01:40 2008 +0000 @@ -0,0 +1,83 @@ +/* + * MPEG-4 Audio common code + * Copyright (c) 2008 Baptiste Coudurier <baptiste.coudurier@free.fr> + * + * 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 "bitstream.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 == 31) + 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 == 5) { + 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); + } else + c->ext_object_type = 0; + + specific_config_bitindex = get_bits_count(&gb); + + if (c->ext_object_type != 5) { + 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 == 5 && (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; +}