dvbsuboverlay: Implement subtitle queueing and syncing with video

Push incoming subtitle pages in a FIFO queue (pending_subtitles)
and dequeue the head when it's time to show it (when video running
time reaches the subtitle page running time).
Keep the subtitle page, that is supposed to be blended on top of video
currently, in a separate object variable (current_subtitle). As a
next step we can then pre-render current_subtitle to a better to blend
format.
This commit is contained in:
Mart Raudsepp 2010-12-01 06:01:15 +02:00 committed by Edward Hervey
parent 41c82583f5
commit 3d09a3b18a
2 changed files with 35 additions and 14 deletions

View file

@ -234,6 +234,9 @@ gst_dvbsub_overlay_init (GstDVBSubOverlay * render,
render->subtitle_mutex = g_mutex_new ();
render->subtitle_cond = g_cond_new ();
render->current_subtitle = NULL;
render->pending_subtitles = g_queue_new ();
render->renderer_init_ok = FALSE;
render->enable = TRUE;
@ -270,6 +273,11 @@ gst_dvbsub_overlay_finalize (GObject * object)
if (overlay->subtitle_cond)
g_cond_free (overlay->subtitle_cond);
if (overlay->pending_subtitles) {
/* FIXME: Free up contents */
g_queue_free (overlay->pending_subtitles);
}
if (overlay->dvb_sub) {
g_object_unref (overlay->dvb_sub);
}
@ -930,7 +938,7 @@ new_dvb_subtitles_cb (DvbSub * dvb_sub, DVBSubtitles * subs, gpointer user_data)
subs->page_time_out, subs->num_rects, subs->pts,
GST_TIME_ARGS (subs->pts));
//GST_OBJECT_LOCK (overlay);
overlay->subtitle_buffer = subs->num_rects;
g_queue_push_tail (overlay->pending_subtitles, subs);
//GST_OBJECT_UNLOCK (overlay);
}
@ -1045,8 +1053,6 @@ gst_dvbsub_overlay_chain_text (GstPad * pad, GstBuffer * buffer)
GST_DEBUG_OBJECT (overlay, "SUBTITLE real running time: %" GST_TIME_FORMAT,
GST_TIME_ARGS (sub_running_time));
overlay->subtitle_buffer = 0; /*buffer FIXME: Need to do buffering elsewhere */
/* That's a new text buffer we need to render */
/*overlay->need_render = TRUE; *//* FIXME: Actually feed it to libdvbsub and set need_render on a callback */
@ -1067,6 +1073,7 @@ gst_dvbsub_overlay_chain_video (GstPad * pad, GstBuffer * buffer)
GstDVBSubOverlay *overlay = GST_DVBSUB_OVERLAY (GST_PAD_PARENT (pad));
GstFlowReturn ret = GST_FLOW_OK;
gint64 start, stop;
GstClockTime vid_running_time;
if (!GST_BUFFER_TIMESTAMP_IS_VALID (buffer))
goto missing_timestamp;
@ -1086,13 +1093,29 @@ gst_dvbsub_overlay_chain_video (GstPad * pad, GstBuffer * buffer)
stop = start + GST_BUFFER_DURATION (buffer);
}
vid_running_time =
gst_segment_to_running_time (&overlay->video_segment, GST_FORMAT_TIME,
GST_BUFFER_TIMESTAMP (buffer));
GST_DEBUG_OBJECT (overlay, "Video running time: %" GST_TIME_FORMAT,
GST_TIME_ARGS (vid_running_time));
/* FIXME: Probably update last_stop somewhere */
/* FIXME: Segment clipping code */
if (overlay->subtitle_buffer > 0) {
GST_DEBUG_OBJECT (overlay, "Should be rendering %u regions",
overlay->subtitle_buffer);
if (!g_queue_is_empty (overlay->pending_subtitles)) {
DVBSubtitles *pending_sub = g_queue_peek_head (overlay->pending_subtitles);
if (vid_running_time >= pending_sub->pts) {
GST_DEBUG_OBJECT (overlay,
"Time to show the next subtitle page (%" GST_TIME_FORMAT " >= %"
GST_TIME_FORMAT ") - it has %u regions",
GST_TIME_ARGS (vid_running_time), GST_TIME_ARGS (pending_sub->pts),
pending_sub->num_rects);
dvb_subtitles_free (overlay->current_subtitle);
overlay->current_subtitle = g_queue_pop_head (overlay->pending_subtitles);
/* FIXME: Pre-convert current_subtitle to a quick-blend format, num_rects=0 means that there are no regions, e.g, a subtitle "clear" happened */
}
}
ret = gst_pad_push (overlay->srcpad, buffer);
@ -1216,6 +1239,8 @@ gst_dvbsub_overlay_event_text (GstPad * pad, GstEvent * event)
break;
case GST_EVENT_FLUSH_START:
GST_DEBUG_OBJECT (render, "begin flushing");
/* FIXME: Reset subtitles queue and any other state */
#if 0 // FIXME
g_mutex_lock (render->ass_mutex);
if (render->ass_track) {

View file

@ -54,14 +54,10 @@ struct _GstDVBSubOverlay
gint fps_n, fps_d;
GstAssRenderBlitFunction blit;
guint subtitle_buffer; /* FIXME: This should hold the pre-rendered
* subtitle regions for fast blending on top
* of each frame. Currently just a number of
* active regions that ought to get blended,
* to get all the timing code working,
* leaving the actual conversion from
* libdvbsub to a suitable cache format and
* blending to later */
DVBSubtitles *current_subtitle; /* The currently active set of subtitle regions, if any */
GQueue *pending_subtitles; /* A queue of raw subtitle region sets with
* metadata that are waiting their running time */
GMutex *subtitle_mutex;
GCond *subtitle_cond; /* to signal removal of a queued text
* buffer, arrival of a text buffer,