]> git.sesse.net Git - ffmpeg/commitdiff
vda_h264_dec: fit the new API
authorXidorn Quan <quanxunzhen@gmail.com>
Fri, 29 Mar 2013 15:15:20 +0000 (23:15 +0800)
committerMichael Niedermayer <michaelni@gmx.at>
Fri, 29 Mar 2013 16:55:48 +0000 (17:55 +0100)
It fixes a memory leak in this decoder caused by the API change.

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
libavcodec/vda_h264_dec.c

index 1bee92baf916990748ae18dd126a477dde0d7baa..4e60de0126201d5034936c3b4a686c07d1a5ae41 100644 (file)
@@ -64,23 +64,30 @@ static enum AVPixelFormat get_format(struct AVCodecContext *avctx,
     return AV_PIX_FMT_VDA_VLD;
 }
 
-static int get_buffer(AVCodecContext *avctx, AVFrame *pic)
+typedef struct {
+    CVPixelBufferRef cv_buffer;
+} VDABufferContext;
+
+static void release_buffer(void *opaque, uint8_t *data)
 {
-    pic->type = FF_BUFFER_TYPE_USER;
-    pic->data[0] = (void *)1;
-    return 0;
+    VDABufferContext *context = opaque;
+    CVPixelBufferUnlockBaseAddress(context->cv_buffer, 0);
+    CVPixelBufferRelease(context->cv_buffer);
+    av_free(context);
 }
 
-static void release_buffer(AVCodecContext *avctx, AVFrame *pic)
+static int get_buffer2(AVCodecContext *avctx, AVFrame *pic, int flag)
 {
-    int i;
-
-    CVPixelBufferRef cv_buffer = (CVPixelBufferRef)pic->data[3];
-    CVPixelBufferUnlockBaseAddress(cv_buffer, 0);
-    CVPixelBufferRelease(cv_buffer);
+    VDABufferContext *context = av_mallocz(sizeof(VDABufferContext));
+    AVBufferRef *buffer = av_buffer_create(NULL, 0, release_buffer, context, 0);
+    if (!context || !buffer) {
+        av_free(context);
+        return AVERROR(ENOMEM);
+    }
 
-    for (i = 0; i < 4; i++)
-        pic->data[i] = NULL;
+    pic->buf[0] = buffer;
+    pic->data[0] = (void *)1;
+    return 0;
 }
 
 static int vdadec_decode(AVCodecContext *avctx,
@@ -92,8 +99,11 @@ static int vdadec_decode(AVCodecContext *avctx,
 
     ret = ff_h264_decoder.decode(avctx, data, got_frame, avpkt);
     if (*got_frame) {
+        AVBufferRef *buffer = pic->buf[0];
+        VDABufferContext *context = av_buffer_get_opaque(buffer);
         CVPixelBufferRef cv_buffer = (CVPixelBufferRef)pic->data[3];
         CVPixelBufferLockBaseAddress(cv_buffer, 0);
+        context->cv_buffer = cv_buffer;
         pic->format = ctx->pix_fmt;
         if (CVPixelBufferIsPlanar(cv_buffer)) {
             int i, count = CVPixelBufferGetPlaneCount(cv_buffer);
@@ -221,8 +231,11 @@ static av_cold int vdadec_init(AVCodecContext *avctx)
 
     /* changes callback functions */
     avctx->get_format = get_format;
-    avctx->get_buffer = get_buffer;
-    avctx->release_buffer = release_buffer;
+    avctx->get_buffer2 = get_buffer2;
+#if FF_API_GET_BUFFER
+    // force the old get_buffer to be empty
+    avctx->get_buffer = NULL;
+#endif
 
     /* init H.264 decoder */
     ret = ff_h264_decoder.init(avctx);