diff options
author | Xidorn Quan <quanxunzhen@gmail.com> | 2013-05-21 12:12:30 +0800 |
---|---|---|
committer | Sebastien Zwickert <dilaroga@gmail.com> | 2013-05-27 09:05:55 +0200 |
commit | ffd7fd79441f97f1edb25181af0603ff6ea9b342 (patch) | |
tree | bc4d4d4314d682acbd3aff4241d434b6f01e6843 /libavcodec/vda_h264.c | |
parent | 53ec1c811e41807a296934eb142f4aebe787e390 (diff) | |
download | ffmpeg-ffd7fd79441f97f1edb25181af0603ff6ea9b342.tar.gz |
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.c | 26 |
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; } |