[FFmpeg-devel] avcodec/mediacodecdec: add debug logging around hw buffer lifecycle

Submitted by Aman Gupta on March 11, 2018, 7:48 a.m.

Details

Message ID 20180311074837.55368-1-ffmpeg@tmm1.net
State New
Headers show

Commit Message

Aman Gupta March 11, 2018, 7:48 a.m.
From: Aman Gupta <aman@tmm1.net>

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.
---
 libavcodec/mediacodec.c           |  7 ++++---
 libavcodec/mediacodecdec_common.c | 11 +++++++++++
 libavcodec/mediacodecdec_common.h |  1 +
 3 files changed, 16 insertions(+), 3 deletions(-)

Comments

Aman Gupta March 12, 2018, 8:26 a.m.
On Sat, Mar 10, 2018 at 11:48 PM, Aman Gupta <ffmpeg@tmm1.net> wrote:

> From: Aman Gupta <aman@tmm1.net>
>
> 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.
> ---
>  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..25491a01ec 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_buffers, 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_buffers));
>          return ff_AMediaCodec_releaseOutputBuffer(ctx->codec,
> buffer->index, render);
>      }
>
> diff --git a/libavcodec/mediacodecdec_common.c b/libavcodec/mediacodecdec_
> common.c
> index 5064809cf6..f699609186 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_buffers, 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_buffers));
>          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_buffers, 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_buffers));
> +
>      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_buffers, 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_buffers, 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..8bfc67942d 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_buffers;
>
>      char *codec_name;
>

Applied to master with s/hw_buffers/hw_buffer_count/g


>
> --
> 2.14.3 (Apple Git-98)
>
>

Patch hide | download patch | download mbox

diff --git a/libavcodec/mediacodec.c b/libavcodec/mediacodec.c
index 3ddd303c97..25491a01ec 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_buffers, 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_buffers));
         return ff_AMediaCodec_releaseOutputBuffer(ctx->codec, buffer->index, render);
     }
 
diff --git a/libavcodec/mediacodecdec_common.c b/libavcodec/mediacodecdec_common.c
index 5064809cf6..f699609186 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_buffers, 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_buffers));
         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_buffers, 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_buffers));
+
     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_buffers, 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_buffers, 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..8bfc67942d 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_buffers;
 
     char *codec_name;