summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog6
-rw-r--r--gst/switch/gstswitch.c125
2 files changed, 120 insertions, 11 deletions
diff --git a/ChangeLog b/ChangeLog
index 620a65bb..d8428b40 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2007-08-29 Zaheer Abbas Merali <zaheerabbas at merali dot org>
+
+ * gst/switch/gstswitch.c (gst_switch_chain, gst_switch_set_property):
+ If all information is known at time of setting start-time
+ property, send new segments then.
+
2007-08-28 Wim Taymans <wim.taymans@gmail.com>
* gst/rtpmanager/gstrtpsession.c: (stop_rtcp_thread),
diff --git a/gst/switch/gstswitch.c b/gst/switch/gstswitch.c
index 6621bc24..52a8ec9d 100644
--- a/gst/switch/gstswitch.c
+++ b/gst/switch/gstswitch.c
@@ -252,7 +252,12 @@ gst_switch_chain (GstPad * pad, GstBuffer * buf)
GST_SWITCH_UNLOCK (gstswitch);
gst_pad_push_event (gstswitch->srcpad, newsegment_event);
GST_SWITCH_LOCK (gstswitch);
+ } else {
+ GST_WARNING_OBJECT (gstswitch,
+ "Sinkpad %s:%s had no previous new segment!",
+ GST_DEBUG_PAD_NAME (gstswitch->previous_sinkpad));
}
+
}
gst_object_unref (GST_OBJECT (gstswitch->previous_sinkpad));
gstswitch->previous_sinkpad = NULL;
@@ -271,20 +276,15 @@ gst_switch_chain (GstPad * pad, GstBuffer * buf)
gst_event_parse_new_segment_full (event, &update, &rate, &applied_rate,
&format, &start, &stop, &position);
- if (gstswitch->start_value != GST_CLOCK_TIME_NONE &&
- gstswitch->start_value <= GST_BUFFER_TIMESTAMP (buf)) {
+ if (gstswitch->start_value <= GST_BUFFER_TIMESTAMP (buf)
+ && gstswitch->start_value != GST_CLOCK_TIME_NONE) {
start = gstswitch->start_value;
} else {
start = GST_BUFFER_TIMESTAMP (buf);
}
if (start == GST_CLOCK_TIME_NONE) {
-
- /*GST_ELEMENT_ERROR (gstswitch, STREAM, FAILED, (NULL), ( */
- g_critical ("Cannot send "
- "new segment event because start value is GST_CLOCK_TIME_NONE"); /*); */
GST_WARNING_OBJECT (gstswitch,
"new segment event requested to be sent but start value is NONE");
-
}
newsegment_event = gst_event_new_new_segment_full (FALSE, rate,
applied_rate, format, start, stop, position);
@@ -296,14 +296,17 @@ gst_switch_chain (GstPad * pad, GstBuffer * buf)
GST_DEBUG_OBJECT (gstswitch,
"Sending new segment with start of %" G_GUINT64_FORMAT, start);
} else {
- GST_WARNING_OBJECT (pad,
- "Couldn't find new segment for pad in hashtable");
+ GST_WARNING_OBJECT (gstswitch,
+ "Couldn't find new segment for pad %s:%s in hashtable",
+ GST_PAD_NAME (pad));
}
/* reset stop and start value */
gstswitch->start_value = GST_CLOCK_TIME_NONE;
gstswitch->stop_value = GST_CLOCK_TIME_NONE;
/* send all the stored buffers if any */
- buffers = g_hash_table_lookup (gstswitch->stored_buffers, active_sinkpad);
+ buffers =
+ g_hash_table_lookup (gstswitch->stored_buffers,
+ gstswitch->active_sinkpad);
while (buffers != NULL) {
gst_buffer_ref (GST_BUFFER (buffers->data));
GST_SWITCH_UNLOCK (gstswitch);
@@ -311,8 +314,9 @@ gst_switch_chain (GstPad * pad, GstBuffer * buf)
GST_SWITCH_LOCK (gstswitch);
buffers = buffers->next;
}
- g_hash_table_remove (gstswitch->stored_buffers, active_sinkpad);
+ g_hash_table_remove (gstswitch->stored_buffers, gstswitch->active_sinkpad);
}
+
gstswitch->last_ts = GST_BUFFER_TIMESTAMP (buf) + GST_BUFFER_DURATION (buf);
if (!gstswitch->queue_buffers) {
/* forward */
@@ -417,6 +421,88 @@ gst_switch_set_property (GObject * object, guint prop_id,
case ARG_START_VALUE:
GST_SWITCH_LOCK (gstswitch);
gstswitch->start_value = g_value_get_uint64 (value);
+ /* let's send new segment here instead of waiting for the next buffer
+ * as we know the start value for the new segment */
+ /* check if we need to send a new segment event */
+ if (gstswitch->start_value != GST_CLOCK_TIME_NONE &&
+ gstswitch->need_to_send_newsegment) {
+ GstEvent *event;
+
+ /* check to see if we need to send a new segment update for stop */
+ if (gstswitch->previous_sinkpad != NULL) {
+ if (gstswitch->stop_value != GST_CLOCK_TIME_NONE) {
+ GstEvent *prev_newsegment =
+ (GstEvent *) g_hash_table_lookup (gstswitch->newsegment_events,
+ gstswitch->previous_sinkpad);
+
+ if (prev_newsegment) {
+ /* need to send a new segment update changing stop */
+ gboolean update;
+ gdouble rate, applied_rate;
+ GstFormat format;
+ gint64 start, stop, position;
+ GstEvent *newsegment_event;
+
+ gst_event_parse_new_segment_full (prev_newsegment, &update, &rate,
+ &applied_rate, &format, &start, &stop, &position);
+ GST_DEBUG_OBJECT (gstswitch,
+ "Sending new segment update with stop of %" G_GUINT64_FORMAT
+ "and start of %" G_GUINT64_FORMAT, gstswitch->stop_value,
+ gstswitch->current_start);
+ newsegment_event = gst_event_new_new_segment_full (TRUE, rate,
+ applied_rate, format, gstswitch->current_start,
+ gstswitch->stop_value, position);
+ GST_SWITCH_UNLOCK (gstswitch);
+ gst_pad_push_event (gstswitch->srcpad, newsegment_event);
+ GST_SWITCH_LOCK (gstswitch);
+ } else {
+ GST_WARNING_OBJECT (gstswitch,
+ "Sinkpad %s:%s had no previous new segment!",
+ GST_DEBUG_PAD_NAME (gstswitch->previous_sinkpad));
+ }
+
+ }
+ gst_object_unref (GST_OBJECT (gstswitch->previous_sinkpad));
+ gstswitch->previous_sinkpad = NULL;
+ }
+ /* retrieve event from hash table */
+ event =
+ (GstEvent *) g_hash_table_lookup (gstswitch->newsegment_events,
+ gstswitch->active_sinkpad);
+ if (event) {
+ /* create a copy of this event so we can change start to match
+ * the start time of this buffer */
+ gboolean update;
+ gdouble rate, applied_rate;
+ GstFormat format;
+ gint64 start, stop, position;
+ GstEvent *newsegment_event;
+
+ gst_event_parse_new_segment_full (event, &update, &rate,
+ &applied_rate, &format, &start, &stop, &position);
+ start = gstswitch->start_value;
+ if (start == GST_CLOCK_TIME_NONE) {
+ GST_WARNING_OBJECT (gstswitch,
+ "new segment event requested to be sent but start value is NONE");
+ }
+ newsegment_event = gst_event_new_new_segment_full (FALSE, rate,
+ applied_rate, format, start, stop, position);
+ GST_SWITCH_UNLOCK (gstswitch);
+ gst_pad_push_event (gstswitch->srcpad, newsegment_event);
+ GST_SWITCH_LOCK (gstswitch);
+ gstswitch->need_to_send_newsegment = FALSE;
+ gstswitch->current_start = start;
+ GST_DEBUG_OBJECT (gstswitch,
+ "Sending new segment with start of %" G_GUINT64_FORMAT, start);
+ } else {
+ GST_WARNING_OBJECT (gstswitch,
+ "Couldn't find new segment for pad %s:%s in hashtable",
+ GST_PAD_NAME (gstswitch->active_sinkpad));
+ }
+ /* reset stop and start value */
+ gstswitch->start_value = GST_CLOCK_TIME_NONE;
+ gstswitch->stop_value = GST_CLOCK_TIME_NONE;
+ }
GST_SWITCH_UNLOCK (gstswitch);
break;
case ARG_STOP_VALUE:
@@ -427,6 +513,23 @@ gst_switch_set_property (GObject * object, guint prop_id,
case ARG_QUEUE_BUFFERS:
GST_SWITCH_LOCK (gstswitch);
gstswitch->queue_buffers = g_value_get_boolean (value);
+ if (!gstswitch->queue_buffers && !gstswitch->need_to_send_newsegment) {
+ GList *buffers;
+
+ /* send all the stored buffers if any */
+ buffers =
+ g_hash_table_lookup (gstswitch->stored_buffers,
+ gstswitch->active_sinkpad);
+ while (buffers != NULL) {
+ gst_buffer_ref (GST_BUFFER (buffers->data));
+ GST_SWITCH_UNLOCK (gstswitch);
+ gst_pad_push (gstswitch->srcpad, GST_BUFFER (buffers->data));
+ GST_SWITCH_LOCK (gstswitch);
+ buffers = buffers->next;
+ }
+ g_hash_table_remove (gstswitch->stored_buffers,
+ gstswitch->active_sinkpad);
+ }
GST_SWITCH_UNLOCK (gstswitch);
break;
default: