mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-17 03:35:21 +00:00
dvbsuboverlay: properly force end-of-display-set
... which is upon receiving new data with different PTS spec-wise, or optionally upon each packet of subtitle data if desired by property. Fixes https://bugzilla.gnome.org/show_bug.cgi?id=669310 Conflicts: gst/dvbsuboverlay/gstdvbsuboverlay.c
This commit is contained in:
parent
76ddd498e2
commit
76b147e803
3 changed files with 52 additions and 4 deletions
|
@ -1187,7 +1187,7 @@ _dvb_sub_parse_display_definition_segment (DvbSub * dvb_sub, guint8 * buf,
|
|||
|
||||
static gint
|
||||
_dvb_sub_parse_end_of_display_set (DvbSub * dvb_sub, guint16 page_id,
|
||||
guint8 * buf, gint buf_size, guint64 pts)
|
||||
guint64 pts)
|
||||
{
|
||||
DVBSubRegionDisplay *display;
|
||||
DVBSubtitles *sub;
|
||||
|
@ -1195,7 +1195,7 @@ _dvb_sub_parse_end_of_display_set (DvbSub * dvb_sub, guint16 page_id,
|
|||
guint32 *clut_table;
|
||||
int i;
|
||||
|
||||
GST_DEBUG ("DISPLAY SET END: page_id = %u, length = %d", page_id, buf_size);
|
||||
GST_DEBUG ("DISPLAY SET END: page_id = %u, length = %d", page_id);
|
||||
|
||||
sub = g_slice_new0 (DVBSubtitles);
|
||||
|
||||
|
@ -1386,7 +1386,13 @@ dvb_sub_feed_with_pts (DvbSub * dvb_sub, guint64 pts, guint8 * data, gint len)
|
|||
|
||||
GST_DEBUG ("pts=%" G_GUINT64_FORMAT " and length %d", pts, len);
|
||||
|
||||
g_return_val_if_fail (data != NULL, -1);
|
||||
g_return_val_if_fail (data != NULL || len == 0, -1);
|
||||
|
||||
if (G_UNLIKELY (data == NULL)) {
|
||||
GST_DEBUG ("no data; forcing end-of-display-set");
|
||||
_dvb_sub_parse_end_of_display_set (dvb_sub, 0, pts);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (len <= 3) { /* len(0x20 0x00 end_of_PES_data_field_marker) */
|
||||
GST_WARNING ("Data length too short");
|
||||
|
@ -1453,7 +1459,7 @@ dvb_sub_feed_with_pts (DvbSub * dvb_sub, guint64 pts, guint8 * data, gint len)
|
|||
break;
|
||||
case DVB_SUB_SEGMENT_END_OF_DISPLAY_SET:
|
||||
GST_DEBUG ("End of display set at buffer pos %u", pos);
|
||||
_dvb_sub_parse_end_of_display_set (dvb_sub, page_id, data + pos, segment_len, pts); /* FIXME: Not sure about args */
|
||||
_dvb_sub_parse_end_of_display_set (dvb_sub, page_id, pts); /* FIXME: Not sure about args */
|
||||
break;
|
||||
default:
|
||||
GST_FIXME ("Unhandled segment type 0x%x", segment_type);
|
||||
|
|
|
@ -57,10 +57,12 @@ enum
|
|||
PROP_0,
|
||||
PROP_ENABLE,
|
||||
PROP_MAX_PAGE_TIMEOUT,
|
||||
PROP_FORCE_END
|
||||
};
|
||||
|
||||
#define DEFAULT_ENABLE (TRUE)
|
||||
#define DEFAULT_MAX_PAGE_TIMEOUT (0)
|
||||
#define DEFAULT_FORCE_END (FALSE)
|
||||
|
||||
static GstStaticPadTemplate src_factory = GST_STATIC_PAD_TEMPLATE ("src",
|
||||
GST_PAD_SRC,
|
||||
|
@ -138,6 +140,11 @@ gst_dvbsub_overlay_class_init (GstDVBSubOverlayClass * klass)
|
|||
0, G_MAXINT, DEFAULT_MAX_PAGE_TIMEOUT,
|
||||
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||
|
||||
g_object_class_install_property (gobject_class, PROP_FORCE_END,
|
||||
g_param_spec_boolean ("force-end", "Force End",
|
||||
"Assume PES-aligned subtitles and force end-of-display",
|
||||
DEFAULT_FORCE_END, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||
|
||||
gstelement_class->change_state =
|
||||
GST_DEBUG_FUNCPTR (gst_dvbsub_overlay_change_state);
|
||||
|
||||
|
@ -178,6 +185,9 @@ gst_dvbsub_overlay_flush_subtitles (GstDVBSubOverlay * render)
|
|||
dvb_sub_set_callbacks (render->dvb_sub, &dvbsub_callbacks, render);
|
||||
}
|
||||
|
||||
render->last_text_pts = GST_CLOCK_TIME_NONE;
|
||||
render->pending_sub = FALSE;
|
||||
|
||||
g_mutex_unlock (&render->dvbsub_mutex);
|
||||
}
|
||||
|
||||
|
@ -220,6 +230,7 @@ gst_dvbsub_overlay_init (GstDVBSubOverlay * render)
|
|||
|
||||
render->enable = DEFAULT_ENABLE;
|
||||
render->max_page_timeout = DEFAULT_MAX_PAGE_TIMEOUT;
|
||||
render->force_end = DEFAULT_FORCE_END;
|
||||
|
||||
g_mutex_init (&render->dvbsub_mutex);
|
||||
gst_dvbsub_overlay_flush_subtitles (render);
|
||||
|
@ -266,6 +277,9 @@ gst_dvbsub_overlay_set_property (GObject * object, guint prop_id,
|
|||
case PROP_MAX_PAGE_TIMEOUT:
|
||||
g_atomic_int_set (&overlay->max_page_timeout, g_value_get_int (value));
|
||||
break;
|
||||
case PROP_FORCE_END:
|
||||
g_atomic_int_set (&overlay->force_end, g_value_get_boolean (value));
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
|
@ -285,6 +299,9 @@ gst_dvbsub_overlay_get_property (GObject * object, guint prop_id,
|
|||
case PROP_MAX_PAGE_TIMEOUT:
|
||||
g_value_set_int (value, g_atomic_int_get (&overlay->max_page_timeout));
|
||||
break;
|
||||
case PROP_FORCE_END:
|
||||
g_value_set_boolean (value, g_atomic_int_get (&overlay->force_end));
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
|
@ -718,10 +735,17 @@ gst_dvbsub_overlay_process_text (GstDVBSubOverlay * overlay, GstBuffer * buffer,
|
|||
|
||||
g_mutex_lock (&overlay->dvbsub_mutex);
|
||||
dvb_sub_feed_with_pts (overlay->dvb_sub, pts, map.data, map.size);
|
||||
overlay->pending_sub = TRUE;
|
||||
g_mutex_unlock (&overlay->dvbsub_mutex);
|
||||
|
||||
gst_buffer_unmap (buffer, &map);
|
||||
gst_buffer_unref (buffer);
|
||||
|
||||
if (overlay->pending_sub && overlay->force_end) {
|
||||
GST_DEBUG_OBJECT (overlay, "forcing subtitle end");
|
||||
dvb_sub_feed_with_pts (overlay->dvb_sub, overlay->last_text_pts, NULL, 0);
|
||||
g_assert (overlay->pending_sub == FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -741,6 +765,7 @@ new_dvb_subtitles_cb (DvbSub * dvb_sub, DVBSubtitles * subs, gpointer user_data)
|
|||
GST_TIME_ARGS (subs->pts));
|
||||
|
||||
g_queue_push_tail (overlay->pending_subtitles, subs);
|
||||
overlay->pending_sub = FALSE;
|
||||
}
|
||||
|
||||
static GstFlowReturn
|
||||
|
@ -768,6 +793,17 @@ gst_dvbsub_overlay_chain_text (GstPad * pad, GstObject * parent,
|
|||
return GST_FLOW_OK;
|
||||
}
|
||||
|
||||
/* spec states multiple PES packets may have same PTS,
|
||||
* and same PTS packets make up a display set */
|
||||
if (overlay->pending_sub &&
|
||||
overlay->last_text_pts != GST_BUFFER_TIMESTAMP (buffer)) {
|
||||
GST_DEBUG_OBJECT (overlay, "finishing previous subtitle");
|
||||
dvb_sub_feed_with_pts (overlay->dvb_sub, overlay->last_text_pts, NULL, 0);
|
||||
overlay->pending_sub = FALSE;
|
||||
}
|
||||
|
||||
overlay->last_text_pts = GST_BUFFER_TIMESTAMP (buffer);
|
||||
|
||||
/* As the passed start and stop is equal, we shouldn't need to care about out of segment at all,
|
||||
* the subtitle data for the PTS is completely out of interest to us. A given display set must
|
||||
* carry the same PTS value. */
|
||||
|
|
|
@ -45,6 +45,7 @@ struct _GstDVBSubOverlay
|
|||
/* properties */
|
||||
gboolean enable;
|
||||
gint max_page_timeout;
|
||||
gboolean force_end;
|
||||
|
||||
/* <private> */
|
||||
GstSegment video_segment;
|
||||
|
@ -58,6 +59,11 @@ struct _GstDVBSubOverlay
|
|||
|
||||
GMutex dvbsub_mutex; /* protects the queue and the DvbSub instance */
|
||||
DvbSub *dvb_sub;
|
||||
|
||||
/* subtitle data submitted to dvb_sub but no sub received yet */
|
||||
gboolean pending_sub;
|
||||
/* last text pts */
|
||||
GstClockTime last_text_pts;
|
||||
};
|
||||
|
||||
struct _GstDVBSubOverlayClass
|
||||
|
|
Loading…
Reference in a new issue