summaryrefslogtreecommitdiff
path: root/libavcodec/vda_h264.c
diff options
context:
space:
mode:
authorXidorn Quan <quanxunzhen@gmail.com>2013-05-21 12:12:30 +0800
committerSebastien Zwickert <dilaroga@gmail.com>2013-05-27 09:05:55 +0200
commitffd7fd79441f97f1edb25181af0603ff6ea9b342 (patch)
treebc4d4d4314d682acbd3aff4241d434b6f01e6843 /libavcodec/vda_h264.c
parent53ec1c811e41807a296934eb142f4aebe787e390 (diff)
avcodec/vda_h264: use av_buffer to manage buffers
This patch fixes a leak of buffer when seeking occurs. It adds a flag in struct vda_context for compatibility with apps which currently use it. If the flag is not set, the hwaccel will behave like before. Signed-off-by: Sebastien Zwickert <dilaroga@gmail.com>
Diffstat (limited to 'libavcodec/vda_h264.c')
-rw-r--r--libavcodec/vda_h264.c26
1 files changed, 26 insertions, 0 deletions
diff --git a/libavcodec/vda_h264.c b/libavcodec/vda_h264.c
index d0237c2279..c01a21a533 100644
--- a/libavcodec/vda_h264.c
+++ b/libavcodec/vda_h264.c
@@ -28,6 +28,9 @@
#include "libavutil/avutil.h"
#include "h264.h"
+struct vda_buffer {
+ 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,
@@ -108,11 +111,20 @@ static int vda_h264_decode_slice(AVCodecContext *avctx,
return 0;
}
+static void vda_h264_release_buffer(void *opaque, uint8_t *data)
+{
+ struct vda_buffer *context = opaque;
+ CVPixelBufferRelease(context->cv_buffer);
+ av_free(context);
+}
+
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_buffer *context;
+ AVBufferRef *buffer;
int status;
if (!vda_ctx->decoder || !vda_ctx->priv_bitstream)
@@ -124,6 +136,20 @@ static int vda_h264_end_frame(AVCodecContext *avctx)
if (status)
av_log(avctx, AV_LOG_ERROR, "Failed to decode frame (%d)\n", status);
+ if (!vda_ctx->use_ref_buffer || status)
+ return status;
+
+ context = av_mallocz(sizeof(*context));
+ buffer = av_buffer_create(NULL, 0, vda_h264_release_buffer, context, 0);
+ if (!context || !buffer) {
+ CVPixelBufferRelease(vda_ctx->cv_buffer);
+ av_free(context);
+ return -1;
+ }
+
+ context->cv_buffer = vda_ctx->cv_buffer;
+ frame->buf[3] = buffer;
+
return status;
}