blob: 585007a82904fcd399865733641d67991d8cb18d [file] [log] [blame]
Tao Guo4b629462020-04-03 13:01:07 +08001/*
2 * gstdummydrm.c
3 *
4 * Created on: 2020年4月1日
5 * Author: tao
6 */
7
8
9#ifdef HAVE_CONFIG_H
10# include <config.h>
11#endif
12#include <stdbool.h>
13#include "gstdummydrm.h"
14#include "gstsecmemallocator.h"
15
16
17
18GST_DEBUG_CATEGORY_STATIC (gst_dummydrm_debug);
19#define GST_CAT_DEFAULT gst_dummydrm_debug
20
21static GstStaticPadTemplate sinktemplate = GST_STATIC_PAD_TEMPLATE ("sink",
22 GST_PAD_SINK,
23 GST_PAD_ALWAYS,
24 GST_STATIC_CAPS_ANY);
25
26static GstStaticPadTemplate srctemplate = GST_STATIC_PAD_TEMPLATE ("src",
27 GST_PAD_SRC,
28 GST_PAD_SOMETIMES,
29 GST_STATIC_CAPS_ANY);
30
31
32#define gst_dummydrm_parent_class parent_class
33G_DEFINE_TYPE(GstDummyDrm, gst_dummydrm, GST_TYPE_BASE_TRANSFORM);
34
35static void gst_dummydrm_set_property(GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec);
36static void gst_dummydrm_get_property(GObject * object, guint prop_id, GValue * value, GParamSpec * pspec);
37static gboolean gst_dummydrm_start(GstBaseTransform *trans);
38static gboolean gst_dummydrm_stop(GstBaseTransform *trans);
39static GstCaps* gst_dummydrm_transform_caps(GstBaseTransform *trans, GstPadDirection direction, GstCaps *caps, GstCaps *filter);
40static GstFlowReturn gst_dummydrm_prepare_output_buffer(GstBaseTransform * trans, GstBuffer *input, GstBuffer **outbuf);
41static GstFlowReturn gst_dummydrm_transform(GstBaseTransform *trans, GstBuffer *inbuf, GstBuffer *outbuf);
42
43
44static void
45gst_dummydrm_class_init (GstDummyDrmClass * klass)
46{
47 GObjectClass *gobject_class = (GObjectClass *) klass;
48 GstElementClass *element_class = (GstElementClass *) klass;
49 GstBaseTransformClass *base_class = GST_BASE_TRANSFORM_CLASS(klass);
50
51 gobject_class->set_property = gst_dummydrm_set_property;
52 gobject_class->get_property = gst_dummydrm_get_property;
53 base_class->start = GST_DEBUG_FUNCPTR(gst_dummydrm_start);
54 base_class->stop = GST_DEBUG_FUNCPTR(gst_dummydrm_stop);
55 base_class->transform_caps = GST_DEBUG_FUNCPTR(gst_dummydrm_transform_caps);
56 base_class->transform = GST_DEBUG_FUNCPTR(gst_dummydrm_transform);
57 base_class->prepare_output_buffer = GST_DEBUG_FUNCPTR(gst_dummydrm_prepare_output_buffer);
58 base_class->passthrough_on_same_caps = FALSE;
59 base_class->transform_ip_on_passthrough = FALSE;
60
61 gst_element_class_add_pad_template (element_class,
62 gst_static_pad_template_get (&sinktemplate));
63 gst_element_class_add_pad_template (element_class,
64 gst_static_pad_template_get (&srctemplate));
65
66 gst_element_class_set_details_simple(element_class,
67 "Amlogic Dummy DRM Plugin",
68 "Filter/DRM/Dummy",
69 "DRM Decryption Plugin",
70 "mm@amlogic.com");
71}
72
73static void
74gst_dummydrm_init(GstDummyDrm * plugin)
75{
76 GstBaseTransform *base = GST_BASE_TRANSFORM (plugin);
77 gst_base_transform_set_passthrough (base, FALSE);
78
79 plugin->allocator = NULL;
80 plugin->outcaps = NULL;
81
82}
83
84void
85gst_dummydrm_set_property(GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec)
86{
87 //TODO
88}
89
90void
91gst_dummydrm_get_property(GObject * object, guint prop_id, GValue * value, GParamSpec * pspec)
92{
93 //TODO
94}
95
96gboolean
97gst_dummydrm_start(GstBaseTransform *trans)
98{
99 GstDummyDrm *plugin = GST_DUMMYDRM(trans);
100
101
102 return TRUE;
103}
104gboolean
105gst_dummydrm_stop(GstBaseTransform *trans)
106{
107 GstDummyDrm *plugin = GST_DUMMYDRM(trans);
108
109 if (plugin->allocator) {
110 gst_object_unref(plugin->allocator);
111 }
112 if (plugin->outcaps) {
113 gst_caps_unref(plugin->outcaps);
114 }
115 return TRUE;
116}
117
118GstCaps*
119gst_dummydrm_transform_caps(GstBaseTransform *trans, GstPadDirection direction,
120 GstCaps *caps, GstCaps *filter)
121{
122 GstDummyDrm *plugin = GST_DUMMYDRM(trans);
123 GstCaps *srccaps, *sinkcaps;
124 GstCaps *ret = NULL;
125
126 GST_DEBUG_OBJECT (plugin, "transform_caps direction:%d caps:%" GST_PTR_FORMAT, direction, caps);
127
128 srccaps = gst_pad_get_pad_template_caps(GST_BASE_TRANSFORM_SRC_PAD(trans));
129 sinkcaps = gst_pad_get_pad_template_caps(GST_BASE_TRANSFORM_SINK_PAD(trans));
130
131 switch (direction) {
132 case GST_PAD_SINK:
133 {
134 if (gst_caps_can_intersect(caps, sinkcaps)) {
135 gboolean find = false;
136 unsigned size;
137
138 ret = gst_caps_copy(caps);
139 size = gst_caps_get_size(ret);
140 for (unsigned i = 0; i < size; ++i) {
141 GstStructure *structure;
142 structure = gst_caps_get_structure(caps, i);
143 if (g_str_has_prefix (gst_structure_get_name (structure), "video/")) {
144 find = true;
145 gst_caps_set_features(ret, i,
146 gst_caps_features_from_string (GST_CAPS_FEATURE_MEMORY_SECMEM_MEMORY));
147 }
148 }
149 if (find) {
150 if (!plugin->allocator) {
Song Zhao24687592020-04-14 17:24:50 -0700151 plugin->allocator = gst_secmem_allocator_new(false, false);
Tao Guo4b629462020-04-03 13:01:07 +0800152 }
153 if (plugin->outcaps) {
154 gst_caps_unref(plugin->outcaps);
155 }
156
157 plugin->outcaps = gst_caps_ref(ret);
158 } else {
159 gst_caps_unref(ret);
160 ret = gst_caps_copy(sinkcaps);
161 }
162 } else {
163 ret = gst_caps_copy(sinkcaps);
164 }
165 break;
166 }
167 case GST_PAD_SRC:
168 if (gst_caps_can_intersect(caps, srccaps)) {
169 ret = gst_caps_copy(caps);
170 unsigned size = gst_caps_get_size(ret);
171 for (unsigned i = 0; i < size; ++i) {
xuesong.jiangf22c5d02022-12-26 15:46:08 +0800172 GstCapsFeatures * feature = gst_caps_get_features(ret, i);
173 gst_caps_features_remove(feature, GST_CAPS_FEATURE_MEMORY_SECMEM_MEMORY);
Tao Guo4b629462020-04-03 13:01:07 +0800174 }
175 } else {
176 ret = gst_caps_copy(srccaps);
177 }
178 break;
179 default:
180 g_assert_not_reached();
181 }
182
183 if (filter) {
184 GstCaps *intersection;
185 intersection = gst_caps_intersect_full(filter, ret, GST_CAPS_INTERSECT_FIRST);
186 gst_caps_unref(ret);
187 ret = intersection;
188 }
189
190 GST_DEBUG_OBJECT (plugin, "transform_caps result:%" GST_PTR_FORMAT, ret);
191
192 gst_caps_unref(srccaps);
193 gst_caps_unref(sinkcaps);
194 return ret;
195}
196
197GstFlowReturn
198gst_dummydrm_prepare_output_buffer(GstBaseTransform * trans, GstBuffer *inbuf, GstBuffer **outbuf)
199{
200 GstDummyDrm *plugin = GST_DUMMYDRM(trans);
201 GstFlowReturn ret = GST_FLOW_OK;
202
203 g_return_val_if_fail(plugin->allocator != NULL, GST_FLOW_ERROR);
204
205 *outbuf = gst_buffer_new_allocate(plugin->allocator, gst_buffer_get_size(inbuf), NULL);
206
207 g_return_val_if_fail(*outbuf != NULL, GST_FLOW_ERROR);
Tao Guo8222b1d2020-09-17 14:56:54 +0800208 GST_BASE_TRANSFORM_CLASS(parent_class)->copy_metadata (trans, inbuf, *outbuf);
Tao Guo4b629462020-04-03 13:01:07 +0800209 return ret;
210}
211
212static GstFlowReturn
213gst_dummydrm_transform(GstBaseTransform *trans, GstBuffer *inbuf, GstBuffer *outbuf)
214{
215 GstFlowReturn ret = GST_FLOW_ERROR;
216 GstMapInfo map;
217 GstMemory *mem;
218 gsize size;
219
220 mem = gst_buffer_peek_memory(outbuf, 0);
221 g_return_val_if_fail(gst_is_secmem_memory(mem), ret);
222
223 gst_memory_get_sizes(mem, NULL, &size);
224 gst_buffer_map(inbuf, &map, GST_MAP_READ);
225 if (map.size > size) {
226 GST_ERROR("buffer size not match");
227 goto beach;
228 }
229 gst_secmem_fill(mem, 0, map.data, map.size);
230 ret = GST_FLOW_OK;
231beach:
232 gst_buffer_unmap(inbuf, &map);
233 return ret;
234}
235
236#ifndef PACKAGE
237#define PACKAGE "gst-aml-drm-plugins"
238#endif
239
240static gboolean
241dummydrm_init (GstPlugin * dummydrm)
242{
243 GST_DEBUG_CATEGORY_INIT(gst_dummydrm_debug, "dummydrm", 0, "Amlogic Dummy DRM Plugin");
244
245 return gst_element_register(dummydrm, "dummydrm", GST_RANK_PRIMARY, GST_TYPE_DUMMYDRM);
246}
247
248
249GST_PLUGIN_DEFINE(
250 GST_VERSION_MAJOR,
251 GST_VERSION_MINOR,
252 dummydrm,
253 "Gstreamer Dummy Drm plugin",
254 dummydrm_init,
255 VERSION,
256 "LGPL",
257 "gst-aml-drm-plugins",
258 "http://amlogic.com/"
259)