static gboolean gst_cc_extractor_sink_event (GstPad * pad, GstObject * parent,
GstEvent * event);
+static gboolean gst_cc_extractor_sink_query (GstPad * pad, GstObject * parent,
+ GstQuery * query);
static GstFlowReturn gst_cc_extractor_chain (GstPad * pad, GstObject * parent,
GstBuffer * buf);
static GstStateChangeReturn gst_cc_extractor_change_state (GstElement *
gst_element_remove_pad ((GstElement *) filter, filter->captionpad);
filter->captionpad = NULL;
}
+
+ memset (&filter->video_info, 0, sizeof (filter->video_info));
}
static void
filter->sinkpad = gst_pad_new_from_static_template (&sinktemplate, "sink");
gst_pad_set_event_function (filter->sinkpad,
GST_DEBUG_FUNCPTR (gst_cc_extractor_sink_event));
+ gst_pad_set_query_function (filter->sinkpad,
+ GST_DEBUG_FUNCPTR (gst_cc_extractor_sink_query));
gst_pad_set_chain_function (filter->sinkpad,
GST_DEBUG_FUNCPTR (gst_cc_extractor_chain));
gst_pad_set_iterate_internal_links_function (filter->sinkpad,
GST_LOG_OBJECT (pad, "received %s event: %" GST_PTR_FORMAT,
GST_EVENT_TYPE_NAME (event), event);
switch (GST_EVENT_TYPE (event)) {
+ case GST_EVENT_CAPS:{
+ GstCaps *caps;
+
+ gst_event_parse_caps (event, &caps);
+ if (!gst_video_info_from_caps (&filter->video_info, caps)) {
+ /* We require any kind of video caps here */
+ gst_event_unref (event);
+ return FALSE;
+ }
+ break;
+ }
case GST_EVENT_EOS:
case GST_EVENT_FLUSH_START:
case GST_EVENT_FLUSH_STOP:
return gst_pad_event_default (pad, parent, event);
}
+static gboolean
+gst_cc_extractor_sink_query (GstPad * pad, GstObject * parent, GstQuery * query)
+{
+ GST_LOG_OBJECT (pad, "received %s query: %" GST_PTR_FORMAT,
+ GST_QUERY_TYPE_NAME (query), query);
+ switch (GST_QUERY_TYPE (query)) {
+ case GST_QUERY_ACCEPT_CAPS:{
+ GstCaps *caps;
+ const GstStructure *s;
+
+ gst_query_parse_accept_caps (query, &caps);
+
+ /* FIXME: Ideally we would declare this in our caps but there's no way
+ * to declare caps of type "video/" and "image/" that would match all
+ * such caps
+ */
+ s = gst_caps_get_structure (caps, 0);
+ if (s && (g_str_has_prefix (gst_structure_get_name (s), "video/")
+ || g_str_has_prefix (gst_structure_get_name (s), "image/")))
+ gst_query_set_accept_caps_result (query, TRUE);
+ else
+ gst_query_set_accept_caps_result (query, FALSE);
+
+ return TRUE;
+ }
+ default:
+ break;
+ }
+
+ return gst_pad_query_default (pad, parent, query);
+}
+
static GstCaps *
-create_caps_from_caption_type (GstVideoCaptionType caption_type)
+create_caps_from_caption_type (GstVideoCaptionType caption_type,
+ const GstVideoInfo * video_info)
{
GstCaps *caption_caps = NULL;
break;
}
+ gst_caps_set_simple (caption_caps, "framerate", GST_TYPE_FRACTION,
+ video_info->fps_n, video_info->fps_d, NULL);
+
return caption_caps;
}
/* Check if the meta type matches the configured one */
if (filter->captionpad == NULL) {
- GstCaps *caption_caps = create_caps_from_caption_type (meta->caption_type);
+ GstCaps *caption_caps =
+ create_caps_from_caption_type (meta->caption_type, &filter->video_info);
GstEvent *stream_event;
GST_DEBUG_OBJECT (filter, "Creating new caption pad");
filter->caption_type = meta->caption_type;
} else if (meta->caption_type != filter->caption_type) {
- GstCaps *caption_caps = create_caps_from_caption_type (meta->caption_type);
+ GstCaps *caption_caps =
+ create_caps_from_caption_type (meta->caption_type, &filter->video_info);
GST_DEBUG_OBJECT (filter, "Caption type changed from %d to %d",
filter->caption_type, meta->caption_type);
#include <string.h>
-static GstStaticCaps foo_bar_caps = GST_STATIC_CAPS ("foo/bar");
+#define VIDEO_CAPS_STR "video/x-raw, " \
+ "format = (string) UYVY, " \
+ "width = (int) 1920, " \
+ "height = (int) 1080, " \
+ "framerate = (fraction) 30/1"
+
+static GstStaticCaps video_caps = GST_STATIC_CAPS (VIDEO_CAPS_STR);
static GstStaticCaps cea708_cc_data_caps =
-GST_STATIC_CAPS ("closedcaption/x-cea-708,format=(string) cc_data");
+ GST_STATIC_CAPS
+ ("closedcaption/x-cea-708,format=(string) cc_data, framerate = (fraction) 30/1");
static GstStaticCaps cea708_cdp_caps =
-GST_STATIC_CAPS ("closedcaption/x-cea-708,format=(string) cdp");
+ GST_STATIC_CAPS
+ ("closedcaption/x-cea-708,format=(string) cdp, framerate = (fraction) 30/1");
GST_START_TEST (no_captions)
{
h = gst_harness_new ("ccextractor");
- gst_harness_set_src_caps_str (h, "foo/bar");
+ gst_harness_set_src_caps_str (h, VIDEO_CAPS_STR);
buf = gst_buffer_new_and_alloc (128);
outbuf = gst_harness_push_and_pull (h, gst_buffer_ref (buf));
caps = gst_pad_get_current_caps (h->sinkpad);
fail_unless (caps != NULL);
fail_unless (gst_caps_can_intersect (caps,
- gst_static_caps_get (&foo_bar_caps)));
+ gst_static_caps_get (&video_caps)));
gst_caps_unref (caps);
gst_buffer_unref (buf);
g_signal_connect (h->element, "pad-added", G_CALLBACK (on_caption_pad_added),
h2);
- gst_harness_set_src_caps_str (h, "foo/bar");
+ gst_harness_set_src_caps_str (h, VIDEO_CAPS_STR);
buf = gst_buffer_new_and_alloc (128);
gst_buffer_add_video_caption_meta (buf, GST_VIDEO_CAPTION_TYPE_CEA708_RAW,
caps = gst_pad_get_current_caps (h->sinkpad);
fail_unless (caps != NULL);
fail_unless (gst_caps_can_intersect (caps,
- gst_static_caps_get (&foo_bar_caps)));
+ gst_static_caps_get (&video_caps)));
gst_caps_unref (caps);
caps = gst_pad_get_current_caps (h2->sinkpad);
caps = gst_pad_get_current_caps (h->sinkpad);
fail_unless (caps != NULL);
fail_unless (gst_caps_can_intersect (caps,
- gst_static_caps_get (&foo_bar_caps)));
+ gst_static_caps_get (&video_caps)));
gst_caps_unref (caps);
caps = gst_pad_get_current_caps (h2->sinkpad);
g_signal_connect (h->element, "pad-added", G_CALLBACK (on_caption_pad_added),
h2);
- gst_harness_set_src_caps_str (h, "foo/bar");
+ gst_harness_set_src_caps_str (h, VIDEO_CAPS_STR);
buf = gst_buffer_new_and_alloc (128);
caps = gst_pad_get_current_caps (h->sinkpad);
fail_unless (caps != NULL);
fail_unless (gst_caps_can_intersect (caps,
- gst_static_caps_get (&foo_bar_caps)));
+ gst_static_caps_get (&video_caps)));
gst_caps_unref (caps);
fail_unless (h2->sinkpad != NULL);
caps = gst_pad_get_current_caps (h->sinkpad);
fail_unless (caps != NULL);
fail_unless (gst_caps_can_intersect (caps,
- gst_static_caps_get (&foo_bar_caps)));
+ gst_static_caps_get (&video_caps)));
gst_caps_unref (caps);
caps = gst_pad_get_current_caps (h2->sinkpad);
caps = gst_pad_get_current_caps (h->sinkpad);
fail_unless (caps != NULL);
fail_unless (gst_caps_can_intersect (caps,
- gst_static_caps_get (&foo_bar_caps)));
+ gst_static_caps_get (&video_caps)));
gst_caps_unref (caps);
caps = gst_pad_get_current_caps (h2->sinkpad);
g_signal_connect (h->element, "pad-added", G_CALLBACK (on_caption_pad_added),
h2);
- gst_harness_set_src_caps_str (h, "foo/bar");
+ gst_harness_set_src_caps_str (h, VIDEO_CAPS_STR);
buf = gst_buffer_new_and_alloc (128);
gst_buffer_add_video_caption_meta (buf, GST_VIDEO_CAPTION_TYPE_CEA708_RAW,
caps = gst_pad_get_current_caps (h->sinkpad);
fail_unless (caps != NULL);
fail_unless (gst_caps_can_intersect (caps,
- gst_static_caps_get (&foo_bar_caps)));
+ gst_static_caps_get (&video_caps)));
gst_caps_unref (caps);
caps = gst_pad_get_current_caps (h2->sinkpad);
caps = gst_pad_get_current_caps (h->sinkpad);
fail_unless (caps != NULL);
fail_unless (gst_caps_can_intersect (caps,
- gst_static_caps_get (&foo_bar_caps)));
+ gst_static_caps_get (&video_caps)));
gst_caps_unref (caps);
caps = gst_pad_get_current_caps (h2->sinkpad);