[FFmpeg-devel] [PATCH 1/2] avcodec/mediacodecdec: add delay_flush option

Matthieu Bouron matthieu.bouron at gmail.com
Wed Mar 7 17:30:00 EET 2018


On Tue, Mar 06, 2018 at 01:15:55PM -0800, Aman Gupta wrote:
> From: Aman Gupta <aman at tmm1.net>
> 
> The default behavior of the mediacodec decoder before this commit
> was to delay flushes until all pending hardware frames were
> returned to the decoder. This was useful for certain types of
> applications, but was unexpected behavior for others.
> 
> The new default behavior with this commit is now to execute
> flushes immediately to invalidate all pending frames. The old
> behavior can be enabled by setting delay_flush=1.
> 
> With the new behavior, video players implementing seek can simply
> call flush on the decoder without having to worry about whether
> they have one or more mediacodec frames still buffered in their
> rendering pipeline. Previously, all these frames had to be
> explictly freed (or rendered) before the seek/flush would execute.
> 
> The new behavior matches the behavior of all other lavc decoders,
> reducing the amount of special casing required when using the
> mediacodec decoder.
> ---
>  libavcodec/mediacodec.c           |  2 +-
>  libavcodec/mediacodecdec.c        | 23 +++++++++++++++++++++++
>  libavcodec/mediacodecdec_common.c | 11 ++++++++---
>  libavcodec/mediacodecdec_common.h |  4 ++++
>  4 files changed, 36 insertions(+), 4 deletions(-)
> 
> diff --git a/libavcodec/mediacodec.c b/libavcodec/mediacodec.c
> index d492eefe0b..bf1b7477f1 100644
> --- a/libavcodec/mediacodec.c
> +++ b/libavcodec/mediacodec.c
> @@ -91,7 +91,7 @@ int av_mediacodec_release_buffer(AVMediaCodecBuffer *buffer, int render)
>      MediaCodecDecContext *ctx = buffer->ctx;
>      int released = atomic_fetch_add(&buffer->released, 1);
>  
> -    if (!released) {
> +    if (!released && (ctx->delay_flush || buffer->serial == atomic_load(&ctx->serial))) {
>          return ff_AMediaCodec_releaseOutputBuffer(ctx->codec, buffer->index, render);
>      }
>  
> diff --git a/libavcodec/mediacodecdec.c b/libavcodec/mediacodecdec.c
> index 0fe14846c3..3582a1377d 100644
> --- a/libavcodec/mediacodecdec.c
> +++ b/libavcodec/mediacodecdec.c
> @@ -41,10 +41,14 @@
>  
>  typedef struct MediaCodecH264DecContext {
>  
> +    AVClass *avclass;
> +
>      MediaCodecDecContext *ctx;
>  
>      AVPacket buffered_pkt;
>  
> +    int delay_flush;
> +
>  } MediaCodecH264DecContext;
>  
>  static av_cold int mediacodec_decode_close(AVCodecContext *avctx)
> @@ -366,6 +370,8 @@ static av_cold int mediacodec_decode_init(AVCodecContext *avctx)
>          goto done;
>      }
>  
> +    s->ctx->delay_flush = s->delay_flush;
> +
>      if ((ret = ff_mediacodec_dec_init(avctx, s->ctx, codec_mime, format)) < 0) {
>          s->ctx = NULL;
>          goto done;
> @@ -485,7 +491,24 @@ static const AVCodecHWConfigInternal *mediacodec_hw_configs[] = {
>      NULL
>  };
>  
> +#define OFFSET(x) offsetof(MediaCodecH264DecContext, x)
> +#define VD AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM
> +static const AVOption ff_mediacodec_vdec_options[] = {
> +    { "delay_flush", "Delay flush until hw output buffers are returned to the decoder",
> +                     OFFSET(delay_flush), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, VD },
> +    { NULL }
> +};
> +
> +#define DECLARE_MEDIACODEC_VCLASS(short_name)                   \
> +static const AVClass ff_##short_name##_mediacodec_dec_class = { \
> +    .class_name = #short_name "_mediacodec",                    \
> +    .item_name  = av_default_item_name,                         \
> +    .option     = ff_mediacodec_vdec_options,                   \
> +    .version    = LIBAVUTIL_VERSION_INT,                        \
> +};
> +
>  #define DECLARE_MEDIACODEC_VDEC(short_name, full_name, codec_id, bsf)                          \
> +DECLARE_MEDIACODEC_VCLASS(short_name)                                                          \
>  AVCodec ff_##short_name##_mediacodec_decoder = {                                               \
>      .name           = #short_name "_mediacodec",                                               \
>      .long_name      = NULL_IF_CONFIG_SMALL(full_name " Android MediaCodec decoder"),           \

The priv_class assignment is missing:

+    .priv_class     = &ff_##short_name##_mediacodec_dec_class, \

You will also need some kind of bump in the libavcodec library as well as
an APIChanges entry.

Other than that the patch looks good to me.

Thanks,

[...]

-- 
Matthieu B.


More information about the ffmpeg-devel mailing list