| diff --git a/doc/bitstream_filters.texi b/doc/bitstream_filters.texi | |
| index 563049e..db0eec8 100644 | |
| --- a/doc/bitstream_filters.texi | |
| +++ b/doc/bitstream_filters.texi | |
| @@ -24,17 +24,6 @@ ffmpeg -i INPUT -c:v copy -bsf:v filter1[=opt1=str1/opt2=str2][,filter2] OUTPUT | |
| Below is a description of the currently available bitstream filters, | |
| with their parameters, if any. | |
| -@section aac_adtstoasc | |
| - | |
| -Convert MPEG-2/4 AAC ADTS to MPEG-4 Audio Specific Configuration | |
| -bitstream filter. | |
| - | |
| -This filter creates an MPEG-4 AudioSpecificConfig from an MPEG-2/4 | |
| -ADTS header and removes the ADTS header. | |
| - | |
| -This is required for example when copying an AAC stream from a raw | |
| -ADTS AAC container to a FLV or a MOV/MP4 file. | |
| - | |
| @section chomp | |
| Remove zero padding at the end of a packet. | |
| diff --git a/libavcodec/aac_ac3_parser.c b/libavcodec/aac_ac3_parser.c | |
| index 2f7d568..a101a60 100644 | |
| --- a/libavcodec/aac_ac3_parser.c | |
| +++ b/libavcodec/aac_ac3_parser.c | |
| @@ -24,6 +24,10 @@ | |
| #include "libavutil/common.h" | |
| #include "parser.h" | |
| #include "aac_ac3_parser.h" | |
| +#include "aacadtsdec.h" | |
| +#include "put_bits.h" | |
| +#include "get_bits.h" | |
| +#include "mpeg4audio.h" | |
| int ff_aac_ac3_parse(AVCodecParserContext *s1, | |
| AVCodecContext *avctx, | |
| @@ -36,25 +40,25 @@ int ff_aac_ac3_parse(AVCodecParserContext *s1, | |
| int new_frame_start; | |
| get_next: | |
| - i=END_NOT_FOUND; | |
| - if(s->remaining_size <= buf_size){ | |
| - if(s->remaining_size && !s->need_next_header){ | |
| - i= s->remaining_size; | |
| + i = END_NOT_FOUND; | |
| + if (s->remaining_size <= buf_size) { | |
| + if (s->remaining_size && !s->need_next_header) { | |
| + i = s->remaining_size; | |
| s->remaining_size = 0; | |
| - }else{ //we need a header first | |
| - len=0; | |
| - for(i=s->remaining_size; i<buf_size; i++){ | |
| - s->state = (s->state<<8) + buf[i]; | |
| - if((len=s->sync(s->state, s, &s->need_next_header, &new_frame_start))) | |
| + } else { //we need a header first | |
| + len = 0; | |
| + for (i = s->remaining_size; i < buf_size; i++){ | |
| + s->state = (s->state << 8) + buf[i]; | |
| + if ((len = s->sync(s->state, s, &s->need_next_header, &new_frame_start))) | |
| break; | |
| } | |
| - if(len<=0){ | |
| - i=END_NOT_FOUND; | |
| - }else{ | |
| - s->state=0; | |
| - i-= s->header_size -1; | |
| + if (len <= 0) { | |
| + i = END_NOT_FOUND; | |
| + } else { | |
| + s->state = 0; | |
| + i -= s->header_size - 1; | |
| s->remaining_size = len; | |
| - if(!new_frame_start || pc->index+i<=0){ | |
| + if (!new_frame_start || pc->index + i <= 0) { | |
| s->remaining_size += i; | |
| goto get_next; | |
| } | |
| @@ -62,16 +66,13 @@ get_next: | |
| } | |
| } | |
| - if(ff_combine_frame(pc, i, &buf, &buf_size)<0){ | |
| + if (ff_combine_frame(pc, i, &buf, &buf_size) < 0) { | |
| s->remaining_size -= FFMIN(s->remaining_size, buf_size); | |
| *poutbuf = NULL; | |
| *poutbuf_size = 0; | |
| return buf_size; | |
| } | |
| - *poutbuf = buf; | |
| - *poutbuf_size = buf_size; | |
| - | |
| /* update codec info */ | |
| if(s->codec_id) | |
| avctx->codec_id = s->codec_id; | |
| @@ -98,8 +99,66 @@ get_next: | |
| } | |
| s1->duration = s->samples; | |
| avctx->audio_service_type = s->service_type; | |
| + } else if (AV_RB16(buf) & 0xfff0 == 0xfff0) { | |
| + GetBitContext gb; | |
| + AACADTSHeaderInfo hdr; | |
| + int pce_size = 0; | |
| + uint8_t pce_data[MAX_PCE_SIZE]; | |
| + init_get_bits(&gb, buf, AAC_ADTS_HEADER_SIZE * 8); | |
| + if (avpriv_aac_parse_header(&gb, &hdr) < 0) { | |
| + av_log(avctx, AV_LOG_ERROR, "Error parsing ADTS frame header!\n"); | |
| + goto skip_extradata; | |
| + } | |
| + if (!hdr.crc_absent && hdr.num_aac_frames > 1) { | |
| + avpriv_report_missing_feature(avctx, "Multiple RDBs per frame with CRC"); | |
| + goto skip_extradata; | |
| + } | |
| + | |
| + buf += AAC_ADTS_HEADER_SIZE + 2 * !hdr.crc_absent; | |
| + buf_size -= AAC_ADTS_HEADER_SIZE + 2 * !hdr.crc_absent; | |
| + | |
| + if (!avctx->extradata) { | |
| + PutBitContext pb; | |
| + if (!hdr.chan_config) { | |
| + init_get_bits(&gb, buf, buf_size * 8); | |
| + if (get_bits(&gb, 3) != 5) { | |
| + avpriv_report_missing_feature(avctx, | |
| + "PCE-based channel configuration " | |
| + "without PCE as first syntax " | |
| + "element"); | |
| + goto skip_extradata; | |
| + } | |
| + init_put_bits(&pb, pce_data, MAX_PCE_SIZE); | |
| + pce_size = avpriv_copy_pce_data(&pb, &gb) / 8; | |
| + flush_put_bits(&pb); | |
| + buf_size -= get_bits_count(&gb) / 8; | |
| + buf += get_bits_count(&gb) / 8; | |
| + } | |
| + av_free(avctx->extradata); | |
| + avctx->extradata_size = 2 + pce_size; | |
| + avctx->extradata = av_mallocz(avctx->extradata_size + AV_INPUT_BUFFER_PADDING_SIZE); | |
| + if (!avctx->extradata) { | |
| + avctx->extradata_size = 0; | |
| + goto skip_extradata; | |
| + } | |
| + | |
| + 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); | |
| + } | |
| } | |
| + *poutbuf = buf; | |
| + *poutbuf_size = buf_size; | |
| + | |
| +skip_extradata: | |
| avctx->bit_rate = s->bit_rate; | |
| return i; | |
| diff --git a/libavcodec/aac_adtstoasc_bsf.c b/libavcodec/aac_adtstoasc_bsf.c | |
| index 9c117c6..17cf2fb 100644 | |
| --- a/libavcodec/aac_adtstoasc_bsf.c | |
| +++ b/libavcodec/aac_adtstoasc_bsf.c | |
| @@ -30,89 +30,19 @@ 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 (avpriv_aac_parse_header(&gb, &hdr) < 0) { | |
| - av_log(avctx, AV_LOG_ERROR, "Error parsing ADTS frame header!\n"); | |
| - return AVERROR_INVALIDDATA; | |
| - } | |
| - | |
| - if (!hdr.crc_absent && hdr.num_aac_frames > 1) { | |
| - avpriv_report_missing_feature(avctx, | |
| - "Multiple RDBs per frame with CRC"); | |
| - return AVERROR_PATCHWELCOME; | |
| - } | |
| - | |
| - 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 * 8); | |
| - if (get_bits(&gb, 3) != 5) { | |
| - avpriv_report_missing_feature(avctx, | |
| - "PCE-based channel configuration " | |
| - "without PCE as first syntax " | |
| - "element"); | |
| - return AVERROR_PATCHWELCOME; | |
| - } | |
| - init_put_bits(&pb, pce_data, MAX_PCE_SIZE); | |
| - pce_size = avpriv_copy_pce_data(&pb, &gb)/8; | |
| - flush_put_bits(&pb); | |
| - buf_size -= get_bits_count(&gb)/8; | |
| - buf += get_bits_count(&gb)/8; | |
| - } | |
| - av_free(avctx->extradata); | |
| - avctx->extradata_size = 2 + pce_size; | |
| - avctx->extradata = av_mallocz(avctx->extradata_size + AV_INPUT_BUFFER_PADDING_SIZE); | |
| - if (!avctx->extradata) { | |
| - avctx->extradata_size = 0; | |
| - return AVERROR(ENOMEM); | |
| - } | |
| - | |
| - 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); | |
| - } | |
| + av_log(avctx, AV_LOG_WARNING, "The aac_adtstoasc bitstream filter is\n" | |
| + "no longer required.\n"); | |
| ctx->first_frame_done = 1; | |
| } | |
| - *poutbuf = (uint8_t*) buf; | |
| - *poutbuf_size = buf_size; | |
| - | |
| return 0; | |
| } | |
| diff --git a/libavcodec/aacdec_template.c b/libavcodec/aacdec_template.c | |
| index c2d7d05..a999013 100644 | |
| --- a/libavcodec/aacdec_template.c | |
| +++ b/libavcodec/aacdec_template.c | |
| @@ -3118,6 +3118,14 @@ static int aac_decode_frame(AVCodecContext *avctx, void *data, | |
| } | |
| } | |
| + if (!avctx->channels && avctx->extradata_size > 0) { | |
| + if ((err = decode_audio_specific_config(ac, ac->avctx, &ac->oc[1].m4ac, | |
| + avctx->extradata, | |
| + avctx->extradata_size * 8LL, | |
| + 1)) < 0) | |
| + return AVERROR_INVALIDDATA; | |
| + } | |
| + | |
| ac->dmono_mode = 0; | |
| if (jp_dualmono && jp_dualmono_size > 0) | |
| ac->dmono_mode = 1 + *jp_dualmono; | |
| diff --git a/libavformat/flvenc.c b/libavformat/flvenc.c | |
| index e217ba8..da8f5b9 100644 | |
| --- a/libavformat/flvenc.c | |
| +++ b/libavformat/flvenc.c | |
| @@ -568,12 +568,6 @@ static int flv_write_packet(AVFormatContext *s, AVPacket *pkt) | |
| return ret; | |
| } else if (enc->codec_id == AV_CODEC_ID_AAC && pkt->size > 2 && | |
| (AV_RB16(pkt->data) & 0xfff0) == 0xfff0) { | |
| - if (!s->streams[pkt->stream_index]->nb_frames) { | |
| - av_log(s, AV_LOG_ERROR, "Malformed AAC bitstream detected: " | |
| - "use the audio bitstream filter 'aac_adtstoasc' to fix it " | |
| - "('-bsf:a aac_adtstoasc' option with ffmpeg)\n"); | |
| - return AVERROR_INVALIDDATA; | |
| - } | |
| av_log(s, AV_LOG_WARNING, "aac bitstream error\n"); | |
| } | |
| diff --git a/libavformat/movenc.c b/libavformat/movenc.c | |
| index af03d1e..1af4031 100644 | |
| --- a/libavformat/movenc.c | |
| +++ b/libavformat/movenc.c | |
| @@ -4382,12 +4382,6 @@ int ff_mov_write_packet(AVFormatContext *s, AVPacket *pkt) | |
| if (enc->codec_id == AV_CODEC_ID_AAC && pkt->size > 2 && | |
| (AV_RB16(pkt->data) & 0xfff0) == 0xfff0) { | |
| - if (!s->streams[pkt->stream_index]->nb_frames) { | |
| - av_log(s, AV_LOG_ERROR, "Malformed AAC bitstream detected: " | |
| - "use the audio bitstream filter 'aac_adtstoasc' to fix it " | |
| - "('-bsf:a aac_adtstoasc' option with ffmpeg)\n"); | |
| - return -1; | |
| - } | |
| av_log(s, AV_LOG_WARNING, "aac bitstream error\n"); | |
| } | |
| if (enc->codec_id == AV_CODEC_ID_H264 && trk->vos_len > 0 && *(uint8_t *)trk->vos_data != 1 && !TAG_IS_AVCI(trk->tag)) { | |
| diff --git a/tests/ref/fate/adts-demux b/tests/ref/fate/adts-demux | |
| index 744ae64..78898cc 100644 | |
| --- a/tests/ref/fate/adts-demux | |
| +++ b/tests/ref/fate/adts-demux | |
| @@ -1 +1 @@ | |
| -CRC=0xbda37454 | |
| +CRC=0x6def5f3d |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment