[FFmpeg-devel] [PATCH 3/5] avcodec/libaomenc: export Sequence Header and Metadata OBUs as extradata

James Almer jamrial at gmail.com
Tue Jul 10 01:52:35 EEST 2018


On 7/9/2018 6:53 PM, Niki Bowe wrote:
> Hi James,
> I passed along your wish for aom_codec_get_global_headers().
> Tom created this bug for tracking:
> https://bugs.chromium.org/p/aomedia/issues/detail?id=2012

Thanks a lot! It would simplify the libaom wrapper a lot and actually
allow us to write the extradata in Matroska directly during transcoding
without requiring some big intrusive changes to that muxer.

To be more specific, aom_codec_get_global_headers() should be callable
and return a sequence header OBU (and any relevant Metadata OBU) after
calling aom_codec_enc_init() but before the first aom_codec_encode()
call. This is what x264_encoder_headers() in libx264 and
ISVCEncoder::EncodeParameterSets in libopenh264 let you do, for example.
Requiring first to pass image data with aom_codec_encode() to be able to
generate the Sequence Header would make virtually no difference compared
to what I'm implementing in this patch.

I see for that matter that aom_codec_control() can be called after
aom_codec_enc_init() and it evidently can have an effect in the eventual
contents of the Sequence Header. Knowing this, and assuming it's not the
case already, perhaps certain aome_enc_control_id values (like for
example color config related ones) should be forbidden to be set after
aom_codec_get_global_headers() is called. Otherwise the headers the
function returns could become invalid if aom_codec_control() was
successfully called afterwards.

> 
> 
> On Mon, Jul 9, 2018 at 11:29 AM James Almer <jamrial at gmail.com> wrote:
> 
>> aom_codec_get_global_headers() is not implemented as of libaom 1.0.0
>> for AV1, so we're forced to extract the relevant header OBUs from the
>> first packet and propagate them as packet side data for now.
>>
>> Signed-off-by: James Almer <jamrial at gmail.com>
>> ---
>> This is far from ideal. Whereas the mp4 muxer can handle extradata
>> propagated as packet side data without issues, the Matroska one can't
>> feasibly do it since it would require to reserve space for it, and we
>> don't know just how big the resulting extradata can be as it may have
>> an arbitrary amount of OBUs.
>>
>> libaom should ideally implement aom_codec_get_global_headers() for
>> AV1 (Which is clearly inspired by similar functionality in libx264
>> and other encoders, and can be used before any kind of image data is
>> sent to the encoder), so lobby is welcome :p
>>
>>  configure              |  1 +
>>  libavcodec/libaomenc.c | 41 +++++++++++++++++++++++++++++++++++++++++
>>  2 files changed, 42 insertions(+)
>>
>> diff --git a/configure b/configure
>> index 1066df6621..a76dd06736 100755
>> --- a/configure
>> +++ b/configure
>> @@ -3046,6 +3046,7 @@ hevc_videotoolbox_encoder_deps="pthreads"
>>  hevc_videotoolbox_encoder_select="videotoolbox_encoder"
>>  libaom_av1_decoder_deps="libaom"
>>  libaom_av1_encoder_deps="libaom"
>> +libaom_av1_encoder_select="extract_extradata_bsf"
>>  libcelt_decoder_deps="libcelt"
>>  libcodec2_decoder_deps="libcodec2"
>>  libcodec2_encoder_deps="libcodec2"
>> diff --git a/libavcodec/libaomenc.c b/libavcodec/libaomenc.c
>> index 41b05dc1c0..0b75dc139c 100644
>> --- a/libavcodec/libaomenc.c
>> +++ b/libavcodec/libaomenc.c
>> @@ -55,6 +55,7 @@ struct FrameListData {
>>
>>  typedef struct AOMEncoderContext {
>>      AVClass *class;
>> +    AVBSFContext *bsf;
>>      struct aom_codec_ctx encoder;
>>      struct aom_image rawimg;
>>      struct aom_fixed_buf twopass_stats;
>> @@ -202,6 +203,7 @@ static av_cold int aom_free(AVCodecContext *avctx)
>>      av_freep(&ctx->twopass_stats.buf);
>>      av_freep(&avctx->stats_out);
>>      free_frame_list(ctx->coded_frame_list);
>> +    av_bsf_free(&ctx->bsf);
>>      return 0;
>>  }
>>
>> @@ -463,6 +465,28 @@ static av_cold int aom_init(AVCodecContext *avctx,
>>      if (!cpb_props)
>>          return AVERROR(ENOMEM);
>>
>> +    if (avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER) {
>> +        const AVBitStreamFilter *filter =
>> av_bsf_get_by_name("extract_extradata");
>> +        int ret;
>> +
>> +        if (!filter) {
>> +            av_log(avctx, AV_LOG_ERROR, "extract_extradata bitstream
>> filter "
>> +                   "not found. This is a bug, please report it.\n");
>> +            return AVERROR_BUG;
>> +        }
>> +        ret = av_bsf_alloc(filter, &ctx->bsf);
>> +        if (ret < 0)
>> +            return ret;
>> +
>> +        ret = avcodec_parameters_from_context(ctx->bsf->par_in, avctx);
>> +        if (ret < 0)
>> +           return ret;
>> +
>> +        ret = av_bsf_init(ctx->bsf);
>> +        if (ret < 0)
>> +           return ret;
>> +    }
>> +
>>      if (enccfg.rc_end_usage == AOM_CBR ||
>>          enccfg.g_pass != AOM_RC_ONE_PASS) {
>>          cpb_props->max_bitrate = avctx->rc_max_rate;
>> @@ -494,6 +518,7 @@ static inline void cx_pktcpy(struct FrameListData *dst,
>>  static int storeframe(AVCodecContext *avctx, struct FrameListData
>> *cx_frame,
>>                        AVPacket *pkt)
>>  {
>> +    AOMContext *ctx = avctx->priv_data;
>>      int ret = ff_alloc_packet2(avctx, pkt, cx_frame->sz, 0);
>>      if (ret < 0) {
>>          av_log(avctx, AV_LOG_ERROR,
>> @@ -505,6 +530,22 @@ static int storeframe(AVCodecContext *avctx, struct
>> FrameListData *cx_frame,
>>
>>      if (!!(cx_frame->flags & AOM_FRAME_IS_KEY))
>>          pkt->flags |= AV_PKT_FLAG_KEY;
>> +
>> +    if (avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER) {
>> +        ret = av_bsf_send_packet(ctx->bsf, pkt);
>> +        if (ret < 0) {
>> +            av_log(avctx, AV_LOG_ERROR, "extract_extradata filter "
>> +                   "failed to send input packet\n");
>> +            return ret;
>> +        }
>> +        ret = av_bsf_receive_packet(ctx->bsf, pkt);
>> +
>> +        if (ret < 0) {
>> +            av_log(avctx, AV_LOG_ERROR, "extract_extradata filter "
>> +                   "failed to receive output packet\n");
>> +            return ret;
>> +        }
>> +    }
>>      return pkt->size;
>>  }
>>
>> --
>> 2.18.0
>>
>> _______________________________________________
>> ffmpeg-devel mailing list
>> ffmpeg-devel at ffmpeg.org
>> http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>>
> 
> 



More information about the ffmpeg-devel mailing list