summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVincent Penquerc'h <vincent.penquerch@collabora.co.uk>2011-01-12 16:39:22 +0000
committerTim-Philipp Müller <tim.muller@collabora.co.uk>2011-01-14 00:28:41 +0000
commit0b790b663c1423948794302b6ed88cefab236cff (patch)
tree13670bc0baf0fba1cc326df016bc7e5239871350
parentb55775a9d39513d41da2cdc7cc6dc6b9013a769f (diff)
kate: ensure the kate pad does not shoot ahead of the video pad
Sync both pads by waiting in the kate chain function. Do not reset our internal segment from segment updates, in order to be able to map video running time to kate running time, to give libtiger the timestamp it expects. This allows us to use running time to sync to video, which is The Right Way. https://bugzilla.gnome.org/show_bug.cgi?id=600929
-rw-r--r--ext/kate/gstkatetiger.c50
-rw-r--r--ext/kate/gstkatetiger.h1
-rw-r--r--ext/kate/gstkateutil.c10
3 files changed, 57 insertions, 4 deletions
diff --git a/ext/kate/gstkatetiger.c b/ext/kate/gstkatetiger.c
index 932bb4259..81ac6f755 100644
--- a/ext/kate/gstkatetiger.c
+++ b/ext/kate/gstkatetiger.c
@@ -309,6 +309,7 @@ gst_kate_tiger_init (GstKateTiger * tiger, GstKateTigerClass * gclass)
GST_DEBUG_OBJECT (tiger, "gst_kate_tiger_init");
tiger->mutex = g_mutex_new ();
+ tiger->cond = g_cond_new ();
tiger->katesinkpad =
gst_pad_new_from_static_template (&kate_sink_factory, "subtitle_sink");
@@ -371,6 +372,9 @@ gst_kate_tiger_dispose (GObject * object)
tiger->default_font_desc = NULL;
}
+ g_cond_free (tiger->cond);
+ tiger->cond = NULL;
+
g_mutex_free (tiger->mutex);
tiger->mutex = NULL;
@@ -631,6 +635,34 @@ gst_kate_tiger_kate_chain (GstPad * pad, GstBuffer * buf)
gst_object_unref (tagpad);
}
+ /* we want to avoid shooting ahead of the video stream, or we will
+ get segment updates which will place us ahead of it, and we won't
+ be able to convert a video timestamp back into a kate timestamp */
+ if (G_LIKELY (GST_BUFFER_TIMESTAMP_IS_VALID (buf))) {
+ while (1) {
+ gint64 kate_time, video_time;
+ kate_time =
+ gst_segment_to_running_time (&tiger->decoder.kate_segment,
+ GST_FORMAT_TIME, GST_BUFFER_TIMESTAMP (buf));
+ video_time =
+ gst_segment_to_running_time (&tiger->video_segment, GST_FORMAT_TIME,
+ tiger->video_segment.last_stop);
+ GST_DEBUG_OBJECT (tiger, "Kate time %.2f, video time %.2f (kts %ld)",
+ kate_time / (float) GST_SECOND, video_time / (float) GST_SECOND,
+ (long) GST_BUFFER_TIMESTAMP (buf));
+ if (kate_time <= video_time) {
+ break;
+ }
+ GST_LOG_OBJECT (tiger, "Waiting to return from chain function");
+ g_cond_wait (tiger->cond, tiger->mutex);
+ if (tiger->decoder.kate_flushing) {
+ GST_DEBUG_OBJECT (tiger, "Flushing while waiting");
+ break;
+ }
+ GST_LOG_OBJECT (tiger, "Woken up, checking time again");
+ }
+ }
+
GST_KATE_TIGER_MUTEX_UNLOCK (tiger);
gst_object_unref (tiger);
@@ -669,8 +701,13 @@ gst_kate_tiger_video_set_caps (GstPad * pad, GstCaps * caps)
static gdouble
gst_kate_tiger_get_time (GstKateTiger * tiger)
{
- return gst_segment_to_running_time (&tiger->video_segment, GST_FORMAT_TIME,
- tiger->video_segment.last_stop) / (gdouble) GST_SECOND;
+ gint64 rt =
+ gst_segment_to_running_time (&tiger->video_segment, GST_FORMAT_TIME,
+ tiger->video_segment.last_stop);
+ gint64 pos =
+ gst_segment_to_position (&tiger->decoder.kate_segment, GST_FORMAT_TIME,
+ rt);
+ return pos / (gdouble) GST_SECOND;
}
static GstFlowReturn
@@ -695,6 +732,7 @@ gst_kate_tiger_video_chain (GstPad * pad, GstBuffer * buf)
if (G_LIKELY (GST_BUFFER_TIMESTAMP_IS_VALID (buf))) {
gst_segment_set_last_stop (&tiger->video_segment, GST_FORMAT_TIME,
GST_BUFFER_TIMESTAMP (buf));
+ g_cond_broadcast (tiger->cond);
}
/* draw on it */
@@ -755,6 +793,8 @@ gst_kate_tiger_change_state (GstElement * element, GstStateChange transition)
case GST_STATE_CHANGE_PAUSED_TO_READY:
GST_DEBUG_OBJECT (tiger, "PAUSED -> READY, clearing kate state");
GST_KATE_TIGER_MUTEX_LOCK (tiger);
+ gst_kate_util_decoder_base_set_flushing (&tiger->decoder, TRUE);
+ g_cond_broadcast (tiger->cond);
if (tiger->tr) {
tiger_renderer_destroy (tiger->tr);
tiger->tr = NULL;
@@ -904,6 +944,7 @@ gst_kate_tiger_handle_kate_event (GstPad * pad, GstEvent * event)
case GST_EVENT_NEWSEGMENT:
GST_INFO_OBJECT (tiger, "New segment on Kate pad");
GST_KATE_TIGER_MUTEX_LOCK (tiger);
+ g_cond_broadcast (tiger->cond);
gst_kate_util_decoder_base_new_segment_event (&tiger->decoder, event);
GST_KATE_TIGER_MUTEX_UNLOCK (tiger);
gst_event_unref (event);
@@ -912,6 +953,7 @@ gst_kate_tiger_handle_kate_event (GstPad * pad, GstEvent * event)
GST_KATE_TIGER_MUTEX_LOCK (tiger);
gst_kate_util_decoder_base_set_flushing (&tiger->decoder, TRUE);
GST_KATE_TIGER_MUTEX_UNLOCK (tiger);
+ g_cond_broadcast (tiger->cond);
gst_event_unref (event);
break;
case GST_EVENT_FLUSH_STOP:
@@ -924,6 +966,9 @@ gst_kate_tiger_handle_kate_event (GstPad * pad, GstEvent * event)
/* we ignore this, it just means we don't have anymore Kate packets, but
the Tiger renderer will still draw (if appropriate) on incoming video */
GST_INFO_OBJECT (tiger, "EOS on Kate pad");
+ GST_KATE_TIGER_MUTEX_LOCK (tiger);
+ g_cond_broadcast (tiger->cond);
+ GST_KATE_TIGER_MUTEX_UNLOCK (tiger);
gst_event_unref (event);
break;
default:
@@ -1000,6 +1045,7 @@ gst_kate_tiger_handle_video_event (GstPad * pad, GstEvent * event)
gst_segment_init (&tiger->video_segment, GST_FORMAT_UNDEFINED);
tiger->video_flushing = TRUE;
GST_KATE_TIGER_MUTEX_UNLOCK (tiger);
+ g_cond_broadcast (tiger->cond);
res = gst_pad_event_default (pad, event);
break;
case GST_EVENT_FLUSH_STOP:
diff --git a/ext/kate/gstkatetiger.h b/ext/kate/gstkatetiger.h
index 48884b1c2..d3880b32b 100644
--- a/ext/kate/gstkatetiger.h
+++ b/ext/kate/gstkatetiger.h
@@ -94,6 +94,7 @@ struct _GstKateTiger
gboolean swap_rgb;
GMutex *mutex;
+ GCond *cond;
GstSegment video_segment;
gboolean video_flushing;
diff --git a/ext/kate/gstkateutil.c b/ext/kate/gstkateutil.c
index b873d0aca..46ae19b9d 100644
--- a/ext/kate/gstkateutil.c
+++ b/ext/kate/gstkateutil.c
@@ -454,8 +454,14 @@ gst_kate_util_decoder_base_new_segment_event (GstKateDecoderBase * decoder,
" %" GST_TIME_FORMAT " position %" GST_TIME_FORMAT,
update, rate, arate, format, GST_TIME_ARGS (start),
GST_TIME_ARGS (stop), GST_TIME_ARGS (time));
- gst_segment_set_newsegment_full (&decoder->kate_segment, update, rate,
- arate, format, start, stop, time);
+ if (!update) {
+ /* Tiger uses this segment is used to remap the video running time to the
+ Kate running time. The sending of segment updates to keep streams in sync
+ does kinda rain on our parade though, and since we don't need these,
+ we just ignore those here */
+ gst_segment_set_newsegment_full (&decoder->kate_segment, update, rate,
+ arate, format, start, stop, time);
+ }
}
gboolean