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