[vlc-commits] nvdec: add a NVDEC decoder device

Steve Lhomme git at videolan.org
Wed Sep 18 09:05:26 CEST 2019


vlc | branch: master | Steve Lhomme <robux4 at ycbcr.xyz> | Wed Sep 18 08:38:48 2019 +0200| [af1d76d352fc9bda6bcfd1f054dd8e4adaf3c42b] | committer: Steve Lhomme

nvdec: add a NVDEC decoder device

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

 include/vlc_codec.h          |  2 ++
 modules/hw/nvdec/nvdec.c     | 53 ++++++++++++++++++++++++++++++++++++++++++++
 modules/hw/nvdec/nvdec_fmt.h |  7 ++++++
 3 files changed, 62 insertions(+)

diff --git a/include/vlc_codec.h b/include/vlc_codec.h
index 8ecdcadb39..55e24cb964 100644
--- a/include/vlc_codec.h
+++ b/include/vlc_codec.h
@@ -491,6 +491,7 @@ enum vlc_decoder_device_type
     VLC_DECODER_DEVICE_DXVA2,
     VLC_DECODER_DEVICE_D3D11VA,
     VLC_DECODER_DEVICE_AWINDOW,
+    VLC_DECODER_DEVICE_NVDEC,
     VLC_DECODER_DEVICE_MMAL,
 };
 
@@ -525,6 +526,7 @@ typedef struct vlc_decoder_device
      * DXVA2: IDirect3DDevice9*
      * D3D11VA: ID3D11DeviceContext*
      * AWindow: android AWindowHandler*
+     * NVDEC: decoder_device_nvdec_t*
      * MMAL: MMAL_PORT_T*
      */
     void *opaque;
diff --git a/modules/hw/nvdec/nvdec.c b/modules/hw/nvdec/nvdec.c
index 561967391f..f6ac3ccbc4 100644
--- a/modules/hw/nvdec/nvdec.c
+++ b/modules/hw/nvdec/nvdec.c
@@ -39,6 +39,7 @@
 
 static int OpenDecoder(vlc_object_t *);
 static void CloseDecoder(vlc_object_t *);
+static int DecoderContextOpen(vlc_decoder_device *, vout_window_t *);
 
 #define DEINTERLACE_MODULE_TEXT N_("Integrated deinterlacing")
 #define DEINTERLACE_MODULE_LONGTEXT N_( "Specify the deinterlace mode to use." )
@@ -64,6 +65,9 @@ vlc_module_begin ()
                  DEINTERLACE_MODULE_TEXT, DEINTERLACE_MODULE_LONGTEXT, true )
         change_integer_list( ppsi_deinterlace_type, ppsz_deinterlace_type )
     set_callbacks(OpenDecoder, CloseDecoder)
+    add_submodule()
+        set_callback_dec_device(DecoderContextOpen, 3)
+        add_shortcut("nvdec-device")
 vlc_module_end ()
 
 /* */
@@ -112,6 +116,7 @@ static inline int CudaCall(decoder_t *p_dec, CUresult result, const char *psz_fu
 }
 
 #define CALL_CUDA_DEC(func, ...) CudaCall(p_dec,  p_sys->cudaFunctions->func(__VA_ARGS__), #func)
+#define CALL_CUDA_DEV(func, ...) CudaCall(device, p_sys->cudaFunctions->func(__VA_ARGS__), #func)
 #define CALL_CUVID(func, ...)    CudaCall(p_dec,  p_sys->cuvidFunctions->func(__VA_ARGS__), #func)
 
 static vlc_fourcc_t MapSurfaceChroma(cudaVideoChromaFormat chroma, unsigned bitDepth)
@@ -932,3 +937,51 @@ static void CloseDecoder(vlc_object_t *p_this)
         hxxx_helper_clean(&p_sys->hh);
 }
 
+/** Decoder Device **/
+static void DecoderContextClose(vlc_decoder_device *device)
+{
+    decoder_device_nvdec_t *p_sys = device->opaque;
+    if (p_sys->cuCtx)
+        CALL_CUDA_DEV(cuCtxDestroy, p_sys->cuCtx);
+    cuda_free_functions(&p_sys->cudaFunctions);
+}
+
+static const struct vlc_decoder_device_operations dev_ops = {
+    .close = DecoderContextClose,
+};
+
+static int
+DecoderContextOpen(vlc_decoder_device *device, vout_window_t *window)
+{
+    VLC_UNUSED(window);
+
+    decoder_device_nvdec_t *p_sys = vlc_obj_malloc(VLC_OBJECT(device), sizeof(*p_sys));
+    if (unlikely(p_sys == NULL))
+        return VLC_ENOMEM;
+    device->opaque = p_sys;
+    p_sys->cudaFunctions = NULL;
+
+    int result = cuda_load_functions(&p_sys->cudaFunctions, device);
+    if (result != VLC_SUCCESS) {
+        return VLC_EGENERIC;
+    }
+
+    result = CALL_CUDA_DEV(cuInit, 0);
+    if (result != VLC_SUCCESS)
+    {
+        DecoderContextClose(device);
+        return result;
+    }
+
+    result = CALL_CUDA_DEV(cuCtxCreate, &p_sys->cuCtx, 0, 0);
+    if (result != VLC_SUCCESS)
+    {
+        DecoderContextClose(device);
+        return result;
+    }
+
+    device->ops = &dev_ops;
+    device->type = VLC_DECODER_DEVICE_NVDEC;
+    return VLC_SUCCESS;
+}
+
diff --git a/modules/hw/nvdec/nvdec_fmt.h b/modules/hw/nvdec/nvdec_fmt.h
index bc0a2f6b88..8572817604 100644
--- a/modules/hw/nvdec/nvdec_fmt.h
+++ b/modules/hw/nvdec/nvdec_fmt.h
@@ -25,6 +25,13 @@
 
 #include <ffnvcodec/dynlink_loader.h>
 
+typedef struct {
+
+    CudaFunctions  *cudaFunctions;
+    CUcontext      cuCtx;
+
+} decoder_device_nvdec_t;
+
 static inline bool is_nvdec_opaque(vlc_fourcc_t fourcc)
 {
     return fourcc == VLC_CODEC_NVDEC_OPAQUE ||



More information about the vlc-commits mailing list