Advertisement
Guest User

Untitled

a guest
Aug 24th, 2019
98
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 13.39 KB | None | 0 0
  1. /**
  2. * SECTION:element-myfilter
  3. *
  4. * FIXME:Describe myfilter here.
  5. *
  6. * <refsect2>
  7. * <title>Example launch line</title>
  8. * |[
  9. * gst-launch -v -m fakesrc ! myfilter ! fakesink silent=TRUE
  10. * ]|
  11. * </refsect2>
  12. */
  13.  
  14. #ifdef HAVE_CONFIG_H
  15. # include <config.h>
  16. #endif
  17.  
  18. #include <gst/gst.h>
  19.  
  20. #include "gstmyfilter.h"
  21.  
  22. GST_DEBUG_CATEGORY_STATIC (gst_my_filter_debug);
  23. #define GST_CAT_DEFAULT gst_my_filter_debug
  24.  
  25. /* Filter signals and args */
  26. enum
  27. {
  28. /* FILL ME */
  29. LAST_SIGNAL
  30. };
  31.  
  32. enum
  33. {
  34. PROP_0,
  35. PROP_SILENT
  36. };
  37.  
  38. /* the capabilities of the inputs and outputs.
  39. *
  40. * describe the real formats here.
  41. */
  42. static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ("sink",
  43. GST_PAD_SINK,
  44. GST_PAD_ALWAYS,
  45. GST_STATIC_CAPS ("ANY")
  46. );
  47.  
  48. static GstStaticPadTemplate src_factory = GST_STATIC_PAD_TEMPLATE ("src",
  49. GST_PAD_SRC,
  50. GST_PAD_ALWAYS,
  51. GST_STATIC_CAPS ("ANY")
  52. );
  53.  
  54. static GstStaticPadTemplate src2_factory =
  55. GST_STATIC_PAD_TEMPLATE (
  56. "src2",
  57. GST_PAD_SRC,
  58. GST_PAD_REQUEST,
  59. GST_STATIC_CAPS (
  60. "video/x-raw, "
  61. "format=(string)RGB, "
  62. "width = (int) [1, 2147483647], "
  63. "height = (int)[1, 2147483647], "
  64. "framerate = (fraction) [0/1, 2147483647/1]"
  65. )
  66. );
  67.  
  68. #define gst_my_filter_parent_class parent_class
  69. G_DEFINE_TYPE (GstMyFilter, gst_my_filter, GST_TYPE_ELEMENT);
  70.  
  71. static void gst_my_filter_set_property (GObject * object, guint prop_id,
  72. const GValue * value, GParamSpec * pspec);
  73. static void gst_my_filter_get_property (GObject * object, guint prop_id,
  74. GValue * value, GParamSpec * pspec);
  75.  
  76. static gboolean gst_my_filter_sink_event (GstPad * pad, GstObject * parent, GstEvent * event);
  77. static GstFlowReturn gst_my_filter_chain (GstPad * pad, GstObject * parent, GstBuffer * buf);
  78.  
  79. static gboolean gst_my_filter_src_event (GstPad * pad, GstObject * parent, GstEvent * event);
  80. static gboolean gst_my_filter_query (GstPad *pad, GstObject * parent, GstQuery * query);
  81. static GstPad * gst_my_filter_request_new_pad (GstElement *element, GstPadTemplate *templ, const gchar *name, const GstCaps *caps);
  82. static void gst_my_filter_release_pad (GstElement *element, GstPad *pad);
  83.  
  84. /* GObject vmethod implementations */
  85.  
  86. /* initialize the myfilter's class */
  87. static void
  88. gst_my_filter_class_init (GstMyFilterClass * klass)
  89. {
  90. GObjectClass *gobject_class;
  91. GstElementClass *gstelement_class;
  92.  
  93. gobject_class = (GObjectClass *) klass;
  94. gstelement_class = (GstElementClass *) klass;
  95.  
  96. gobject_class->set_property = gst_my_filter_set_property;
  97. gobject_class->get_property = gst_my_filter_get_property;
  98.  
  99. g_object_class_install_property (gobject_class, PROP_SILENT,
  100. g_param_spec_boolean ("silent", "Silent", "Produce verbose output ?",
  101. FALSE, G_PARAM_READWRITE));
  102.  
  103. gst_element_class_set_details_simple(gstelement_class,
  104. "MyFilter",
  105. "FIXME:Generic",
  106. "FIXME:Generic Template Element",
  107. "HarshAggarwal <<user@hostname.org>>");
  108.  
  109. gst_element_class_add_pad_template (gstelement_class,
  110. gst_static_pad_template_get (&src_factory));
  111. gst_element_class_add_pad_template (gstelement_class,
  112. gst_static_pad_template_get (&sink_factory));
  113.  
  114. gst_element_class_add_pad_template (gstelement_class,
  115. gst_static_pad_template_get (&src2_factory));
  116.  
  117. gstelement_class->request_new_pad = gst_my_filter_request_new_pad;
  118. gstelement_class->release_pad = gst_my_filter_release_pad;
  119. }
  120.  
  121. /* initialize the new element
  122. * instantiate pads and add them to element
  123. * set pad calback functions
  124. * initialize instance structure
  125. */
  126. static void
  127. gst_my_filter_init (GstMyFilter * filter)
  128. {
  129. filter->sinkpad = gst_pad_new_from_static_template (&sink_factory, "sink");
  130. gst_pad_set_event_function (filter->sinkpad,
  131. GST_DEBUG_FUNCPTR(gst_my_filter_sink_event));
  132. gst_pad_set_chain_function (filter->sinkpad,
  133. GST_DEBUG_FUNCPTR(gst_my_filter_chain));
  134. GST_PAD_SET_PROXY_CAPS (filter->sinkpad);
  135. gst_element_add_pad (GST_ELEMENT (filter), filter->sinkpad);
  136.  
  137. filter->srcpad = gst_pad_new_from_static_template (&src_factory, "src");
  138. GST_PAD_SET_PROXY_CAPS (filter->srcpad);
  139. gst_element_add_pad (GST_ELEMENT (filter), filter->srcpad);
  140.  
  141. filter->silent = FALSE;
  142. }
  143.  
  144. static void
  145. gst_my_filter_set_property (GObject * object, guint prop_id,
  146. const GValue * value, GParamSpec * pspec)
  147. {
  148. GstMyFilter *filter = GST_MYFILTER (object);
  149.  
  150. switch (prop_id) {
  151. case PROP_SILENT:
  152. filter->silent = g_value_get_boolean (value);
  153. break;
  154. default:
  155. G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
  156. break;
  157. }
  158. }
  159.  
  160. static void
  161. gst_my_filter_get_property (GObject * object, guint prop_id,
  162. GValue * value, GParamSpec * pspec)
  163. {
  164. GstMyFilter *filter = GST_MYFILTER (object);
  165.  
  166. switch (prop_id) {
  167. case PROP_SILENT:
  168. g_value_set_boolean (value, filter->silent);
  169. break;
  170. default:
  171. G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
  172. break;
  173. }
  174. }
  175.  
  176. static GstPad *
  177. gst_my_filter_request_new_pad (GstElement *element,
  178. GstPadTemplate *templ,
  179. const gchar *name,
  180. const GstCaps *caps)
  181. {
  182. GstMyFilter *filter = GST_MYFILTER (element);
  183. GstMyFilterInputContext *context;
  184.  
  185. context = g_new0 (GstMyFilterInputContext, 1);
  186. context->width = 100;
  187. context->height = 100;
  188. context->bpp = 4;
  189.  
  190. filter->src2pad = gst_pad_new_from_static_template (&src2_factory, "src2");
  191.  
  192. // GST_PAD_SET_PROXY_CAPS (filter->src2pad);
  193. // gst_pad_use_fixed_caps(filter->src2pad);//use_fixed_caps
  194.  
  195. gst_pad_set_element_private (filter->src2pad, context);
  196.  
  197. gst_pad_set_event_function (filter->src2pad,
  198. GST_DEBUG_FUNCPTR(gst_my_filter_src_event));
  199. gst_pad_set_query_function (filter->src2pad,
  200. GST_DEBUG_FUNCPTR(gst_my_filter_query));
  201. gst_element_add_pad (element, filter->src2pad);
  202.  
  203. return filter->src2pad;
  204. }
  205.  
  206. static void
  207. gst_my_filter_release_pad (GstElement *element,
  208. GstPad *pad)
  209. {
  210. GstMyFilterInputContext *context;
  211.  
  212. g_print("%s:%d --------------- \n", __func__, __LINE__);
  213. context = gst_pad_get_element_private (pad);
  214. g_free (context);
  215.  
  216. gst_element_remove_pad (element, pad);
  217. }
  218.  
  219. /* GstElement vmethod implementations */
  220.  
  221. /* this function handles sink events */
  222. static gboolean
  223. gst_my_filter_sink_event (GstPad * pad, GstObject * parent, GstEvent * event)
  224. {
  225. GstMyFilter *filter;
  226. gboolean ret;
  227.  
  228. filter = GST_MYFILTER (parent);
  229.  
  230. GST_LOG_OBJECT (filter, "Received %s event: %" GST_PTR_FORMAT,
  231. GST_EVENT_TYPE_NAME (event), event);
  232.  
  233. switch (GST_EVENT_TYPE (event)) {
  234. case GST_EVENT_CAPS:
  235. {
  236. GstCaps * caps;
  237.  
  238. gst_event_parse_caps (event, &caps);
  239. /* do something with the caps */
  240.  
  241. /* and forward */
  242. ret = gst_pad_event_default (pad, parent, event);
  243. break;
  244. }
  245. default:
  246. ret = gst_pad_event_default (pad, parent, event);
  247. break;
  248. }
  249. return ret;
  250. }
  251.  
  252. /* chain function
  253. * this function does the actual processing
  254. */
  255. static GstFlowReturn
  256. gst_my_filter_chain (GstPad * pad, GstObject * parent, GstBuffer * buf)
  257. {
  258. GstMyFilter *filter;
  259. GstFlowReturn ret;
  260. GstBuffer *buffer;
  261. guint size;
  262.  
  263. filter = GST_MYFILTER (parent);
  264.  
  265. if (filter->silent == FALSE)
  266. g_print ("I'm plugged, therefore I'm in.\n");
  267.  
  268. ret = gst_pad_push (filter->srcpad, buf);
  269.  
  270. if (filter->src2pad) {
  271. #if 1
  272. GstMyFilterInputContext *context;
  273. context = gst_pad_get_element_private (filter->src2pad);
  274. GST_DEBUG_OBJECT (filter->src2pad, "push hello");
  275.  
  276.  
  277. GstCaps *outcaps;
  278. outcaps = gst_caps_new_simple ("video/x-raw",
  279. "format", G_TYPE_STRING, "RGB",
  280. "width", G_TYPE_INT, 300,
  281. "height", G_TYPE_INT, 300,
  282. "framerate", GST_TYPE_FRACTION, 24, 1, NULL);
  283. ret = gst_pad_set_caps (filter->src2pad, outcaps);
  284.  
  285.  
  286.  
  287.  
  288. ret = gst_pad_push (filter->src2pad, gst_buffer_ref(buf));
  289. size = context->width * context->height * context->bpp;
  290. buffer = gst_buffer_new_and_alloc (size);
  291.  
  292. ret = gst_pad_push (filter->src2pad, buffer);
  293. #else
  294.  
  295. ret = gst_pad_push (filter->src2pad, gst_buffer_ref(buf));
  296. #endif
  297. }
  298. /* just push out the incoming buffer without touching it */
  299. return ret;
  300. }
  301.  
  302. /* Functions below print the Capabilities in a human-friendly format */
  303. static gboolean
  304. print_field (GQuark field, const GValue * value, gpointer pfx)
  305. {
  306. gchar *str = gst_value_serialize (value);
  307.  
  308. g_print (" %15s: %s\n", g_quark_to_string (field), str);
  309. g_free (str);
  310. return TRUE;
  311. }
  312.  
  313. static gboolean
  314. gst_my_filter_setcaps (GstMyFilter *filter,
  315. GstCaps *caps)
  316. {
  317. GstStructure *structure;
  318. int width, height;
  319. gboolean ret;
  320. GstCaps *outcaps;
  321.  
  322. #if 0
  323. g_print("%s:%d --SET CAPS------------- \n", __func__, __LINE__);
  324. structure = gst_caps_get_structure (caps, 0);
  325. ret = gst_structure_get_int (structure, "width", &width);
  326. ret = ret && gst_structure_get_int (structure, "height", &height);
  327. if (!ret) {
  328. GST_LOG_OBJECT (filter, "Hello error ----------<<<<< \n");
  329. return FALSE;
  330. }
  331.  
  332. #endif
  333. outcaps = gst_caps_new_simple ("video/x-raw",
  334. "format", G_TYPE_STRING, "RGB",
  335. "width", G_TYPE_INT, 300,
  336. "height", G_TYPE_INT, 300,
  337. "framerate", GST_TYPE_FRACTION, 24, 1, NULL);
  338. ret = gst_pad_set_caps (filter->src2pad, outcaps);
  339. gst_caps_unref (outcaps);
  340.  
  341. return ret;
  342. }
  343.  
  344. static gboolean
  345. gst_my_filter_query (GstPad *pad, GstObject * parent, GstQuery * query)
  346. {
  347. gboolean ret;
  348. GstMyFilter *filter = GST_MYFILTER (parent);
  349.  
  350.  
  351. switch (GST_QUERY_TYPE (query)) {
  352. case GST_QUERY_CAPS:
  353. {
  354. g_print("%s:%d --------------- \n", __func__, __LINE__);
  355. #if 0
  356. GstPad *otherpad;
  357. GstCaps *temp, *caps, *filt, *tcaps;
  358. gint i;
  359.  
  360. otherpad = (pad == filter->srcpad) ? filter->sinkpad :
  361. filter->srcpad;
  362. caps = gst_pad_get_allowed_caps (otherpad);
  363.  
  364. gst_query_parse_caps (query, &filt);
  365.  
  366. /* We support *any* samplerate, indifferent from the samplerate
  367. * supported by the linked elements on both sides. */
  368. for (i = 0; i < gst_caps_get_size (caps); i++) {
  369. GstStructure *structure = gst_caps_get_structure (caps, i);
  370.  
  371. gst_structure_remove_field (structure, "rate");
  372. }
  373.  
  374. /* make sure we only return results that intersect our
  375. * padtemplate */
  376. tcaps = gst_pad_get_pad_template_caps (pad);
  377. if (tcaps) {
  378. temp = gst_caps_intersect (caps, tcaps);
  379. gst_caps_unref (caps);
  380. gst_caps_unref (tcaps);
  381. caps = temp;
  382. }
  383. /* filter against the query filter when needed */
  384. if (filt) {
  385. temp = gst_caps_intersect (caps, filt);
  386. gst_caps_unref (caps);
  387. caps = temp;
  388. }
  389. gst_query_set_caps_result (query, caps);
  390. gst_caps_unref (caps);
  391.  
  392. #else
  393.  
  394. GstCaps *outcaps;
  395. outcaps = gst_caps_new_simple ("video/x-raw",
  396. "width", G_TYPE_INT, 300,
  397. "height", G_TYPE_INT, 300,
  398. "format", G_TYPE_STRING, "RGB",
  399. "framerate", GST_TYPE_FRACTION, 24, 1, NULL);
  400.  
  401. if (!gst_pad_set_caps (filter->src2pad, outcaps)) {
  402. GST_ELEMENT_ERROR (filter, CORE, NEGOTIATION, (NULL),
  403. ("Some debug information here"));
  404. }
  405.  
  406. gst_caps_unref(outcaps);
  407. #endif
  408. ret = TRUE;
  409. break;
  410. }
  411. default:
  412. ret = gst_pad_query_default (pad, parent, query);
  413. break;
  414. }
  415. return ret;
  416. }
  417.  
  418. /* this function handles sink events */
  419. static gboolean
  420. gst_my_filter_src_event (GstPad * pad, GstObject * parent, GstEvent * event)
  421. {
  422. GstMyFilter *filter;
  423. gboolean ret;
  424.  
  425. filter = GST_MYFILTER (parent);
  426.  
  427. g_print("==EVENT===============>>> %s:%d --------------- \n", __func__, __LINE__);
  428. GST_LOG_OBJECT (filter, "Received %s event: %" GST_PTR_FORMAT,
  429. GST_EVENT_TYPE_NAME (event), event);
  430.  
  431. switch (GST_EVENT_TYPE (event)) {
  432. case GST_EVENT_CAPS:
  433. {
  434. GstCaps * caps;
  435.  
  436. gst_event_parse_caps (event, &caps);
  437. /* do something with the caps */
  438. #if 0
  439. GstStructure *structure = gst_caps_get_structure(caps, 0);
  440. g_assert(structure);
  441. g_print ("%s\n", gst_structure_get_name (structure));
  442. gst_structure_foreach (structure, print_field, (gpointer) NULL);
  443.  
  444. // const gchar *format = gst_structure_get_string(structure, "format");
  445. //#else
  446.  
  447. ret = gst_my_filter_setcaps (filter, caps);
  448. #endif
  449.  
  450. /* and forward */
  451. ret = gst_pad_event_default (pad, parent, event);
  452. break;
  453. }
  454. default:
  455. ret = gst_pad_event_default (pad, parent, event);
  456. break;
  457. }
  458. return ret;
  459. }
  460.  
  461. /* entry point to initialize the plug-in
  462. * initialize the plug-in itself
  463. * register the element factories and other features
  464. */
  465. static gboolean
  466. myfilter_init (GstPlugin * myfilter)
  467. {
  468. /* debug category for fltering log messages
  469. *
  470. * exchange the string 'Template myfilter' with your description
  471. */
  472. GST_DEBUG_CATEGORY_INIT (gst_my_filter_debug, "myfilter",
  473. 0, "Template myfilter");
  474.  
  475. return gst_element_register (myfilter, "myfilter", GST_RANK_NONE,
  476. GST_TYPE_MYFILTER);
  477. }
  478.  
  479. /* PACKAGE: this is usually set by autotools depending on some _INIT macro
  480. * in configure.ac and then written into and defined in config.h, but we can
  481. * just set it ourselves here in case someone doesn't use autotools to
  482. * compile this code. GST_PLUGIN_DEFINE needs PACKAGE to be defined.
  483. */
  484. #ifndef PACKAGE
  485. #define PACKAGE "myfirstmyfilter"
  486. #endif
  487.  
  488. /* gstreamer looks for this structure to register myfilters
  489. *
  490. * exchange the string 'Template myfilter' with your myfilter description
  491. */
  492. GST_PLUGIN_DEFINE (
  493. GST_VERSION_MAJOR,
  494. GST_VERSION_MINOR,
  495. myfilter,
  496. "Template myfilter",
  497. myfilter_init,
  498. PACKAGE_VERSION,
  499. GST_LICENSE,
  500. GST_PACKAGE_NAME,
  501. GST_PACKAGE_ORIGIN
  502. )
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement