[vlc-commits] core: add vlc_decoder_device

Thomas Guillem git at videolan.org
Sun Feb 24 15:21:38 CET 2019


vlc | branch: master | Thomas Guillem <thomas at gllm.fr> | Sun Feb 24 12:08:16 2019 +0100| [f58bd455bdb0aaa3364f9cd72bfde799eb728b2d] | committer: Thomas Guillem

core: add vlc_decoder_device

This struct hold the hardware decoder device that will be filled from a
"decoder device" module depending on the "vout window" type.

This will allow decoders to know the type of the hardware device before
initializing hardware decoding.

> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=f58bd455bdb0aaa3364f9cd72bfde799eb728b2d
---

 include/vlc_codec.h         | 76 ++++++++++++++++++++++++++++++++++++++++++++
 src/input/decoder_helpers.c | 77 +++++++++++++++++++++++++++++++++++++++++++++
 src/libvlc-module.c         |  3 ++
 src/libvlccore.sym          |  3 ++
 4 files changed, 159 insertions(+)

diff --git a/include/vlc_codec.h b/include/vlc_codec.h
index 96ceee8feb..983b209db9 100644
--- a/include/vlc_codec.h
+++ b/include/vlc_codec.h
@@ -27,6 +27,7 @@
 
 #include <vlc_block.h>
 #include <vlc_es.h>
+#include <vlc_vout_window.h>
 #include <vlc_picture.h>
 #include <vlc_subpicture.h>
 
@@ -472,5 +473,80 @@ static inline float decoder_GetDisplayRate( decoder_t *dec )
 }
 
 /** @} */
+
+/**
+ * \defgroup decoder_device Decoder hardware device
+ * \ingroup input
+ * @{
+ */
+
+/** Decoder device type */
+enum vlc_decoder_device_type
+{
+    VLC_DECODER_DEVICE_NONE,
+    VLC_DECODER_DEVICE_VAAPI,
+    VLC_DECODER_DEVICE_VDPAU,
+    VLC_DECODER_DEVICE_DXVA2,
+    VLC_DECODER_DEVICE_D3D11VA,
+    VLC_DECODER_DEVICE_AWINDOW,
+};
+
+/**
+ * Decoder context struct
+ */
+typedef struct vlc_decoder_device
+{
+    struct vlc_common_members obj;
+
+    /** Private context that could be used by the "decoder device" module
+     * implementation */
+    void *sys;
+
+    /** Must be set from the "decoder device" module open entry point */
+    enum vlc_decoder_device_type type;
+
+    /**
+     * Could be set from the "decoder device" module open entry point and will
+     * be used by hardware decoder modules.
+     *
+     * The type of pointer will depend of the type:
+     * VAAPI: VADisplay
+     * VDPAU: vdp_t *
+     */
+    void *opaque;
+} vlc_decoder_device;
+
+/**
+ * "decoder device" module open entry point
+ *
+ * @param device the "decoder device" structure to initialize
+ * @param window pointer to a window to help device initialization (can be NULL)
+ **/
+typedef int (*vlc_decoder_device_Open)(vlc_decoder_device *device,
+                                        vout_window_t *window);
+/** "decoder device" module close entry point */
+typedef void (*vlc_decoder_device_Close)(vlc_decoder_device *device);
+
+/**
+ * Create a decoder device from a window
+ *
+ * This function will be hidden in the future. It is now used by opengl vout
+ * module as a transition.
+ */
+VLC_API /* temporary */ VLC_USED vlc_decoder_device *
+vlc_decoder_device_Create(vout_window_t *window);
+
+/**
+ * Hold a decoder device
+ */
+VLC_API vlc_decoder_device *
+vlc_decoder_device_Hold(vlc_decoder_device *device);
+
+/**
+ * Release a decoder device
+ */
+VLC_API void
+vlc_decoder_device_Release(vlc_decoder_device *device);
+
 /** @} */
 #endif /* _VLC_CODEC_H */
diff --git a/src/input/decoder_helpers.c b/src/input/decoder_helpers.c
index b0a7c1890a..2dcdc1c82a 100644
--- a/src/input/decoder_helpers.c
+++ b/src/input/decoder_helpers.c
@@ -28,6 +28,7 @@
 
 #include <vlc_common.h>
 #include <vlc_codec.h>
+#include <vlc_atomic.h>
 #include <vlc_meta.h>
 #include <vlc_modules.h>
 
@@ -88,3 +89,79 @@ picture_t *decoder_NewPicture( decoder_t *dec )
     vlc_assert( dec->fmt_in.i_cat == VIDEO_ES && dec->cbs != NULL );
     return dec->cbs->video.buffer_new( dec );
 }
+
+struct vlc_decoder_device_priv
+{
+    struct vlc_decoder_device device;
+    vlc_atomic_rc_t rc;
+    module_t *module;
+};
+
+static int decoder_device_Open(void *func, va_list ap)
+{
+    vlc_decoder_device_Open open = func;
+    vlc_decoder_device *device = va_arg(ap, vlc_decoder_device *);
+    vout_window_t *window = va_arg(ap, vout_window_t *);
+    int ret = open(device, window);
+    if (ret != VLC_SUCCESS)
+    {
+        device->sys = NULL;
+        device->type = VLC_DECODER_DEVICE_NONE;
+        device->opaque = NULL;
+    }
+    else
+    {
+        assert(device->type != VLC_DECODER_DEVICE_NONE);
+    }
+    return ret;
+}
+
+static void decoder_device_Close(void *func, va_list ap)
+{
+    vlc_decoder_device_Close close = func;
+    vlc_decoder_device *device = va_arg(ap, vlc_decoder_device *);
+    close(device);
+}
+
+vlc_decoder_device *
+vlc_decoder_device_Create(vout_window_t *window)
+{
+    struct vlc_decoder_device_priv *priv =
+            vlc_object_create(window, sizeof (*priv));
+    if (!priv)
+        return NULL;
+    char *name = var_InheritString(window, "dec-dev");
+    priv->module = vlc_module_load(&priv->device, "decoder device", name,
+                                    true, decoder_device_Open, &priv->device,
+                                    window);
+    free(name);
+    if (!priv->module)
+    {
+        vlc_object_release(&priv->device);
+        return NULL;
+    }
+    vlc_atomic_rc_init(&priv->rc);
+    return &priv->device;
+}
+
+vlc_decoder_device *
+vlc_decoder_device_Hold(vlc_decoder_device *device)
+{
+    struct vlc_decoder_device_priv *priv =
+            container_of(device, struct vlc_decoder_device_priv, device);
+    vlc_atomic_rc_inc(&priv->rc);
+    return device;
+}
+
+void
+vlc_decoder_device_Release(vlc_decoder_device *device)
+{
+    struct vlc_decoder_device_priv *priv =
+            container_of(device, struct vlc_decoder_device_priv, device);
+    if (vlc_atomic_rc_dec(&priv->rc))
+    {
+        vlc_module_unload(device, priv->module, decoder_device_Close,
+                          device);
+        vlc_object_release(device);
+    }
+}
diff --git a/src/libvlc-module.c b/src/libvlc-module.c
index 2465c8c3d7..9dc4a2c09f 100644
--- a/src/libvlc-module.c
+++ b/src/libvlc-module.c
@@ -931,6 +931,8 @@ static const char *const ppsz_prefres[] = {
     "This allows you to select a list of encoders that VLC will use in " \
     "priority.")
 
+#define DEC_DEV_TEXT N_("Preferred decoder hardware device")
+
 /*****************************************************************************
  * Sout
  ****************************************************************************/
@@ -1963,6 +1965,7 @@ vlc_module_begin ()
                 CODEC_LONGTEXT, true )
     add_string( "encoder",  NULL, ENCODER_TEXT,
                 ENCODER_LONGTEXT, true )
+    add_string( "dec-dev", NULL, DEC_DEV_TEXT, NULL, true )
 
     set_subcategory( SUBCAT_INPUT_ACCESS )
     add_category_hint(N_("Input"), INPUT_CAT_LONGTEXT)
diff --git a/src/libvlccore.sym b/src/libvlccore.sym
index a9d468265b..4ba7bbb3c2 100644
--- a/src/libvlccore.sym
+++ b/src/libvlccore.sym
@@ -80,6 +80,9 @@ decoder_Destroy
 decoder_AbortPictures
 decoder_NewAudioBuffer
 decoder_UpdateVideoFormat
+vlc_decoder_device_Create
+vlc_decoder_device_Hold
+vlc_decoder_device_Release
 demux_PacketizerDestroy
 demux_PacketizerNew
 demux_New



More information about the vlc-commits mailing list