summaryrefslogtreecommitdiffstats
path: root/libhb/muxavformat.c
diff options
context:
space:
mode:
Diffstat (limited to 'libhb/muxavformat.c')
-rw-r--r--libhb/muxavformat.c196
1 files changed, 106 insertions, 90 deletions
diff --git a/libhb/muxavformat.c b/libhb/muxavformat.c
index abdee80b5..5167ddb6c 100644
--- a/libhb/muxavformat.c
+++ b/libhb/muxavformat.c
@@ -33,7 +33,7 @@ struct hb_mux_data_s
int64_t prev_chapter_tc;
int16_t current_chapter;
- AVBitStreamFilterContext* bitstream_filter;
+ AVBSFContext * bitstream_context;
};
struct hb_mux_object_s
@@ -204,11 +204,9 @@ static int avformatInit( hb_mux_object_t * m )
hb_error("Could not initialize video stream");
goto error;
}
- track->st->time_base = m->time_base;
- avcodec_get_context_defaults3(track->st->codec, NULL);
- track->st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
- track->st->codec->flags |= CODEC_FLAG_GLOBAL_HEADER;
+ track->st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
+ track->st->time_base = m->time_base;
uint8_t *priv_data = NULL;
int priv_size = 0;
@@ -217,7 +215,7 @@ static int avformatInit( hb_mux_object_t * m )
case HB_VCODEC_X264_8BIT:
case HB_VCODEC_X264_10BIT:
case HB_VCODEC_QSV_H264:
- track->st->codec->codec_id = AV_CODEC_ID_H264;
+ track->st->codecpar->codec_id = AV_CODEC_ID_H264;
/* Taken from x264 muxers.c */
priv_size = 5 + 1 + 2 + job->config.h264.sps_length + 1 + 2 +
@@ -253,7 +251,7 @@ static int avformatInit( hb_mux_object_t * m )
break;
case HB_VCODEC_FFMPEG_MPEG4:
- track->st->codec->codec_id = AV_CODEC_ID_MPEG4;
+ track->st->codecpar->codec_id = AV_CODEC_ID_MPEG4;
if (job->config.mpeg4.length != 0)
{
@@ -269,7 +267,7 @@ static int avformatInit( hb_mux_object_t * m )
break;
case HB_VCODEC_FFMPEG_MPEG2:
- track->st->codec->codec_id = AV_CODEC_ID_MPEG2VIDEO;
+ track->st->codecpar->codec_id = AV_CODEC_ID_MPEG2VIDEO;
if (job->config.mpeg4.length != 0)
{
@@ -285,20 +283,20 @@ static int avformatInit( hb_mux_object_t * m )
break;
case HB_VCODEC_FFMPEG_VP8:
- track->st->codec->codec_id = AV_CODEC_ID_VP8;
+ track->st->codecpar->codec_id = AV_CODEC_ID_VP8;
priv_data = NULL;
priv_size = 0;
break;
case HB_VCODEC_FFMPEG_VP9:
- track->st->codec->codec_id = AV_CODEC_ID_VP9;
+ track->st->codecpar->codec_id = AV_CODEC_ID_VP9;
priv_data = NULL;
priv_size = 0;
break;
case HB_VCODEC_THEORA:
{
- track->st->codec->codec_id = AV_CODEC_ID_THEORA;
+ track->st->codecpar->codec_id = AV_CODEC_ID_THEORA;
int size = 0;
ogg_packet *ogg_headers[3];
@@ -333,7 +331,7 @@ static int avformatInit( hb_mux_object_t * m )
case HB_VCODEC_X265_12BIT:
case HB_VCODEC_X265_16BIT:
case HB_VCODEC_QSV_H265:
- track->st->codec->codec_id = AV_CODEC_ID_HEVC;
+ track->st->codecpar->codec_id = AV_CODEC_ID_HEVC;
if (job->config.h265.headers_length > 0)
{
@@ -352,15 +350,15 @@ static int avformatInit( hb_mux_object_t * m )
hb_error("muxavformat: Unknown video codec: %x", job->vcodec);
goto error;
}
- track->st->codec->extradata = priv_data;
- track->st->codec->extradata_size = priv_size;
+ track->st->codecpar->extradata = priv_data;
+ track->st->codecpar->extradata_size = priv_size;
track->st->sample_aspect_ratio.num = job->par.num;
track->st->sample_aspect_ratio.den = job->par.den;
- track->st->codec->sample_aspect_ratio.num = job->par.num;
- track->st->codec->sample_aspect_ratio.den = job->par.den;
- track->st->codec->width = job->width;
- track->st->codec->height = job->height;
+ track->st->codecpar->sample_aspect_ratio.num = job->par.num;
+ track->st->codecpar->sample_aspect_ratio.den = job->par.den;
+ track->st->codecpar->width = job->width;
+ track->st->codecpar->height = job->height;
track->st->disposition |= AV_DISPOSITION_DEFAULT;
hb_rational_t vrate = job->vrate;
@@ -384,20 +382,6 @@ static int avformatInit( hb_mux_object_t * m )
}
}
hb_reduce(&vrate.num, &vrate.den, vrate.num, vrate.den);
- if (job->mux == HB_MUX_AV_MP4)
- {
- // libavformat mp4 muxer requires that the codec time_base have the
- // same denominator as the stream time_base, it uses it for the
- // mdhd timescale.
- double scale = (double)track->st->time_base.den / vrate.num;
- track->st->codec->time_base.den = track->st->time_base.den;
- track->st->codec->time_base.num = vrate.den * scale;
- }
- else
- {
- track->st->codec->time_base.num = vrate.den;
- track->st->codec->time_base.den = vrate.num;
- }
track->st->avg_frame_rate.num = vrate.num;
track->st->avg_frame_rate.den = vrate.den;
@@ -416,20 +400,15 @@ static int avformatInit( hb_mux_object_t * m )
hb_error("Could not initialize audio stream");
goto error;
}
- avcodec_get_context_defaults3(track->st->codec, NULL);
- track->st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
- track->st->codec->flags |= CODEC_FLAG_GLOBAL_HEADER;
+ track->st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
if (job->mux == HB_MUX_AV_MP4)
{
- track->st->codec->time_base.num = audio->config.out.samples_per_frame;
- track->st->codec->time_base.den = audio->config.out.samplerate;
track->st->time_base.num = 1;
track->st->time_base.den = audio->config.out.samplerate;
}
else
{
- track->st->codec->time_base = m->time_base;
track->st->time_base = m->time_base;
}
@@ -439,24 +418,24 @@ static int avformatInit( hb_mux_object_t * m )
{
case HB_ACODEC_DCA:
case HB_ACODEC_DCA_HD:
- track->st->codec->codec_id = AV_CODEC_ID_DTS;
+ track->st->codecpar->codec_id = AV_CODEC_ID_DTS;
break;
case HB_ACODEC_AC3:
- track->st->codec->codec_id = AV_CODEC_ID_AC3;
+ track->st->codecpar->codec_id = AV_CODEC_ID_AC3;
break;
case HB_ACODEC_FFEAC3:
- track->st->codec->codec_id = AV_CODEC_ID_EAC3;
+ track->st->codecpar->codec_id = AV_CODEC_ID_EAC3;
break;
case HB_ACODEC_FFTRUEHD:
- track->st->codec->codec_id = AV_CODEC_ID_TRUEHD;
+ track->st->codecpar->codec_id = AV_CODEC_ID_TRUEHD;
break;
case HB_ACODEC_LAME:
case HB_ACODEC_MP3:
- track->st->codec->codec_id = AV_CODEC_ID_MP3;
+ track->st->codecpar->codec_id = AV_CODEC_ID_MP3;
break;
case HB_ACODEC_VORBIS:
{
- track->st->codec->codec_id = AV_CODEC_ID_VORBIS;
+ track->st->codecpar->codec_id = AV_CODEC_ID_VORBIS;
int jj, size = 0;
ogg_packet *ogg_headers[3];
@@ -486,7 +465,7 @@ static int avformatInit( hb_mux_object_t * m )
}
} break;
case HB_ACODEC_OPUS:
- track->st->codec->codec_id = AV_CODEC_ID_OPUS;
+ track->st->codecpar->codec_id = AV_CODEC_ID_OPUS;
if (audio->priv.config.extradata.length)
{
@@ -504,7 +483,7 @@ static int avformatInit( hb_mux_object_t * m )
break;
case HB_ACODEC_FFFLAC:
case HB_ACODEC_FFFLAC24:
- track->st->codec->codec_id = AV_CODEC_ID_FLAC;
+ track->st->codecpar->codec_id = AV_CODEC_ID_FLAC;
if (audio->priv.config.extradata.length)
{
@@ -525,7 +504,7 @@ static int avformatInit( hb_mux_object_t * m )
case HB_ACODEC_CA_HAAC:
case HB_ACODEC_FDK_AAC:
case HB_ACODEC_FDK_HAAC:
- track->st->codec->codec_id = AV_CODEC_ID_AAC;
+ track->st->codecpar->codec_id = AV_CODEC_ID_AAC;
// libav mkv muxer expects there to be extradata for
// AAC and will crash if it is NULL.
@@ -551,7 +530,20 @@ static int avformatInit( hb_mux_object_t * m )
// 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");
+ const AVBitStreamFilter * bsf;
+ AVBSFContext * ctx;
+ int ret;
+
+ bsf = av_bsf_get_by_name("aac_adtstoasc");
+ ret = av_bsf_alloc(bsf, &ctx);
+ if (ret < 0)
+ {
+ hb_error("AAC bistream filter: alloc failure");
+ goto error;
+ }
+ ctx->time_base_in.num = 1;
+ ctx->time_base_in.den = audio->config.out.samplerate;
+ track->bitstream_context = ctx;
}
break;
default:
@@ -559,8 +551,21 @@ static int avformatInit( hb_mux_object_t * m )
audio->config.out.codec);
goto error;
}
- track->st->codec->extradata = priv_data;
- track->st->codec->extradata_size = priv_size;
+ track->st->codecpar->extradata = priv_data;
+ track->st->codecpar->extradata_size = priv_size;
+ if (track->bitstream_context != NULL)
+ {
+ int ret;
+
+ avcodec_parameters_copy(track->bitstream_context->par_in,
+ track->st->codecpar);
+ ret = av_bsf_init(track->bitstream_context);
+ if (ret < 0)
+ {
+ hb_error("bistream filter: init failure");
+ goto error;
+ }
+ }
if( default_track_flag )
{
@@ -573,22 +578,22 @@ static int avformatInit( hb_mux_object_t * m )
{
av_dict_set(&track->st->metadata, "language", lang, 0);
}
- track->st->codec->sample_rate = audio->config.out.samplerate;
+ track->st->codecpar->sample_rate = audio->config.out.samplerate;
if (audio->config.out.codec & HB_ACODEC_PASS_FLAG)
{
- track->st->codec->channels = av_get_channel_layout_nb_channels(audio->config.in.channel_layout);
- track->st->codec->channel_layout = audio->config.in.channel_layout;
+ track->st->codecpar->channels = av_get_channel_layout_nb_channels(audio->config.in.channel_layout);
+ track->st->codecpar->channel_layout = audio->config.in.channel_layout;
}
else
{
- track->st->codec->channels = hb_mixdown_get_discrete_channel_count(audio->config.out.mixdown);
- track->st->codec->channel_layout = hb_ff_mixdown_xlat(audio->config.out.mixdown, NULL);
+ track->st->codecpar->channels = hb_mixdown_get_discrete_channel_count(audio->config.out.mixdown);
+ track->st->codecpar->channel_layout = hb_ff_mixdown_xlat(audio->config.out.mixdown, NULL);
}
char *name;
if (audio->config.out.name == NULL)
{
- switch (track->st->codec->channels)
+ switch (track->st->codecpar->channels)
{
case 1:
name = "Mono";
@@ -724,14 +729,11 @@ static int avformatInit( hb_mux_object_t * m )
hb_error("Could not initialize subtitle stream");
goto error;
}
- avcodec_get_context_defaults3(track->st->codec, NULL);
- track->st->codec->codec_type = AVMEDIA_TYPE_SUBTITLE;
- track->st->codec->flags |= CODEC_FLAG_GLOBAL_HEADER;
+ track->st->codecpar->codec_type = AVMEDIA_TYPE_SUBTITLE;
track->st->time_base = m->time_base;
- track->st->codec->time_base = m->time_base;
- track->st->codec->width = subtitle->width;
- track->st->codec->height = subtitle->height;
+ track->st->codecpar->width = subtitle->width;
+ track->st->codecpar->height = subtitle->height;
priv_data = NULL;
priv_size = 0;
@@ -740,7 +742,7 @@ static int avformatInit( hb_mux_object_t * m )
case VOBSUB:
{
int jj;
- track->st->codec->codec_id = AV_CODEC_ID_DVD_SUBTITLE;
+ track->st->codecpar->codec_id = AV_CODEC_ID_DVD_SUBTITLE;
for (jj = 0; jj < 16; jj++)
rgb[jj] = hb_yuv2rgb(subtitle->palette[jj]);
@@ -764,7 +766,7 @@ static int avformatInit( hb_mux_object_t * m )
case PGSSUB:
{
- track->st->codec->codec_id = AV_CODEC_ID_HDMV_PGS_SUBTITLE;
+ track->st->codecpar->codec_id = AV_CODEC_ID_HDMV_PGS_SUBTITLE;
} break;
case CC608SUB:
@@ -776,11 +778,11 @@ static int avformatInit( hb_mux_object_t * m )
{
if (job->mux == HB_MUX_AV_MP4)
{
- track->st->codec->codec_id = AV_CODEC_ID_MOV_TEXT;
+ track->st->codecpar->codec_id = AV_CODEC_ID_MOV_TEXT;
}
else
{
- track->st->codec->codec_id = AV_CODEC_ID_SSA;
+ track->st->codecpar->codec_id = AV_CODEC_ID_SSA;
need_fonts = 1;
if (subtitle->extradata_size)
@@ -800,7 +802,7 @@ static int avformatInit( hb_mux_object_t * m )
default:
continue;
}
- if (track->st->codec->codec_id == AV_CODEC_ID_MOV_TEXT)
+ if (track->st->codecpar->codec_id == AV_CODEC_ID_MOV_TEXT)
{
// Build codec extradata for tx3g.
// If we were using a libav codec to generate this data
@@ -828,8 +830,8 @@ static int avformatInit( hb_mux_object_t * m )
int width, height = 60;
width = job->width * job->par.num / job->par.den;
- track->st->codec->width = width;
- track->st->codec->height = height;
+ track->st->codecpar->width = width;
+ track->st->codecpar->height = height;
properties[14] = height >> 8;
properties[15] = height & 0xff;
properties[16] = width >> 8;
@@ -844,8 +846,8 @@ static int avformatInit( hb_mux_object_t * m )
}
memcpy(priv_data, properties, priv_size);
}
- track->st->codec->extradata = priv_data;
- track->st->codec->extradata_size = priv_size;
+ track->st->codecpar->extradata = priv_data;
+ track->st->codecpar->extradata_size = priv_size;
if (ii == subtitle_default)
{
@@ -880,16 +882,15 @@ static int avformatInit( hb_mux_object_t * m )
hb_error("Could not initialize attachment stream");
goto error;
}
- avcodec_get_context_defaults3(st->codec, NULL);
- st->codec->codec_type = AVMEDIA_TYPE_ATTACHMENT;
+ st->codecpar->codec_type = AVMEDIA_TYPE_ATTACHMENT;
if (attachment->type == FONT_TTF_ATTACH)
{
- st->codec->codec_id = AV_CODEC_ID_TTF;
+ st->codecpar->codec_id = AV_CODEC_ID_TTF;
}
else if (attachment->type == FONT_OTF_ATTACH)
{
- st->codec->codec_id = MKBETAG( 0 ,'O','T','F');
+ st->codecpar->codec_id = MKBETAG( 0 ,'O','T','F');
av_dict_set(&st->metadata, "mimetype", "application/vnd.ms-opentype", 0);
}
@@ -902,8 +903,8 @@ static int avformatInit( hb_mux_object_t * m )
}
memcpy(priv_data, attachment->data, priv_size);
- st->codec->extradata = priv_data;
- st->codec->extradata_size = priv_size;
+ st->codecpar->extradata = priv_data;
+ st->codecpar->extradata_size = priv_size;
av_dict_set(&st->metadata, "filename", attachment->name, 0);
}
@@ -1090,7 +1091,6 @@ static int avformatMux(hb_mux_object_t *m, hb_mux_data_t *track, hb_buffer_t *bu
empty_pkt.dts = track->duration;
empty_pkt.pts = track->duration;
empty_pkt.duration = 90;
- empty_pkt.convergence_duration = empty_pkt.duration;
empty_pkt.stream_index = track->st->index;
av_interleaved_write_frame(m->oc, &empty_pkt);
}
@@ -1147,7 +1147,7 @@ static int avformatMux(hb_mux_object_t *m, hb_mux_data_t *track, hb_buffer_t *bu
// 10 seconds in this case. Unless they are PGS subs which should
// have zero duration.
if (track->type == MUX_TYPE_SUBTITLE &&
- track->st->codec->codec_id != AV_CODEC_ID_HDMV_PGS_SUBTITLE)
+ track->st->codecpar->codec_id != AV_CODEC_ID_HDMV_PGS_SUBTITLE)
duration = av_rescale_q(10, (AVRational){1,1},
track->st->time_base);
else
@@ -1231,7 +1231,6 @@ static int avformatMux(hb_mux_object_t *m, hb_mux_data_t *track, hb_buffer_t *bu
empty_pkt.dts = track->duration;
empty_pkt.pts = track->duration;
empty_pkt.duration = pts - track->duration;
- empty_pkt.convergence_duration = empty_pkt.duration;
empty_pkt.stream_index = track->st->index;
int ret = av_interleaved_write_frame(m->oc, &empty_pkt);
if (ret < 0)
@@ -1245,7 +1244,7 @@ static int avformatMux(hb_mux_object_t *m, hb_mux_data_t *track, hb_buffer_t *bu
return -1;
}
}
- if (track->st->codec->codec_id == AV_CODEC_ID_MOV_TEXT)
+ if (track->st->codecpar->codec_id == AV_CODEC_ID_MOV_TEXT)
{
uint8_t * styleatom;
uint16_t stylesize = 0;
@@ -1280,7 +1279,7 @@ static int avformatMux(hb_mux_object_t *m, hb_mux_data_t *track, hb_buffer_t *bu
free(styleatom);
}
}
- if (track->st->codec->codec_id == AV_CODEC_ID_SSA &&
+ if (track->st->codecpar->codec_id == AV_CODEC_ID_SSA &&
job->mux == HB_MUX_AV_MKV)
{
// avformat requires the this additional information
@@ -1323,7 +1322,6 @@ static int avformatMux(hb_mux_object_t *m, hb_mux_data_t *track, hb_buffer_t *bu
*job->die = 1;
return -1;
}
- pkt.convergence_duration = pkt.duration;
} break;
case MUX_TYPE_AUDIO:
default:
@@ -1331,9 +1329,27 @@ 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)
+ if (track->bitstream_context)
{
- av_bitstream_filter_filter(track->bitstream_filter, track->st->codec, NULL, &pkt.data, &pkt.size, pkt.data, pkt.size, 0);
+ int ret;
+ ret = av_bsf_send_packet(track->bitstream_context, &pkt);
+ if (ret < 0)
+ {
+ hb_error("avformatMux: track %d av_bsf_send_packet failed",
+ track->st->index);
+ return ret;
+ }
+ ret = av_bsf_receive_packet(track->bitstream_context, &pkt);
+ if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
+ {
+ return 0;
+ }
+ else if (ret < 0)
+ {
+ hb_error("avformatMux: track %d av_bsf_receive_packet failed",
+ track->st->index);
+ return ret;
+ }
}
pkt.stream_index = track->st->index;
@@ -1379,9 +1395,9 @@ static int avformatEnd(hb_mux_object_t *m)
{
avformatMux(m, m->tracks[ii], NULL);
- if (m->tracks[ii]->bitstream_filter)
+ if (m->tracks[ii]->bitstream_context)
{
- av_bitstream_filter_close(m->tracks[ii]->bitstream_filter);
+ av_bsf_free(&m->tracks[ii]->bitstream_context);
}
}
@@ -1428,7 +1444,7 @@ static int avformatEnd(hb_mux_object_t *m)
int priv_size;
priv_size = audio->priv.config.extradata.length;
- priv_data = av_realloc(st->codec->extradata, priv_size +
+ priv_data = av_realloc(st->codecpar->extradata, priv_size +
FF_INPUT_BUFFER_PADDING_SIZE);
if (priv_data == NULL)
{
@@ -1437,8 +1453,8 @@ static int avformatEnd(hb_mux_object_t *m)
memcpy(priv_data,
audio->priv.config.extradata.bytes,
audio->priv.config.extradata.length);
- st->codec->extradata = priv_data;
- st->codec->extradata_size = priv_size;
+ st->codecpar->extradata = priv_data;
+ st->codecpar->extradata_size = priv_size;
}
break;
default: