CUresult (CUDAAPI *
CuGraphicsResourceSetMapFlags) (CUgraphicsResource resource,
unsigned int flags);
+ CUresult (CUDAAPI * CuGLGetDevices) (unsigned int *pCudaDeviceCount,
+ CUdevice * pCudaDevices, unsigned int cudaDeviceCount,
+ CUGLDeviceList deviceList);
} GstNvCodecCudaVTable;
static GstNvCodecCudaVTable gst_cuda_vtable = { 0, };
LOAD_SYMBOL (cuGraphicsGLRegisterImage, CuGraphicsGLRegisterImage);
LOAD_SYMBOL (cuGraphicsGLRegisterBuffer, CuGraphicsGLRegisterBuffer);
LOAD_SYMBOL (cuGraphicsResourceSetMapFlags, CuGraphicsResourceSetMapFlags);
+ LOAD_SYMBOL (cuGLGetDevices, CuGLGetDevices);
vtable->loaded = TRUE;
return gst_cuda_vtable.CuGraphicsResourceSetMapFlags (resource, flags);
}
+
+CUresult CUDAAPI
+CuGLGetDevices (unsigned int *pCudaDeviceCount, CUdevice * pCudaDevices,
+ unsigned int cudaDeviceCount, CUGLDeviceList deviceList)
+{
+ g_assert (gst_cuda_vtable.CuGLGetDevices != NULL);
+
+ return gst_cuda_vtable.CuGLGetDevices (pCudaDeviceCount, pCudaDevices,
+ cudaDeviceCount, deviceList);
+}
if (nvdec->mem_type == GST_NVDEC_MEM_TYPE_GL &&
!gst_nvdec_ensure_gl_context (nvdec)) {
GST_WARNING_OBJECT (nvdec,
- "OpenGL context cannot support PBO memory, fallback to system memory");
+ "OpenGL context is not CUDA-compatible, fallback to system memory");
nvdec->mem_type = GST_NVDEC_MEM_TYPE_SYSTEM;
}
GstVideoCodecFrame *frame = NULL;
GstBuffer *output_buffer = NULL;
GstFlowReturn ret = GST_FLOW_OK;
- gboolean copy_ret;
+ gboolean copy_ret = FALSE;
GST_LOG_OBJECT (nvdec, "picture index: %u", dispinfo->picture_index);
#ifdef HAVE_NVCODEC_GST_GL
if (nvdec->mem_type == GST_NVDEC_MEM_TYPE_GL) {
copy_ret = gst_nvdec_copy_device_to_gl (nvdec, dispinfo, output_buffer);
- } else
+
+ /* FIXME: This is the case where OpenGL context of downstream glbufferpool
+ * belongs to non-nvidia (or different device).
+ * There should be enhancement to ensure nvdec has compatible OpenGL context
+ */
+ if (!copy_ret) {
+ GST_WARNING_OBJECT (nvdec,
+ "Couldn't copy frame to GL memory, fallback to system memory");
+ nvdec->mem_type = GST_NVDEC_MEM_TYPE_SYSTEM;
+ }
+ }
+
+ if (!copy_ret)
#endif
{
copy_ret = gst_nvdec_copy_device_to_system (nvdec, dispinfo, output_buffer);
}
#ifdef HAVE_NVCODEC_GST_GL
+static void
+gst_nvdec_check_cuda_device_from_context (GstGLContext * context,
+ gboolean * ret)
+{
+ guint device_count = 0;
+ CUdevice device_list[1] = { 0, };
+ CUresult cuda_ret;
+
+ *ret = FALSE;
+
+ cuda_ret = CuGLGetDevices (&device_count,
+ device_list, 1, CU_GL_DEVICE_LIST_ALL);
+
+ if (!gst_cuda_result (cuda_ret) || device_count == 0)
+ return;
+
+ *ret = TRUE;
+
+ return;
+}
+
static gboolean
gst_nvdec_ensure_gl_context (GstNvDec * nvdec)
{
+ gboolean ret;
+
if (!nvdec->gl_display) {
GST_DEBUG_OBJECT (nvdec, "No available OpenGL display");
return FALSE;
return FALSE;
}
+ gst_gl_context_thread_add (nvdec->gl_context,
+ (GstGLContextThreadFunc) gst_nvdec_check_cuda_device_from_context, &ret);
+
+ if (!ret) {
+ GST_WARNING_OBJECT (nvdec, "Current OpenGL context is not CUDA-compatible");
+ return FALSE;
+ }
+
return TRUE;
}