[vlc-devel] [PATCH 2/6] core: add vlc_decoder_context

Thomas Guillem thomas at gllm.fr
Sun Feb 24 12:27:04 CET 2019


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

This will allow decoders to know the type of the hardware context before
initializing hardware decoding.
---
 include/vlc_codec.h         | 72 ++++++++++++++++++++++++++++++++++
 src/input/decoder_helpers.c | 77 +++++++++++++++++++++++++++++++++++++
 src/libvlc-module.c         |  3 ++
 src/libvlccore.sym          |  3 ++
 4 files changed, 155 insertions(+)

diff --git a/include/vlc_codec.h b/include/vlc_codec.h
index 96ceee8feb..26163cb09e 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,76 @@ static inline float decoder_GetDisplayRate( decoder_t *dec )
 }
 
 /** @} */
+
+/**
+ * \defgroup decoder_context Decoder hardware context
+ * \ingroup input
+ * @{
+ */
+
+
+/** Decoder context type */
+enum vlc_decoder_context_type
+{
+    VLC_DECODER_CONTEXT_NONE,
+    VLC_DECODER_CONTEXT_VAAPI,
+    VLC_DECODER_CONTEXT_VDPAU,
+    VLC_DECODER_CONTEXT_DXVA2,
+    VLC_DECODER_CONTEXT_D3D11VA,
+    VLC_DECODER_CONTEXT_AWINDOW,
+};
+
+/**
+ * Decoder context struct
+ */
+typedef struct vlc_decoder_context
+{
+    struct vlc_common_members obj;
+
+    /** Private context that could be used by the "decoder context" module
+     * implementation */
+    void *sys;
+
+    /** Must be set from the "decoder context" module open entry point */
+    enum vlc_decoder_context_type type;
+
+    /**
+     * Could be set from the "decoder context" 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_context;
+
+/** "decoder context" module open entry point */
+typedef int (*vlc_decoder_context_Open)(vlc_decoder_context *context,
+                                        vout_window_t *window);
+/** "decoder context" module close entry point */
+typedef void (*vlc_decoder_context_Close)(vlc_decoder_context *context);
+
+/**
+ * Create a decoder context 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_context *
+vlc_decoder_context_Create(vout_window_t *window);
+
+/**
+ * Hold a decoder context
+ */
+VLC_API vlc_decoder_context *
+vlc_decoder_context_Hold(vlc_decoder_context *context);
+
+/**
+ * Release a decoder context
+ */
+VLC_API void
+vlc_decoder_context_Release(vlc_decoder_context *context);
+
 /** @} */
 #endif /* _VLC_CODEC_H */
diff --git a/src/input/decoder_helpers.c b/src/input/decoder_helpers.c
index b0a7c1890a..47918aa47f 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_context_owner
+{
+    struct vlc_decoder_context context;
+    vlc_atomic_rc_t rc;
+    module_t *module;
+};
+
+static int decoder_context_Open(void *func, va_list ap)
+{
+    vlc_decoder_context_Open open = func;
+    vlc_decoder_context *context = va_arg(ap, vlc_decoder_context *);
+    vout_window_t *window = va_arg(ap, vout_window_t *);
+    int ret = open(context, window);
+    if (ret != VLC_SUCCESS)
+    {
+        context->sys = NULL;
+        context->type = VLC_DECODER_CONTEXT_NONE;
+        context->opaque = NULL;
+    }
+    else
+    {
+        assert(context->type != VLC_DECODER_CONTEXT_NONE);
+    }
+    return ret;
+}
+
+static void decoder_context_Close(void *func, va_list ap)
+{
+    vlc_decoder_context_Close close = func;
+    vlc_decoder_context *context = va_arg(ap, vlc_decoder_context *);
+    close(context);
+}
+
+vlc_decoder_context *
+vlc_decoder_context_Create(vout_window_t *window)
+{
+    struct vlc_decoder_context_owner *owner =
+            vlc_object_create(window, sizeof (*owner));
+    if (!owner)
+        return NULL;
+    char *name = var_InheritString(window, "dec-ctx");
+    owner->module = vlc_module_load(&owner->context, "decoder context", name,
+                                    true, decoder_context_Open, &owner->context,
+                                    window);
+    free(name);
+    if (!owner->module)
+    {
+        vlc_object_release(&owner->context);
+        return NULL;
+    }
+    vlc_atomic_rc_init(&owner->rc);
+    return &owner->context;
+}
+
+vlc_decoder_context *
+vlc_decoder_context_Hold(vlc_decoder_context *context)
+{
+    struct vlc_decoder_context_owner *owner =
+            container_of(context, struct vlc_decoder_context_owner, context);
+    vlc_atomic_rc_inc(&owner->rc);
+    return context;
+}
+
+void
+vlc_decoder_context_Release(vlc_decoder_context *context)
+{
+    struct vlc_decoder_context_owner *owner =
+            container_of(context, struct vlc_decoder_context_owner, context);
+    if (vlc_atomic_rc_dec(&owner->rc))
+    {
+        vlc_module_unload(context, owner->module, decoder_context_Close,
+                          context);
+        vlc_object_release(context);
+    }
+}
diff --git a/src/libvlc-module.c b/src/libvlc-module.c
index 360a3b00c2..14e889dbdf 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_CTX_TEXT N_("Preferred decoder hardware context")
+
 /*****************************************************************************
  * Sout
  ****************************************************************************/
@@ -1963,6 +1965,7 @@ vlc_module_begin ()
                 CODEC_LONGTEXT, true )
     add_string( "encoder",  NULL, ENCODER_TEXT,
                 ENCODER_LONGTEXT, true )
+    add_string( "dec-ctx", NULL, DEC_CTX_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..2dfe3d147c 100644
--- a/src/libvlccore.sym
+++ b/src/libvlccore.sym
@@ -80,6 +80,9 @@ decoder_Destroy
 decoder_AbortPictures
 decoder_NewAudioBuffer
 decoder_UpdateVideoFormat
+vlc_decoder_context_Create
+vlc_decoder_context_Hold
+vlc_decoder_context_Release
 demux_PacketizerDestroy
 demux_PacketizerNew
 demux_New
-- 
2.20.1



More information about the vlc-devel mailing list