Libav
|
00001 /* 00002 * MPEG-2/4 AAC ADTS to MPEG-4 Audio Specific Configuration bitstream filter 00003 * Copyright (c) 2009 Alex Converse <alex.converse@gmail.com> 00004 * 00005 * This file is part of FFmpeg. 00006 * 00007 * FFmpeg is free software; you can redistribute it and/or 00008 * modify it under the terms of the GNU Lesser General Public 00009 * License as published by the Free Software Foundation; either 00010 * version 2.1 of the License, or (at your option) any later version. 00011 * 00012 * FFmpeg is distributed in the hope that it will be useful, 00013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00015 * Lesser General Public License for more details. 00016 * 00017 * You should have received a copy of the GNU Lesser General Public 00018 * License along with FFmpeg; if not, write to the Free Software 00019 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 00020 */ 00021 00022 #include "avcodec.h" 00023 #include "aac_parser.h" 00024 #include "put_bits.h" 00025 #include "get_bits.h" 00026 #include "mpeg4audio.h" 00027 #include "internal.h" 00028 00029 typedef struct AACBSFContext { 00030 int first_frame_done; 00031 } AACBSFContext; 00032 00037 static int aac_adtstoasc_filter(AVBitStreamFilterContext *bsfc, 00038 AVCodecContext *avctx, const char *args, 00039 uint8_t **poutbuf, int *poutbuf_size, 00040 const uint8_t *buf, int buf_size, 00041 int keyframe) 00042 { 00043 GetBitContext gb; 00044 PutBitContext pb; 00045 AACADTSHeaderInfo hdr; 00046 00047 AACBSFContext *ctx = bsfc->priv_data; 00048 00049 init_get_bits(&gb, buf, AAC_ADTS_HEADER_SIZE*8); 00050 00051 *poutbuf = (uint8_t*) buf; 00052 *poutbuf_size = buf_size; 00053 00054 if (avctx->extradata) 00055 if (show_bits(&gb, 12) != 0xfff) 00056 return 0; 00057 00058 if (ff_aac_parse_header(&gb, &hdr) < 0) { 00059 av_log(avctx, AV_LOG_ERROR, "Error parsing ADTS frame header!\n"); 00060 return -1; 00061 } 00062 00063 if (!hdr.crc_absent && hdr.num_aac_frames > 1) { 00064 av_log_missing_feature(avctx, "Multiple RDBs per frame with CRC is", 0); 00065 return -1; 00066 } 00067 00068 buf += AAC_ADTS_HEADER_SIZE + 2*!hdr.crc_absent; 00069 buf_size -= AAC_ADTS_HEADER_SIZE + 2*!hdr.crc_absent; 00070 00071 if (!ctx->first_frame_done) { 00072 int pce_size = 0; 00073 uint8_t pce_data[MAX_PCE_SIZE]; 00074 if (!hdr.chan_config) { 00075 init_get_bits(&gb, buf, buf_size); 00076 if (get_bits(&gb, 3) != 5) { 00077 av_log_missing_feature(avctx, "PCE based channel configuration, where the PCE is not the first syntax element is", 0); 00078 return -1; 00079 } 00080 init_put_bits(&pb, pce_data, MAX_PCE_SIZE); 00081 pce_size = ff_copy_pce_data(&pb, &gb)/8; 00082 flush_put_bits(&pb); 00083 buf_size -= get_bits_count(&gb)/8; 00084 buf += get_bits_count(&gb)/8; 00085 } 00086 avctx->extradata_size = 2 + pce_size; 00087 avctx->extradata = av_mallocz(avctx->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE); 00088 00089 init_put_bits(&pb, avctx->extradata, avctx->extradata_size); 00090 put_bits(&pb, 5, hdr.object_type); 00091 put_bits(&pb, 4, hdr.sampling_index); 00092 put_bits(&pb, 4, hdr.chan_config); 00093 put_bits(&pb, 1, 0); //frame length - 1024 samples 00094 put_bits(&pb, 1, 0); //does not depend on core coder 00095 put_bits(&pb, 1, 0); //is not extension 00096 flush_put_bits(&pb); 00097 if (pce_size) { 00098 memcpy(avctx->extradata + 2, pce_data, pce_size); 00099 } 00100 00101 ctx->first_frame_done = 1; 00102 } 00103 00104 *poutbuf = (uint8_t*) buf; 00105 *poutbuf_size = buf_size; 00106 00107 return 0; 00108 } 00109 00110 AVBitStreamFilter aac_adtstoasc_bsf = { 00111 "aac_adtstoasc", 00112 sizeof(AACBSFContext), 00113 aac_adtstoasc_filter, 00114 };