mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-26 19:51:11 +00:00
nvdec: Port to GstCUDAContext
... and drop CUvideoctxlock usage. The CUvideoctxlock basically has the identical role of cuda context push/pop but nvdec specific way. Since we can share the CUDA context among encoders and decoders, use CUDA context directly for accessing GPU API.
This commit is contained in:
parent
5cf0351418
commit
d69b590683
2 changed files with 48 additions and 55 deletions
|
@ -30,6 +30,8 @@
|
|||
#endif
|
||||
|
||||
#include "gstnvdec.h"
|
||||
#include "gstcudautils.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
GST_DEBUG_CATEGORY_STATIC (gst_nvdec_debug_category);
|
||||
|
@ -78,7 +80,7 @@ register_cuda_resource (GstGLContext * context, gpointer * args)
|
|||
guint texture_id;
|
||||
GstNvDec *nvdec = cgr_info->nvdec;
|
||||
|
||||
if (!cuda_OK (CuvidCtxLock (nvdec->ctx_lock, 0)))
|
||||
if (!gst_cuda_context_push (nvdec->cuda_ctx))
|
||||
GST_WARNING_OBJECT (nvdec, "failed to lock CUDA context");
|
||||
|
||||
if (gst_memory_map (mem, &map_info, GST_MAP_READ | GST_MAP_GL)) {
|
||||
|
@ -92,7 +94,7 @@ register_cuda_resource (GstGLContext * context, gpointer * args)
|
|||
} else
|
||||
GST_WARNING_OBJECT (nvdec, "failed to map memory");
|
||||
|
||||
if (!cuda_OK (CuvidCtxUnlock (nvdec->ctx_lock, 0)))
|
||||
if (!gst_cuda_context_pop (NULL))
|
||||
GST_WARNING_OBJECT (nvdec, "failed to unlock CUDA context");
|
||||
}
|
||||
|
||||
|
@ -102,14 +104,14 @@ unregister_cuda_resource (GstGLContext * context,
|
|||
{
|
||||
GstNvDec *nvdec = cgr_info->nvdec;
|
||||
|
||||
if (!cuda_OK (CuvidCtxLock (nvdec->ctx_lock, 0)))
|
||||
if (!gst_cuda_context_push (nvdec->cuda_ctx))
|
||||
GST_WARNING_OBJECT (nvdec, "failed to lock CUDA context");
|
||||
|
||||
if (!cuda_OK (CuGraphicsUnregisterResource ((const CUgraphicsResource)
|
||||
cgr_info->resource)))
|
||||
GST_WARNING_OBJECT (nvdec, "failed to unregister resource");
|
||||
|
||||
if (!cuda_OK (CuvidCtxUnlock (nvdec->ctx_lock, 0)))
|
||||
if (!gst_cuda_context_pop (NULL))
|
||||
GST_WARNING_OBJECT (nvdec, "failed to unlock CUDA context");
|
||||
}
|
||||
|
||||
|
@ -158,6 +160,7 @@ ensure_cuda_graphics_resource (GstMemory * mem, GstNvDec * nvdec)
|
|||
static gboolean gst_nvdec_open (GstVideoDecoder * decoder);
|
||||
static gboolean gst_nvdec_start (GstVideoDecoder * decoder);
|
||||
static gboolean gst_nvdec_stop (GstVideoDecoder * decoder);
|
||||
static gboolean gst_nvdec_close (GstVideoDecoder * decoder);
|
||||
static gboolean gst_nvdec_set_format (GstVideoDecoder * decoder,
|
||||
GstVideoCodecState * state);
|
||||
static GstFlowReturn gst_nvdec_handle_frame (GstVideoDecoder * decoder,
|
||||
|
@ -182,6 +185,7 @@ gst_nvdec_class_init (GstNvDecClass * klass)
|
|||
video_decoder_class->open = GST_DEBUG_FUNCPTR (gst_nvdec_open);
|
||||
video_decoder_class->start = GST_DEBUG_FUNCPTR (gst_nvdec_start);
|
||||
video_decoder_class->stop = GST_DEBUG_FUNCPTR (gst_nvdec_stop);
|
||||
video_decoder_class->close = GST_DEBUG_FUNCPTR (gst_nvdec_close);
|
||||
video_decoder_class->set_format = GST_DEBUG_FUNCPTR (gst_nvdec_set_format);
|
||||
video_decoder_class->handle_frame =
|
||||
GST_DEBUG_FUNCPTR (gst_nvdec_handle_frame);
|
||||
|
@ -209,13 +213,14 @@ parser_sequence_callback (GstNvDec * nvdec, CUVIDEOFORMAT * format)
|
|||
CUVIDDECODECREATEINFO create_info = { 0, };
|
||||
GstVideoFormat out_format = GST_VIDEO_FORMAT_NV12;
|
||||
GstVideoInfo *info = &nvdec->input_state->info;
|
||||
GstCudaContext *ctx = nvdec->cuda_ctx;
|
||||
|
||||
width = format->display_area.right - format->display_area.left;
|
||||
height = format->display_area.bottom - format->display_area.top;
|
||||
GST_DEBUG_OBJECT (nvdec, "width: %u, height: %u", width, height);
|
||||
|
||||
if (!nvdec->decoder || (nvdec->width != width || nvdec->height != height)) {
|
||||
if (!cuda_OK (CuvidCtxLock (nvdec->ctx_lock, 0))) {
|
||||
if (!gst_cuda_context_push (ctx)) {
|
||||
GST_ERROR_OBJECT (nvdec, "failed to lock CUDA context");
|
||||
goto error;
|
||||
}
|
||||
|
@ -256,7 +261,6 @@ parser_sequence_callback (GstNvDec * nvdec, CUVIDEOFORMAT * format)
|
|||
create_info.ulTargetWidth = width;
|
||||
create_info.ulTargetHeight = height;
|
||||
create_info.ulNumOutputSurfaces = 1;
|
||||
create_info.vidLock = nvdec->ctx_lock;
|
||||
create_info.target_rect.left = 0;
|
||||
create_info.target_rect.top = 0;
|
||||
create_info.target_rect.right = width;
|
||||
|
@ -268,7 +272,7 @@ parser_sequence_callback (GstNvDec * nvdec, CUVIDEOFORMAT * format)
|
|||
goto error;
|
||||
}
|
||||
|
||||
if (!cuda_OK (CuvidCtxUnlock (nvdec->ctx_lock, 0))) {
|
||||
if (!gst_cuda_context_pop (NULL)) {
|
||||
GST_ERROR_OBJECT (nvdec, "failed to unlock CUDA context");
|
||||
goto error;
|
||||
}
|
||||
|
@ -418,10 +422,11 @@ static gboolean
|
|||
parser_decode_callback (GstNvDec * nvdec, CUVIDPICPARAMS * params)
|
||||
{
|
||||
GList *iter, *pending_frames;
|
||||
GstCudaContext *ctx = nvdec->cuda_ctx;
|
||||
|
||||
GST_LOG_OBJECT (nvdec, "picture index: %u", params->CurrPicIdx);
|
||||
|
||||
if (!cuda_OK (CuvidCtxLock (nvdec->ctx_lock, 0))) {
|
||||
if (!gst_cuda_context_push (ctx)) {
|
||||
GST_ERROR_OBJECT (nvdec, "failed to lock CUDA context");
|
||||
goto error;
|
||||
}
|
||||
|
@ -431,7 +436,7 @@ parser_decode_callback (GstNvDec * nvdec, CUVIDPICPARAMS * params)
|
|||
goto error;
|
||||
}
|
||||
|
||||
if (!cuda_OK (CuvidCtxUnlock (nvdec->ctx_lock, 0))) {
|
||||
if (!gst_cuda_context_pop (NULL)) {
|
||||
GST_ERROR_OBJECT (nvdec, "failed to unlock CUDA context");
|
||||
goto error;
|
||||
}
|
||||
|
@ -598,32 +603,9 @@ gst_nvdec_open (GstVideoDecoder * decoder)
|
|||
|
||||
GST_DEBUG_OBJECT (nvdec, "creating CUDA context");
|
||||
|
||||
if (!cuda_OK (CuInit (0))) {
|
||||
GST_ERROR_OBJECT (nvdec, "failed to init CUDA");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!cuda_OK (CuCtxCreate (&nvdec->context, 0, klass->cuda_device_id))) {
|
||||
GST_ERROR_OBJECT (nvdec,
|
||||
"failed to create CUDA context with device id %d",
|
||||
klass->cuda_device_id);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!cuda_OK (CuCtxPopCurrent (NULL))) {
|
||||
GST_ERROR_OBJECT (nvdec, "failed to pop current CUDA context");
|
||||
CuCtxDestroy (nvdec->context);
|
||||
nvdec->context = NULL;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!cuda_OK (CuvidCtxLockCreate (&nvdec->ctx_lock, nvdec->context))) {
|
||||
GST_ERROR_OBJECT (nvdec, "failed to create CUDA context lock");
|
||||
|
||||
CuCtxDestroy (nvdec->context);
|
||||
nvdec->context = NULL;
|
||||
|
||||
if (!gst_cuda_ensure_element_context (GST_ELEMENT_CAST (decoder),
|
||||
klass->cuda_device_id, &nvdec->cuda_ctx)) {
|
||||
GST_ERROR_OBJECT (nvdec, "failed to create CUDA context");
|
||||
return FALSE;
|
||||
}
|
||||
#if HAVE_NVCODEC_GST_GL
|
||||
|
@ -650,7 +632,7 @@ maybe_destroy_decoder_and_parser (GstNvDec * nvdec)
|
|||
{
|
||||
gboolean ret = TRUE;
|
||||
|
||||
if (!cuda_OK (CuvidCtxLock (nvdec->ctx_lock, 0))) {
|
||||
if (!gst_cuda_context_push (nvdec->cuda_ctx)) {
|
||||
GST_ERROR_OBJECT (nvdec, "failed to lock CUDA context");
|
||||
return FALSE;
|
||||
}
|
||||
|
@ -664,7 +646,7 @@ maybe_destroy_decoder_and_parser (GstNvDec * nvdec)
|
|||
GST_ERROR_OBJECT (nvdec, "failed to destroy decoder");
|
||||
}
|
||||
|
||||
if (!cuda_OK (CuvidCtxUnlock (nvdec->ctx_lock, 0))) {
|
||||
if (!gst_cuda_context_pop (NULL)) {
|
||||
GST_ERROR_OBJECT (nvdec, "failed to unlock CUDA context");
|
||||
return FALSE;
|
||||
}
|
||||
|
@ -718,15 +700,15 @@ gst_nvdec_stop (GstVideoDecoder * decoder)
|
|||
nvdec->output_state = NULL;
|
||||
}
|
||||
|
||||
if (nvdec->ctx_lock) {
|
||||
CuvidCtxLockDestroy (nvdec->ctx_lock);
|
||||
nvdec->ctx_lock = NULL;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (nvdec->context) {
|
||||
CuCtxDestroy (nvdec->context);
|
||||
nvdec->context = NULL;
|
||||
}
|
||||
static gboolean
|
||||
gst_nvdec_close (GstVideoDecoder * decoder)
|
||||
{
|
||||
GstNvDec *nvdec = GST_NVDEC (decoder);
|
||||
|
||||
gst_clear_object (&nvdec->cuda_ctx);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -803,7 +785,7 @@ copy_video_frame_to_gl_textures (GstGLContext * context,
|
|||
|
||||
data->ret = TRUE;
|
||||
|
||||
if (!cuda_OK (CuvidCtxLock (nvdec->ctx_lock, 0))) {
|
||||
if (!gst_cuda_context_push (nvdec->cuda_ctx)) {
|
||||
GST_WARNING_OBJECT (nvdec, "failed to lock CUDA context");
|
||||
data->ret = FALSE;
|
||||
return;
|
||||
|
@ -857,7 +839,7 @@ unmap_video_frame:
|
|||
GST_WARNING_OBJECT (nvdec, "failed to unmap CUDA video frame");
|
||||
|
||||
unlock_cuda_context:
|
||||
if (!cuda_OK (CuvidCtxUnlock (nvdec->ctx_lock, 0)))
|
||||
if (!gst_cuda_context_pop (NULL))
|
||||
GST_WARNING_OBJECT (nvdec, "failed to unlock CUDA context");
|
||||
}
|
||||
|
||||
|
@ -900,14 +882,14 @@ gst_nvdec_copy_device_to_system (GstNvDec * nvdec,
|
|||
GstVideoInfo *info = &nvdec->output_state->info;
|
||||
gint i;
|
||||
|
||||
if (!cuda_OK (CuvidCtxLock (nvdec->ctx_lock, 0))) {
|
||||
if (!gst_cuda_context_push (nvdec->cuda_ctx)) {
|
||||
GST_WARNING_OBJECT (nvdec, "failed to lock CUDA context");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!gst_video_frame_map (&video_frame, info, output_buffer, GST_MAP_WRITE)) {
|
||||
GST_ERROR_OBJECT (nvdec, "frame map failure");
|
||||
CuvidCtxUnlock (nvdec->ctx_lock, 0);
|
||||
gst_cuda_context_pop (NULL);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
@ -919,7 +901,7 @@ gst_nvdec_copy_device_to_system (GstNvDec * nvdec,
|
|||
if (!cuda_OK (CuvidMapVideoFrame (nvdec->decoder,
|
||||
dispinfo->picture_index, &dptr, &pitch, ¶ms))) {
|
||||
GST_ERROR_OBJECT (nvdec, "failed to map video frame");
|
||||
CuvidCtxUnlock (nvdec->ctx_lock, 0);
|
||||
gst_cuda_context_pop (NULL);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
@ -939,7 +921,7 @@ gst_nvdec_copy_device_to_system (GstNvDec * nvdec,
|
|||
GST_ERROR_OBJECT (nvdec, "failed to copy %dth plane", i);
|
||||
CuvidUnmapVideoFrame (nvdec->decoder, dptr);
|
||||
gst_video_frame_unmap (&video_frame);
|
||||
CuvidCtxUnlock (nvdec->ctx_lock, 0);
|
||||
gst_cuda_context_pop (NULL);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
@ -951,7 +933,7 @@ gst_nvdec_copy_device_to_system (GstNvDec * nvdec,
|
|||
if (!cuda_OK (CuvidUnmapVideoFrame (nvdec->decoder, dptr)))
|
||||
GST_WARNING_OBJECT (nvdec, "failed to unmap video frame");
|
||||
|
||||
if (!cuda_OK (CuvidCtxUnlock (nvdec->ctx_lock, 0)))
|
||||
if (!gst_cuda_context_pop (NULL))
|
||||
GST_WARNING_OBJECT (nvdec, "failed to unlock CUDA context");
|
||||
|
||||
return TRUE;
|
||||
|
@ -1130,6 +1112,10 @@ gst_nvdec_src_query (GstVideoDecoder * decoder, GstQuery * query)
|
|||
|
||||
switch (GST_QUERY_TYPE (query)) {
|
||||
case GST_QUERY_CONTEXT:
|
||||
if (gst_cuda_handle_context_query (GST_ELEMENT (decoder),
|
||||
query, nvdec->cuda_ctx)) {
|
||||
return TRUE;
|
||||
}
|
||||
if (gst_gl_handle_context_query (GST_ELEMENT (decoder), query,
|
||||
nvdec->gl_display, nvdec->gl_context, nvdec->other_gl_context))
|
||||
return TRUE;
|
||||
|
@ -1147,14 +1133,21 @@ static void
|
|||
gst_nvdec_set_context (GstElement * element, GstContext * context)
|
||||
{
|
||||
GstNvDec *nvdec = GST_NVDEC (element);
|
||||
GstNvDecClass *klass = GST_NVDEC_GET_CLASS (nvdec);
|
||||
|
||||
GST_DEBUG_OBJECT (nvdec, "set context");
|
||||
GST_DEBUG_OBJECT (nvdec, "set context %s",
|
||||
gst_context_get_context_type (context));
|
||||
|
||||
if (gst_cuda_handle_set_context (element,
|
||||
context, klass->cuda_device_id, &nvdec->cuda_ctx)) {
|
||||
goto done;
|
||||
}
|
||||
#ifdef HAVE_NVCODEC_GST_GL
|
||||
gst_gl_handle_set_context (element, context, &nvdec->gl_display,
|
||||
&nvdec->other_gl_context);
|
||||
#endif
|
||||
|
||||
done:
|
||||
GST_ELEMENT_CLASS (gst_nvdec_parent_class)->set_context (element, context);
|
||||
}
|
||||
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
#include <gst/video/video.h>
|
||||
#include "gstcuvidloader.h"
|
||||
#include "gstcudaloader.h"
|
||||
#include "gstcudacontext.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
|
@ -75,8 +76,7 @@ struct _GstNvDec
|
|||
|
||||
CUvideoparser parser;
|
||||
CUvideodecoder decoder;
|
||||
CUcontext context;
|
||||
CUvideoctxlock ctx_lock;
|
||||
GstCudaContext *cuda_ctx;
|
||||
|
||||
guint width;
|
||||
guint height;
|
||||
|
|
Loading…
Reference in a new issue