blob: 219f584a75cab460ef82e6458b213dba027c2c15 [file] [log] [blame]
David Schleefe9ea2372010-10-09 15:08:39 -07001/* GStreamer
2 * Copyright (C) 2010 David Schleef <ds@schleef.org>
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
Tim-Philipp Müller9e1b75f2012-11-03 20:38:00 +000016 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
17 * Boston, MA 02110-1301, USA.
David Schleefe9ea2372010-10-09 15:08:39 -070018 */
19/**
20 * SECTION:element-gstdiracparse
Thibault Saunier78022a62017-03-08 15:01:13 -030021 * @title: gstdiracparse
David Schleefe9ea2372010-10-09 15:08:39 -070022 *
23 * The gstdiracparse element does FIXME stuff.
24 *
Thibault Saunier78022a62017-03-08 15:01:13 -030025 * ## Example launch line
David Schleefe9ea2372010-10-09 15:08:39 -070026 * |[
Vineeth TM7c42ba92015-12-14 11:09:46 +090027 * gst-launch-1.0 -v fakesrc ! gstdiracparse ! FIXME ! fakesink
David Schleefe9ea2372010-10-09 15:08:39 -070028 * ]|
29 * FIXME Describe what the pipeline does.
Thibault Saunier78022a62017-03-08 15:01:13 -030030 *
David Schleefe9ea2372010-10-09 15:08:39 -070031 */
32
33#ifdef HAVE_CONFIG_H
34#include "config.h"
35#endif
36
37#include <gst/gst.h>
Sebastian Drögee65b9b92013-12-16 10:13:36 +010038#include <gst/base/base.h>
39#include <gst/pbutils/pbutils.h>
David Schleeff21e36b2011-07-04 16:18:18 -070040#include <string.h>
David Schleefe9ea2372010-10-09 15:08:39 -070041#include "gstdiracparse.h"
David Schleeff21e36b2011-07-04 16:18:18 -070042#include "dirac_parse.h"
David Schleefe9ea2372010-10-09 15:08:39 -070043
44/* prototypes */
45
46
47static void gst_dirac_parse_set_property (GObject * object,
48 guint property_id, const GValue * value, GParamSpec * pspec);
49static void gst_dirac_parse_get_property (GObject * object,
50 guint property_id, GValue * value, GParamSpec * pspec);
51static void gst_dirac_parse_dispose (GObject * object);
52static void gst_dirac_parse_finalize (GObject * object);
53
54static gboolean gst_dirac_parse_start (GstBaseParse * parse);
55static gboolean gst_dirac_parse_stop (GstBaseParse * parse);
56static gboolean gst_dirac_parse_set_sink_caps (GstBaseParse * parse,
57 GstCaps * caps);
Edward Herveyb78b9802011-11-25 12:48:58 +010058static GstCaps *gst_dirac_parse_get_sink_caps (GstBaseParse * parse,
59 GstCaps * filter);
Mark Nauwelaertsb10b9cf2012-02-13 18:44:01 +010060static GstFlowReturn gst_dirac_parse_handle_frame (GstBaseParse * parse,
61 GstBaseParseFrame * frame, gint * skipsize);
David Schleefe9ea2372010-10-09 15:08:39 -070062static gboolean gst_dirac_parse_convert (GstBaseParse * parse,
63 GstFormat src_format, gint64 src_value, GstFormat dest_format,
64 gint64 * dest_value);
David Schleefe9ea2372010-10-09 15:08:39 -070065static GstFlowReturn gst_dirac_parse_pre_push_frame (GstBaseParse * parse,
66 GstBaseParseFrame * frame);
67
68enum
69{
70 PROP_0
71};
72
73/* pad templates */
74
75static GstStaticPadTemplate gst_dirac_parse_sink_template =
76GST_STATIC_PAD_TEMPLATE ("sink",
77 GST_PAD_SINK,
78 GST_PAD_ALWAYS,
Sebastian Dröge2adf76e2011-09-07 11:22:07 +020079 GST_STATIC_CAPS ("video/x-dirac")
David Schleefe9ea2372010-10-09 15:08:39 -070080 );
81
82static GstStaticPadTemplate gst_dirac_parse_src_template =
83GST_STATIC_PAD_TEMPLATE ("src",
84 GST_PAD_SRC,
85 GST_PAD_ALWAYS,
Sebastian Dröge89aa5da2011-09-07 11:24:14 +020086 GST_STATIC_CAPS ("video/x-dirac, parsed=(boolean)TRUE, "
87 "width=(int)[1,MAX], height=(int)[1,MAX], "
88 "framerate=(fraction)[0/1,MAX], "
89 "pixel-aspect-ratio=(fraction)[0/1,MAX], "
Tim-Philipp Müller0ff01fa2012-09-03 12:41:33 +010090 "interlace-mode=(string) { progressive, interleaved }, "
Tim-Philipp Müller39ca8d02012-09-03 12:33:51 +010091 "profile=(string){ vc2-low-delay, vc2-simple, vc2-main, main }, "
92 "level=(string) { 0, 1, 128}")
David Schleefe9ea2372010-10-09 15:08:39 -070093 );
94
95/* class initialization */
96
René Stadlere6df0b62011-11-24 12:01:48 +010097#define parent_class gst_dirac_parse_parent_class
98G_DEFINE_TYPE (GstDiracParse, gst_dirac_parse, GST_TYPE_BASE_PARSE);
David Schleefe9ea2372010-10-09 15:08:39 -070099
100static void
René Stadlere6df0b62011-11-24 12:01:48 +0100101gst_dirac_parse_class_init (GstDiracParseClass * klass)
David Schleefe9ea2372010-10-09 15:08:39 -0700102{
René Stadlere6df0b62011-11-24 12:01:48 +0100103 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
104 GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
105 GstBaseParseClass *base_parse_class = GST_BASE_PARSE_CLASS (klass);
106
107 gobject_class->set_property = gst_dirac_parse_set_property;
108 gobject_class->get_property = gst_dirac_parse_get_property;
109 gobject_class->dispose = gst_dirac_parse_dispose;
110 gobject_class->finalize = gst_dirac_parse_finalize;
David Schleefe9ea2372010-10-09 15:08:39 -0700111
Vineeth TM8cdfb132016-03-04 15:50:26 +0900112 gst_element_class_add_static_pad_template (element_class,
113 &gst_dirac_parse_src_template);
114 gst_element_class_add_static_pad_template (element_class,
115 &gst_dirac_parse_sink_template);
David Schleefe9ea2372010-10-09 15:08:39 -0700116
Tim-Philipp Müller32ba17c2012-10-17 17:34:26 +0100117 gst_element_class_set_static_metadata (element_class, "Dirac parser",
Sebastian Dröge935675a2011-03-11 14:37:06 +0100118 "Codec/Parser/Video", "Parses Dirac streams",
119 "David Schleef <ds@schleef.org>");
David Schleefe9ea2372010-10-09 15:08:39 -0700120
David Schleefe9ea2372010-10-09 15:08:39 -0700121 base_parse_class->start = GST_DEBUG_FUNCPTR (gst_dirac_parse_start);
122 base_parse_class->stop = GST_DEBUG_FUNCPTR (gst_dirac_parse_stop);
123 base_parse_class->set_sink_caps =
124 GST_DEBUG_FUNCPTR (gst_dirac_parse_set_sink_caps);
Sebastian Drögeb10c1f22011-11-24 10:08:27 +0100125 base_parse_class->get_sink_caps =
126 GST_DEBUG_FUNCPTR (gst_dirac_parse_get_sink_caps);
Mark Nauwelaertsb10b9cf2012-02-13 18:44:01 +0100127 base_parse_class->handle_frame =
128 GST_DEBUG_FUNCPTR (gst_dirac_parse_handle_frame);
David Schleefe9ea2372010-10-09 15:08:39 -0700129 base_parse_class->convert = GST_DEBUG_FUNCPTR (gst_dirac_parse_convert);
David Schleefe9ea2372010-10-09 15:08:39 -0700130 base_parse_class->pre_push_frame =
131 GST_DEBUG_FUNCPTR (gst_dirac_parse_pre_push_frame);
132
133}
134
135static void
René Stadlere6df0b62011-11-24 12:01:48 +0100136gst_dirac_parse_init (GstDiracParse * diracparse)
David Schleefe9ea2372010-10-09 15:08:39 -0700137{
138 gst_base_parse_set_min_frame_size (GST_BASE_PARSE (diracparse), 13);
Jan Schmidtb7d63d32012-09-12 22:58:04 -0700139 gst_base_parse_set_pts_interpolation (GST_BASE_PARSE (diracparse), FALSE);
Wim Taymans9ac2cee2013-12-04 09:13:31 +0100140 GST_PAD_SET_ACCEPT_INTERSECT (GST_BASE_PARSE_SINK_PAD (diracparse));
Thiago Santosc4cd1ce2015-08-14 11:43:18 -0300141 GST_PAD_SET_ACCEPT_TEMPLATE (GST_BASE_PARSE_SINK_PAD (diracparse));
David Schleefe9ea2372010-10-09 15:08:39 -0700142}
143
144void
145gst_dirac_parse_set_property (GObject * object, guint property_id,
146 const GValue * value, GParamSpec * pspec)
147{
David Schleefe9ea2372010-10-09 15:08:39 -0700148 g_return_if_fail (GST_IS_DIRAC_PARSE (object));
David Schleefe9ea2372010-10-09 15:08:39 -0700149
150 switch (property_id) {
151 default:
152 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
153 break;
154 }
155}
156
157void
158gst_dirac_parse_get_property (GObject * object, guint property_id,
159 GValue * value, GParamSpec * pspec)
160{
David Schleefe9ea2372010-10-09 15:08:39 -0700161 g_return_if_fail (GST_IS_DIRAC_PARSE (object));
David Schleefe9ea2372010-10-09 15:08:39 -0700162
163 switch (property_id) {
164 default:
165 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
166 break;
167 }
168}
169
170void
171gst_dirac_parse_dispose (GObject * object)
172{
David Schleefe9ea2372010-10-09 15:08:39 -0700173 g_return_if_fail (GST_IS_DIRAC_PARSE (object));
David Schleefe9ea2372010-10-09 15:08:39 -0700174
175 /* clean up as possible. may be called multiple times */
176
177 G_OBJECT_CLASS (parent_class)->dispose (object);
178}
179
180void
181gst_dirac_parse_finalize (GObject * object)
182{
David Schleefe9ea2372010-10-09 15:08:39 -0700183 g_return_if_fail (GST_IS_DIRAC_PARSE (object));
David Schleefe9ea2372010-10-09 15:08:39 -0700184
185 /* clean up object here */
186
187 G_OBJECT_CLASS (parent_class)->finalize (object);
188}
189
190
191static gboolean
192gst_dirac_parse_start (GstBaseParse * parse)
193{
Sebastian Drögee65b9b92013-12-16 10:13:36 +0100194 GstDiracParse *diracparse = GST_DIRAC_PARSE (parse);
195
David Schleeff21e36b2011-07-04 16:18:18 -0700196 gst_base_parse_set_min_frame_size (parse, 13);
197
Sebastian Drögee65b9b92013-12-16 10:13:36 +0100198 diracparse->sent_codec_tag = FALSE;
199
David Schleefe9ea2372010-10-09 15:08:39 -0700200 return TRUE;
201}
202
203static gboolean
204gst_dirac_parse_stop (GstBaseParse * parse)
205{
206 return TRUE;
207}
208
209static gboolean
210gst_dirac_parse_set_sink_caps (GstBaseParse * parse, GstCaps * caps)
211{
212 /* Called when sink caps are set */
213 return TRUE;
214}
215
Tim-Philipp Müller39ca8d02012-09-03 12:33:51 +0100216static const gchar *
217get_profile_name (int profile)
218{
219 switch (profile) {
220 case 0:
221 return "vc2-low-delay";
222 case 1:
223 return "vc2-simple";
224 case 2:
225 return "vc2-main";
Tim-Philipp Müller9e53df72012-09-03 13:58:16 +0100226 case 8:
Tim-Philipp Müller39ca8d02012-09-03 12:33:51 +0100227 return "main";
228 default:
229 break;
230 }
231 return "unknown";
232}
233
234static const gchar *
235get_level_name (int level)
236{
237 switch (level) {
238 case 0:
239 return "0";
240 case 1:
241 return "1";
242 case 128:
243 return "128";
244 default:
245 break;
246 }
247 /* need to add it to template caps, so return 0 for now */
248 GST_WARNING ("unhandled dirac level %u", level);
249 return "0";
250}
251
Mark Nauwelaertsb10b9cf2012-02-13 18:44:01 +0100252static GstFlowReturn
253gst_dirac_parse_handle_frame (GstBaseParse * parse,
254 GstBaseParseFrame * frame, gint * skipsize)
David Schleefe9ea2372010-10-09 15:08:39 -0700255{
David Schleefe9ea2372010-10-09 15:08:39 -0700256 int off;
257 guint32 next_header;
Mark Nauwelaerts9dc75712012-01-25 16:20:41 +0100258 GstMapInfo map;
David Schleeff21e36b2011-07-04 16:18:18 -0700259 guint8 *data;
René Stadlere6df0b62011-11-24 12:01:48 +0100260 gsize size;
David Schleeff21e36b2011-07-04 16:18:18 -0700261 gboolean have_picture = FALSE;
262 int offset;
Mark Nauwelaertsb10b9cf2012-02-13 18:44:01 +0100263 guint framesize = 0;
David Schleefe9ea2372010-10-09 15:08:39 -0700264
Mark Nauwelaerts9dc75712012-01-25 16:20:41 +0100265 gst_buffer_map (frame->buffer, &map, GST_MAP_READ);
266 data = map.data;
267 size = map.size;
David Schleeff21e36b2011-07-04 16:18:18 -0700268
Mark Nauwelaertsb10b9cf2012-02-13 18:44:01 +0100269 if (G_UNLIKELY (size < 13)) {
270 *skipsize = 1;
René Stadlere6df0b62011-11-24 12:01:48 +0100271 goto out;
Mark Nauwelaertsb10b9cf2012-02-13 18:44:01 +0100272 }
David Schleefe9ea2372010-10-09 15:08:39 -0700273
Matej Knoppf9499302011-11-27 20:24:39 +0100274 GST_DEBUG ("%" G_GSIZE_FORMAT ": %02x %02x %02x %02x", size, data[0], data[1],
275 data[2], data[3]);
David Schleefe9ea2372010-10-09 15:08:39 -0700276
David Schleeff21e36b2011-07-04 16:18:18 -0700277 if (GST_READ_UINT32_BE (data) != 0x42424344) {
René Stadlere6df0b62011-11-24 12:01:48 +0100278 GstByteReader reader;
279
280 gst_byte_reader_init (&reader, data, size);
David Schleeff21e36b2011-07-04 16:18:18 -0700281 off = gst_byte_reader_masked_scan_uint32 (&reader, 0xffffffff,
René Stadlere6df0b62011-11-24 12:01:48 +0100282 0x42424344, 0, size);
David Schleefe9ea2372010-10-09 15:08:39 -0700283
David Schleeff21e36b2011-07-04 16:18:18 -0700284 if (off < 0) {
René Stadlere6df0b62011-11-24 12:01:48 +0100285 *skipsize = size - 3;
286 goto out;
David Schleeff21e36b2011-07-04 16:18:18 -0700287 }
David Schleefe9ea2372010-10-09 15:08:39 -0700288
David Schleeff21e36b2011-07-04 16:18:18 -0700289 GST_LOG_OBJECT (parse, "possible sync at buffer offset %d", off);
290
291 GST_DEBUG ("skipping %d", off);
David Schleefe9ea2372010-10-09 15:08:39 -0700292 *skipsize = off;
René Stadlere6df0b62011-11-24 12:01:48 +0100293 goto out;
David Schleefe9ea2372010-10-09 15:08:39 -0700294 }
295
David Schleeff21e36b2011-07-04 16:18:18 -0700296 /* have sync, parse chunks */
David Schleefe9ea2372010-10-09 15:08:39 -0700297
David Schleeff21e36b2011-07-04 16:18:18 -0700298 offset = 0;
299 while (!have_picture) {
300 GST_DEBUG ("offset %d:", offset);
David Schleefe9ea2372010-10-09 15:08:39 -0700301
David Schleeff21e36b2011-07-04 16:18:18 -0700302 if (offset + 13 >= size) {
Mark Nauwelaertsb10b9cf2012-02-13 18:44:01 +0100303 framesize = offset + 13;
René Stadlere6df0b62011-11-24 12:01:48 +0100304 goto out;
David Schleeff21e36b2011-07-04 16:18:18 -0700305 }
David Schleefe9ea2372010-10-09 15:08:39 -0700306
David Schleeff21e36b2011-07-04 16:18:18 -0700307 GST_DEBUG ("chunk type %02x", data[offset + 4]);
308
309 if (GST_READ_UINT32_BE (data + offset) != 0x42424344) {
310 GST_DEBUG ("bad header");
311 *skipsize = 3;
René Stadlere6df0b62011-11-24 12:01:48 +0100312 goto out;
David Schleeff21e36b2011-07-04 16:18:18 -0700313 }
314
315 next_header = GST_READ_UINT32_BE (data + offset + 5);
316 GST_DEBUG ("next_header %d", next_header);
317 if (next_header == 0)
318 next_header = 13;
319
320 if (SCHRO_PARSE_CODE_IS_PICTURE (data[offset + 4])) {
321 have_picture = TRUE;
322 }
323
324 offset += next_header;
325 if (offset >= size) {
Mark Nauwelaertsb10b9cf2012-02-13 18:44:01 +0100326 framesize = offset;
René Stadlere6df0b62011-11-24 12:01:48 +0100327 goto out;
David Schleefe9ea2372010-10-09 15:08:39 -0700328 }
329 }
330
Mark Nauwelaerts9dc75712012-01-25 16:20:41 +0100331 gst_buffer_unmap (frame->buffer, &map);
René Stadlere6df0b62011-11-24 12:01:48 +0100332
Mark Nauwelaertsb10b9cf2012-02-13 18:44:01 +0100333 framesize = offset;
334 GST_DEBUG ("framesize %d", framesize);
David Schleeff21e36b2011-07-04 16:18:18 -0700335
Mark Nauwelaertsb10b9cf2012-02-13 18:44:01 +0100336 g_assert (framesize <= size);
David Schleefe9ea2372010-10-09 15:08:39 -0700337
David Schleeff21e36b2011-07-04 16:18:18 -0700338 if (data[4] == SCHRO_PARSE_CODE_SEQUENCE_HEADER) {
339 GstCaps *caps;
Mark Nauwelaertsb10b9cf2012-02-13 18:44:01 +0100340 GstDiracParse *diracparse = GST_DIRAC_PARSE (parse);
David Schleeff21e36b2011-07-04 16:18:18 -0700341 DiracSequenceHeader sequence_header;
342 int ret;
343
344 ret = dirac_sequence_header_parse (&sequence_header, data + 13, size - 13);
345 if (ret) {
346 memcpy (&diracparse->sequence_header, &sequence_header,
347 sizeof (sequence_header));
348 caps = gst_caps_new_simple ("video/x-dirac",
349 "width", G_TYPE_INT, sequence_header.width,
350 "height", G_TYPE_INT, sequence_header.height,
351 "framerate", GST_TYPE_FRACTION,
352 sequence_header.frame_rate_numerator,
353 sequence_header.frame_rate_denominator,
354 "pixel-aspect-ratio", GST_TYPE_FRACTION,
355 sequence_header.aspect_ratio_numerator,
356 sequence_header.aspect_ratio_denominator,
Tim-Philipp Müller0ff01fa2012-09-03 12:41:33 +0100357 "interlace-mode", G_TYPE_STRING,
358 sequence_header.interlaced ? "interleaved" : "progressive",
Tim-Philipp Müller39ca8d02012-09-03 12:33:51 +0100359 "profile", G_TYPE_STRING, get_profile_name (sequence_header.profile),
360 "level", G_TYPE_STRING, get_level_name (sequence_header.level), NULL);
David Schleeff21e36b2011-07-04 16:18:18 -0700361 gst_pad_set_caps (GST_BASE_PARSE_SRC_PAD (parse), caps);
362 gst_caps_unref (caps);
363
364 gst_base_parse_set_frame_rate (parse,
365 sequence_header.frame_rate_numerator,
366 sequence_header.frame_rate_denominator, 0, 0);
367 }
David Schleefe9ea2372010-10-09 15:08:39 -0700368 }
369
David Schleefe9ea2372010-10-09 15:08:39 -0700370 gst_base_parse_set_min_frame_size (parse, 13);
371
Mark Nauwelaertsb10b9cf2012-02-13 18:44:01 +0100372 return gst_base_parse_finish_frame (parse, frame, framesize);
373
374out:
375 gst_buffer_unmap (frame->buffer, &map);
376 if (framesize)
377 gst_base_parse_set_min_frame_size (parse, framesize);
David Schleefe9ea2372010-10-09 15:08:39 -0700378 return GST_FLOW_OK;
379}
380
381static gboolean
382gst_dirac_parse_convert (GstBaseParse * parse, GstFormat src_format,
383 gint64 src_value, GstFormat dest_format, gint64 * dest_value)
384{
385 /* Convert between formats */
386
387 return FALSE;
388}
389
David Schleefe9ea2372010-10-09 15:08:39 -0700390static GstFlowReturn
391gst_dirac_parse_pre_push_frame (GstBaseParse * parse, GstBaseParseFrame * frame)
392{
Sebastian Drögee65b9b92013-12-16 10:13:36 +0100393 GstDiracParse *diracparse = GST_DIRAC_PARSE (parse);
394
395 if (!diracparse->sent_codec_tag) {
396 GstTagList *taglist;
397 GstCaps *caps;
398
Sebastian Drögee65b9b92013-12-16 10:13:36 +0100399 /* codec tag */
400 caps = gst_pad_get_current_caps (GST_BASE_PARSE_SRC_PAD (parse));
Dave Craig88d7beb2015-12-15 17:10:00 +0000401 if (G_UNLIKELY (caps == NULL)) {
402 if (GST_PAD_IS_FLUSHING (GST_BASE_PARSE_SRC_PAD (parse))) {
403 GST_INFO_OBJECT (parse, "Src pad is flushing");
404 return GST_FLOW_FLUSHING;
405 } else {
406 GST_INFO_OBJECT (parse, "Src pad is not negotiated!");
407 return GST_FLOW_NOT_NEGOTIATED;
408 }
409 }
410
411 taglist = gst_tag_list_new_empty ();
Sebastian Drögee65b9b92013-12-16 10:13:36 +0100412 gst_pb_utils_add_codec_description_to_tag_list (taglist,
413 GST_TAG_VIDEO_CODEC, caps);
414 gst_caps_unref (caps);
415
Olivier Crête567b1e82015-03-17 17:55:26 -0400416 gst_base_parse_merge_tags (parse, taglist, GST_TAG_MERGE_REPLACE);
417 gst_tag_list_unref (taglist);
Sebastian Drögee65b9b92013-12-16 10:13:36 +0100418
419 /* also signals the end of first-frame processing */
420 diracparse->sent_codec_tag = TRUE;
421 }
David Schleefe9ea2372010-10-09 15:08:39 -0700422
423 return GST_FLOW_OK;
424}
Sebastian Drögeb10c1f22011-11-24 10:08:27 +0100425
Wim Taymansd5a16bc2013-12-04 09:00:43 +0100426static void
427remove_fields (GstCaps * caps)
428{
429 guint i, n;
430
431 n = gst_caps_get_size (caps);
432 for (i = 0; i < n; i++) {
433 GstStructure *s = gst_caps_get_structure (caps, i);
434
435 gst_structure_remove_field (s, "parsed");
436 }
437}
438
Sebastian Drögeb10c1f22011-11-24 10:08:27 +0100439static GstCaps *
Edward Herveyb78b9802011-11-25 12:48:58 +0100440gst_dirac_parse_get_sink_caps (GstBaseParse * parse, GstCaps * filter)
Sebastian Drögeb10c1f22011-11-24 10:08:27 +0100441{
Sebastian Dröge7c609332012-06-05 09:30:00 +0200442 GstCaps *peercaps, *templ;
Sebastian Drögeb10c1f22011-11-24 10:08:27 +0100443 GstCaps *res;
444
Sebastian Dröge7c609332012-06-05 09:30:00 +0200445 templ = gst_pad_get_pad_template_caps (GST_BASE_PARSE_SINK_PAD (parse));
Wim Taymanse9dd2df2013-12-04 09:03:45 +0100446 if (filter) {
447 GstCaps *fcopy = gst_caps_copy (filter);
448 /* Remove the fields we convert */
449 remove_fields (fcopy);
450 peercaps = gst_pad_peer_query_caps (GST_BASE_PARSE_SRC_PAD (parse), fcopy);
451 gst_caps_unref (fcopy);
452 } else
453 peercaps = gst_pad_peer_query_caps (GST_BASE_PARSE_SRC_PAD (parse), NULL);
Sebastian Dröge7c609332012-06-05 09:30:00 +0200454
Sebastian Drögeb10c1f22011-11-24 10:08:27 +0100455 if (peercaps) {
Sebastian Drögeb10c1f22011-11-24 10:08:27 +0100456 /* Remove the parsed field */
457 peercaps = gst_caps_make_writable (peercaps);
Wim Taymansd5a16bc2013-12-04 09:00:43 +0100458 remove_fields (peercaps);
Sebastian Drögeb10c1f22011-11-24 10:08:27 +0100459
Sebastian Dröge7c609332012-06-05 09:30:00 +0200460 res = gst_caps_intersect_full (peercaps, templ, GST_CAPS_INTERSECT_FIRST);
Sebastian Drögeb10c1f22011-11-24 10:08:27 +0100461 gst_caps_unref (peercaps);
Wim Taymans9ac2cee2013-12-04 09:13:31 +0100462 gst_caps_unref (templ);
Sebastian Drögeb10c1f22011-11-24 10:08:27 +0100463 } else {
Sebastian Dröge7c609332012-06-05 09:30:00 +0200464 res = templ;
465 }
466
467 if (filter) {
468 GstCaps *intersection;
469
470 intersection =
471 gst_caps_intersect_full (filter, res, GST_CAPS_INTERSECT_FIRST);
472 gst_caps_unref (res);
473 res = intersection;
Sebastian Drögeb10c1f22011-11-24 10:08:27 +0100474 }
475
476 return res;
477}