summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--contrib/ffmpeg/module.defs1
-rw-r--r--libhb/decavcodec.c30
-rw-r--r--libhb/muxavformat.c21
3 files changed, 51 insertions, 1 deletions
diff --git a/contrib/ffmpeg/module.defs b/contrib/ffmpeg/module.defs
index 9956083f4..5c4a1a8e4 100644
--- a/contrib/ffmpeg/module.defs
+++ b/contrib/ffmpeg/module.defs
@@ -17,6 +17,7 @@ FFMPEG.CONFIGURE.extra = \
--enable-gpl \
--disable-doc \
--disable-bsfs \
+ --enable-bsf=aac_adtstoasc \
--disable-avconv \
--disable-avplay \
--disable-avprobe \
diff --git a/libhb/decavcodec.c b/libhb/decavcodec.c
index d7fe2244d..2029aa21d 100644
--- a/libhb/decavcodec.c
+++ b/libhb/decavcodec.c
@@ -606,6 +606,7 @@ static int decavcodecaBSInfo( hb_work_object_t *w, const hb_buffer_t *buf,
{
hb_work_private_t *pv = w->private_data;
int ret = 0;
+ hb_audio_t *audio = w->audio;
memset( info, 0, sizeof(*info) );
@@ -630,7 +631,7 @@ static int decavcodecaBSInfo( hb_work_object_t *w, const hb_buffer_t *buf,
if (w->title && w->title->opaque_priv != NULL)
{
AVFormatContext *ic = (AVFormatContext*)w->title->opaque_priv;
- avcodec_copy_context(context, ic->streams[w->audio->id]->codec);
+ avcodec_copy_context(context, ic->streams[audio->id]->codec);
// libav's eac3 parser toggles the codec_id in the context as
// it reads eac3 data between AV_CODEC_ID_AC3 and AV_CODEC_ID_EAC3.
// It detects an AC3 sync pattern sometimes in ac3_sync() which
@@ -778,6 +779,33 @@ static int decavcodecaBSInfo( hb_work_object_t *w, const hb_buffer_t *buf,
info->mode = context->audio_service_type;
}
}
+ else if (context->codec_id == AV_CODEC_ID_AAC &&
+ context->extradata_size == 0)
+ {
+ // Parse ADTS AAC streams for AudioSpecificConfig.
+ // This data is required in order to write
+ // proper headers in MP4 and MKV files.
+ AVBitStreamFilterContext* aac_adtstoasc;
+ aac_adtstoasc = av_bitstream_filter_init("aac_adtstoasc");
+ if (aac_adtstoasc)
+ {
+ int ret, size;
+ uint8_t *data;
+ ret = av_bitstream_filter_filter(aac_adtstoasc, context,
+ NULL, &data, &size, avp.data, avp.size, 0);
+ if (ret >= 0 &&
+ context->extradata_size > 0 &&
+ audio->priv.config.extradata.length == 0)
+ {
+ int len;
+ len = MIN(context->extradata_size, HB_CONFIG_MAX_SIZE);
+ memcpy(audio->priv.config.extradata.bytes,
+ context->extradata, len);
+ audio->priv.config.extradata.length = len;
+ }
+ av_bitstream_filter_close(aac_adtstoasc);
+ }
+ }
ret = 1;
av_frame_free(&frame);
diff --git a/libhb/muxavformat.c b/libhb/muxavformat.c
index c5ebeb16a..9934c3551 100644
--- a/libhb/muxavformat.c
+++ b/libhb/muxavformat.c
@@ -32,6 +32,8 @@ struct hb_mux_data_s
int64_t prev_chapter_tc;
int16_t current_chapter;
+
+ AVBitStreamFilterContext* bitstream_filter;
};
struct hb_mux_object_s
@@ -524,6 +526,15 @@ static int avformatInit( hb_mux_object_t * m )
memcpy(priv_data,
audio->priv.config.extradata.bytes,
audio->priv.config.extradata.length);
+
+ // AAC from pass-through source may be ADTS.
+ // Therefore inserting "aac_adtstoasc" bitstream filter is
+ // preferred.
+ // The filter does nothing for non-ADTS bitstream.
+ if (audio->config.out.codec == HB_ACODEC_AAC_PASS)
+ {
+ track->bitstream_filter = av_bitstream_filter_init("aac_adtstoasc");
+ }
break;
default:
hb_error("muxavformat: Unknown audio codec: %x",
@@ -1177,6 +1188,11 @@ static int avformatMux(hb_mux_object_t *m, hb_mux_data_t *track, hb_buffer_t *bu
}
track->duration = pts + pkt.duration;
+ if (track->bitstream_filter)
+ {
+ av_bitstream_filter_filter(track->bitstream_filter, track->st->codec, NULL, &pkt.data, &pkt.size, pkt.data, pkt.size, 0);
+ }
+
pkt.stream_index = track->st->index;
int ret = av_interleaved_write_frame(m->oc, &pkt);
// Many avformat muxer functions do not check the error status
@@ -1215,6 +1231,11 @@ static int avformatEnd(hb_mux_object_t *m)
for (ii = 0; ii < m->ntracks; ii++)
{
avformatMux(m, m->tracks[ii], NULL);
+
+ if (m->tracks[ii]->bitstream_filter)
+ {
+ av_bitstream_filter_close(m->tracks[ii]->bitstream_filter);
+ }
}
if (job->chapter_markers)