mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-19 14:56:36 +00:00
nvcodec: Add cuda-device-id read-only property to stateless decoders
... and remove unnecessary intermediate subclass from class hierarchy Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/2665>
This commit is contained in:
parent
1e11c05591
commit
85fe9fb61d
10 changed files with 490 additions and 394 deletions
|
@ -17,6 +17,21 @@
|
||||||
* Boston, MA 02110-1301, USA.
|
* Boston, MA 02110-1301, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SECTION:element-nvav1dec
|
||||||
|
* @title: nvav1dec
|
||||||
|
*
|
||||||
|
* GstCodecs based NVIDIA AV1 video decoder
|
||||||
|
*
|
||||||
|
* ## Example launch line
|
||||||
|
* ```
|
||||||
|
* gst-launch-1.0 filesrc location=/path/to/av1/file ! parsebin ! nvav1dec ! videoconvert ! autovideosink
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* Since: 1.22
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#endif
|
#endif
|
||||||
|
@ -66,12 +81,11 @@ typedef struct _GstNvAV1DecClass
|
||||||
guint cuda_device_id;
|
guint cuda_device_id;
|
||||||
} GstNvAV1DecClass;
|
} GstNvAV1DecClass;
|
||||||
|
|
||||||
typedef struct
|
enum
|
||||||
{
|
{
|
||||||
GstCaps *sink_caps;
|
PROP_0,
|
||||||
GstCaps *src_caps;
|
PROP_CUDA_DEVICE_ID,
|
||||||
guint cuda_device_id;
|
};
|
||||||
} GstNvAV1DecClassData;
|
|
||||||
|
|
||||||
static GTypeClass *parent_class = NULL;
|
static GTypeClass *parent_class = NULL;
|
||||||
|
|
||||||
|
@ -79,6 +93,9 @@ static GTypeClass *parent_class = NULL;
|
||||||
#define GST_NV_AV1_DEC_GET_CLASS(object) \
|
#define GST_NV_AV1_DEC_GET_CLASS(object) \
|
||||||
(G_TYPE_INSTANCE_GET_CLASS ((object),G_TYPE_FROM_INSTANCE (object),GstNvAV1DecClass))
|
(G_TYPE_INSTANCE_GET_CLASS ((object),G_TYPE_FROM_INSTANCE (object),GstNvAV1DecClass))
|
||||||
|
|
||||||
|
static void gst_nv_av1_dec_get_property (GObject * object, guint prop_id,
|
||||||
|
GValue * value, GParamSpec * pspec);
|
||||||
|
|
||||||
static void gst_nv_av1_dec_set_context (GstElement * element,
|
static void gst_nv_av1_dec_set_context (GstElement * element,
|
||||||
GstContext * context);
|
GstContext * context);
|
||||||
static gboolean gst_nv_av1_dec_open (GstVideoDecoder * decoder);
|
static gboolean gst_nv_av1_dec_open (GstVideoDecoder * decoder);
|
||||||
|
@ -108,12 +125,20 @@ static guint gst_nv_av1_dec_get_preferred_output_delay (GstAV1Decoder * decoder,
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gst_nv_av1_dec_class_init (GstNvAV1DecClass * klass,
|
gst_nv_av1_dec_class_init (GstNvAV1DecClass * klass,
|
||||||
GstNvAV1DecClassData * cdata)
|
GstNvDecoderClassData * cdata)
|
||||||
{
|
{
|
||||||
|
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||||
GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
|
GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
|
||||||
GstVideoDecoderClass *decoder_class = GST_VIDEO_DECODER_CLASS (klass);
|
GstVideoDecoderClass *decoder_class = GST_VIDEO_DECODER_CLASS (klass);
|
||||||
GstAV1DecoderClass *av1decoder_class = GST_AV1_DECODER_CLASS (klass);
|
GstAV1DecoderClass *av1decoder_class = GST_AV1_DECODER_CLASS (klass);
|
||||||
|
|
||||||
|
object_class->get_property = gst_nv_av1_dec_get_property;
|
||||||
|
|
||||||
|
g_object_class_install_property (object_class, PROP_CUDA_DEVICE_ID,
|
||||||
|
g_param_spec_uint ("cuda-device-id", "CUDA device id",
|
||||||
|
"Assigned CUDA device id", 0, G_MAXINT, 0,
|
||||||
|
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
|
||||||
|
|
||||||
element_class->set_context = GST_DEBUG_FUNCPTR (gst_nv_av1_dec_set_context);
|
element_class->set_context = GST_DEBUG_FUNCPTR (gst_nv_av1_dec_set_context);
|
||||||
|
|
||||||
parent_class = (GTypeClass *) g_type_class_peek_parent (klass);
|
parent_class = (GTypeClass *) g_type_class_peek_parent (klass);
|
||||||
|
@ -164,6 +189,22 @@ gst_nv_av1_dec_init (GstNvAV1Dec * self)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gst_nv_av1_dec_get_property (GObject * object, guint prop_id, GValue * value,
|
||||||
|
GParamSpec * pspec)
|
||||||
|
{
|
||||||
|
GstNvAV1DecClass *klass = GST_NV_AV1_DEC_GET_CLASS (object);
|
||||||
|
|
||||||
|
switch (prop_id) {
|
||||||
|
case PROP_CUDA_DEVICE_ID:
|
||||||
|
g_value_set_uint (value, klass->cuda_device_id);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gst_nv_av1_dec_set_context (GstElement * element, GstContext * context)
|
gst_nv_av1_dec_set_context (GstElement * element, GstContext * context)
|
||||||
{
|
{
|
||||||
|
@ -874,11 +915,11 @@ gst_nv_av1_dec_register (GstPlugin * plugin, guint device_id, guint rank,
|
||||||
0,
|
0,
|
||||||
(GInstanceInitFunc) gst_nv_av1_dec_init,
|
(GInstanceInitFunc) gst_nv_av1_dec_init,
|
||||||
};
|
};
|
||||||
GstNvAV1DecClassData *cdata;
|
GstNvDecoderClassData *cdata;
|
||||||
|
|
||||||
GST_DEBUG_CATEGORY_INIT (gst_nv_av1_dec_debug, "nvav1dec", 0, "nvav1dec");
|
GST_DEBUG_CATEGORY_INIT (gst_nv_av1_dec_debug, "nvav1dec", 0, "nvav1dec");
|
||||||
|
|
||||||
cdata = g_new0 (GstNvAV1DecClassData, 1);
|
cdata = g_new0 (GstNvDecoderClassData, 1);
|
||||||
cdata->sink_caps = gst_caps_ref (sink_caps);
|
cdata->sink_caps = gst_caps_ref (sink_caps);
|
||||||
cdata->src_caps = gst_caps_ref (src_caps);
|
cdata->src_caps = gst_caps_ref (src_caps);
|
||||||
cdata->cuda_device_id = device_id;
|
cdata->cuda_device_id = device_id;
|
||||||
|
|
|
@ -49,6 +49,13 @@ typedef struct _GstNvDecoderFrame
|
||||||
gint ref_count;
|
gint ref_count;
|
||||||
} GstNvDecoderFrame;
|
} GstNvDecoderFrame;
|
||||||
|
|
||||||
|
typedef struct _GstNvDecoderClassData
|
||||||
|
{
|
||||||
|
GstCaps *sink_caps;
|
||||||
|
GstCaps *src_caps;
|
||||||
|
guint cuda_device_id;
|
||||||
|
} GstNvDecoderClassData;
|
||||||
|
|
||||||
GstNvDecoder * gst_nv_decoder_new (GstCudaContext * context);
|
GstNvDecoder * gst_nv_decoder_new (GstCudaContext * context);
|
||||||
|
|
||||||
gboolean gst_nv_decoder_is_configured (GstNvDecoder * decoder);
|
gboolean gst_nv_decoder_is_configured (GstNvDecoder * decoder);
|
||||||
|
|
|
@ -70,6 +70,21 @@
|
||||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SECTION:element-nvh264sldec
|
||||||
|
* @title: nvh264sldec
|
||||||
|
*
|
||||||
|
* GstCodecs based NVIDIA H.264 video decoder
|
||||||
|
*
|
||||||
|
* ## Example launch line
|
||||||
|
* ```
|
||||||
|
* gst-launch-1.0 filesrc location=/path/to/h264/file ! parsebin ! nvh264sldec ! videoconvert ! autovideosink
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* Since: 1.18
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#endif
|
#endif
|
||||||
|
@ -84,7 +99,7 @@
|
||||||
GST_DEBUG_CATEGORY_STATIC (gst_nv_h264_dec_debug);
|
GST_DEBUG_CATEGORY_STATIC (gst_nv_h264_dec_debug);
|
||||||
#define GST_CAT_DEFAULT gst_nv_h264_dec_debug
|
#define GST_CAT_DEFAULT gst_nv_h264_dec_debug
|
||||||
|
|
||||||
struct _GstNvH264Dec
|
typedef struct _GstNvH264Dec
|
||||||
{
|
{
|
||||||
GstH264Decoder parent;
|
GstH264Decoder parent;
|
||||||
|
|
||||||
|
@ -114,18 +129,30 @@ struct _GstNvH264Dec
|
||||||
gboolean interlaced;
|
gboolean interlaced;
|
||||||
|
|
||||||
GArray *ref_list;
|
GArray *ref_list;
|
||||||
};
|
} GstNvH264Dec;
|
||||||
|
|
||||||
struct _GstNvH264DecClass
|
typedef struct _GstNvH264DecClass
|
||||||
{
|
{
|
||||||
GstH264DecoderClass parent_class;
|
GstH264DecoderClass parent_class;
|
||||||
guint cuda_device_id;
|
guint cuda_device_id;
|
||||||
|
} GstNvH264DecClass;
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
PROP_0,
|
||||||
|
PROP_CUDA_DEVICE_ID,
|
||||||
};
|
};
|
||||||
|
|
||||||
#define gst_nv_h264_dec_parent_class parent_class
|
static GTypeClass *parent_class = NULL;
|
||||||
G_DEFINE_TYPE (GstNvH264Dec, gst_nv_h264_dec, GST_TYPE_H264_DECODER);
|
|
||||||
|
#define GST_NV_H264_DEC(object) ((GstNvH264Dec *) (object))
|
||||||
|
#define GST_NV_H264_DEC_GET_CLASS(object) \
|
||||||
|
(G_TYPE_INSTANCE_GET_CLASS ((object),G_TYPE_FROM_INSTANCE (object),GstNvH264DecClass))
|
||||||
|
|
||||||
static void gst_nv_h264_decoder_dispose (GObject * object);
|
static void gst_nv_h264_decoder_dispose (GObject * object);
|
||||||
|
static void gst_nv_h264_dec_get_property (GObject * object, guint prop_id,
|
||||||
|
GValue * value, GParamSpec * pspec);
|
||||||
|
|
||||||
static void gst_nv_h264_dec_set_context (GstElement * element,
|
static void gst_nv_h264_dec_set_context (GstElement * element,
|
||||||
GstContext * context);
|
GstContext * context);
|
||||||
static gboolean gst_nv_h264_dec_open (GstVideoDecoder * decoder);
|
static gboolean gst_nv_h264_dec_open (GstVideoDecoder * decoder);
|
||||||
|
@ -158,23 +185,44 @@ gst_nv_h264_dec_get_preferred_output_delay (GstH264Decoder * decoder,
|
||||||
gboolean live);
|
gboolean live);
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gst_nv_h264_dec_class_init (GstNvH264DecClass * klass)
|
gst_nv_h264_dec_class_init (GstNvH264DecClass * klass,
|
||||||
|
GstNvDecoderClassData * cdata)
|
||||||
{
|
{
|
||||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||||
GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
|
GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
|
||||||
GstVideoDecoderClass *decoder_class = GST_VIDEO_DECODER_CLASS (klass);
|
GstVideoDecoderClass *decoder_class = GST_VIDEO_DECODER_CLASS (klass);
|
||||||
GstH264DecoderClass *h264decoder_class = GST_H264_DECODER_CLASS (klass);
|
GstH264DecoderClass *h264decoder_class = GST_H264_DECODER_CLASS (klass);
|
||||||
|
|
||||||
/**
|
|
||||||
* GstNvH264Dec
|
|
||||||
*
|
|
||||||
* Since: 1.18
|
|
||||||
*/
|
|
||||||
|
|
||||||
object_class->dispose = gst_nv_h264_decoder_dispose;
|
object_class->dispose = gst_nv_h264_decoder_dispose;
|
||||||
|
object_class->get_property = gst_nv_h264_dec_get_property;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GstNvH264SLDec:cuda-device-id:
|
||||||
|
*
|
||||||
|
* Assigned CUDA device id
|
||||||
|
*
|
||||||
|
* Since: 1.22
|
||||||
|
*/
|
||||||
|
g_object_class_install_property (object_class, PROP_CUDA_DEVICE_ID,
|
||||||
|
g_param_spec_uint ("cuda-device-id", "CUDA device id",
|
||||||
|
"Assigned CUDA device id", 0, G_MAXINT, 0,
|
||||||
|
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
|
||||||
|
|
||||||
element_class->set_context = GST_DEBUG_FUNCPTR (gst_nv_h264_dec_set_context);
|
element_class->set_context = GST_DEBUG_FUNCPTR (gst_nv_h264_dec_set_context);
|
||||||
|
|
||||||
|
parent_class = (GTypeClass *) g_type_class_peek_parent (klass);
|
||||||
|
gst_element_class_set_static_metadata (element_class,
|
||||||
|
"NVDEC H.264 Stateless Decoder",
|
||||||
|
"Codec/Decoder/Video/Hardware",
|
||||||
|
"NVIDIA H.264 video decoder", "Seungha Yang <seungha@centricular.com>");
|
||||||
|
|
||||||
|
gst_element_class_add_pad_template (element_class,
|
||||||
|
gst_pad_template_new ("sink", GST_PAD_SINK, GST_PAD_ALWAYS,
|
||||||
|
cdata->sink_caps));
|
||||||
|
gst_element_class_add_pad_template (element_class,
|
||||||
|
gst_pad_template_new ("src", GST_PAD_SRC, GST_PAD_ALWAYS,
|
||||||
|
cdata->src_caps));
|
||||||
|
|
||||||
decoder_class->open = GST_DEBUG_FUNCPTR (gst_nv_h264_dec_open);
|
decoder_class->open = GST_DEBUG_FUNCPTR (gst_nv_h264_dec_open);
|
||||||
decoder_class->close = GST_DEBUG_FUNCPTR (gst_nv_h264_dec_close);
|
decoder_class->close = GST_DEBUG_FUNCPTR (gst_nv_h264_dec_close);
|
||||||
decoder_class->negotiate = GST_DEBUG_FUNCPTR (gst_nv_h264_dec_negotiate);
|
decoder_class->negotiate = GST_DEBUG_FUNCPTR (gst_nv_h264_dec_negotiate);
|
||||||
|
@ -199,10 +247,11 @@ gst_nv_h264_dec_class_init (GstNvH264DecClass * klass)
|
||||||
h264decoder_class->get_preferred_output_delay =
|
h264decoder_class->get_preferred_output_delay =
|
||||||
GST_DEBUG_FUNCPTR (gst_nv_h264_dec_get_preferred_output_delay);
|
GST_DEBUG_FUNCPTR (gst_nv_h264_dec_get_preferred_output_delay);
|
||||||
|
|
||||||
GST_DEBUG_CATEGORY_INIT (gst_nv_h264_dec_debug,
|
klass->cuda_device_id = cdata->cuda_device_id;
|
||||||
"nvh264dec", 0, "Nvidia H.264 Decoder");
|
|
||||||
|
|
||||||
gst_type_mark_as_plugin_api (GST_TYPE_NV_H264_DEC, 0);
|
gst_caps_unref (cdata->sink_caps);
|
||||||
|
gst_caps_unref (cdata->src_caps);
|
||||||
|
g_free (cdata);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -224,6 +273,22 @@ gst_nv_h264_decoder_dispose (GObject * object)
|
||||||
G_OBJECT_CLASS (parent_class)->dispose (object);
|
G_OBJECT_CLASS (parent_class)->dispose (object);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gst_nv_h264_dec_get_property (GObject * object, guint prop_id, GValue * value,
|
||||||
|
GParamSpec * pspec)
|
||||||
|
{
|
||||||
|
GstNvH264DecClass *klass = GST_NV_H264_DEC_GET_CLASS (object);
|
||||||
|
|
||||||
|
switch (prop_id) {
|
||||||
|
case PROP_CUDA_DEVICE_ID:
|
||||||
|
g_value_set_uint (value, klass->cuda_device_id);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gst_nv_h264_dec_set_context (GstElement * element, GstContext * context)
|
gst_nv_h264_dec_set_context (GstElement * element, GstContext * context)
|
||||||
{
|
{
|
||||||
|
@ -885,68 +950,32 @@ gst_nv_h264_dec_get_preferred_output_delay (GstH264Decoder * decoder,
|
||||||
return 4;
|
return 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
GstCaps *sink_caps;
|
|
||||||
GstCaps *src_caps;
|
|
||||||
guint cuda_device_id;
|
|
||||||
gboolean is_default;
|
|
||||||
} GstNvH264DecClassData;
|
|
||||||
|
|
||||||
static void
|
|
||||||
gst_nv_h264_dec_subclass_init (gpointer klass, GstNvH264DecClassData * cdata)
|
|
||||||
{
|
|
||||||
GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
|
|
||||||
GstNvH264DecClass *nvdec_class = (GstNvH264DecClass *) (klass);
|
|
||||||
gchar *long_name;
|
|
||||||
|
|
||||||
if (cdata->is_default) {
|
|
||||||
long_name = g_strdup_printf ("NVDEC H.264 Stateless Decoder");
|
|
||||||
} else {
|
|
||||||
long_name = g_strdup_printf ("NVDEC H.264 Stateless Decoder with device %d",
|
|
||||||
cdata->cuda_device_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
gst_element_class_set_metadata (element_class, long_name,
|
|
||||||
"Codec/Decoder/Video/Hardware",
|
|
||||||
"Nvidia H.264 video decoder", "Seungha Yang <seungha@centricular.com>");
|
|
||||||
g_free (long_name);
|
|
||||||
|
|
||||||
gst_element_class_add_pad_template (element_class,
|
|
||||||
gst_pad_template_new ("sink", GST_PAD_SINK, GST_PAD_ALWAYS,
|
|
||||||
cdata->sink_caps));
|
|
||||||
gst_element_class_add_pad_template (element_class,
|
|
||||||
gst_pad_template_new ("src", GST_PAD_SRC, GST_PAD_ALWAYS,
|
|
||||||
cdata->src_caps));
|
|
||||||
|
|
||||||
nvdec_class->cuda_device_id = cdata->cuda_device_id;
|
|
||||||
|
|
||||||
gst_caps_unref (cdata->sink_caps);
|
|
||||||
gst_caps_unref (cdata->src_caps);
|
|
||||||
g_free (cdata);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
gst_nv_h264_dec_register (GstPlugin * plugin, guint device_id, guint rank,
|
gst_nv_h264_dec_register (GstPlugin * plugin, guint device_id, guint rank,
|
||||||
GstCaps * sink_caps, GstCaps * src_caps, gboolean is_primary)
|
GstCaps * sink_caps, GstCaps * src_caps, gboolean is_primary)
|
||||||
{
|
{
|
||||||
GTypeQuery type_query;
|
GType type;
|
||||||
GTypeInfo type_info = { 0, };
|
|
||||||
GType subtype;
|
|
||||||
gchar *type_name;
|
gchar *type_name;
|
||||||
gchar *feature_name;
|
gchar *feature_name;
|
||||||
GstNvH264DecClassData *cdata;
|
GstNvDecoderClassData *cdata;
|
||||||
gboolean is_default = TRUE;
|
gint index = 0;
|
||||||
const GValue *value;
|
const GValue *value;
|
||||||
GstStructure *s;
|
GstStructure *s;
|
||||||
|
GTypeInfo type_info = {
|
||||||
|
sizeof (GstNvH264DecClass),
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
(GClassInitFunc) gst_nv_h264_dec_class_init,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
sizeof (GstNvH264Dec),
|
||||||
|
0,
|
||||||
|
(GInstanceInitFunc) gst_nv_h264_dec_init,
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
GST_DEBUG_CATEGORY_INIT (gst_nv_h264_dec_debug, "nvh264dec", 0, "nvh264dec");
|
||||||
* element-nvh264sldec
|
|
||||||
*
|
|
||||||
* Since: 1.18
|
|
||||||
*/
|
|
||||||
|
|
||||||
cdata = g_new0 (GstNvH264DecClassData, 1);
|
cdata = g_new0 (GstNvDecoderClassData, 1);
|
||||||
cdata->sink_caps = gst_caps_from_string ("video/x-h264, "
|
cdata->sink_caps = gst_caps_from_string ("video/x-h264, "
|
||||||
"stream-format= (string) { avc, avc3, byte-stream }, "
|
"stream-format= (string) { avc, avc3, byte-stream }, "
|
||||||
"alignment= (string) au, "
|
"alignment= (string) au, "
|
||||||
|
@ -965,45 +994,37 @@ gst_nv_h264_dec_register (GstPlugin * plugin, guint device_id, guint rank,
|
||||||
cdata->src_caps = gst_caps_ref (src_caps);
|
cdata->src_caps = gst_caps_ref (src_caps);
|
||||||
cdata->cuda_device_id = device_id;
|
cdata->cuda_device_id = device_id;
|
||||||
|
|
||||||
g_type_query (GST_TYPE_NV_H264_DEC, &type_query);
|
|
||||||
memset (&type_info, 0, sizeof (type_info));
|
|
||||||
type_info.class_size = type_query.class_size;
|
|
||||||
type_info.instance_size = type_query.instance_size;
|
|
||||||
type_info.class_init = (GClassInitFunc) gst_nv_h264_dec_subclass_init;
|
|
||||||
type_info.class_data = cdata;
|
|
||||||
|
|
||||||
if (is_primary) {
|
if (is_primary) {
|
||||||
type_name = g_strdup ("GstNvH264StatelessPrimaryDec");
|
type_name = g_strdup ("GstNvH264Dec");
|
||||||
feature_name = g_strdup ("nvh264dec");
|
feature_name = g_strdup ("nvh264dec");
|
||||||
} else {
|
} else {
|
||||||
type_name = g_strdup ("GstNvH264StatelessDec");
|
type_name = g_strdup ("GstNvH264SLDec");
|
||||||
feature_name = g_strdup ("nvh264sldec");
|
feature_name = g_strdup ("nvh264sldec");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (g_type_from_name (type_name) != 0) {
|
while (g_type_from_name (type_name)) {
|
||||||
|
index++;
|
||||||
g_free (type_name);
|
g_free (type_name);
|
||||||
g_free (feature_name);
|
g_free (feature_name);
|
||||||
if (is_primary) {
|
if (is_primary) {
|
||||||
type_name =
|
type_name = g_strdup_printf ("GstNvH264Device%dDec", index);
|
||||||
g_strdup_printf ("GstNvH264StatelessPrimaryDevice%dDec", device_id);
|
feature_name = g_strdup_printf ("nvh264device%ddec", index);
|
||||||
feature_name = g_strdup_printf ("nvh264device%ddec", device_id);
|
|
||||||
} else {
|
} else {
|
||||||
type_name = g_strdup_printf ("GstNvH264StatelessDevice%dDec", device_id);
|
type_name = g_strdup_printf ("GstNvH264SLDevice%dDec", index);
|
||||||
feature_name = g_strdup_printf ("nvh264sldevice%ddec", device_id);
|
feature_name = g_strdup_printf ("nvh264sldevice%ddec", index);
|
||||||
}
|
}
|
||||||
|
|
||||||
is_default = FALSE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cdata->is_default = is_default;
|
type_info.class_data = cdata;
|
||||||
subtype = g_type_register_static (GST_TYPE_NV_H264_DEC,
|
|
||||||
|
type = g_type_register_static (GST_TYPE_H264_DECODER,
|
||||||
type_name, &type_info, 0);
|
type_name, &type_info, 0);
|
||||||
|
|
||||||
/* make lower rank than default device */
|
/* make lower rank than default device */
|
||||||
if (rank > 0 && !is_default)
|
if (rank > 0 && index > 0)
|
||||||
rank--;
|
rank--;
|
||||||
|
|
||||||
if (!gst_element_register (plugin, feature_name, rank, subtype))
|
if (!gst_element_register (plugin, feature_name, rank, type))
|
||||||
GST_WARNING ("Failed to register plugin '%s'", type_name);
|
GST_WARNING ("Failed to register plugin '%s'", type_name);
|
||||||
|
|
||||||
g_free (type_name);
|
g_free (type_name);
|
||||||
|
|
|
@ -25,16 +25,6 @@
|
||||||
|
|
||||||
G_BEGIN_DECLS
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
#define GST_TYPE_NV_H264_DEC (gst_nv_h264_dec_get_type())
|
|
||||||
#define GST_NV_H264_DEC(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), GST_TYPE_NV_H264_DEC, GstNvH264Dec))
|
|
||||||
#define GST_NV_H264_DEC_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), GST_TYPE_NV_H264_DEC, GstNvH264DecClass))
|
|
||||||
#define GST_NV_H264_DEC_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GST_TYPE_NV_H264_DEC, GstNvH264DecClass))
|
|
||||||
|
|
||||||
typedef struct _GstNvH264Dec GstNvH264Dec;
|
|
||||||
typedef struct _GstNvH264DecClass GstNvH264DecClass;
|
|
||||||
|
|
||||||
GType gst_nv_h264_dec_get_type (void);
|
|
||||||
|
|
||||||
void gst_nv_h264_dec_register (GstPlugin * plugin,
|
void gst_nv_h264_dec_register (GstPlugin * plugin,
|
||||||
guint device_id,
|
guint device_id,
|
||||||
guint rank,
|
guint rank,
|
||||||
|
|
|
@ -70,6 +70,21 @@
|
||||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SECTION:element-nvh265sldec
|
||||||
|
* @title: nvh265sldec
|
||||||
|
*
|
||||||
|
* GstCodecs based NVIDIA H.265 video decoder
|
||||||
|
*
|
||||||
|
* ## Example launch line
|
||||||
|
* ```
|
||||||
|
* gst-launch-1.0 filesrc location=/path/to/h265/file ! parsebin ! nvh265sldec ! videoconvert ! autovideosink
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* Since: 1.18
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#endif
|
#endif
|
||||||
|
@ -83,7 +98,7 @@
|
||||||
GST_DEBUG_CATEGORY_STATIC (gst_nv_h265_dec_debug);
|
GST_DEBUG_CATEGORY_STATIC (gst_nv_h265_dec_debug);
|
||||||
#define GST_CAT_DEFAULT gst_nv_h265_dec_debug
|
#define GST_CAT_DEFAULT gst_nv_h265_dec_debug
|
||||||
|
|
||||||
struct _GstNvH265Dec
|
typedef struct _GstNvH265Dec
|
||||||
{
|
{
|
||||||
GstH265Decoder parent;
|
GstH265Decoder parent;
|
||||||
|
|
||||||
|
@ -108,16 +123,28 @@ struct _GstNvH265Dec
|
||||||
guint coded_width, coded_height;
|
guint coded_width, coded_height;
|
||||||
guint bitdepth;
|
guint bitdepth;
|
||||||
guint chroma_format_idc;
|
guint chroma_format_idc;
|
||||||
};
|
} GstNvH265Dec;
|
||||||
|
|
||||||
struct _GstNvH265DecClass
|
typedef struct _GstNvH265DecClass
|
||||||
{
|
{
|
||||||
GstH265DecoderClass parent_class;
|
GstH265DecoderClass parent_class;
|
||||||
guint cuda_device_id;
|
guint cuda_device_id;
|
||||||
|
} GstNvH265DecClass;
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
PROP_0,
|
||||||
|
PROP_CUDA_DEVICE_ID,
|
||||||
};
|
};
|
||||||
|
|
||||||
#define gst_nv_h265_dec_parent_class parent_class
|
static GTypeClass *parent_class = NULL;
|
||||||
G_DEFINE_TYPE (GstNvH265Dec, gst_nv_h265_dec, GST_TYPE_H265_DECODER);
|
|
||||||
|
#define GST_NV_H265_DEC(object) ((GstNvH265Dec *) (object))
|
||||||
|
#define GST_NV_H265_DEC_GET_CLASS(object) \
|
||||||
|
(G_TYPE_INSTANCE_GET_CLASS ((object),G_TYPE_FROM_INSTANCE (object),GstNvH265DecClass))
|
||||||
|
|
||||||
|
static void gst_nv_h265_dec_get_property (GObject * object, guint prop_id,
|
||||||
|
GValue * value, GParamSpec * pspec);
|
||||||
|
|
||||||
static void gst_nv_h265_dec_set_context (GstElement * element,
|
static void gst_nv_h265_dec_set_context (GstElement * element,
|
||||||
GstContext * context);
|
GstContext * context);
|
||||||
|
@ -148,20 +175,43 @@ gst_nv_h265_dec_get_preferred_output_delay (GstH265Decoder * decoder,
|
||||||
gboolean live);
|
gboolean live);
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gst_nv_h265_dec_class_init (GstNvH265DecClass * klass)
|
gst_nv_h265_dec_class_init (GstNvH265DecClass * klass,
|
||||||
|
GstNvDecoderClassData * cdata)
|
||||||
{
|
{
|
||||||
|
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||||
GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
|
GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
|
||||||
GstVideoDecoderClass *decoder_class = GST_VIDEO_DECODER_CLASS (klass);
|
GstVideoDecoderClass *decoder_class = GST_VIDEO_DECODER_CLASS (klass);
|
||||||
GstH265DecoderClass *h265decoder_class = GST_H265_DECODER_CLASS (klass);
|
GstH265DecoderClass *h265decoder_class = GST_H265_DECODER_CLASS (klass);
|
||||||
|
|
||||||
|
object_class->get_property = gst_nv_h265_dec_get_property;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* GstNvH265Dec
|
* GstNvH265SLDec:cuda-device-id:
|
||||||
*
|
*
|
||||||
* Since: 1.18
|
* Assigned CUDA device id
|
||||||
|
*
|
||||||
|
* Since: 1.22
|
||||||
*/
|
*/
|
||||||
|
g_object_class_install_property (object_class, PROP_CUDA_DEVICE_ID,
|
||||||
|
g_param_spec_uint ("cuda-device-id", "CUDA device id",
|
||||||
|
"Assigned CUDA device id", 0, G_MAXINT, 0,
|
||||||
|
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
|
||||||
|
|
||||||
element_class->set_context = GST_DEBUG_FUNCPTR (gst_nv_h265_dec_set_context);
|
element_class->set_context = GST_DEBUG_FUNCPTR (gst_nv_h265_dec_set_context);
|
||||||
|
|
||||||
|
parent_class = (GTypeClass *) g_type_class_peek_parent (klass);
|
||||||
|
gst_element_class_set_static_metadata (element_class,
|
||||||
|
"NVDEC H.265 Stateless Decoder",
|
||||||
|
"Codec/Decoder/Video/Hardware",
|
||||||
|
"NVIDIA H.265 video decoder", "Seungha Yang <seungha@centricular.com>");
|
||||||
|
|
||||||
|
gst_element_class_add_pad_template (element_class,
|
||||||
|
gst_pad_template_new ("sink", GST_PAD_SINK, GST_PAD_ALWAYS,
|
||||||
|
cdata->sink_caps));
|
||||||
|
gst_element_class_add_pad_template (element_class,
|
||||||
|
gst_pad_template_new ("src", GST_PAD_SRC, GST_PAD_ALWAYS,
|
||||||
|
cdata->src_caps));
|
||||||
|
|
||||||
decoder_class->open = GST_DEBUG_FUNCPTR (gst_nv_h265_dec_open);
|
decoder_class->open = GST_DEBUG_FUNCPTR (gst_nv_h265_dec_open);
|
||||||
decoder_class->close = GST_DEBUG_FUNCPTR (gst_nv_h265_dec_close);
|
decoder_class->close = GST_DEBUG_FUNCPTR (gst_nv_h265_dec_close);
|
||||||
decoder_class->negotiate = GST_DEBUG_FUNCPTR (gst_nv_h265_dec_negotiate);
|
decoder_class->negotiate = GST_DEBUG_FUNCPTR (gst_nv_h265_dec_negotiate);
|
||||||
|
@ -184,10 +234,11 @@ gst_nv_h265_dec_class_init (GstNvH265DecClass * klass)
|
||||||
h265decoder_class->get_preferred_output_delay =
|
h265decoder_class->get_preferred_output_delay =
|
||||||
GST_DEBUG_FUNCPTR (gst_nv_h265_dec_get_preferred_output_delay);
|
GST_DEBUG_FUNCPTR (gst_nv_h265_dec_get_preferred_output_delay);
|
||||||
|
|
||||||
GST_DEBUG_CATEGORY_INIT (gst_nv_h265_dec_debug,
|
klass->cuda_device_id = cdata->cuda_device_id;
|
||||||
"nvh265dec", 0, "Nvidia H.265 Decoder");
|
|
||||||
|
|
||||||
gst_type_mark_as_plugin_api (GST_TYPE_NV_H265_DEC, 0);
|
gst_caps_unref (cdata->sink_caps);
|
||||||
|
gst_caps_unref (cdata->src_caps);
|
||||||
|
g_free (cdata);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -195,6 +246,22 @@ gst_nv_h265_dec_init (GstNvH265Dec * self)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gst_nv_h265_dec_get_property (GObject * object, guint prop_id, GValue * value,
|
||||||
|
GParamSpec * pspec)
|
||||||
|
{
|
||||||
|
GstNvH265DecClass *klass = GST_NV_H265_DEC_GET_CLASS (object);
|
||||||
|
|
||||||
|
switch (prop_id) {
|
||||||
|
case PROP_CUDA_DEVICE_ID:
|
||||||
|
g_value_set_uint (value, klass->cuda_device_id);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gst_nv_h265_dec_set_context (GstElement * element, GstContext * context)
|
gst_nv_h265_dec_set_context (GstElement * element, GstContext * context)
|
||||||
{
|
{
|
||||||
|
@ -931,68 +998,32 @@ gst_nv_h265_dec_get_preferred_output_delay (GstH265Decoder * decoder,
|
||||||
return 4;
|
return 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
GstCaps *sink_caps;
|
|
||||||
GstCaps *src_caps;
|
|
||||||
guint cuda_device_id;
|
|
||||||
gboolean is_default;
|
|
||||||
} GstNvH265DecClassData;
|
|
||||||
|
|
||||||
static void
|
|
||||||
gst_nv_h265_dec_subclass_init (gpointer klass, GstNvH265DecClassData * cdata)
|
|
||||||
{
|
|
||||||
GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
|
|
||||||
GstNvH265DecClass *nvdec_class = (GstNvH265DecClass *) (klass);
|
|
||||||
gchar *long_name;
|
|
||||||
|
|
||||||
if (cdata->is_default) {
|
|
||||||
long_name = g_strdup_printf ("NVDEC H.265 Stateless Decoder");
|
|
||||||
} else {
|
|
||||||
long_name = g_strdup_printf ("NVDEC H.265 Stateless Decoder with device %d",
|
|
||||||
cdata->cuda_device_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
gst_element_class_set_metadata (element_class, long_name,
|
|
||||||
"Codec/Decoder/Video/Hardware",
|
|
||||||
"Nvidia H.265 video decoder", "Seungha Yang <seungha@centricular.com>");
|
|
||||||
g_free (long_name);
|
|
||||||
|
|
||||||
gst_element_class_add_pad_template (element_class,
|
|
||||||
gst_pad_template_new ("sink", GST_PAD_SINK, GST_PAD_ALWAYS,
|
|
||||||
cdata->sink_caps));
|
|
||||||
gst_element_class_add_pad_template (element_class,
|
|
||||||
gst_pad_template_new ("src", GST_PAD_SRC, GST_PAD_ALWAYS,
|
|
||||||
cdata->src_caps));
|
|
||||||
|
|
||||||
nvdec_class->cuda_device_id = cdata->cuda_device_id;
|
|
||||||
|
|
||||||
gst_caps_unref (cdata->sink_caps);
|
|
||||||
gst_caps_unref (cdata->src_caps);
|
|
||||||
g_free (cdata);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
gst_nv_h265_dec_register (GstPlugin * plugin, guint device_id, guint rank,
|
gst_nv_h265_dec_register (GstPlugin * plugin, guint device_id, guint rank,
|
||||||
GstCaps * sink_caps, GstCaps * src_caps, gboolean is_primary)
|
GstCaps * sink_caps, GstCaps * src_caps, gboolean is_primary)
|
||||||
{
|
{
|
||||||
GTypeQuery type_query;
|
GType type;
|
||||||
GTypeInfo type_info = { 0, };
|
|
||||||
GType subtype;
|
|
||||||
gchar *type_name;
|
gchar *type_name;
|
||||||
gchar *feature_name;
|
gchar *feature_name;
|
||||||
GstNvH265DecClassData *cdata;
|
GstNvDecoderClassData *cdata;
|
||||||
gboolean is_default = TRUE;
|
gint index = 0;
|
||||||
GValue value_list = G_VALUE_INIT;
|
GValue value_list = G_VALUE_INIT;
|
||||||
GValue value = G_VALUE_INIT;
|
GValue value = G_VALUE_INIT;
|
||||||
|
GTypeInfo type_info = {
|
||||||
|
sizeof (GstNvH265DecClass),
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
(GClassInitFunc) gst_nv_h265_dec_class_init,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
sizeof (GstNvH265Dec),
|
||||||
|
0,
|
||||||
|
(GInstanceInitFunc) gst_nv_h265_dec_init,
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
GST_DEBUG_CATEGORY_INIT (gst_nv_h265_dec_debug, "nvh265dec", 0, "nvh265dec");
|
||||||
* element-nvh265sldec
|
|
||||||
*
|
|
||||||
* Since: 1.18
|
|
||||||
*/
|
|
||||||
|
|
||||||
cdata = g_new0 (GstNvH265DecClassData, 1);
|
cdata = g_new0 (GstNvDecoderClassData, 1);
|
||||||
cdata->sink_caps = gst_caps_copy (sink_caps);
|
cdata->sink_caps = gst_caps_copy (sink_caps);
|
||||||
|
|
||||||
/* Update stream-format since we support packetized format as well */
|
/* Update stream-format since we support packetized format as well */
|
||||||
|
@ -1017,45 +1048,36 @@ gst_nv_h265_dec_register (GstPlugin * plugin, guint device_id, guint rank,
|
||||||
cdata->src_caps = gst_caps_ref (src_caps);
|
cdata->src_caps = gst_caps_ref (src_caps);
|
||||||
cdata->cuda_device_id = device_id;
|
cdata->cuda_device_id = device_id;
|
||||||
|
|
||||||
g_type_query (GST_TYPE_NV_H265_DEC, &type_query);
|
|
||||||
memset (&type_info, 0, sizeof (type_info));
|
|
||||||
type_info.class_size = type_query.class_size;
|
|
||||||
type_info.instance_size = type_query.instance_size;
|
|
||||||
type_info.class_init = (GClassInitFunc) gst_nv_h265_dec_subclass_init;
|
|
||||||
type_info.class_data = cdata;
|
|
||||||
|
|
||||||
if (is_primary) {
|
if (is_primary) {
|
||||||
type_name = g_strdup ("GstNvH265StatelessPrimaryDec");
|
type_name = g_strdup ("GstNvH265Dec");
|
||||||
feature_name = g_strdup ("nvh265dec");
|
feature_name = g_strdup ("nvh265dec");
|
||||||
} else {
|
} else {
|
||||||
type_name = g_strdup ("GstNvH265StatelessDec");
|
type_name = g_strdup ("GstNvH265SLDec");
|
||||||
feature_name = g_strdup ("nvh265sldec");
|
feature_name = g_strdup ("nvh265sldec");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (g_type_from_name (type_name) != 0) {
|
while (g_type_from_name (type_name)) {
|
||||||
|
index++;
|
||||||
g_free (type_name);
|
g_free (type_name);
|
||||||
g_free (feature_name);
|
g_free (feature_name);
|
||||||
if (is_primary) {
|
if (is_primary) {
|
||||||
type_name =
|
type_name = g_strdup_printf ("GstNvH265Device%dDec", index);
|
||||||
g_strdup_printf ("GstNvH265StatelessPrimaryDevice%dDec", device_id);
|
feature_name = g_strdup_printf ("nvh265device%ddec", index);
|
||||||
feature_name = g_strdup_printf ("nvh265device%ddec", device_id);
|
|
||||||
} else {
|
} else {
|
||||||
type_name = g_strdup_printf ("GstNvH265StatelessDevice%dDec", device_id);
|
type_name = g_strdup_printf ("GstNvH265SLDevice%dDec", index);
|
||||||
feature_name = g_strdup_printf ("nvh265sldevice%ddec", device_id);
|
feature_name = g_strdup_printf ("nvh265sldevice%ddec", index);
|
||||||
}
|
}
|
||||||
|
|
||||||
is_default = FALSE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cdata->is_default = is_default;
|
type_info.class_data = cdata;
|
||||||
subtype = g_type_register_static (GST_TYPE_NV_H265_DEC,
|
type = g_type_register_static (GST_TYPE_H265_DECODER,
|
||||||
type_name, &type_info, 0);
|
type_name, &type_info, 0);
|
||||||
|
|
||||||
/* make lower rank than default device */
|
/* make lower rank than default device */
|
||||||
if (rank > 0 && !is_default)
|
if (rank > 0 && index > 0)
|
||||||
rank--;
|
rank--;
|
||||||
|
|
||||||
if (!gst_element_register (plugin, feature_name, rank, subtype))
|
if (!gst_element_register (plugin, feature_name, rank, type))
|
||||||
GST_WARNING ("Failed to register plugin '%s'", type_name);
|
GST_WARNING ("Failed to register plugin '%s'", type_name);
|
||||||
|
|
||||||
g_free (type_name);
|
g_free (type_name);
|
||||||
|
|
|
@ -25,16 +25,6 @@
|
||||||
|
|
||||||
G_BEGIN_DECLS
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
#define GST_TYPE_NV_H265_DEC (gst_nv_h265_dec_get_type())
|
|
||||||
#define GST_NV_H265_DEC(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), GST_TYPE_NV_H265_DEC, GstNvH265Dec))
|
|
||||||
#define GST_NV_H265_DEC_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), GST_TYPE_NV_H265_DEC, GstNvH265DecClass))
|
|
||||||
#define GST_NV_H265_DEC_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GST_TYPE_NV_H265_DEC, GstNvH265DecClass))
|
|
||||||
|
|
||||||
typedef struct _GstNvH265Dec GstNvH265Dec;
|
|
||||||
typedef struct _GstNvH265DecClass GstNvH265DecClass;
|
|
||||||
|
|
||||||
GType gst_nv_h265_dec_get_type (void);
|
|
||||||
|
|
||||||
void gst_nv_h265_dec_register (GstPlugin * plugin,
|
void gst_nv_h265_dec_register (GstPlugin * plugin,
|
||||||
guint device_id,
|
guint device_id,
|
||||||
guint rank,
|
guint rank,
|
||||||
|
|
|
@ -17,6 +17,21 @@
|
||||||
* Boston, MA 02110-1301, USA.
|
* Boston, MA 02110-1301, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SECTION:element-nvvp8sldec
|
||||||
|
* @title: nvvp8sldec
|
||||||
|
*
|
||||||
|
* GstCodecs based NVIDIA VP8 video decoder
|
||||||
|
*
|
||||||
|
* ## Example launch line
|
||||||
|
* ```
|
||||||
|
* gst-launch-1.0 filesrc location=/path/to/vp8/file ! parsebin ! nvvp8sldec ! videoconvert ! autovideosink
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* Since: 1.20
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#endif
|
#endif
|
||||||
|
@ -31,7 +46,7 @@
|
||||||
GST_DEBUG_CATEGORY_STATIC (gst_nv_vp8_dec_debug);
|
GST_DEBUG_CATEGORY_STATIC (gst_nv_vp8_dec_debug);
|
||||||
#define GST_CAT_DEFAULT gst_nv_vp8_dec_debug
|
#define GST_CAT_DEFAULT gst_nv_vp8_dec_debug
|
||||||
|
|
||||||
struct _GstNvVp8Dec
|
typedef struct _GstNvVp8Dec
|
||||||
{
|
{
|
||||||
GstVp8Decoder parent;
|
GstVp8Decoder parent;
|
||||||
|
|
||||||
|
@ -42,22 +57,28 @@ struct _GstNvVp8Dec
|
||||||
CUVIDPICPARAMS params;
|
CUVIDPICPARAMS params;
|
||||||
|
|
||||||
guint width, height;
|
guint width, height;
|
||||||
};
|
} GstNvVp8Dec;
|
||||||
|
|
||||||
struct _GstNvVp8DecClass
|
typedef struct _GstNvVp8DecClass
|
||||||
{
|
{
|
||||||
GstVp8DecoderClass parent_class;
|
GstVp8DecoderClass parent_class;
|
||||||
guint cuda_device_id;
|
guint cuda_device_id;
|
||||||
|
} GstNvVp8DecClass;
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
PROP_0,
|
||||||
|
PROP_CUDA_DEVICE_ID,
|
||||||
};
|
};
|
||||||
|
|
||||||
#define gst_nv_vp8_dec_parent_class parent_class
|
static GTypeClass *parent_class = NULL;
|
||||||
|
|
||||||
/**
|
#define GST_NV_VP8_DEC(object) ((GstNvVp8Dec *) (object))
|
||||||
* GstNvVp8Dec:
|
#define GST_NV_VP8_DEC_GET_CLASS(object) \
|
||||||
*
|
(G_TYPE_INSTANCE_GET_CLASS ((object),G_TYPE_FROM_INSTANCE (object),GstNvVp8DecClass))
|
||||||
* Since: 1.20
|
|
||||||
*/
|
static void gst_nv_vp8_dec_get_property (GObject * object, guint prop_id,
|
||||||
G_DEFINE_TYPE (GstNvVp8Dec, gst_nv_vp8_dec, GST_TYPE_VP8_DECODER);
|
GValue * value, GParamSpec * pspec);
|
||||||
|
|
||||||
static void gst_nv_vp8_dec_set_context (GstElement * element,
|
static void gst_nv_vp8_dec_set_context (GstElement * element,
|
||||||
GstContext * context);
|
GstContext * context);
|
||||||
|
@ -82,14 +103,43 @@ static guint gst_nv_vp8_dec_get_preferred_output_delay (GstVp8Decoder * decoder,
|
||||||
gboolean is_live);
|
gboolean is_live);
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gst_nv_vp8_dec_class_init (GstNvVp8DecClass * klass)
|
gst_nv_vp8_dec_class_init (GstNvVp8DecClass * klass,
|
||||||
|
GstNvDecoderClassData * cdata)
|
||||||
{
|
{
|
||||||
|
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||||
GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
|
GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
|
||||||
GstVideoDecoderClass *decoder_class = GST_VIDEO_DECODER_CLASS (klass);
|
GstVideoDecoderClass *decoder_class = GST_VIDEO_DECODER_CLASS (klass);
|
||||||
GstVp8DecoderClass *vp8decoder_class = GST_VP8_DECODER_CLASS (klass);
|
GstVp8DecoderClass *vp8decoder_class = GST_VP8_DECODER_CLASS (klass);
|
||||||
|
|
||||||
|
object_class->get_property = gst_nv_vp8_dec_get_property;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GstNvVp8SLDec:cuda-device-id:
|
||||||
|
*
|
||||||
|
* Assigned CUDA device id
|
||||||
|
*
|
||||||
|
* Since: 1.22
|
||||||
|
*/
|
||||||
|
g_object_class_install_property (object_class, PROP_CUDA_DEVICE_ID,
|
||||||
|
g_param_spec_uint ("cuda-device-id", "CUDA device id",
|
||||||
|
"Assigned CUDA device id", 0, G_MAXINT, 0,
|
||||||
|
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
|
||||||
|
|
||||||
element_class->set_context = GST_DEBUG_FUNCPTR (gst_nv_vp8_dec_set_context);
|
element_class->set_context = GST_DEBUG_FUNCPTR (gst_nv_vp8_dec_set_context);
|
||||||
|
|
||||||
|
parent_class = (GTypeClass *) g_type_class_peek_parent (klass);
|
||||||
|
gst_element_class_set_metadata (element_class,
|
||||||
|
"NVDEC VP8 Stateless Decoder",
|
||||||
|
"Codec/Decoder/Video/Hardware",
|
||||||
|
"NVIDIA VP8 video decoder", "Seungha Yang <seungha@centricular.com>");
|
||||||
|
|
||||||
|
gst_element_class_add_pad_template (element_class,
|
||||||
|
gst_pad_template_new ("sink", GST_PAD_SINK, GST_PAD_ALWAYS,
|
||||||
|
cdata->sink_caps));
|
||||||
|
gst_element_class_add_pad_template (element_class,
|
||||||
|
gst_pad_template_new ("src", GST_PAD_SRC, GST_PAD_ALWAYS,
|
||||||
|
cdata->src_caps));
|
||||||
|
|
||||||
decoder_class->open = GST_DEBUG_FUNCPTR (gst_nv_vp8_dec_open);
|
decoder_class->open = GST_DEBUG_FUNCPTR (gst_nv_vp8_dec_open);
|
||||||
decoder_class->close = GST_DEBUG_FUNCPTR (gst_nv_vp8_dec_close);
|
decoder_class->close = GST_DEBUG_FUNCPTR (gst_nv_vp8_dec_close);
|
||||||
decoder_class->negotiate = GST_DEBUG_FUNCPTR (gst_nv_vp8_dec_negotiate);
|
decoder_class->negotiate = GST_DEBUG_FUNCPTR (gst_nv_vp8_dec_negotiate);
|
||||||
|
@ -108,10 +158,11 @@ gst_nv_vp8_dec_class_init (GstNvVp8DecClass * klass)
|
||||||
vp8decoder_class->get_preferred_output_delay =
|
vp8decoder_class->get_preferred_output_delay =
|
||||||
GST_DEBUG_FUNCPTR (gst_nv_vp8_dec_get_preferred_output_delay);
|
GST_DEBUG_FUNCPTR (gst_nv_vp8_dec_get_preferred_output_delay);
|
||||||
|
|
||||||
GST_DEBUG_CATEGORY_INIT (gst_nv_vp8_dec_debug,
|
klass->cuda_device_id = cdata->cuda_device_id;
|
||||||
"nvvp8dec", 0, "NVIDIA VP8 Decoder");
|
|
||||||
|
|
||||||
gst_type_mark_as_plugin_api (GST_TYPE_NV_VP8_DEC, 0);
|
gst_caps_unref (cdata->sink_caps);
|
||||||
|
gst_caps_unref (cdata->src_caps);
|
||||||
|
g_free (cdata);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -119,6 +170,22 @@ gst_nv_vp8_dec_init (GstNvVp8Dec * self)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gst_nv_vp8_dec_get_property (GObject * object, guint prop_id, GValue * value,
|
||||||
|
GParamSpec * pspec)
|
||||||
|
{
|
||||||
|
GstNvVp8DecClass *klass = GST_NV_VP8_DEC_GET_CLASS (object);
|
||||||
|
|
||||||
|
switch (prop_id) {
|
||||||
|
case PROP_CUDA_DEVICE_ID:
|
||||||
|
g_value_set_uint (value, klass->cuda_device_id);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gst_nv_vp8_dec_set_context (GstElement * element, GstContext * context)
|
gst_nv_vp8_dec_set_context (GstElement * element, GstContext * context)
|
||||||
{
|
{
|
||||||
|
@ -444,109 +511,64 @@ gst_nv_vp8_dec_get_preferred_output_delay (GstVp8Decoder * decoder,
|
||||||
return 4;
|
return 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
GstCaps *sink_caps;
|
|
||||||
GstCaps *src_caps;
|
|
||||||
guint cuda_device_id;
|
|
||||||
gboolean is_default;
|
|
||||||
} GstNvVp8DecClassData;
|
|
||||||
|
|
||||||
static void
|
|
||||||
gst_nv_vp8_dec_subclass_init (gpointer klass, GstNvVp8DecClassData * cdata)
|
|
||||||
{
|
|
||||||
GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
|
|
||||||
GstNvVp8DecClass *nvdec_class = (GstNvVp8DecClass *) (klass);
|
|
||||||
gchar *long_name;
|
|
||||||
|
|
||||||
if (cdata->is_default) {
|
|
||||||
long_name = g_strdup_printf ("NVDEC VP8 Stateless Decoder");
|
|
||||||
} else {
|
|
||||||
long_name = g_strdup_printf ("NVDEC VP8 Stateless Decoder with device %d",
|
|
||||||
cdata->cuda_device_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
gst_element_class_set_metadata (element_class, long_name,
|
|
||||||
"Codec/Decoder/Video/Hardware",
|
|
||||||
"NVIDIA VP8 video decoder", "Seungha Yang <seungha@centricular.com>");
|
|
||||||
g_free (long_name);
|
|
||||||
|
|
||||||
gst_element_class_add_pad_template (element_class,
|
|
||||||
gst_pad_template_new ("sink", GST_PAD_SINK, GST_PAD_ALWAYS,
|
|
||||||
cdata->sink_caps));
|
|
||||||
gst_element_class_add_pad_template (element_class,
|
|
||||||
gst_pad_template_new ("src", GST_PAD_SRC, GST_PAD_ALWAYS,
|
|
||||||
cdata->src_caps));
|
|
||||||
|
|
||||||
nvdec_class->cuda_device_id = cdata->cuda_device_id;
|
|
||||||
|
|
||||||
gst_caps_unref (cdata->sink_caps);
|
|
||||||
gst_caps_unref (cdata->src_caps);
|
|
||||||
g_free (cdata);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
gst_nv_vp8_dec_register (GstPlugin * plugin, guint device_id, guint rank,
|
gst_nv_vp8_dec_register (GstPlugin * plugin, guint device_id, guint rank,
|
||||||
GstCaps * sink_caps, GstCaps * src_caps, gboolean is_primary)
|
GstCaps * sink_caps, GstCaps * src_caps, gboolean is_primary)
|
||||||
{
|
{
|
||||||
GTypeQuery type_query;
|
GType type;
|
||||||
GTypeInfo type_info = { 0, };
|
|
||||||
GType subtype;
|
|
||||||
gchar *type_name;
|
gchar *type_name;
|
||||||
gchar *feature_name;
|
gchar *feature_name;
|
||||||
GstNvVp8DecClassData *cdata;
|
GstNvDecoderClassData *cdata;
|
||||||
gboolean is_default = TRUE;
|
gint index = 0;
|
||||||
|
GTypeInfo type_info = {
|
||||||
|
sizeof (GstNvVp8DecClass),
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
(GClassInitFunc) gst_nv_vp8_dec_class_init,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
sizeof (GstNvVp8Dec),
|
||||||
|
0,
|
||||||
|
(GInstanceInitFunc) gst_nv_vp8_dec_init,
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
GST_DEBUG_CATEGORY_INIT (gst_nv_vp8_dec_debug, "nvvp8dec", 0, "nvvp8dec");
|
||||||
* element-nvvp8sldec:
|
|
||||||
*
|
|
||||||
* Since: 1.20
|
|
||||||
*/
|
|
||||||
|
|
||||||
cdata = g_new0 (GstNvVp8DecClassData, 1);
|
cdata = g_new0 (GstNvDecoderClassData, 1);
|
||||||
cdata->sink_caps = gst_caps_ref (sink_caps);
|
cdata->sink_caps = gst_caps_ref (sink_caps);
|
||||||
cdata->src_caps = gst_caps_ref (src_caps);
|
cdata->src_caps = gst_caps_ref (src_caps);
|
||||||
cdata->cuda_device_id = device_id;
|
cdata->cuda_device_id = device_id;
|
||||||
|
|
||||||
g_type_query (GST_TYPE_NV_VP8_DEC, &type_query);
|
|
||||||
memset (&type_info, 0, sizeof (type_info));
|
|
||||||
type_info.class_size = type_query.class_size;
|
|
||||||
type_info.instance_size = type_query.instance_size;
|
|
||||||
type_info.class_init = (GClassInitFunc) gst_nv_vp8_dec_subclass_init;
|
|
||||||
type_info.class_data = cdata;
|
|
||||||
|
|
||||||
if (is_primary) {
|
if (is_primary) {
|
||||||
type_name = g_strdup ("GstNvVP8StatelessPrimaryDec");
|
type_name = g_strdup ("GstNvVp8Dec");
|
||||||
feature_name = g_strdup ("nvvp8dec");
|
feature_name = g_strdup ("nvvp8dec");
|
||||||
} else {
|
} else {
|
||||||
type_name = g_strdup ("GstNvVP8StatelessDec");
|
type_name = g_strdup ("GstNvVp8SLDec");
|
||||||
feature_name = g_strdup ("nvvp8sldec");
|
feature_name = g_strdup ("nvvp8sldec");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (g_type_from_name (type_name) != 0) {
|
while (g_type_from_name (type_name)) {
|
||||||
|
index++;
|
||||||
g_free (type_name);
|
g_free (type_name);
|
||||||
g_free (feature_name);
|
g_free (feature_name);
|
||||||
if (is_primary) {
|
if (is_primary) {
|
||||||
type_name =
|
type_name = g_strdup_printf ("GstNvVp8Device%dDec", index);
|
||||||
g_strdup_printf ("GstNvVP8StatelessPrimaryDevice%dDec", device_id);
|
feature_name = g_strdup_printf ("nvvp8device%ddec", index);
|
||||||
feature_name = g_strdup_printf ("nvvp8device%ddec", device_id);
|
|
||||||
} else {
|
} else {
|
||||||
type_name = g_strdup_printf ("GstNvVP8StatelessDevice%dDec", device_id);
|
type_name = g_strdup_printf ("GstNvVp8SLDevice%dDec", index);
|
||||||
feature_name = g_strdup_printf ("nvvp8sldevice%ddec", device_id);
|
feature_name = g_strdup_printf ("nvvp8sldevice%ddec", index);
|
||||||
}
|
}
|
||||||
|
|
||||||
is_default = FALSE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cdata->is_default = is_default;
|
type_info.class_data = cdata;
|
||||||
subtype = g_type_register_static (GST_TYPE_NV_VP8_DEC,
|
type = g_type_register_static (GST_TYPE_VP8_DECODER,
|
||||||
type_name, &type_info, 0);
|
type_name, &type_info, 0);
|
||||||
|
|
||||||
/* make lower rank than default device */
|
/* make lower rank than default device */
|
||||||
if (rank > 0 && !is_default)
|
if (rank > 0 && index > 0)
|
||||||
rank--;
|
rank--;
|
||||||
|
|
||||||
if (!gst_element_register (plugin, feature_name, rank, subtype))
|
if (!gst_element_register (plugin, feature_name, rank, type))
|
||||||
GST_WARNING ("Failed to register plugin '%s'", type_name);
|
GST_WARNING ("Failed to register plugin '%s'", type_name);
|
||||||
|
|
||||||
g_free (type_name);
|
g_free (type_name);
|
||||||
|
|
|
@ -25,16 +25,6 @@
|
||||||
|
|
||||||
G_BEGIN_DECLS
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
#define GST_TYPE_NV_VP8_DEC (gst_nv_vp8_dec_get_type())
|
|
||||||
#define GST_NV_VP8_DEC(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), GST_TYPE_NV_VP8_DEC, GstNvVp8Dec))
|
|
||||||
#define GST_NV_VP8_DEC_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), GST_TYPE_NV_VP8_DEC, GstNvVp8DecClass))
|
|
||||||
#define GST_NV_VP8_DEC_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GST_TYPE_NV_VP8_DEC, GstNvVp8DecClass))
|
|
||||||
|
|
||||||
typedef struct _GstNvVp8Dec GstNvVp8Dec;
|
|
||||||
typedef struct _GstNvVp8DecClass GstNvVp8DecClass;
|
|
||||||
|
|
||||||
GType gst_nv_vp8_dec_get_type (void);
|
|
||||||
|
|
||||||
void gst_nv_vp8_dec_register (GstPlugin * plugin,
|
void gst_nv_vp8_dec_register (GstPlugin * plugin,
|
||||||
guint device_id,
|
guint device_id,
|
||||||
guint rank,
|
guint rank,
|
||||||
|
|
|
@ -17,6 +17,21 @@
|
||||||
* Boston, MA 02110-1301, USA.
|
* Boston, MA 02110-1301, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SECTION:element-nvvp9sldec
|
||||||
|
* @title: nvvp9sldec
|
||||||
|
*
|
||||||
|
* GstCodecs based NVIDIA VP9 video decoder
|
||||||
|
*
|
||||||
|
* ## Example launch line
|
||||||
|
* ```
|
||||||
|
* gst-launch-1.0 filesrc location=/path/to/vp9/file ! parsebin ! nvvp9sldec ! videoconvert ! autovideosink
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* Since: 1.20
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#endif
|
#endif
|
||||||
|
@ -31,7 +46,7 @@
|
||||||
GST_DEBUG_CATEGORY_STATIC (gst_nv_vp9_dec_debug);
|
GST_DEBUG_CATEGORY_STATIC (gst_nv_vp9_dec_debug);
|
||||||
#define GST_CAT_DEFAULT gst_nv_vp9_dec_debug
|
#define GST_CAT_DEFAULT gst_nv_vp9_dec_debug
|
||||||
|
|
||||||
struct _GstNvVp9Dec
|
typedef struct _GstNvVp9Dec
|
||||||
{
|
{
|
||||||
GstVp9Decoder parent;
|
GstVp9Decoder parent;
|
||||||
|
|
||||||
|
@ -43,22 +58,28 @@ struct _GstNvVp9Dec
|
||||||
|
|
||||||
guint width, height;
|
guint width, height;
|
||||||
GstVP9Profile profile;
|
GstVP9Profile profile;
|
||||||
};
|
} GstNvVp9Dec;
|
||||||
|
|
||||||
struct _GstNvVp9DecClass
|
typedef struct _GstNvVp9DecClass
|
||||||
{
|
{
|
||||||
GstVp9DecoderClass parent_class;
|
GstVp9DecoderClass parent_class;
|
||||||
guint cuda_device_id;
|
guint cuda_device_id;
|
||||||
|
} GstNvVp9DecClass;
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
PROP_0,
|
||||||
|
PROP_CUDA_DEVICE_ID,
|
||||||
};
|
};
|
||||||
|
|
||||||
#define gst_nv_vp9_dec_parent_class parent_class
|
static GTypeClass *parent_class = NULL;
|
||||||
|
|
||||||
/**
|
#define GST_NV_VP9_DEC(object) ((GstNvVp9Dec *) (object))
|
||||||
* GstNvVp9Dec:
|
#define GST_NV_VP9_DEC_GET_CLASS(object) \
|
||||||
*
|
(G_TYPE_INSTANCE_GET_CLASS ((object),G_TYPE_FROM_INSTANCE (object),GstNvVp9DecClass))
|
||||||
* Since: 1.20
|
|
||||||
*/
|
static void gst_nv_vp9_dec_get_property (GObject * object, guint prop_id,
|
||||||
G_DEFINE_TYPE (GstNvVp9Dec, gst_nv_vp9_dec, GST_TYPE_VP9_DECODER);
|
GValue * value, GParamSpec * pspec);
|
||||||
|
|
||||||
static void gst_nv_vp9_dec_set_context (GstElement * element,
|
static void gst_nv_vp9_dec_set_context (GstElement * element,
|
||||||
GstContext * context);
|
GstContext * context);
|
||||||
|
@ -85,14 +106,43 @@ static guint gst_nv_vp9_dec_get_preferred_output_delay (GstVp9Decoder * decoder,
|
||||||
gboolean is_live);
|
gboolean is_live);
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gst_nv_vp9_dec_class_init (GstNvVp9DecClass * klass)
|
gst_nv_vp9_dec_class_init (GstNvVp9DecClass * klass,
|
||||||
|
GstNvDecoderClassData * cdata)
|
||||||
{
|
{
|
||||||
|
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||||
GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
|
GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
|
||||||
GstVideoDecoderClass *decoder_class = GST_VIDEO_DECODER_CLASS (klass);
|
GstVideoDecoderClass *decoder_class = GST_VIDEO_DECODER_CLASS (klass);
|
||||||
GstVp9DecoderClass *vp9decoder_class = GST_VP9_DECODER_CLASS (klass);
|
GstVp9DecoderClass *vp9decoder_class = GST_VP9_DECODER_CLASS (klass);
|
||||||
|
|
||||||
|
object_class->get_property = gst_nv_vp9_dec_get_property;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GstNvVp9SLDec:cuda-device-id:
|
||||||
|
*
|
||||||
|
* Assigned CUDA device id
|
||||||
|
*
|
||||||
|
* Since: 1.22
|
||||||
|
*/
|
||||||
|
g_object_class_install_property (object_class, PROP_CUDA_DEVICE_ID,
|
||||||
|
g_param_spec_uint ("cuda-device-id", "CUDA device id",
|
||||||
|
"Assigned CUDA device id", 0, G_MAXINT, 0,
|
||||||
|
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
|
||||||
|
|
||||||
element_class->set_context = GST_DEBUG_FUNCPTR (gst_nv_vp9_dec_set_context);
|
element_class->set_context = GST_DEBUG_FUNCPTR (gst_nv_vp9_dec_set_context);
|
||||||
|
|
||||||
|
parent_class = (GTypeClass *) g_type_class_peek_parent (klass);
|
||||||
|
gst_element_class_set_metadata (element_class,
|
||||||
|
"NVDEC VP9 Stateless Decoder",
|
||||||
|
"Codec/Decoder/Video/Hardware",
|
||||||
|
"NVIDIA VP9 video decoder", "Seungha Yang <seungha@centricular.com>");
|
||||||
|
|
||||||
|
gst_element_class_add_pad_template (element_class,
|
||||||
|
gst_pad_template_new ("sink", GST_PAD_SINK, GST_PAD_ALWAYS,
|
||||||
|
cdata->sink_caps));
|
||||||
|
gst_element_class_add_pad_template (element_class,
|
||||||
|
gst_pad_template_new ("src", GST_PAD_SRC, GST_PAD_ALWAYS,
|
||||||
|
cdata->src_caps));
|
||||||
|
|
||||||
decoder_class->open = GST_DEBUG_FUNCPTR (gst_nv_vp9_dec_open);
|
decoder_class->open = GST_DEBUG_FUNCPTR (gst_nv_vp9_dec_open);
|
||||||
decoder_class->close = GST_DEBUG_FUNCPTR (gst_nv_vp9_dec_close);
|
decoder_class->close = GST_DEBUG_FUNCPTR (gst_nv_vp9_dec_close);
|
||||||
decoder_class->negotiate = GST_DEBUG_FUNCPTR (gst_nv_vp9_dec_negotiate);
|
decoder_class->negotiate = GST_DEBUG_FUNCPTR (gst_nv_vp9_dec_negotiate);
|
||||||
|
@ -113,10 +163,11 @@ gst_nv_vp9_dec_class_init (GstNvVp9DecClass * klass)
|
||||||
vp9decoder_class->get_preferred_output_delay =
|
vp9decoder_class->get_preferred_output_delay =
|
||||||
GST_DEBUG_FUNCPTR (gst_nv_vp9_dec_get_preferred_output_delay);
|
GST_DEBUG_FUNCPTR (gst_nv_vp9_dec_get_preferred_output_delay);
|
||||||
|
|
||||||
GST_DEBUG_CATEGORY_INIT (gst_nv_vp9_dec_debug,
|
klass->cuda_device_id = cdata->cuda_device_id;
|
||||||
"nvvp9dec", 0, "NVIDIA VP9 Decoder");
|
|
||||||
|
|
||||||
gst_type_mark_as_plugin_api (GST_TYPE_NV_VP9_DEC, 0);
|
gst_caps_unref (cdata->sink_caps);
|
||||||
|
gst_caps_unref (cdata->src_caps);
|
||||||
|
g_free (cdata);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -124,6 +175,22 @@ gst_nv_vp9_dec_init (GstNvVp9Dec * self)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gst_nv_vp9_dec_get_property (GObject * object, guint prop_id, GValue * value,
|
||||||
|
GParamSpec * pspec)
|
||||||
|
{
|
||||||
|
GstNvVp9DecClass *klass = GST_NV_VP9_DEC_GET_CLASS (object);
|
||||||
|
|
||||||
|
switch (prop_id) {
|
||||||
|
case PROP_CUDA_DEVICE_ID:
|
||||||
|
g_value_set_uint (value, klass->cuda_device_id);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gst_nv_vp9_dec_set_context (GstElement * element, GstContext * context)
|
gst_nv_vp9_dec_set_context (GstElement * element, GstContext * context)
|
||||||
{
|
{
|
||||||
|
@ -539,66 +606,30 @@ gst_nv_vp9_dec_get_preferred_output_delay (GstVp9Decoder * decoder,
|
||||||
return 4;
|
return 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
GstCaps *sink_caps;
|
|
||||||
GstCaps *src_caps;
|
|
||||||
guint cuda_device_id;
|
|
||||||
gboolean is_default;
|
|
||||||
} GstNvVp9DecClassData;
|
|
||||||
|
|
||||||
static void
|
|
||||||
gst_nv_vp9_dec_subclass_init (gpointer klass, GstNvVp9DecClassData * cdata)
|
|
||||||
{
|
|
||||||
GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
|
|
||||||
GstNvVp9DecClass *nvdec_class = (GstNvVp9DecClass *) (klass);
|
|
||||||
gchar *long_name;
|
|
||||||
|
|
||||||
if (cdata->is_default) {
|
|
||||||
long_name = g_strdup_printf ("NVDEC VP9 Stateless Decoder");
|
|
||||||
} else {
|
|
||||||
long_name = g_strdup_printf ("NVDEC VP9 Stateless Decoder with device %d",
|
|
||||||
cdata->cuda_device_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
gst_element_class_set_metadata (element_class, long_name,
|
|
||||||
"Codec/Decoder/Video/Hardware",
|
|
||||||
"NVIDIA VP9 video decoder", "Seungha Yang <seungha@centricular.com>");
|
|
||||||
g_free (long_name);
|
|
||||||
|
|
||||||
gst_element_class_add_pad_template (element_class,
|
|
||||||
gst_pad_template_new ("sink", GST_PAD_SINK, GST_PAD_ALWAYS,
|
|
||||||
cdata->sink_caps));
|
|
||||||
gst_element_class_add_pad_template (element_class,
|
|
||||||
gst_pad_template_new ("src", GST_PAD_SRC, GST_PAD_ALWAYS,
|
|
||||||
cdata->src_caps));
|
|
||||||
|
|
||||||
nvdec_class->cuda_device_id = cdata->cuda_device_id;
|
|
||||||
|
|
||||||
gst_caps_unref (cdata->sink_caps);
|
|
||||||
gst_caps_unref (cdata->src_caps);
|
|
||||||
g_free (cdata);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
gst_nv_vp9_dec_register (GstPlugin * plugin, guint device_id, guint rank,
|
gst_nv_vp9_dec_register (GstPlugin * plugin, guint device_id, guint rank,
|
||||||
GstCaps * sink_caps, GstCaps * src_caps, gboolean is_primary)
|
GstCaps * sink_caps, GstCaps * src_caps, gboolean is_primary)
|
||||||
{
|
{
|
||||||
GTypeQuery type_query;
|
GType type;
|
||||||
GTypeInfo type_info = { 0, };
|
|
||||||
GType subtype;
|
|
||||||
gchar *type_name;
|
gchar *type_name;
|
||||||
gchar *feature_name;
|
gchar *feature_name;
|
||||||
GstNvVp9DecClassData *cdata;
|
GstNvDecoderClassData *cdata;
|
||||||
gboolean is_default = TRUE;
|
gint index = 0;
|
||||||
|
GTypeInfo type_info = {
|
||||||
|
sizeof (GstNvVp9DecClass),
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
(GClassInitFunc) gst_nv_vp9_dec_class_init,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
sizeof (GstNvVp9Dec),
|
||||||
|
0,
|
||||||
|
(GInstanceInitFunc) gst_nv_vp9_dec_init,
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
GST_DEBUG_CATEGORY_INIT (gst_nv_vp9_dec_debug, "nvvp9dec", 0, "nvvp9dec");
|
||||||
* element-nvvp9sldec:
|
|
||||||
*
|
|
||||||
* Since: 1.20
|
|
||||||
*/
|
|
||||||
|
|
||||||
cdata = g_new0 (GstNvVp9DecClassData, 1);
|
cdata = g_new0 (GstNvDecoderClassData, 1);
|
||||||
cdata->sink_caps = gst_caps_copy (sink_caps);
|
cdata->sink_caps = gst_caps_copy (sink_caps);
|
||||||
gst_caps_set_simple (cdata->sink_caps,
|
gst_caps_set_simple (cdata->sink_caps,
|
||||||
"alignment", G_TYPE_STRING, "frame", NULL);
|
"alignment", G_TYPE_STRING, "frame", NULL);
|
||||||
|
@ -607,45 +638,37 @@ gst_nv_vp9_dec_register (GstPlugin * plugin, guint device_id, guint rank,
|
||||||
cdata->src_caps = gst_caps_ref (src_caps);
|
cdata->src_caps = gst_caps_ref (src_caps);
|
||||||
cdata->cuda_device_id = device_id;
|
cdata->cuda_device_id = device_id;
|
||||||
|
|
||||||
g_type_query (GST_TYPE_NV_VP9_DEC, &type_query);
|
|
||||||
memset (&type_info, 0, sizeof (type_info));
|
|
||||||
type_info.class_size = type_query.class_size;
|
|
||||||
type_info.instance_size = type_query.instance_size;
|
|
||||||
type_info.class_init = (GClassInitFunc) gst_nv_vp9_dec_subclass_init;
|
|
||||||
type_info.class_data = cdata;
|
|
||||||
|
|
||||||
if (is_primary) {
|
if (is_primary) {
|
||||||
type_name = g_strdup ("GstNvVP9StatelessPrimaryDec");
|
type_name = g_strdup ("GstNvVp9Dec");
|
||||||
feature_name = g_strdup ("nvvp9dec");
|
feature_name = g_strdup ("nvvp9dec");
|
||||||
} else {
|
} else {
|
||||||
type_name = g_strdup ("GstNvVP9StatelessDec");
|
type_name = g_strdup ("GstNvVp9SLDec");
|
||||||
feature_name = g_strdup ("nvvp9sldec");
|
feature_name = g_strdup ("nvvp9sldec");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (g_type_from_name (type_name) != 0) {
|
while (g_type_from_name (type_name)) {
|
||||||
|
index++;
|
||||||
g_free (type_name);
|
g_free (type_name);
|
||||||
g_free (feature_name);
|
g_free (feature_name);
|
||||||
if (is_primary) {
|
if (is_primary) {
|
||||||
type_name =
|
type_name = g_strdup_printf ("GstNvVp9Device%dDec", index);
|
||||||
g_strdup_printf ("GstNvVP9StatelessPrimaryDevice%dDec", device_id);
|
feature_name = g_strdup_printf ("nvvp9device%ddec", index);
|
||||||
feature_name = g_strdup_printf ("nvvp9device%ddec", device_id);
|
|
||||||
} else {
|
} else {
|
||||||
type_name = g_strdup_printf ("GstNvVP9StatelessDevice%dDec", device_id);
|
type_name = g_strdup_printf ("GstNvVp9SLDevice%dDec", index);
|
||||||
feature_name = g_strdup_printf ("nvvp9sldevice%ddec", device_id);
|
feature_name = g_strdup_printf ("nvvp9sldevice%ddec", index);
|
||||||
}
|
}
|
||||||
|
|
||||||
is_default = FALSE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cdata->is_default = is_default;
|
type_info.class_data = cdata;
|
||||||
subtype = g_type_register_static (GST_TYPE_NV_VP9_DEC,
|
|
||||||
|
type = g_type_register_static (GST_TYPE_VP9_DECODER,
|
||||||
type_name, &type_info, 0);
|
type_name, &type_info, 0);
|
||||||
|
|
||||||
/* make lower rank than default device */
|
/* make lower rank than default device */
|
||||||
if (rank > 0 && !is_default)
|
if (rank > 0 && index > 0)
|
||||||
rank--;
|
rank--;
|
||||||
|
|
||||||
if (!gst_element_register (plugin, feature_name, rank, subtype))
|
if (!gst_element_register (plugin, feature_name, rank, type))
|
||||||
GST_WARNING ("Failed to register plugin '%s'", type_name);
|
GST_WARNING ("Failed to register plugin '%s'", type_name);
|
||||||
|
|
||||||
g_free (type_name);
|
g_free (type_name);
|
||||||
|
|
|
@ -25,16 +25,6 @@
|
||||||
|
|
||||||
G_BEGIN_DECLS
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
#define GST_TYPE_NV_VP9_DEC (gst_nv_vp9_dec_get_type())
|
|
||||||
#define GST_NV_VP9_DEC(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), GST_TYPE_NV_VP9_DEC, GstNvVp9Dec))
|
|
||||||
#define GST_NV_VP9_DEC_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), GST_TYPE_NV_VP9_DEC, GstNvVp9DecClass))
|
|
||||||
#define GST_NV_VP9_DEC_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GST_TYPE_NV_VP9_DEC, GstNvVp9DecClass))
|
|
||||||
|
|
||||||
typedef struct _GstNvVp9Dec GstNvVp9Dec;
|
|
||||||
typedef struct _GstNvVp9DecClass GstNvVp9DecClass;
|
|
||||||
|
|
||||||
GType gst_nv_vp9_dec_get_type (void);
|
|
||||||
|
|
||||||
void gst_nv_vp9_dec_register (GstPlugin * plugin,
|
void gst_nv_vp9_dec_register (GstPlugin * plugin,
|
||||||
guint device_id,
|
guint device_id,
|
||||||
guint rank,
|
guint rank,
|
||||||
|
|
Loading…
Reference in a new issue