mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-23 18:21:04 +00:00
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:
parent
41c82583f5
commit
3d09a3b18a
2 changed files with 35 additions and 14 deletions
|
@ -234,6 +234,9 @@ gst_dvbsub_overlay_init (GstDVBSubOverlay * render,
|
||||||
render->subtitle_mutex = g_mutex_new ();
|
render->subtitle_mutex = g_mutex_new ();
|
||||||
render->subtitle_cond = g_cond_new ();
|
render->subtitle_cond = g_cond_new ();
|
||||||
|
|
||||||
|
render->current_subtitle = NULL;
|
||||||
|
render->pending_subtitles = g_queue_new ();
|
||||||
|
|
||||||
render->renderer_init_ok = FALSE;
|
render->renderer_init_ok = FALSE;
|
||||||
render->enable = TRUE;
|
render->enable = TRUE;
|
||||||
|
|
||||||
|
@ -270,6 +273,11 @@ gst_dvbsub_overlay_finalize (GObject * object)
|
||||||
if (overlay->subtitle_cond)
|
if (overlay->subtitle_cond)
|
||||||
g_cond_free (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) {
|
if (overlay->dvb_sub) {
|
||||||
g_object_unref (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,
|
subs->page_time_out, subs->num_rects, subs->pts,
|
||||||
GST_TIME_ARGS (subs->pts));
|
GST_TIME_ARGS (subs->pts));
|
||||||
//GST_OBJECT_LOCK (overlay);
|
//GST_OBJECT_LOCK (overlay);
|
||||||
overlay->subtitle_buffer = subs->num_rects;
|
g_queue_push_tail (overlay->pending_subtitles, subs);
|
||||||
//GST_OBJECT_UNLOCK (overlay);
|
//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_DEBUG_OBJECT (overlay, "SUBTITLE real running time: %" GST_TIME_FORMAT,
|
||||||
GST_TIME_ARGS (sub_running_time));
|
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 */
|
/* 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 */
|
/*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));
|
GstDVBSubOverlay *overlay = GST_DVBSUB_OVERLAY (GST_PAD_PARENT (pad));
|
||||||
GstFlowReturn ret = GST_FLOW_OK;
|
GstFlowReturn ret = GST_FLOW_OK;
|
||||||
gint64 start, stop;
|
gint64 start, stop;
|
||||||
|
GstClockTime vid_running_time;
|
||||||
|
|
||||||
if (!GST_BUFFER_TIMESTAMP_IS_VALID (buffer))
|
if (!GST_BUFFER_TIMESTAMP_IS_VALID (buffer))
|
||||||
goto missing_timestamp;
|
goto missing_timestamp;
|
||||||
|
@ -1086,13 +1093,29 @@ gst_dvbsub_overlay_chain_video (GstPad * pad, GstBuffer * buffer)
|
||||||
stop = start + GST_BUFFER_DURATION (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: Probably update last_stop somewhere */
|
||||||
|
|
||||||
/* FIXME: Segment clipping code */
|
/* FIXME: Segment clipping code */
|
||||||
|
|
||||||
if (overlay->subtitle_buffer > 0) {
|
if (!g_queue_is_empty (overlay->pending_subtitles)) {
|
||||||
GST_DEBUG_OBJECT (overlay, "Should be rendering %u regions",
|
DVBSubtitles *pending_sub = g_queue_peek_head (overlay->pending_subtitles);
|
||||||
overlay->subtitle_buffer);
|
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);
|
ret = gst_pad_push (overlay->srcpad, buffer);
|
||||||
|
@ -1216,6 +1239,8 @@ gst_dvbsub_overlay_event_text (GstPad * pad, GstEvent * event)
|
||||||
break;
|
break;
|
||||||
case GST_EVENT_FLUSH_START:
|
case GST_EVENT_FLUSH_START:
|
||||||
GST_DEBUG_OBJECT (render, "begin flushing");
|
GST_DEBUG_OBJECT (render, "begin flushing");
|
||||||
|
|
||||||
|
/* FIXME: Reset subtitles queue and any other state */
|
||||||
#if 0 // FIXME
|
#if 0 // FIXME
|
||||||
g_mutex_lock (render->ass_mutex);
|
g_mutex_lock (render->ass_mutex);
|
||||||
if (render->ass_track) {
|
if (render->ass_track) {
|
||||||
|
|
|
@ -54,14 +54,10 @@ struct _GstDVBSubOverlay
|
||||||
gint fps_n, fps_d;
|
gint fps_n, fps_d;
|
||||||
GstAssRenderBlitFunction blit;
|
GstAssRenderBlitFunction blit;
|
||||||
|
|
||||||
guint subtitle_buffer; /* FIXME: This should hold the pre-rendered
|
DVBSubtitles *current_subtitle; /* The currently active set of subtitle regions, if any */
|
||||||
* subtitle regions for fast blending on top
|
GQueue *pending_subtitles; /* A queue of raw subtitle region sets with
|
||||||
* of each frame. Currently just a number of
|
* metadata that are waiting their running time */
|
||||||
* 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 */
|
|
||||||
GMutex *subtitle_mutex;
|
GMutex *subtitle_mutex;
|
||||||
GCond *subtitle_cond; /* to signal removal of a queued text
|
GCond *subtitle_cond; /* to signal removal of a queued text
|
||||||
* buffer, arrival of a text buffer,
|
* buffer, arrival of a text buffer,
|
||||||
|
|
Loading…
Reference in a new issue