Commit fb204242 authored by Felix Paul Kühne's avatar Felix Paul Kühne

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

parent 30a6e1a9
...@@ -650,10 +650,13 @@ static int OpenDecoder(vlc_object_t *p_this) ...@@ -650,10 +650,13 @@ static int OpenDecoder(vlc_object_t *p_this)
/* return our proper VLC internal state */ /* return our proper VLC internal state */
p_dec->fmt_out.i_cat = VIDEO_ES; 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; 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->fmt_out.i_codec = VLC_CODEC_I420;
}
p_dec->b_need_packetized = true; p_dec->b_need_packetized = true;
...@@ -1045,9 +1048,17 @@ skip: ...@@ -1045,9 +1048,17 @@ skip:
CVPixelBufferGetWidthOfPlane(imageBuffer, 0), CVPixelBufferGetWidthOfPlane(imageBuffer, 0),
CVPixelBufferGetHeightOfPlane(imageBuffer, 0)); CVPixelBufferGetHeightOfPlane(imageBuffer, 0));
} else { } else {
p_pic->p_sys = malloc(sizeof(picture_sys_t)); /* the structure is allocated by the vout's pool */
if (p_pic->p_sys) 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); p_pic->p_sys->pixelBuffer = CFBridgingRetain(imageBufferObject);
}
/* will be freed by the vout */ /* will be freed by the vout */
} }
......
...@@ -127,17 +127,18 @@ static NSString *const vertexShaderString = @" \ ...@@ -127,17 +127,18 @@ static NSString *const vertexShaderString = @" \
static int Open(vlc_object_t *); static int Open(vlc_object_t *);
static void Close(vlc_object_t *); static void Close(vlc_object_t *);
static picture_pool_t* PicturePool(vout_display_t *vd, unsigned requested_count); static picture_pool_t* PicturePool(vout_display_t *, unsigned);
static void PictureRender(vout_display_t* vd, picture_t *pic, subpicture_t *subpicture); static void PictureRender(vout_display_t *, picture_t *, subpicture_t *);
static void PictureDisplay(vout_display_t* vd, picture_t *pic, subpicture_t *subpicture); static void PictureDisplay(vout_display_t *, picture_t *, subpicture_t *);
static int Control(vout_display_t* vd, int query, va_list ap); static int Control(vout_display_t*, int, va_list);
static void *OurGetProcAddress(vlc_gl_t *, const char *); static void *OurGetProcAddress(vlc_gl_t *, const char *);
static int OpenglESClean(vlc_gl_t* gl); static int OpenglESClean(vlc_gl_t *);
static void OpenglESSwap(vlc_gl_t* gl); static void OpenglESSwap(vlc_gl_t *);
static picture_pool_t *ZeroCopyPicturePool(vout_display_t *, unsigned); static picture_pool_t *ZeroCopyPicturePool(vout_display_t *, unsigned);
static void DestroyZeroCopyPoolPicture(picture_t *);
static void ZeroCopyDisplay(vout_display_t *, picture_t *, subpicture_t *); static void ZeroCopyDisplay(vout_display_t *, picture_t *, subpicture_t *);
/** /**
...@@ -369,6 +370,10 @@ void Close (vlc_object_t *this) ...@@ -369,6 +370,10 @@ void Close (vlc_object_t *this)
[sys->glESView release]; [sys->glESView release];
if (sys->picturePool)
picture_pool_Release(sys->picturePool);
sys->picturePool = NULL;
free(sys); free(sys);
} }
...@@ -504,11 +509,62 @@ static void OpenglESSwap(vlc_gl_t *gl) ...@@ -504,11 +509,62 @@ static void OpenglESSwap(vlc_gl_t *gl)
static picture_pool_t *ZeroCopyPicturePool(vout_display_t *vd, unsigned requested_count) static picture_pool_t *ZeroCopyPicturePool(vout_display_t *vd, unsigned requested_count)
{ {
vout_display_sys_t *sys = vd->sys; vout_display_sys_t *sys = vd->sys;
if (!sys->picturePool) if (sys->picturePool != NULL)
sys->picturePool = picture_pool_NewFromFormat(&vd->fmt, requested_count); 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; 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) static void ZeroCopyDisplay(vout_display_t *vd, picture_t *pic, subpicture_t *subpicture)
{ {
vout_display_sys_t *sys = vd->sys; vout_display_sys_t *sys = vd->sys;
...@@ -520,9 +576,6 @@ static void ZeroCopyDisplay(vout_display_t *vd, picture_t *pic, subpicture_t *su ...@@ -520,9 +576,6 @@ static void ZeroCopyDisplay(vout_display_t *vd, picture_t *pic, subpicture_t *su
if (picsys->pixelBuffer != nil) { if (picsys->pixelBuffer != nil) {
[sys->glESView displayPixelBuffer: picsys->pixelBuffer]; [sys->glESView displayPixelBuffer: picsys->pixelBuffer];
CFRelease(picsys->pixelBuffer);
picsys->pixelBuffer = nil;
} }
} }
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment