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

Niki Bowe nbowe at google.com
Tue Jul 10 00:53:39 EEST 2018


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


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
>


-- 

Nikolas Bowe |  SWE |  nbowe at google.com |  408-565-5137


More information about the ffmpeg-devel mailing list