diff options
author | Aman Gupta <aman@tmm1.net> | 2018-03-06 13:07:32 -0800 |
---|---|---|
committer | Aman Gupta <aman@tmm1.net> | 2018-03-07 16:22:47 -0800 |
commit | 2a0eb8685728ccb260e42f60e1dbefe47ababbc3 (patch) | |
tree | f84f97754d63a1bbf77baccc9520e5b8d24dff41 /libavcodec/mediacodecdec_common.c | |
parent | 840f6eb77aed6c9dc2eff1a89add3611ec305262 (diff) | |
download | ffmpeg-2a0eb8685728ccb260e42f60e1dbefe47ababbc3.tar.gz |
avcodec/mediacodecdec: add delay_flush option
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.
Signed-off-by: Aman Gupta <aman@tmm1.net>
Signed-off-by: Matthieu Bouron <matthieu.bouron@gmail.com>
Diffstat (limited to 'libavcodec/mediacodecdec_common.c')
-rw-r--r-- | libavcodec/mediacodecdec_common.c | 11 |
1 files changed, 8 insertions, 3 deletions
diff --git a/libavcodec/mediacodecdec_common.c b/libavcodec/mediacodecdec_common.c index 0bd660f7c9..693524abd6 100644 --- a/libavcodec/mediacodecdec_common.c +++ b/libavcodec/mediacodecdec_common.c @@ -178,11 +178,12 @@ static void mediacodec_buffer_release(void *opaque, uint8_t *data) MediaCodecDecContext *ctx = buffer->ctx; int released = atomic_load(&buffer->released); - if (!released) { + if (!released && (ctx->delay_flush || buffer->serial == atomic_load(&ctx->serial))) { ff_AMediaCodec_releaseOutputBuffer(ctx->codec, buffer->index, 0); } - ff_mediacodec_dec_unref(ctx); + if (ctx->delay_flush) + ff_mediacodec_dec_unref(ctx); av_freep(&buffer); } @@ -236,7 +237,9 @@ FF_ENABLE_DEPRECATION_WARNINGS } buffer->ctx = s; - ff_mediacodec_dec_ref(s); + buffer->serial = atomic_load(&s->serial); + if (s->delay_flush) + ff_mediacodec_dec_ref(s); buffer->index = index; buffer->pts = info->presentationTimeUs; @@ -425,6 +428,7 @@ static int mediacodec_dec_flush_codec(AVCodecContext *avctx, MediaCodecDecContex s->draining = 0; s->flushing = 0; s->eos = 0; + atomic_fetch_add(&s->serial, 1); status = ff_AMediaCodec_flush(codec); if (status < 0) { @@ -449,6 +453,7 @@ int ff_mediacodec_dec_init(AVCodecContext *avctx, MediaCodecDecContext *s, }; atomic_init(&s->refcount, 1); + atomic_init(&s->serial, 1); pix_fmt = ff_get_format(avctx, pix_fmts); if (pix_fmt == AV_PIX_FMT_MEDIACODEC) { |