summaryrefslogtreecommitdiff
path: root/src/gsttools/gstvideoconnector.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/gsttools/gstvideoconnector.c')
-rw-r--r--src/gsttools/gstvideoconnector.c199
1 files changed, 185 insertions, 14 deletions
diff --git a/src/gsttools/gstvideoconnector.c b/src/gsttools/gstvideoconnector.c
index 3e08fe53..ff3f9a36 100644
--- a/src/gsttools/gstvideoconnector.c
+++ b/src/gsttools/gstvideoconnector.c
@@ -67,26 +67,93 @@ GST_STATIC_PAD_TEMPLATE ("src",
GST_PAD_ALWAYS,
GST_STATIC_CAPS_ANY);
+
+#if GST_CHECK_VERSION(1,0,0)
+
+G_DEFINE_TYPE(GstVideoConnector, gst_video_connector, GST_TYPE_ELEMENT);
+#else
#define _do_init(bla) \
GST_DEBUG_CATEGORY_INIT (video_connector_debug, \
"video-connector", 0, "An identity like element for reconnecting video stream");
GST_BOILERPLATE_FULL (GstVideoConnector, gst_video_connector, GstElement,
GST_TYPE_ELEMENT, _do_init);
+#endif
static void gst_video_connector_dispose (GObject * object);
+
+#if GST_CHECK_VERSION(1,0,0)
+static GstFlowReturn gst_video_connector_chain (GstPad * pad, GstObject* parent, GstBuffer * buf);
+#else
static GstFlowReturn gst_video_connector_chain (GstPad * pad, GstBuffer * buf);
static GstFlowReturn gst_video_connector_buffer_alloc (GstPad * pad,
guint64 offset, guint size, GstCaps * caps, GstBuffer ** buf);
+#endif
+
static GstStateChangeReturn gst_video_connector_change_state (GstElement *
element, GstStateChange transition);
+
+#if GST_CHECK_VERSION(1,0,0)
+static gboolean gst_video_connector_handle_sink_event (GstPad * pad, GstObject* parent,
+ GstEvent * event);
+#else
static gboolean gst_video_connector_handle_sink_event (GstPad * pad,
GstEvent * event);
+#endif
+
+#if GST_CHECK_VERSION(1,0,0)
+static GstPadProbeReturn gst_video_connector_new_buffer_probe(GstPad *pad, GstPadProbeInfo *info, gpointer object);
+static GstPadProbeReturn gst_video_connector_new_event_probe(GstPad *pad, GstPadProbeInfo *info, gpointer object);
+static GstPadProbeReturn gst_video_connector_new_query_probe(GstPad *pad, GstPadProbeInfo *info, gpointer object);
+#else
static gboolean gst_video_connector_new_buffer_probe(GstObject *pad, GstBuffer *buffer, guint * object);
-static void gst_video_connector_resend_new_segment(GstElement * element, gboolean emitFailedSignal);
static gboolean gst_video_connector_setcaps (GstPad *pad, GstCaps *caps);
static GstCaps *gst_video_connector_getcaps (GstPad * pad);
static gboolean gst_video_connector_acceptcaps (GstPad * pad, GstCaps * caps);
+#endif
+
+static void gst_video_connector_resend_new_segment(GstElement * element, gboolean emitFailedSignal);
+
+#if GST_CHECK_VERSION(1,0,0)
+static void
+gst_video_connector_class_init (GstVideoConnectorClass * klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+ GstElementClass *gstelement_class = GST_ELEMENT_CLASS (klass);
+
+ gst_element_class_set_details_simple (gstelement_class, "Video Connector",
+ "Generic",
+ "An identity like element used for reconnecting video stream",
+ "Dmytro Poplavskiy <dmytro.poplavskiy@nokia.com>");
+ gst_element_class_add_pad_template (gstelement_class,
+ gst_static_pad_template_get (&gst_video_connector_sink_factory));
+ gst_element_class_add_pad_template (gstelement_class,
+ gst_static_pad_template_get (&gst_video_connector_src_factory));
+
+ gst_video_connector_parent_class = g_type_class_peek_parent (klass);
+
+ gobject_class->dispose = gst_video_connector_dispose;
+ gstelement_class->change_state = gst_video_connector_change_state;
+ klass->resend_new_segment = gst_video_connector_resend_new_segment;
+
+ gst_video_connector_signals[SIGNAL_RESEND_NEW_SEGMENT] =
+ g_signal_new ("resend-new-segment", G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
+ G_STRUCT_OFFSET (GstVideoConnectorClass, resend_new_segment), NULL, NULL,
+ g_cclosure_marshal_VOID__BOOLEAN, G_TYPE_NONE, 1, G_TYPE_BOOLEAN);
+
+ gst_video_connector_signals[SIGNAL_CONNECTION_FAILED] =
+ g_signal_new ("connection-failed", G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ 0, NULL, NULL,
+ g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
+
+ GST_DEBUG_CATEGORY_INIT(video_connector_debug, "video-connector", 0,
+ "An identity like element for reconnecting video stream");
+
+}
+
+#else
static void
gst_video_connector_base_init (gpointer g_class)
@@ -128,18 +195,33 @@ gst_video_connector_class_init (GstVideoConnectorClass * klass)
g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
}
+#endif
+
static void
-gst_video_connector_init (GstVideoConnector *element,
- GstVideoConnectorClass *g_class)
+gst_video_connector_init (GstVideoConnector *element
+#if GST_CHECK_VERSION(1,0,0)
+#else
+ ,GstVideoConnectorClass *g_class
+#endif
+ )
{
+#if GST_CHECK_VERSION(1,0,0)
+#else
(void) g_class;
+#endif
element->sinkpad =
gst_pad_new_from_static_template (&gst_video_connector_sink_factory,
"sink");
gst_pad_set_chain_function(element->sinkpad,
GST_DEBUG_FUNCPTR (gst_video_connector_chain));
+#if GST_CHECK_VERSION(1,0,0)
+ /* gstreamer 1.x uses QUERIES and EVENTS for allocation and caps handiling purposes */
+ GST_OBJECT_FLAG_SET (element->sinkpad, GST_PAD_FLAG_PROXY_CAPS);
+ GST_OBJECT_FLAG_SET (element->sinkpad, GST_PAD_FLAG_PROXY_ALLOCATION);
+#else
gst_pad_set_event_function(element->sinkpad,
GST_DEBUG_FUNCPTR (gst_video_connector_handle_sink_event));
+
gst_pad_set_bufferalloc_function(element->sinkpad,
GST_DEBUG_FUNCPTR (gst_video_connector_buffer_alloc));
gst_pad_set_setcaps_function(element->sinkpad,
@@ -148,14 +230,23 @@ gst_video_connector_init (GstVideoConnector *element,
GST_DEBUG_FUNCPTR(gst_video_connector_getcaps));
gst_pad_set_acceptcaps_function(element->sinkpad,
GST_DEBUG_FUNCPTR(gst_video_connector_acceptcaps));
-
+#endif
gst_element_add_pad (GST_ELEMENT (element), element->sinkpad);
element->srcpad =
gst_pad_new_from_static_template (&gst_video_connector_src_factory,
"src");
+#if GST_CHECK_VERSION(1,0,0)
+ gst_pad_add_probe(element->srcpad, GST_PAD_PROBE_TYPE_BUFFER,
+ gst_video_connector_new_buffer_probe, element, NULL);
+ gst_pad_add_probe(element->srcpad, GST_PAD_PROBE_TYPE_QUERY_DOWNSTREAM,
+ gst_video_connector_new_query_probe, element, NULL);
+ gst_pad_add_probe(element->sinkpad, GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM,
+ gst_video_connector_new_event_probe, element, NULL);
+#else
gst_pad_add_buffer_probe(element->srcpad,
G_CALLBACK(gst_video_connector_new_buffer_probe), element);
+#endif
gst_element_add_pad (GST_ELEMENT (element), element->srcpad);
element->relinked = FALSE;
@@ -183,9 +274,16 @@ gst_video_connector_dispose (GObject * object)
gst_video_connector_reset (element);
+#if GST_CHECK_VERSION(1,0,0)
+ G_OBJECT_CLASS (gst_video_connector_parent_class)->dispose (object);
+#else
G_OBJECT_CLASS (parent_class)->dispose (object);
+#endif
}
+#if GST_CHECK_VERSION(1,0,0)
+/* For gstreamer 1.x we handle it in ALLOCATION Query */
+#else
// "When this function returns anything else than GST_FLOW_OK,
// the buffer allocation failed and buf does not contain valid data."
static GstFlowReturn
@@ -229,6 +327,7 @@ gst_video_connector_buffer_alloc (GstPad * pad, guint64 offset, guint size,
if (state == GST_STATE_NULL) {
GST_DEBUG_OBJECT (element, "Downstream element is in NULL state");
// Downstream filter seems to be in the wrong state
+
return GST_FLOW_UNEXPECTED;
}
}
@@ -301,6 +400,7 @@ static GstCaps *gst_video_connector_getcaps (GstPad * pad)
return caps;
}
+
static gboolean gst_video_connector_acceptcaps (GstPad * pad, GstCaps * caps)
{
GstVideoConnector *element;
@@ -308,6 +408,7 @@ static gboolean gst_video_connector_acceptcaps (GstPad * pad, GstCaps * caps)
return gst_pad_peer_accept_caps(element->srcpad, caps);
}
+#endif
static void
gst_video_connector_resend_new_segment(GstElement * element, gboolean emitFailedSignal)
@@ -319,11 +420,39 @@ gst_video_connector_resend_new_segment(GstElement * element, gboolean emitFailed
connector->failedSignalEmited = FALSE;
}
+#if GST_CHECK_VERSION(1,0,0)
+static GstPadProbeReturn gst_video_connector_new_event_probe(GstPad *pad, GstPadProbeInfo *info, gpointer object)
+{
+ GstVideoConnector *connector = GST_VIDEO_CONNECTOR (object);
+ GstEvent *event = gst_pad_probe_info_get_event(info);
+
+ GST_DEBUG_OBJECT(connector, "Event %"GST_PTR_FORMAT" received\n", event);
+
+ return GST_PAD_PROBE_OK;
+}
+
+static GstPadProbeReturn gst_video_connector_new_query_probe(GstPad *pad, GstPadProbeInfo *info, gpointer object)
+{
+ GstVideoConnector *connector = GST_VIDEO_CONNECTOR (object);
+ GstQuery *query = gst_pad_probe_info_get_query(info);
+
+ GST_DEBUG_OBJECT(connector, "Query %"GST_PTR_FORMAT" received\n", query);
+
+ return GST_PAD_PROBE_OK;
+}
+#endif
+#if GST_CHECK_VERSION(1,0,0)
+static GstPadProbeReturn gst_video_connector_new_buffer_probe(GstPad *pad, GstPadProbeInfo *info, gpointer object)
+{
+ (void) info;
+#else
static gboolean gst_video_connector_new_buffer_probe(GstObject *pad, GstBuffer *buffer, guint * object)
{
- (void) pad;
(void) buffer;
+#endif
+ (void) pad;
+
GstVideoConnector *element = GST_VIDEO_CONNECTOR (object);
@@ -335,16 +464,23 @@ static gboolean gst_video_connector_new_buffer_probe(GstObject *pad, GstBuffer *
if (element->relinked)
GST_LOG_OBJECT(element, "rejected buffer because of new segment request");
- return !element->relinked;
+ return element->relinked ? GST_PAD_PROBE_DROP : GST_PAD_PROBE_OK;
}
-
static GstFlowReturn
+#if GST_CHECK_VERSION(1,0,0)
+gst_video_connector_chain (GstPad * pad, GstObject* parent, GstBuffer * buf)
+#else
gst_video_connector_chain (GstPad * pad, GstBuffer * buf)
+#endif
{
GstFlowReturn res;
GstVideoConnector *element;
+#if GST_CHECK_VERSION(1,0,0)
+ (void)parent;
+#endif
+
element = GST_VIDEO_CONNECTOR (gst_pad_get_parent (pad));
do {
@@ -356,20 +492,29 @@ gst_video_connector_chain (GstPad * pad, GstBuffer * buf)
*/
while (element->relinked) {
element->relinked = FALSE;
-
+#if GST_CHECK_VERSION(1,0,0)
+ if (element->latest_buffer && GST_BUFFER_TIMESTAMP_IS_VALID(element->latest_buffer)) {
+ element->segment.position = GST_BUFFER_TIMESTAMP (element->latest_buffer);
+ }
+#else
gint64 pos = element->segment.last_stop;
-
if (element->latest_buffer && GST_BUFFER_TIMESTAMP_IS_VALID(element->latest_buffer)) {
pos = GST_BUFFER_TIMESTAMP (element->latest_buffer);
}
+#endif
//push a new segment and last buffer
+#if GST_CHECK_VERSION(1,0,0)
+ GstEvent *ev = gst_event_new_segment (&element->segment);
+
+#else
GstEvent *ev = gst_event_new_new_segment (TRUE,
element->segment.rate,
element->segment.format,
pos, //start
element->segment.stop,
pos);
+#endif
GST_DEBUG_OBJECT (element, "Pushing new segment event");
if (!gst_pad_push_event (element->srcpad, ev)) {
@@ -432,8 +577,11 @@ gst_video_connector_change_state (GstElement * element,
GstStateChangeReturn result;
connector = GST_VIDEO_CONNECTOR(element);
+#if GST_CHECK_VERSION(1,0,0)
+ result = GST_ELEMENT_CLASS (gst_video_connector_parent_class)->change_state(element, transition);
+#else
result = GST_ELEMENT_CLASS (parent_class)->change_state(element, transition);
-
+#endif
switch (transition) {
case GST_STATE_CHANGE_PAUSED_TO_READY:
gst_video_connector_reset (connector);
@@ -448,9 +596,32 @@ gst_video_connector_change_state (GstElement * element,
return result;
}
-static gboolean
-gst_video_connector_handle_sink_event (GstPad * pad, GstEvent * event)
+#if GST_CHECK_VERSION(1,0,0)
+static gboolean gst_video_connector_handle_sink_event (GstPad * pad, GstObject* parent,
+ GstEvent * event)
+{
+ GstVideoConnector *element = GST_VIDEO_CONNECTOR (gst_pad_get_parent (pad));
+
+ switch (GST_EVENT_TYPE (event)) {
+ case GST_EVENT_SEGMENT:
+ break;
+ case GST_EVENT_CAPS:
+ break;
+ default:
+ break;
+ }
+
+ gst_object_unref (element);
+ return gst_pad_event_default (pad, parent, event);
+}
+
+#else
+
+static gboolean gst_video_connector_handle_sink_event (GstPad * pad,
+ GstEvent * event)
{
+ (void)parent;
+
if (GST_EVENT_TYPE (event) == GST_EVENT_NEWSEGMENT) {
GstVideoConnector *element = GST_VIDEO_CONNECTOR (gst_pad_get_parent (pad));
@@ -461,7 +632,6 @@ gst_video_connector_handle_sink_event (GstPad * pad, GstEvent * event)
gst_event_parse_new_segment_full (event, &update, &rate, &arate, &format,
&start, &stop, &time);
-
GST_LOG_OBJECT (element,
"NEWSEGMENT update %d, rate %lf, applied rate %lf, "
"format %d, " "%" G_GINT64_FORMAT " -- %" G_GINT64_FORMAT ", time %"
@@ -469,9 +639,10 @@ gst_video_connector_handle_sink_event (GstPad * pad, GstEvent * event)
gst_segment_set_newsegment_full (&element->segment, update,
rate, arate, format, start, stop, time);
-
gst_object_unref (element);
}
return gst_pad_event_default (pad, event);
}
+
+#endif