[vlc-devel] [PATCH 28/31] video context: allow storing extra data in the video context

Steve Lhomme robux4 at ycbcr.xyz
Fri Jul 5 16:20:07 CEST 2019


Each video context can store extra objects, like the IDirect3DDevice9* for D3D9,
which is not found in the decoder device.
---
 include/vlc_picture.h           | 19 ++++++++++++++++++-
 modules/codec/avcodec/d3d11va.c |  2 +-
 modules/codec/avcodec/dxva2.c   |  2 +-
 modules/codec/avcodec/vaapi.c   |  4 ++++
 src/audio_output/filters.c      |  5 +++--
 src/input/decoder_helpers.c     | 29 ++++++++++++++++++++++++-----
 src/libvlccore.sym              |  2 ++
 7 files changed, 53 insertions(+), 10 deletions(-)

diff --git a/include/vlc_picture.h b/include/vlc_picture.h
index d4b474c1e0..9319de5404 100644
--- a/include/vlc_picture.h
+++ b/include/vlc_picture.h
@@ -82,12 +82,29 @@ typedef struct picture_buffer_t
 typedef struct vlc_decoder_device vlc_decoder_device;
 typedef struct vlc_video_context vlc_video_context;
 
+/** Decoder device type */
+enum vlc_video_context_type
+{
+    VLC_VIDEO_CONTEXT_NONE,
+    VLC_VIDEO_CONTEXT_VAAPI,
+    VLC_VIDEO_CONTEXT_VDPAU,
+    VLC_VIDEO_CONTEXT_DXVA2,
+    VLC_VIDEO_CONTEXT_D3D11VA,
+    VLC_VIDEO_CONTEXT_AWINDOW,
+    VLC_VIDEO_CONTEXT_MMAL,
+};
+
 VLC_API vlc_video_context * vlc_video_context_Create(vlc_decoder_device *device,
-                                        void *opaque, void (*destroy)(void *));
+                                        size_t private_size,
+                                        enum vlc_video_context_type private_type,
+                                        void *opaque, void (*destroy)(void *opaque, void *priv));
 
 VLC_API vlc_video_context *vlc_video_context_Hold(vlc_video_context *);
 VLC_API void vlc_video_context_Release(vlc_video_context *);
 
+VLC_API void *vlc_video_context_GetPrivate(vlc_video_context *, enum vlc_video_context_type);
+VLC_API enum vlc_video_context_type vlc_video_context_GetType(const vlc_video_context *);
+
 /**
  * Get the decoder device used by the device context.
  *
diff --git a/modules/codec/avcodec/d3d11va.c b/modules/codec/avcodec/d3d11va.c
index 0c3b0d373d..e066729cbb 100644
--- a/modules/codec/avcodec/d3d11va.c
+++ b/modules/codec/avcodec/d3d11va.c
@@ -370,7 +370,7 @@ static int Open(vlc_va_t *va, AVCodecContext *ctx, enum PixelFormat pix_fmt,
             if (sys->d3d_dev.context_mutex == INVALID_HANDLE_VALUE)
                 msg_Warn(va, "No mutex found to lock the decoder");
 
-            vlc_video_context *vctx = vlc_video_context_Create( dec_device, NULL, NULL );
+            vlc_video_context *vctx = vlc_video_context_Create( dec_device, 0, VLC_VIDEO_CONTEXT_NONE, NULL, NULL );
             if (likely(vctx != NULL))
             {
                 void *d3dvidctx = NULL;
diff --git a/modules/codec/avcodec/dxva2.c b/modules/codec/avcodec/dxva2.c
index 63a2d11217..1a127bfc7d 100644
--- a/modules/codec/avcodec/dxva2.c
+++ b/modules/codec/avcodec/dxva2.c
@@ -274,7 +274,7 @@ static int Open(vlc_va_t *va, AVCodecContext *ctx, enum PixelFormat pix_fmt,
     d3d9_decoder_device_t *d3d9_decoder = GetD3D9OpaqueDevice( dec_device );
     if ( d3d9_decoder != NULL )
     {
-        vlc_video_context *vctx = vlc_video_context_Create( dec_device, NULL, NULL );
+        vlc_video_context *vctx = vlc_video_context_Create( dec_device, 0, VLC_VIDEO_CONTEXT_NONE, NULL, NULL );
         if (likely(vctx != NULL))
         {
             D3D9_CloneExternal(&sys->hd3d, d3d9_decoder->device);
diff --git a/modules/codec/avcodec/vaapi.c b/modules/codec/avcodec/vaapi.c
index ba18a2c01b..88574aadeb 100644
--- a/modules/codec/avcodec/vaapi.c
+++ b/modules/codec/avcodec/vaapi.c
@@ -200,6 +200,10 @@ static int Create(vlc_va_t *va, AVCodecContext *ctx, enum PixelFormat pix_fmt,
 
     msg_Info(va, "Using %s", vaQueryVendorString(sys->hw_ctx.display));
 
+    *vctx_out = vlc_video_context_Create( dec_device, 0, VLC_VIDEO_CONTEXT_NONE, NULL, NULL );
+    if (*vctx_out == NULL)
+        goto error;
+
     ctx->hwaccel_context = &sys->hw_ctx;
     va->sys = sys;
     va->get = Get;
diff --git a/src/audio_output/filters.c b/src/audio_output/filters.c
index ffd2e97694..add18f52f1 100644
--- a/src/audio_output/filters.c
+++ b/src/audio_output/filters.c
@@ -399,8 +399,9 @@ vout_thread_t *aout_filter_GetVout(filter_t *filter, const video_format_t *fmt)
     vlc_decoder_device *dec_dev = NULL;
     if (vout_RequestDevice(&cfg, &dec_dev) == 0)
     {
-        vlc_video_context *vctx = vlc_video_context_Create(dec_dev, NULL, NULL);
-        if (vout_RequestDisplay(&cfg, vctx, NULL) == 0)
+        vlc_video_context *vctx =
+            vlc_video_context_Create( dec_dev, 0, VLC_VIDEO_CONTEXT_NONE, NULL, NULL );
+        if (vctx != NULL)
         {
             vlc_decoder_device_Release(dec_dev);
             /* don't keep it for now */
diff --git a/src/input/decoder_helpers.c b/src/input/decoder_helpers.c
index afc9f85a48..3f5f407f4d 100644
--- a/src/input/decoder_helpers.c
+++ b/src/input/decoder_helpers.c
@@ -104,7 +104,7 @@ int decoder_UpdateVideoOutput( decoder_t *dec )
     if (dec->vctx_out == NULL)
     {
         // Create a default video context as the decoder didn't create one
-        dec->vctx_out = vlc_video_context_Create( dec->init_device, NULL, NULL);
+        dec->vctx_out = vlc_video_context_Create( dec->init_device, 0, VLC_VIDEO_CONTEXT_NONE, NULL, NULL);
         if (unlikely(dec->vctx_out == NULL))
             return -1;
     }
@@ -203,22 +203,41 @@ struct vlc_video_context
     vlc_atomic_rc_t    rc;
     vlc_decoder_device *device;
     void *opaque;
-    void (*destroy)(void *);
+    void (*destroy)(void *, void *);
+    size_t private_size;
+    enum vlc_video_context_type type;
+    uint8_t private[];
 };
 
 vlc_video_context * vlc_video_context_Create(vlc_decoder_device *device,
-                                          void *opaque, void (*destroy)(void *))
+                                          size_t private_size,
+                                          enum vlc_video_context_type private_type,
+                                          void *opaque, void (*destroy)(void *, void*))
 {
-    vlc_video_context *vctx = malloc(sizeof(*vctx));
+    vlc_video_context *vctx = malloc(sizeof(*vctx) + private_size);
     if (unlikely(vctx == NULL))
         return NULL;
     vlc_atomic_rc_init( &vctx->rc );
+    vctx->private_size = private_size;
+    vctx->type = private_type;
     vctx->device = vlc_decoder_device_Hold( device );
     vctx->opaque = opaque;
     vctx->destroy = destroy;
     return vctx;
 }
 
+enum vlc_video_context_type vlc_video_context_GetType(const vlc_video_context *vctx)
+{
+    return vctx->type;
+}
+
+void *vlc_video_context_GetPrivate(vlc_video_context *vctx, enum vlc_video_context_type type)
+{
+    if (vctx->type == type)
+        return &vctx->private;
+    return NULL;
+}
+
 vlc_video_context *vlc_video_context_Hold(vlc_video_context *vctx)
 {
     vlc_atomic_rc_inc( &vctx->rc );
@@ -231,7 +250,7 @@ void vlc_video_context_Release(vlc_video_context *vctx)
     {
         vlc_decoder_device_Release( vctx->device );
         if ( vctx->destroy )
-            vctx->destroy( vctx->opaque );
+            vctx->destroy( vctx->opaque, vlc_video_context_GetPrivate(vctx, vctx->type) );
     }
 }
 
diff --git a/src/libvlccore.sym b/src/libvlccore.sym
index bae8efe401..90cf0ea017 100644
--- a/src/libvlccore.sym
+++ b/src/libvlccore.sym
@@ -944,3 +944,5 @@ vlc_video_context_Create
 vlc_video_context_Hold
 vlc_video_context_Release
 vlc_video_context_GetDevice
+vlc_video_context_GetType
+vlc_video_context_GetPrivate
-- 
2.17.1



More information about the vlc-devel mailing list