[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