On Tue, 28 May 2013 09:15:36 +0200, Sebastien Zwickert <[email protected]> wrote: > From: Xidorn Quan <[email protected]> > > 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. > --- > libavcodec/vda.h | 11 +++++++++++ > libavcodec/vda_h264.c | 27 +++++++++++++++++++++++++++ > 2 files changed, 38 insertions(+) > > diff --git a/libavcodec/vda.h b/libavcodec/vda.h > index 987b94f..13e4fc5 100644 > --- a/libavcodec/vda.h > +++ b/libavcodec/vda.h > @@ -125,6 +125,17 @@ struct vda_context { > * The reference size used for fast reallocation. > */ > int priv_allocated_size; > + > + /** > + * Use av_buffer to manage buffer. > + * When the flag is set, the CVPixelBuffers returned by the decoder will > + * be released automatically, so you have to retain them if necessary. > + * Not setting this flag may cause memory leak. > + * > + * encoding: unused > + * decoding: Set by user. > + */ > + int use_ref_buffer; > }; > > /** Create the video decoder. */ > diff --git a/libavcodec/vda_h264.c b/libavcodec/vda_h264.c > index 6c1845a..a183afa 100644 > --- a/libavcodec/vda_h264.c > +++ b/libavcodec/vda_h264.c > @@ -28,6 +28,10 @@ > #include "h264.h" > #include "vda.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, > CFDictionaryRef user_info, > @@ -107,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) > @@ -123,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;
Are the previous 3 entries always filled? I think the code currently assumes the buffers are filled continuously. -- Anton Khirnov _______________________________________________ libav-devel mailing list [email protected] https://lists.libav.org/mailman/listinfo/libav-devel
