[vlc-devel] [PATCH 01/34] picture: add a video context to the picture

Steve Lhomme robux4 at ycbcr.xyz
Fri Nov 8 15:40:05 CET 2019


The video context is only held if the picture is created successfully. It is
released after the picture is destroyed.
---
 include/vlc_picture.h                          | 14 ++++++++++++--
 modules/codec/vt_utils.c                       |  2 +-
 modules/hw/d3d11/d3d11_surface.c               |  2 +-
 modules/hw/d3d9/dxa9.c                         |  2 +-
 modules/hw/mmal/vout.c                         |  2 +-
 modules/hw/nvdec/nvdec.c                       |  2 +-
 modules/hw/vaapi/vlc_vaapi.c                   |  2 +-
 modules/hw/vdpau/picture.c                     |  2 +-
 modules/video_chroma/copy.c                    |  2 +-
 modules/video_output/android/display.c         |  2 +-
 modules/video_output/fb.c                      |  2 +-
 modules/video_output/kms.c                     |  2 +-
 .../video_output/opengl/converter_android.c    |  2 +-
 modules/video_output/opengl/converter_sw.c     |  2 +-
 modules/video_output/vmem.c                    |  2 +-
 modules/video_output/win32/direct3d11.c        |  4 ++--
 modules/video_output/win32/direct3d9.c         |  2 +-
 src/libvlccore.sym                             |  2 +-
 src/misc/picture.c                             | 18 +++++++++++++++---
 src/misc/picture_pool.c                        |  2 +-
 20 files changed, 46 insertions(+), 24 deletions(-)

diff --git a/include/vlc_picture.h b/include/vlc_picture.h
index 3298630e02a..a5931ef67af 100644
--- a/include/vlc_picture.h
+++ b/include/vlc_picture.h
@@ -128,6 +128,7 @@ struct picture_t
      * The properties of the picture
      */
     video_frame_format_t format;
+    vlc_video_context    *vctx;
 
     plane_t         p[PICTURE_PLANE_MAX];     /**< description of the planes */
     int             i_planes;                /**< number of allocated planes */
@@ -175,7 +176,14 @@ VLC_API picture_t * picture_New( vlc_fourcc_t i_chroma, int i_width, int i_heigh
  * When possible, it is preferred to use this function over picture_New
  * as more information about the format is kept.
  */
-VLC_API picture_t * picture_NewFromFormat( const video_format_t *p_fmt ) VLC_USED;
+VLC_API picture_t * picture_NewFromFormatCtx( const video_format_t *p_fmt,
+                                              vlc_video_context *vctx ) VLC_USED;
+
+VLC_USED
+static inline picture_t * picture_NewFromFormat( const video_format_t *p_fmt )
+{
+    return picture_NewFromFormatCtx( p_fmt, NULL );
+}
 
 /**
  * Resource for a picture.
@@ -202,7 +210,9 @@ typedef struct
  *
  * If the resource is NULL then a plain picture_NewFromFormat is returned.
  */
-VLC_API picture_t * picture_NewFromResource( const video_format_t *, const picture_resource_t * ) VLC_USED;
+VLC_API picture_t * picture_NewFromResource( const video_format_t *,
+                                             vlc_video_context *,
+                                             const picture_resource_t * ) VLC_USED;
 
 /**
  * Destroys a picture without references.
diff --git a/modules/codec/vt_utils.c b/modules/codec/vt_utils.c
index 88224c4e5fd..10222b08604 100644
--- a/modules/codec/vt_utils.c
+++ b/modules/codec/vt_utils.c
@@ -182,7 +182,7 @@ cvpxpic_create_mapped(const video_format_t *fmt, CVPixelBufferRef cvpx,
     void (*pf_destroy)(picture_context_t *) = readonly ?
         cvpxpic_destroy_mapped_ro_cb : cvpxpic_destroy_mapped_rw_cb;
 
-    picture_t *pic = picture_NewFromResource(fmt, &rsc);
+    picture_t *pic = picture_NewFromResource(fmt, NULL, &rsc);
     if (pic == NULL
      || cvpxpic_attach_common(pic, cvpx, pf_destroy, NULL, NULL) != VLC_SUCCESS)
     {
diff --git a/modules/hw/d3d11/d3d11_surface.c b/modules/hw/d3d11/d3d11_surface.c
index 3989a0a37bf..68fdc88c2b3 100644
--- a/modules/hw/d3d11/d3d11_surface.c
+++ b/modules/hw/d3d11/d3d11_surface.c
@@ -721,7 +721,7 @@ int D3D11OpenCPUConverter( vlc_object_t *obj )
     fmt_staging.i_height = texDesc.Height;
     fmt_staging.i_width  = texDesc.Width;
 
-    picture_t *p_dst = picture_NewFromResource(&fmt_staging, &res);
+    picture_t *p_dst = picture_NewFromResource(&fmt_staging, NULL /* TODO */, &res);
     if (p_dst == NULL) {
         msg_Err(p_filter, "Failed to map create the temporary picture.");
         goto done;
diff --git a/modules/hw/d3d9/dxa9.c b/modules/hw/d3d9/dxa9.c
index 0f5700b9e87..393d85262aa 100644
--- a/modules/hw/d3d9/dxa9.c
+++ b/modules/hw/d3d9/dxa9.c
@@ -405,7 +405,7 @@ int D3D9OpenCPUConverter( vlc_object_t *obj )
         fmt_staging.i_height = texDesc.Height;
         fmt_staging.i_width  = texDesc.Width;
 
-        p_dst = picture_NewFromResource(&fmt_staging, &res);
+        p_dst = picture_NewFromResource(&fmt_staging, NULL /* TODO */, &res);
         if (p_dst == NULL) {
             msg_Err(p_filter, "Failed to map create the temporary picture.");
             goto done;
diff --git a/modules/hw/mmal/vout.c b/modules/hw/mmal/vout.c
index 1134f1eb810..8c1b07fd438 100644
--- a/modules/hw/mmal/vout.c
+++ b/modules/hw/mmal/vout.c
@@ -521,7 +521,7 @@ static picture_pool_t *vd_pool(vout_display_t *vd, unsigned count)
         picture_res.p_sys->owner = (vlc_object_t *)vd;
         picture_res.p_sys->buffer = mmal_queue_get(sys->pool->queue);
 
-        sys->pictures[i] = picture_NewFromResource(&vd->fmt, &picture_res);
+        sys->pictures[i] = picture_NewFromResource(&vd->fmt, NULL /*TODO*/, &picture_res);
         if (!sys->pictures[i]) {
             msg_Err(vd, "Failed to create picture");
             free(picture_res.p_sys);
diff --git a/modules/hw/nvdec/nvdec.c b/modules/hw/nvdec/nvdec.c
index 4feae961339..75bc54b06b1 100644
--- a/modules/hw/nvdec/nvdec.c
+++ b/modules/hw/nvdec/nvdec.c
@@ -255,7 +255,7 @@ static int CUDAAPI HandleVideoSequence(void *p_opaque, CUVIDEOFORMAT *p_format)
             picture_resource_t res = {
                 .p_sys = (void*)(uintptr_t)i,
             };
-            pics[i] = picture_NewFromResource( &p_dec->fmt_out.video, &res );
+            pics[i] = picture_NewFromResource( &p_dec->fmt_out.video, p_sys->vctx_out, &res );
             if (unlikely(pics[i] == NULL))
             {
                 msg_Dbg(p_dec, "failed to get a picture for the buffer");
diff --git a/modules/hw/vaapi/vlc_vaapi.c b/modules/hw/vaapi/vlc_vaapi.c
index 2a75ccaa535..756785d0699 100644
--- a/modules/hw/vaapi/vlc_vaapi.c
+++ b/modules/hw/vaapi/vlc_vaapi.c
@@ -525,7 +525,7 @@ vlc_vaapi_PoolNew(vlc_object_t *o, vlc_decoder_device *dec_device,
             .p_sys = p_sys,
             .pf_destroy = pool_pic_destroy_cb,
         };
-        pics[i] = picture_NewFromResource(fmt, &rsc);
+        pics[i] = picture_NewFromResource(fmt, NULL /*TODO*/, &rsc);
         if (pics[i] == NULL)
         {
             free(p_sys);
diff --git a/modules/hw/vdpau/picture.c b/modules/hw/vdpau/picture.c
index cbc5c21ec4b..55db236c4f1 100644
--- a/modules/hw/vdpau/picture.c
+++ b/modules/hw/vdpau/picture.c
@@ -163,7 +163,7 @@ error:
         .pf_destroy = vlc_vdp_output_surface_destroy,
     };
 
-    picture_t *pic = picture_NewFromResource(fmt, &res);
+    picture_t *pic = picture_NewFromResource(fmt, NULL /*TODO*/, &res);
     if (unlikely(pic == NULL))
     {
         vdp_output_surface_destroy(vdp, sys->surface);
diff --git a/modules/video_chroma/copy.c b/modules/video_chroma/copy.c
index 57e2ba23852..2708a96a77d 100644
--- a/modules/video_chroma/copy.c
+++ b/modules/video_chroma/copy.c
@@ -1102,7 +1102,7 @@ static picture_t *pic_new_unaligned(const video_format_t *fmt)
         rsc.p[i].p_pixels = malloc(rsc.p[i].i_lines * rsc.p[i].i_pitch);
         assert(rsc.p[i].p_pixels);
     }
-    return picture_NewFromResource(fmt, &rsc);
+    return picture_NewFromResource(fmt, NULL, &rsc);
 }
 
 int main(void)
diff --git a/modules/video_output/android/display.c b/modules/video_output/android/display.c
index e5c9553bcd6..9c45f687473 100644
--- a/modules/video_output/android/display.c
+++ b/modules/video_output/android/display.c
@@ -209,7 +209,7 @@ static picture_t *PictureAlloc(vout_display_sys_t *sys, video_format_t *fmt,
         rsc.pf_destroy = AndroidPicture_Destroy;
     }
 
-    p_pic = picture_NewFromResource(fmt, &rsc);
+    p_pic = picture_NewFromResource(fmt, NULL /*TODO*/, &rsc);
     if (!p_pic)
     {
         free(p_picsys);
diff --git a/modules/video_output/fb.c b/modules/video_output/fb.c
index 1538af34659..60910d6dba1 100644
--- a/modules/video_output/fb.c
+++ b/modules/video_output/fb.c
@@ -606,7 +606,7 @@ static int OpenDisplay(vout_display_t *vd, bool force_resolution)
        },
     };
 
-    sys->picture = picture_NewFromResource(&vd->fmt, &rsc);
+    sys->picture = picture_NewFromResource(&vd->fmt, NULL, &rsc);
     if (unlikely(sys->picture == NULL)) {
         munmap(rsc.p[0].p_pixels, sys->video_size);
         ioctl(sys->fd, FBIOPUT_VSCREENINFO, &sys->old_info);
diff --git a/modules/video_output/kms.c b/modules/video_output/kms.c
index 7626254b658..c5dd35f55c8 100644
--- a/modules/video_output/kms.c
+++ b/modules/video_output/kms.c
@@ -640,7 +640,7 @@ static picture_pool_t *Pool(vout_display_t *vd, unsigned count)
         rsc.p_sys = psys;
         rsc.pf_destroy = CustomDestroyPicture;
 
-        sys->picture = picture_NewFromResource(&vd->fmt, &rsc);
+        sys->picture = picture_NewFromResource(&vd->fmt, NULL, &rsc);
 
         if (!sys->picture) {
             free((void*)psys);
diff --git a/modules/video_output/opengl/converter_android.c b/modules/video_output/opengl/converter_android.c
index 92ddd291fcb..d26449ead24 100644
--- a/modules/video_output/opengl/converter_android.c
+++ b/modules/video_output/opengl/converter_android.c
@@ -99,7 +99,7 @@ tc_anop_get_pool(const opengl_tex_converter_t *tc, unsigned requested_count)
         p_picsys->hw.i_index = -1;
         vlc_mutex_init(&p_picsys->hw.lock);
 
-        picture[count] = picture_NewFromResource(&tc->fmt, &rsc);
+        picture[count] = picture_NewFromResource(&tc->fmt, NULL /*TODO*/, &rsc);
         if (!picture[count])
         {
             free(p_picsys);
diff --git a/modules/video_output/opengl/converter_sw.c b/modules/video_output/opengl/converter_sw.c
index b5746a637b9..feb532144cd 100644
--- a/modules/video_output/opengl/converter_sw.c
+++ b/modules/video_output/opengl/converter_sw.c
@@ -80,7 +80,7 @@ pbo_picture_create(const opengl_tex_converter_t *tc)
         .p_sys = picsys,
         .pf_destroy = pbo_picture_destroy,
     };
-    picture_t *pic = picture_NewFromResource(&tc->fmt, &rsc);
+    picture_t *pic = picture_NewFromResource(&tc->fmt, NULL, &rsc);
     if (pic == NULL)
     {
         free(picsys);
diff --git a/modules/video_output/vmem.c b/modules/video_output/vmem.c
index 2bdcd63d9e6..3c9b3658308 100644
--- a/modules/video_output/vmem.c
+++ b/modules/video_output/vmem.c
@@ -250,7 +250,7 @@ static void Prepare(vout_display_t *vd, picture_t *pic, subpicture_t *subpic,
         rsc.p[i].i_pitch  = sys->pitches[i];
     }
 
-    picture_t *locked = picture_NewFromResource(&vd->fmt, &rsc);
+    picture_t *locked = picture_NewFromResource(&vd->fmt, NULL, &rsc);
     if (likely(locked != NULL)) {
         picture_CopyPixels(locked, pic);
         picture_Release(locked);
diff --git a/modules/video_output/win32/direct3d11.c b/modules/video_output/win32/direct3d11.c
index c73c1d3682d..6a2f30c3656 100644
--- a/modules/video_output/win32/direct3d11.c
+++ b/modules/video_output/win32/direct3d11.c
@@ -447,7 +447,7 @@ static picture_pool_t *Pool(vout_display_t *vd, unsigned pool_size)
             .pf_destroy = DestroyDisplayPoolPicture,
         };
 
-        picture = picture_NewFromResource(&sys->area.texture_source, &resource);
+        picture = picture_NewFromResource(&sys->area.texture_source, NULL /*TODO*/, &resource);
         if (unlikely(picture == NULL)) {
             free(picsys);
             msg_Err( vd, "Failed to create picture %d in the pool.", picture_count );
@@ -1442,7 +1442,7 @@ static int Direct3D11MapSubpicture(vout_display_t *vd, int *subpicture_region_co
                 .p_sys      = (picture_sys_d3d11_t *) d3dquad,
                 .pf_destroy = DestroyPictureQuad,
             };
-            (*region)[i] = picture_NewFromResource(&r->p_picture->format, &picres);
+            (*region)[i] = picture_NewFromResource(&r->p_picture->format, r->p_picture->vctx, &picres);
             if ((*region)[i] == NULL) {
                 msg_Err(vd, "Failed to create %dx%d picture for OSD",
                         r->fmt.i_width, r->fmt.i_height);
diff --git a/modules/video_output/win32/direct3d9.c b/modules/video_output/win32/direct3d9.c
index b75ac2e323b..8ee6da63b42 100644
--- a/modules/video_output/win32/direct3d9.c
+++ b/modules/video_output/win32/direct3d9.c
@@ -259,7 +259,7 @@ static picture_pool_t *Direct3D9CreatePicturePool(vlc_object_t *o,
             .pf_destroy = DestroyPicture,
         };
 
-        picture_t *picture = picture_NewFromResource(fmt, &resource);
+        picture_t *picture = picture_NewFromResource(fmt, NULL /*TODO*/, &resource);
         if (unlikely(picture == NULL)) {
             free(picsys);
             goto error;
diff --git a/src/libvlccore.sym b/src/libvlccore.sym
index ce18e3ad6b6..7dce1c2c25b 100644
--- a/src/libvlccore.sym
+++ b/src/libvlccore.sym
@@ -308,7 +308,7 @@ picture_fifo_Peek
 picture_fifo_Pop
 picture_fifo_Push
 picture_New
-picture_NewFromFormat
+picture_NewFromFormatCtx
 picture_NewFromResource
 picture_pool_Release
 picture_pool_Get
diff --git a/src/misc/picture.c b/src/misc/picture.c
index cdde6f9951a..02a4d66f3ec 100644
--- a/src/misc/picture.c
+++ b/src/misc/picture.c
@@ -219,7 +219,8 @@ static picture_priv_t *picture_NewPrivate(const video_format_t *restrict p_fmt,
     return priv;
 }
 
-picture_t *picture_NewFromResource( const video_format_t *p_fmt, const picture_resource_t *p_resource )
+picture_t *picture_NewFromResource( const video_format_t *p_fmt, vlc_video_context *vctx,
+                                    const picture_resource_t *p_resource )
 {
     assert(p_resource != NULL);
 
@@ -230,6 +231,9 @@ picture_t *picture_NewFromResource( const video_format_t *p_fmt, const picture_r
     picture_t *p_picture = &priv->picture;
 
     p_picture->p_sys = p_resource->p_sys;
+    p_picture->vctx  = vctx;
+    if (p_picture->vctx)
+        vlc_video_context_Hold(p_picture->vctx);
 
     if( p_resource->pf_destroy != NULL )
         priv->gc.destroy = p_resource->pf_destroy;
@@ -248,7 +252,7 @@ picture_t *picture_NewFromResource( const video_format_t *p_fmt, const picture_r
 
 #define PICTURE_SW_SIZE_MAX (UINT32_C(1) << 28) /* 256MB: 8K * 8K * 4*/
 
-picture_t *picture_NewFromFormat(const video_format_t *restrict fmt)
+picture_t *picture_NewFromFormatCtx(const video_format_t *restrict fmt, vlc_video_context *vctx)
 {
     picture_priv_t *priv = picture_NewPrivate(fmt, sizeof (picture_buffer_t));
     if (unlikely(priv == NULL))
@@ -259,6 +263,10 @@ picture_t *picture_NewFromFormat(const video_format_t *restrict fmt)
     picture_t *pic = &priv->picture;
     if (pic->i_planes == 0) {
         pic->p_sys = NULL;
+        if (vctx)
+        {
+            pic->vctx = vlc_video_context_Hold( vctx );
+        }
         return pic;
     }
 
@@ -298,6 +306,7 @@ picture_t *picture_NewFromFormat(const video_format_t *restrict fmt)
 
     return pic;
 error:
+    if (vctx) vlc_video_context_Release( vctx );
     free(pic);
     return NULL;
 }
@@ -328,6 +337,8 @@ void picture_Destroy(picture_t *picture)
     picture_priv_t *priv = container_of(picture, picture_priv_t, picture);
     assert(priv->gc.destroy != NULL);
     priv->gc.destroy(picture);
+    if (picture->vctx)
+        vlc_video_context_Release(picture->vctx);
     free(priv);
 }
 
@@ -419,7 +430,8 @@ picture_t *picture_Clone(picture_t *picture)
         res.p[i].i_pitch = picture->p[i].i_pitch;
     }
 
-    picture_t *clone = picture_NewFromResource(&picture->format, &res);
+    picture_t *clone = picture_NewFromResource(&picture->format, picture->vctx,
+                                               &res);
     if (likely(clone != NULL)) {
         ((picture_priv_t *)clone)->gc.opaque = picture;
         picture_Hold(picture);
diff --git a/src/misc/picture_pool.c b/src/misc/picture_pool.c
index 7015f07fa07..25f73b021a1 100644
--- a/src/misc/picture_pool.c
+++ b/src/misc/picture_pool.c
@@ -106,7 +106,7 @@ static picture_t *picture_pool_ClonePicture(picture_pool_t *pool,
         res.p[i].i_pitch = picture->p[i].i_pitch;
     }
 
-    picture_t *clone = picture_NewFromResource(&picture->format, &res);
+    picture_t *clone = picture_NewFromResource(&picture->format, picture->vctx, &res);
     if (likely(clone != NULL)) {
         ((picture_priv_t *)clone)->gc.opaque = (void *)sys;
         picture_Hold(picture);
-- 
2.17.1



More information about the vlc-devel mailing list