Skip to content

Instantly share code, notes, and snippets.

@rcombs

rcombs/stdin Secret

Created September 21, 2015 22:54
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rcombs/310646411402baa7e068 to your computer and use it in GitHub Desktop.
Save rcombs/310646411402baa7e068 to your computer and use it in GitHub Desktop.
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