vlc | branch: master | Felix Paul Kühne <[email protected]> | 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; } } } _______________________________________________ vlc-commits mailing list [email protected] https://mailman.videolan.org/listinfo/vlc-commits
