-
-
Save rcombs/310646411402baa7e068 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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