From 36cfff2deda5a602a7224b355a5d9b1196a12b2f Mon Sep 17 00:00:00 2001 From: John Stebbins Date: Thu, 1 Nov 2018 13:56:44 -0700 Subject: [PATCH] encavcodec: fix passing extradata to muxer The extradata handling hasn't changed since 0.7 when we only used encavcodec for mpeg4 encoding. It was not designed to handle the additional codecs we are encoding now. --- libhb/encavcodec.c | 37 +++------------------- libhb/muxavformat.c | 76 ++++++++++++++++++++++++++++++++++++++------- 2 files changed, 69 insertions(+), 44 deletions(-) diff --git a/libhb/encavcodec.c b/libhb/encavcodec.c index 5cdc5df38..dc94310c6 100644 --- a/libhb/encavcodec.c +++ b/libhb/encavcodec.c @@ -400,10 +400,7 @@ int encavcodecInit( hb_work_object_t * w, hb_job_t * job ) context->color_trc = job->color_transfer; context->colorspace = job->color_matrix; - if( job->mux & HB_MUX_MASK_MP4 ) - { - context->flags |= AV_CODEC_FLAG_GLOBAL_HEADER; - } + context->flags |= AV_CODEC_FLAG_GLOBAL_HEADER; if( job->grayscale ) { context->flags |= AV_CODEC_FLAG_GRAY; @@ -555,35 +552,11 @@ int encavcodecInit( hb_work_object_t * w, hb_job_t * job ) job->areBframes = 1; } - if( ( job->mux & HB_MUX_MASK_MP4 ) && job->pass_id != HB_PASS_ENCODE_1ST ) + if (context->extradata != NULL) { - if (w->codec_param == AV_CODEC_ID_H264) // FIXME: h265 as well? - { - // Scan extradata for the SPS/PPS headers - unsigned char *data = context->extradata; - unsigned char *dataEnd = context->extradata + context->extradata_size; - size_t len = dataEnd - data; - - while ((data = hb_annexb_find_next_nalu(data, &len)) != NULL) { - if ((data[0] & 0x1f) == 7) { - // SPS found, copy into work object - w->config->h264.sps_length = len; - memcpy(w->config->h264.sps, data, len); - } - if ((data[0] & 0x1f) == 8) { - // PPS found, copy into work object - w->config->h264.pps_length = len; - memcpy(w->config->h264.pps, data, len); - } - len = dataEnd - data; - } - } - else - { - w->config->mpeg4.length = context->extradata_size; - memcpy( w->config->mpeg4.bytes, context->extradata, - context->extradata_size ); - } + memcpy(w->config->extradata.bytes, context->extradata, + context->extradata_size); + w->config->extradata.length = context->extradata_size; } done: diff --git a/libhb/muxavformat.c b/libhb/muxavformat.c index 65d706565..0df30d412 100644 --- a/libhb/muxavformat.c +++ b/libhb/muxavformat.c @@ -207,8 +207,6 @@ static int avformatInit( hb_mux_object_t * m ) case HB_VCODEC_X264_8BIT: case HB_VCODEC_X264_10BIT: case HB_VCODEC_QSV_H264: - case HB_VCODEC_FFMPEG_VCE_H264: - case HB_VCODEC_FFMPEG_NVENC_H264: track->st->codecpar->codec_id = AV_CODEC_ID_H264; if (job->mux == HB_MUX_AV_MP4 && job->inline_parameter_sets) { @@ -252,35 +250,65 @@ static int avformatInit( hb_mux_object_t * m ) job->config.h264.pps, job->config.h264.pps_length ); break; + case HB_VCODEC_FFMPEG_VCE_H264: + case HB_VCODEC_FFMPEG_NVENC_H264: + track->st->codecpar->codec_id = AV_CODEC_ID_H264; + if (job->mux == HB_MUX_AV_MP4 && job->inline_parameter_sets) + { + track->st->codecpar->codec_tag = MKTAG('a','v','c','3'); + } + else + { + track->st->codecpar->codec_tag = MKTAG('a','v','c','1'); + } + if (job->config.extradata.length > 0) + { + priv_size = job->config.extradata.length; + priv_data = av_malloc(priv_size + AV_INPUT_BUFFER_PADDING_SIZE); + if (priv_data == NULL) + { + hb_error("h.265 extradata: malloc failure"); + goto error; + } + memcpy(priv_data, + job->config.extradata.bytes, + job->config.extradata.length); + } + break; + case HB_VCODEC_FFMPEG_MPEG4: track->st->codecpar->codec_id = AV_CODEC_ID_MPEG4; - if (job->config.mpeg4.length != 0) + if (job->config.extradata.length > 0) { - priv_size = job->config.mpeg4.length; + priv_size = job->config.extradata.length; priv_data = av_malloc(priv_size + AV_INPUT_BUFFER_PADDING_SIZE); if (priv_data == NULL) { - hb_error("MPEG4 extradata: malloc failure"); + hb_error("h.265 extradata: malloc failure"); goto error; } - memcpy(priv_data, job->config.mpeg4.bytes, priv_size); + memcpy(priv_data, + job->config.extradata.bytes, + job->config.extradata.length); } break; case HB_VCODEC_FFMPEG_MPEG2: track->st->codecpar->codec_id = AV_CODEC_ID_MPEG2VIDEO; - if (job->config.mpeg4.length != 0) + if (job->config.extradata.length > 0) { - priv_size = job->config.mpeg4.length; + priv_size = job->config.extradata.length; priv_data = av_malloc(priv_size + AV_INPUT_BUFFER_PADDING_SIZE); if (priv_data == NULL) { - hb_error("MPEG2 extradata: malloc failure"); + hb_error("h.265 extradata: malloc failure"); goto error; } - memcpy(priv_data, job->config.mpeg4.bytes, priv_size); + memcpy(priv_data, + job->config.extradata.bytes, + job->config.extradata.length); } break; @@ -334,8 +362,6 @@ static int avformatInit( hb_mux_object_t * m ) case HB_VCODEC_X265_16BIT: case HB_VCODEC_QSV_H265: case HB_VCODEC_QSV_H265_10BIT: - case HB_VCODEC_FFMPEG_VCE_H265: - case HB_VCODEC_FFMPEG_NVENC_H265: track->st->codecpar->codec_id = AV_CODEC_ID_HEVC; if (job->mux == HB_MUX_AV_MP4 && job->inline_parameter_sets) { @@ -359,6 +385,32 @@ static int avformatInit( hb_mux_object_t * m ) } break; + case HB_VCODEC_FFMPEG_VCE_H265: + case HB_VCODEC_FFMPEG_NVENC_H265: + track->st->codecpar->codec_id = AV_CODEC_ID_HEVC; + if (job->mux == HB_MUX_AV_MP4 && job->inline_parameter_sets) + { + track->st->codecpar->codec_tag = MKTAG('h','e','v','1'); + } + else + { + track->st->codecpar->codec_tag = MKTAG('h','v','c','1'); + } + if (job->config.extradata.length > 0) + { + priv_size = job->config.extradata.length; + priv_data = av_malloc(priv_size + AV_INPUT_BUFFER_PADDING_SIZE); + if (priv_data == NULL) + { + hb_error("h.265 extradata: malloc failure"); + goto error; + } + memcpy(priv_data, + job->config.extradata.bytes, + job->config.extradata.length); + } + break; + default: hb_error("muxavformat: Unknown video codec: %x", job->vcodec); goto error; -- 2.40.0