Mercurial > libavcodec.hg
changeset 9788:b9563486a234 libavcodec
AAC ADTS to AudioSpecificConfig bitstream filter
author | alexc |
---|---|
date | Wed, 03 Jun 2009 18:50:46 +0000 |
parents | f114b5f2ac47 |
children | 391014285c25 |
files | Makefile aac_adtstoasc_bsf.c allcodecs.c |
diffstat | 3 files changed, 116 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- a/Makefile Wed Jun 03 11:23:16 2009 +0000 +++ b/Makefile Wed Jun 03 18:50:46 2009 +0000 @@ -416,6 +416,7 @@ OBJS-$(CONFIG_VP3_PARSER) += vp3_parser.o # bitstream filters +OBJS-$(CONFIG_AAC_ADTSTOASC_BSF) += aac_adtstoasc_bsf.o aac_parser.o mpeg4audio.o OBJS-$(CONFIG_DUMP_EXTRADATA_BSF) += dump_extradata_bsf.o OBJS-$(CONFIG_H264_MP4TOANNEXB_BSF) += h264_mp4toannexb_bsf.o OBJS-$(CONFIG_IMX_DUMP_HEADER_BSF) += imx_dump_header_bsf.o
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/aac_adtstoasc_bsf.c Wed Jun 03 18:50:46 2009 +0000 @@ -0,0 +1,114 @@ +/* + * MPEG-2/4 AAC ADTS to MPEG-4 Audio Specific Configuration bitstream filter + * 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 "avcodec.h" +#include "aac_parser.h" +#include "put_bits.h" +#include "get_bits.h" +#include "mpeg4audio.h" +#include "internal.h" + +typedef struct AACBSFContext { + int first_frame_done; +} AACBSFContext; + +/** + * This filter creates an MPEG-4 AudioSpecificConfig from an MPEG-2/4 + * ADTS header and removes the ADTS header. + */ +static int aac_adtstoasc_filter(AVBitStreamFilterContext *bsfc, + AVCodecContext *avctx, const char *args, + uint8_t **poutbuf, int *poutbuf_size, + const uint8_t *buf, int buf_size, + int keyframe) +{ + GetBitContext gb; + PutBitContext pb; + AACADTSHeaderInfo hdr; + + AACBSFContext *ctx = bsfc->priv_data; + + init_get_bits(&gb, buf, AAC_ADTS_HEADER_SIZE*8); + + *poutbuf = (uint8_t*) buf; + *poutbuf_size = buf_size; + + if (avctx->extradata) + if (show_bits(&gb, 12) != 0xfff) + return 0; + + if (ff_aac_parse_header(&gb, &hdr) < 0) { + av_log(avctx, AV_LOG_ERROR, "Error parsing ADTS frame header!\n"); + return -1; + } + + if (!hdr.crc_absent && hdr.num_aac_frames > 1) { + ff_log_missing_feature(avctx, "Multiple RDBs per frame with CRC is", 0); + return -1; + } + + buf += AAC_ADTS_HEADER_SIZE + 2*!hdr.crc_absent; + buf_size -= AAC_ADTS_HEADER_SIZE + 2*!hdr.crc_absent; + + if (!ctx->first_frame_done) { + int pce_size = 0; + uint8_t pce_data[MAX_PCE_SIZE]; + if (!hdr.chan_config) { + init_get_bits(&gb, buf, buf_size); + if (get_bits(&gb, 3) != 5) { + ff_log_missing_feature(avctx, "PCE based channel configuration, where the PCE is not the first syntax element is", 0); + return -1; + } + init_put_bits(&pb, pce_data, MAX_PCE_SIZE); + pce_size = ff_copy_pce_data(&pb, &gb)/8; + flush_put_bits(&pb); + buf_size -= get_bits_count(&gb)/8; + buf += get_bits_count(&gb)/8; + } + avctx->extradata_size = 2 + pce_size; + avctx->extradata = av_malloc(avctx->extradata_size); + + init_put_bits(&pb, avctx->extradata, avctx->extradata_size); + put_bits(&pb, 5, hdr.object_type); + put_bits(&pb, 4, hdr.sampling_index); + put_bits(&pb, 4, hdr.chan_config); + put_bits(&pb, 1, 0); //frame length - 1024 samples + put_bits(&pb, 1, 0); //does not depend on core coder + put_bits(&pb, 1, 0); //is not extension + flush_put_bits(&pb); + if (pce_size) { + memcpy(avctx->extradata + 2, pce_data, pce_size); + } + + ctx->first_frame_done = 1; + } + + *poutbuf = (uint8_t*) buf; + *poutbuf_size = buf_size; + + return 0; +} + +AVBitStreamFilter aac_adtstoasc_bsf = { + "aac_adtstoasc", + sizeof(AACBSFContext), + aac_adtstoasc_filter, +};
--- a/allcodecs.c Wed Jun 03 11:23:16 2009 +0000 +++ b/allcodecs.c Wed Jun 03 18:50:46 2009 +0000 @@ -339,6 +339,7 @@ REGISTER_PARSER (VP3, vp3); /* bitstream filters */ + REGISTER_BSF (AAC_ADTSTOASC, aac_adtstoasc); REGISTER_BSF (DUMP_EXTRADATA, dump_extradata); REGISTER_BSF (H264_MP4TOANNEXB, h264_mp4toannexb); REGISTER_BSF (IMX_DUMP_HEADER, imx_dump_header);