[vlc-commits] vout ios: implement proper memory management for the zero-copy pipeline

Felix Paul Kühne git at videolan.org
Wed Sep 2 14:55:54 CEST 2015


vlc | branch: master | Felix Paul Kühne <fkuehne at videolan.org> | Wed Sep  2 11:08:47 2015 +0200| [fb204242b542ea469d7a96946da8a11e41d1d461] | committer: Felix Paul Kühne

vout ios: implement proper memory management for the zero-copy pipeline

> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=fb204242b542ea469d7a96946da8a11e41d1d461
---

 modules/codec/videotoolbox.m |   19 ++++++++---
 modules/video_output/ios2.m  |   75 +++++++++++++++++++++++++++++++++++-------
 2 files changed, 79 insertions(+), 15 deletions(-)

diff --git a/modules/codec/videotoolbox.m b/modules/codec/videotoolbox.m
index 36a459d..92b250b 100644
--- a/modules/codec/videotoolbox.m
+++ b/modules/codec/videotoolbox.m
@@ -650,10 +650,13 @@ static int OpenDecoder(vlc_object_t *p_this)
 
     /* return our proper VLC internal state */
     p_dec->fmt_out.i_cat = VIDEO_ES;
-    if (p_sys->b_zero_copy)
+    if (p_sys->b_zero_copy) {
+        msg_Dbg(p_dec, "zero-copy rendering pipeline enabled");
         p_dec->fmt_out.i_codec = VLC_CODEC_CVPX_OPAQUE;
-    else
+    } else {
+        msg_Dbg(p_dec, "copy rendering pipeline enabled");
         p_dec->fmt_out.i_codec = VLC_CODEC_I420;
+    }
 
     p_dec->b_need_packetized = true;
 
@@ -1045,9 +1048,17 @@ skip:
                                          CVPixelBufferGetWidthOfPlane(imageBuffer, 0),
                                          CVPixelBufferGetHeightOfPlane(imageBuffer, 0));
                 } else {
-                    p_pic->p_sys = malloc(sizeof(picture_sys_t));
-                    if (p_pic->p_sys)
+                    /* the structure is allocated by the vout's pool */
+                    if (p_pic->p_sys) {
+                        /* if we received a recycled picture from the pool
+                         * we need release the previous reference first,
+                         * otherwise we would leak it */
+                        if (p_pic->p_sys->pixelBuffer != nil) {
+                            CFRelease(p_pic->p_sys->pixelBuffer);
+                        }
+
                         p_pic->p_sys->pixelBuffer = CFBridgingRetain(imageBufferObject);
+                    }
                     /* will be freed by the vout */
                 }
 
diff --git a/modules/video_output/ios2.m b/modules/video_output/ios2.m
index db4a743..8e3be0b 100644
--- a/modules/video_output/ios2.m
+++ b/modules/video_output/ios2.m
@@ -127,17 +127,18 @@ static NSString *const vertexShaderString = @" \
 static int Open(vlc_object_t *);
 static void Close(vlc_object_t *);
 
-static picture_pool_t* PicturePool(vout_display_t *vd, unsigned requested_count);
-static void PictureRender(vout_display_t* vd, picture_t *pic, subpicture_t *subpicture);
-static void PictureDisplay(vout_display_t* vd, picture_t *pic, subpicture_t *subpicture);
-static int Control(vout_display_t* vd, int query, va_list ap);
+static picture_pool_t* PicturePool(vout_display_t *, unsigned);
+static void PictureRender(vout_display_t *, picture_t *, subpicture_t *);
+static void PictureDisplay(vout_display_t *, picture_t *, subpicture_t *);
+static int Control(vout_display_t*, int, va_list);
 
 static void *OurGetProcAddress(vlc_gl_t *, const char *);
 
-static int OpenglESClean(vlc_gl_t* gl);
-static void OpenglESSwap(vlc_gl_t* gl);
+static int OpenglESClean(vlc_gl_t *);
+static void OpenglESSwap(vlc_gl_t *);
 
 static picture_pool_t *ZeroCopyPicturePool(vout_display_t *, unsigned);
+static void DestroyZeroCopyPoolPicture(picture_t *);
 static void ZeroCopyDisplay(vout_display_t *, picture_t *, subpicture_t *);
 
 /**
@@ -369,6 +370,10 @@ void Close (vlc_object_t *this)
 
     [sys->glESView release];
 
+    if (sys->picturePool)
+        picture_pool_Release(sys->picturePool);
+    sys->picturePool = NULL;
+
     free(sys);
 }
 
@@ -504,11 +509,62 @@ static void OpenglESSwap(vlc_gl_t *gl)
 static picture_pool_t *ZeroCopyPicturePool(vout_display_t *vd, unsigned requested_count)
 {
     vout_display_sys_t *sys = vd->sys;
-    if (!sys->picturePool)
-        sys->picturePool = picture_pool_NewFromFormat(&vd->fmt, requested_count);
+    if (sys->picturePool != NULL)
+        return sys->picturePool;
+
+    picture_t** pictures = calloc(requested_count, sizeof(*pictures));
+    if (!pictures)
+        goto bailout;
+
+    for (unsigned x = 0; x < requested_count; x++) {
+        picture_sys_t *picsys = calloc(1, sizeof(*picsys));
+        if (unlikely(!picsys)) {
+            goto bailout;
+        }
+
+        picture_resource_t picture_resource;
+        picture_resource.p_sys = picsys;
+        picture_resource.pf_destroy = DestroyZeroCopyPoolPicture;
+
+        picture_t *picture = picture_NewFromResource(&vd->fmt, &picture_resource);
+        if (unlikely(picture == NULL)) {
+            free(picsys);
+            goto bailout;
+        }
+
+        pictures[x] = picture;
+    }
+
+    picture_pool_configuration_t pool_config;
+    memset(&pool_config, 0, sizeof(pool_config));
+    pool_config.picture_count = requested_count;
+    pool_config.picture = pictures;
+
+    sys->picturePool = picture_pool_NewExtended(&pool_config);
+
+bailout:
+    if (sys->picturePool == NULL && pictures) {
+        for (unsigned x = 0; x < requested_count; x++)
+            DestroyZeroCopyPoolPicture(pictures[x]);
+        free(pictures);
+    }
+
     return sys->picturePool;
 }
 
+static void DestroyZeroCopyPoolPicture(picture_t *picture)
+{
+    picture_sys_t *p_sys = (picture_sys_t *)picture->p_sys;
+
+    if (p_sys->pixelBuffer != nil) {
+        CFRelease(p_sys->pixelBuffer);
+        p_sys->pixelBuffer = nil;
+    }
+
+    free(p_sys);
+    free(picture);
+}
+
 static void ZeroCopyDisplay(vout_display_t *vd, picture_t *pic, subpicture_t *subpicture)
 {
     vout_display_sys_t *sys = vd->sys;
@@ -520,9 +576,6 @@ static void ZeroCopyDisplay(vout_display_t *vd, picture_t *pic, subpicture_t *su
 
                 if (picsys->pixelBuffer != nil) {
                     [sys->glESView displayPixelBuffer: picsys->pixelBuffer];
-
-                    CFRelease(picsys->pixelBuffer);
-                    picsys->pixelBuffer = nil;
                 }
             }
         }



More information about the vlc-commits mailing list