• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* GStreamer
2  * Copyright (C) <2019> Seungha Yang <seungha.yang@navercorp.com>
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Library General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Library General Public License for more details.
13  *
14  * You should have received a copy of the GNU Library General Public
15  * License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
17  * Boston, MA 02110-1301, USA.
18  */
19 
20 /**
21  * element-cudaupload:
22  *
23  * Uploads data to NVIDA GPU via CUDA APIs
24  *
25  * Since: 1.20
26  */
27 
28 #ifdef HAVE_CONFIG_H
29 #  include <config.h>
30 #endif
31 
32 #include "gstcudaupload.h"
33 
34 GST_DEBUG_CATEGORY_STATIC (gst_cuda_upload_debug);
35 #define GST_CAT_DEFAULT gst_cuda_upload_debug
36 
37 static GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE ("sink",
38     GST_PAD_SINK,
39     GST_PAD_ALWAYS,
40     GST_STATIC_CAPS ("video/x-raw; video/x-raw("
41         GST_CAPS_FEATURE_MEMORY_CUDA_MEMORY ")"));
42 
43 static GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE ("src",
44     GST_PAD_SRC,
45     GST_PAD_ALWAYS,
46     GST_STATIC_CAPS ("video/x-raw(" GST_CAPS_FEATURE_MEMORY_CUDA_MEMORY ")"));
47 
48 G_DEFINE_TYPE (GstCudaUpload, gst_cuda_upload, GST_TYPE_CUDA_BASE_TRANSFORM);
49 
50 static GstCaps *gst_cuda_upload_transform_caps (GstBaseTransform * trans,
51     GstPadDirection direction, GstCaps * caps, GstCaps * filter);
52 
53 static void
gst_cuda_upload_class_init(GstCudaUploadClass * klass)54 gst_cuda_upload_class_init (GstCudaUploadClass * klass)
55 {
56   GstElementClass *element_class;
57   GstBaseTransformClass *trans_class;
58 
59   element_class = GST_ELEMENT_CLASS (klass);
60   trans_class = GST_BASE_TRANSFORM_CLASS (klass);
61 
62   gst_element_class_add_static_pad_template (element_class, &sink_template);
63   gst_element_class_add_static_pad_template (element_class, &src_template);
64 
65   gst_element_class_set_static_metadata (element_class,
66       "CUDA uploader", "Filter/Video",
67       "Uploads data into NVIDA GPU via CUDA APIs",
68       "Seungha Yang <seungha.yang@navercorp.com>");
69 
70   trans_class->passthrough_on_same_caps = TRUE;
71 
72   trans_class->transform_caps =
73       GST_DEBUG_FUNCPTR (gst_cuda_upload_transform_caps);
74 
75   gst_type_mark_as_plugin_api (GST_TYPE_CUDA_BASE_TRANSFORM, 0);
76   GST_DEBUG_CATEGORY_INIT (gst_cuda_upload_debug,
77       "cudaupload", 0, "cudaupload Element");
78 }
79 
80 static void
gst_cuda_upload_init(GstCudaUpload * upload)81 gst_cuda_upload_init (GstCudaUpload * upload)
82 {
83 }
84 
85 static GstCaps *
_set_caps_features(const GstCaps * caps,const gchar * feature_name)86 _set_caps_features (const GstCaps * caps, const gchar * feature_name)
87 {
88   GstCaps *tmp = gst_caps_copy (caps);
89   guint n = gst_caps_get_size (tmp);
90   guint i = 0;
91 
92   for (i = 0; i < n; i++)
93     gst_caps_set_features (tmp, i,
94         gst_caps_features_from_string (feature_name));
95 
96   return tmp;
97 }
98 
99 static GstCaps *
gst_cuda_upload_transform_caps(GstBaseTransform * trans,GstPadDirection direction,GstCaps * caps,GstCaps * filter)100 gst_cuda_upload_transform_caps (GstBaseTransform * trans,
101     GstPadDirection direction, GstCaps * caps, GstCaps * filter)
102 {
103   GstCaps *result, *tmp;
104 
105   GST_DEBUG_OBJECT (trans,
106       "Transforming caps %" GST_PTR_FORMAT " in direction %s", caps,
107       (direction == GST_PAD_SINK) ? "sink" : "src");
108 
109   if (direction == GST_PAD_SINK) {
110     tmp = _set_caps_features (caps, GST_CAPS_FEATURE_MEMORY_CUDA_MEMORY);
111     tmp = gst_caps_merge (gst_caps_ref (caps), tmp);
112   } else {
113     GstCaps *newcaps;
114     tmp = gst_caps_ref (caps);
115 
116     newcaps = _set_caps_features (caps, GST_CAPS_FEATURE_MEMORY_SYSTEM_MEMORY);
117     tmp = gst_caps_merge (tmp, newcaps);
118   }
119 
120   if (filter) {
121     result = gst_caps_intersect_full (filter, tmp, GST_CAPS_INTERSECT_FIRST);
122     gst_caps_unref (tmp);
123   } else {
124     result = tmp;
125   }
126 
127   GST_DEBUG_OBJECT (trans, "returning caps: %" GST_PTR_FORMAT, result);
128 
129   return result;
130 }
131