From 936312d18c985335d8e90b04bb15b4227bce7b31 Mon Sep 17 00:00:00 2001 From: Aman Gupta Date: Sat, 10 Mar 2018 23:43:42 -0800 Subject: [PATCH] avcodec/mediacodecdec: add debug logging around hw buffer lifecycle Some Android devices are very finicky about how quicky output buffers are returned back to the decoder, especially when they are associated with a Surface. This commit adds a new counter that keeps track of exactly how many hw output buffers are being retained by the user, along with DEBUG level logging that makes it easy to track the lifecycle of these buffers. Signed-off-by: Aman Gupta Signed-off-by: Matthieu Bouron --- libavcodec/mediacodec.c | 7 ++++--- libavcodec/mediacodecdec_common.c | 11 +++++++++++ libavcodec/mediacodecdec_common.h | 1 + 3 files changed, 16 insertions(+), 3 deletions(-) diff --git a/libavcodec/mediacodec.c b/libavcodec/mediacodec.c index 3ddd303c97..b0aae43a87 100644 --- a/libavcodec/mediacodec.c +++ b/libavcodec/mediacodec.c @@ -92,9 +92,10 @@ int av_mediacodec_release_buffer(AVMediaCodecBuffer *buffer, int render) int released = atomic_fetch_add(&buffer->released, 1); if (!released && (ctx->delay_flush || buffer->serial == atomic_load(&ctx->serial))) { - av_log(ctx->avctx, AV_LOG_TRACE, - "Releasing output buffer %zd ts=%"PRId64" render=%d\n", - buffer->index, buffer->pts, render); + atomic_fetch_sub(&ctx->hw_buffer_count, 1); + av_log(ctx->avctx, AV_LOG_DEBUG, + "Releasing output buffer %zd (%p) ts=%"PRId64" with render=%d [%d pending]\n", + buffer->index, buffer, buffer->pts, render, atomic_load(&ctx->hw_buffer_count)); return ff_AMediaCodec_releaseOutputBuffer(ctx->codec, buffer->index, render); } diff --git a/libavcodec/mediacodecdec_common.c b/libavcodec/mediacodecdec_common.c index 5064809cf6..2697af3d08 100644 --- a/libavcodec/mediacodecdec_common.c +++ b/libavcodec/mediacodecdec_common.c @@ -179,6 +179,10 @@ static void mediacodec_buffer_release(void *opaque, uint8_t *data) int released = atomic_load(&buffer->released); if (!released && (ctx->delay_flush || buffer->serial == atomic_load(&ctx->serial))) { + atomic_fetch_sub(&ctx->hw_buffer_count, 1); + av_log(ctx->avctx, AV_LOG_DEBUG, + "Releasing output buffer %zd (%p) ts=%"PRId64" on free() [%d pending]\n", + buffer->index, buffer, buffer->pts, atomic_load(&ctx->hw_buffer_count)); ff_AMediaCodec_releaseOutputBuffer(ctx->codec, buffer->index, 0); } @@ -246,6 +250,11 @@ FF_ENABLE_DEPRECATION_WARNINGS frame->data[3] = (uint8_t *)buffer; + atomic_fetch_add(&s->hw_buffer_count, 1); + av_log(avctx, AV_LOG_DEBUG, + "Wrapping output buffer %zd (%p) ts=%"PRId64" [%d pending]\n", + buffer->index, buffer, buffer->pts, atomic_load(&s->hw_buffer_count)); + return 0; fail: av_freep(buffer); @@ -429,6 +438,7 @@ static int mediacodec_dec_flush_codec(AVCodecContext *avctx, MediaCodecDecContex s->flushing = 0; s->eos = 0; atomic_fetch_add(&s->serial, 1); + atomic_init(&s->hw_buffer_count, 0); status = ff_AMediaCodec_flush(codec); if (status < 0) { @@ -454,6 +464,7 @@ int ff_mediacodec_dec_init(AVCodecContext *avctx, MediaCodecDecContext *s, s->avctx = avctx; atomic_init(&s->refcount, 1); + atomic_init(&s->hw_buffer_count, 0); atomic_init(&s->serial, 1); pix_fmt = ff_get_format(avctx, pix_fmts); diff --git a/libavcodec/mediacodecdec_common.h b/libavcodec/mediacodecdec_common.h index 3fd2412a65..4f3b4f9fa5 100644 --- a/libavcodec/mediacodecdec_common.h +++ b/libavcodec/mediacodecdec_common.h @@ -38,6 +38,7 @@ typedef struct MediaCodecDecContext { AVCodecContext *avctx; atomic_int refcount; + atomic_int hw_buffer_count; char *codec_name;