[FFmpeg-devel] [PATCH 2/2] vda: use hwaccel custom callback for releasing private picture context.

Sebastien Zwickert dilaroga at gmail.com
Wed May 22 21:53:14 CEST 2013


     Note: it is recommended to use AVCodecContext.get_buffer2() to
     release correctly the dropped buffers and fix memory leaks.
---
 libavcodec/vda.h      |   12 +++++++++++-
 libavcodec/vda_h264.c |   18 ++++++++++++++++++
 2 files changed, 29 insertions(+), 1 deletion(-)

diff --git a/libavcodec/vda.h b/libavcodec/vda.h
index 281785f..5539baa 100644
--- a/libavcodec/vda.h
+++ b/libavcodec/vda.h
@@ -67,11 +67,21 @@ struct vda_context {
      * The Core Video pixel buffer that contains the current image data.
      *
      * encoding: unused
-     * decoding: Set by libavcodec. Unset by user.
+     * decoding: Set by libavcodec. Unset by libavcodec or user.
      */
     CVPixelBufferRef    cv_buffer;
 
     /**
+     * If this property is set the core video buffer is released by the decoder, otherwise
+     * the user is responsible itself for releasing the core video buffer in AVFrame.data[3]
+     * with CVPixelBufferRelease().
+     *
+     * encoding: unused
+     * decoding: Set by user.
+     */
+    int                 autorelease_buffer;
+
+    /**
      * Use the hardware decoder in synchronous mode.
      *
      * encoding: unused
diff --git a/libavcodec/vda_h264.c b/libavcodec/vda_h264.c
index d0237c2..5516b48 100644
--- a/libavcodec/vda_h264.c
+++ b/libavcodec/vda_h264.c
@@ -28,6 +28,9 @@
 #include "libavutil/avutil.h"
 #include "h264.h"
 
+struct vda_picture_context {
+    CVPixelBufferRef cv_buffer;
+};
 
 /* Decoder callback that adds the vda frame to the queue in display order. */
 static void vda_decoder_callback (void *vda_hw_ctx,
@@ -113,6 +116,7 @@ static int vda_h264_end_frame(AVCodecContext *avctx)
     H264Context *h                      = avctx->priv_data;
     struct vda_context *vda_ctx         = avctx->hwaccel_context;
     AVFrame *frame                      = &h->cur_pic_ptr->f;
+    struct vda_picture_context *pic_ctx = h->cur_pic_ptr->hwaccel_picture_private;
     int status;
 
     if (!vda_ctx->decoder || !vda_ctx->priv_bitstream)
@@ -120,6 +124,10 @@ static int vda_h264_end_frame(AVCodecContext *avctx)
 
     status = vda_sync_decode(vda_ctx);
     frame->data[3] = (void*)vda_ctx->cv_buffer;
+    pic_ctx->cv_buffer = vda_ctx->cv_buffer;
+
+    if (!vda_ctx->autorelease_buffer)
+        CVPixelBufferRetain(pic_ctx->cv_buffer);
 
     if (status)
         av_log(avctx, AV_LOG_ERROR, "Failed to decode frame (%d)\n", status);
@@ -127,6 +135,14 @@ static int vda_h264_end_frame(AVCodecContext *avctx)
     return status;
 }
 
+static void vda_h264_release_buffer(void *opaque, uint8_t *data)
+{
+    struct vda_picture_context *pic_ctx = opaque;
+
+    CVPixelBufferRelease(pic_ctx->cv_buffer);
+    av_free(pic_ctx);
+}
+
 int ff_vda_create_decoder(struct vda_context *vda_ctx,
                           uint8_t *extradata,
                           int extradata_size)
@@ -234,4 +250,6 @@ AVHWAccel ff_h264_vda_hwaccel = {
     .start_frame    = vda_h264_start_frame,
     .decode_slice   = vda_h264_decode_slice,
     .end_frame      = vda_h264_end_frame,
+    .release_buffer = vda_h264_release_buffer,
+    .priv_data_size = sizeof(struct vda_picture_context),
 };
-- 
1.7.9.6 (Apple Git-31.1)



More information about the ffmpeg-devel mailing list