mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-20 21:16:24 +00:00
cccombiner: add support for timing out captions without EOS
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/6335>
This commit is contained in:
parent
a9378c048e
commit
da35ed6916
3 changed files with 80 additions and 12 deletions
|
@ -7872,6 +7872,20 @@
|
|||
"readable": true,
|
||||
"type": "gboolean",
|
||||
"writable": true
|
||||
},
|
||||
"schedule-timeout": {
|
||||
"blurb": "How long after not receiving caption data on the caption pad to continue adding (padding) caption data on output buffers",
|
||||
"conditionally-available": false,
|
||||
"construct": false,
|
||||
"construct-only": false,
|
||||
"controllable": false,
|
||||
"default": "18446744073709551615",
|
||||
"max": "18446744073709551615",
|
||||
"min": "0",
|
||||
"mutable": "playing",
|
||||
"readable": true,
|
||||
"type": "guint64",
|
||||
"writable": true
|
||||
}
|
||||
},
|
||||
"rank": "none"
|
||||
|
|
|
@ -65,6 +65,7 @@ enum
|
|||
PROP_MAX_SCHEDULED,
|
||||
PROP_CEA608_PADDING_STRATEGY,
|
||||
PROP_CEA608_VALID_PADDING_TIMEOUT,
|
||||
PROP_SCHEDULE_TIMEOUT,
|
||||
};
|
||||
|
||||
#define DEFAULT_MAX_SCHEDULED 30
|
||||
|
@ -72,6 +73,7 @@ enum
|
|||
#define DEFAULT_OUTPUT_PADDING TRUE
|
||||
#define DEFAULT_CEA608_PADDING_STRATEGY CC_BUFFER_CEA608_PADDING_STRATEGY_VALID
|
||||
#define DEFAULT_CEA608_VALID_PADDING_TIMEOUT GST_CLOCK_TIME_NONE
|
||||
#define DEFAULT_SCHEDULE_TIMEOUT GST_CLOCK_TIME_NONE
|
||||
|
||||
typedef struct
|
||||
{
|
||||
|
@ -277,25 +279,24 @@ schedule_caption (GstCCCombiner * self, GstBuffer * caption_buf,
|
|||
const GstVideoTimeCode * tc)
|
||||
{
|
||||
GstMapInfo map;
|
||||
GstClockTime pts, duration;
|
||||
GstClockTime pts, duration, running_time;
|
||||
GstAggregatorPad *caption_pad;
|
||||
|
||||
pts = GST_BUFFER_PTS (caption_buf);
|
||||
duration = GST_BUFFER_DURATION (caption_buf);
|
||||
|
||||
if (self->current_scheduled + 1 >= self->max_scheduled) {
|
||||
GstClockTime stream_time, running_time;
|
||||
GstAggregatorPad *caption_pad;
|
||||
caption_pad =
|
||||
GST_AGGREGATOR_PAD_CAST (gst_element_get_static_pad (GST_ELEMENT_CAST
|
||||
(self), "caption"));
|
||||
running_time =
|
||||
gst_segment_to_running_time (&caption_pad->segment, GST_FORMAT_TIME, pts);
|
||||
|
||||
caption_pad =
|
||||
GST_AGGREGATOR_PAD_CAST (gst_element_get_static_pad (GST_ELEMENT_CAST
|
||||
(self), "caption"));
|
||||
if (self->current_scheduled + 1 >= self->max_scheduled) {
|
||||
GstClockTime stream_time;
|
||||
|
||||
GST_WARNING_OBJECT (self,
|
||||
"scheduled queue runs too long, discarding stored");
|
||||
|
||||
running_time =
|
||||
gst_segment_to_running_time (&caption_pad->segment, GST_FORMAT_TIME,
|
||||
pts);
|
||||
stream_time =
|
||||
gst_segment_to_stream_time (&caption_pad->segment, GST_FORMAT_TIME,
|
||||
pts);
|
||||
|
@ -306,10 +307,12 @@ schedule_caption (GstCCCombiner * self, GstBuffer * caption_buf,
|
|||
|
||||
cc_buffer_discard (self->cc_buffer);
|
||||
self->current_scheduled = 0;
|
||||
|
||||
gst_clear_object (&caption_pad);
|
||||
}
|
||||
|
||||
self->last_caption_ts = running_time;
|
||||
|
||||
gst_clear_object (&caption_pad);
|
||||
|
||||
gst_buffer_map (caption_buf, &map, GST_MAP_READ);
|
||||
|
||||
switch (self->caption_type) {
|
||||
|
@ -346,6 +349,24 @@ dequeue_caption (GstCCCombiner * self, GstVideoTimeCode * tc, gboolean drain)
|
|||
if (drain && cc_buffer_is_empty (self->cc_buffer))
|
||||
return;
|
||||
|
||||
if (self->prop_schedule_timeout != GST_CLOCK_TIME_NONE) {
|
||||
if (self->last_caption_ts == GST_CLOCK_TIME_NONE) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (self->current_video_running_time > self->last_caption_ts
|
||||
&& self->current_video_running_time - self->last_caption_ts
|
||||
> self->prop_schedule_timeout) {
|
||||
GST_LOG_OBJECT (self, "Not outputting caption as last caption buffer ts %"
|
||||
GST_TIME_FORMAT " is more than the schedule timeout %" GST_TIME_FORMAT
|
||||
" from the current output time %" GST_TIME_FORMAT,
|
||||
GST_TIME_ARGS (self->last_caption_ts),
|
||||
GST_TIME_ARGS (self->prop_schedule_timeout),
|
||||
GST_TIME_ARGS (self->current_video_running_time));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
caption_data.caption_type = self->caption_type;
|
||||
switch (self->caption_type) {
|
||||
case GST_VIDEO_CAPTION_TYPE_CEA708_CDP:
|
||||
|
@ -859,6 +880,11 @@ gst_cc_combiner_sink_event (GstAggregator * aggregator,
|
|||
}
|
||||
break;
|
||||
}
|
||||
case GST_EVENT_STREAM_START:{
|
||||
if (strcmp (GST_OBJECT_NAME (agg_pad), "caption") == 0) {
|
||||
self->last_caption_ts = GST_CLOCK_TIME_NONE;
|
||||
}
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -1138,6 +1164,9 @@ gst_cc_combiner_set_property (GObject * object, guint prop_id,
|
|||
cc_buffer_set_cea608_valid_timeout (self->cc_buffer,
|
||||
self->prop_cea608_valid_padding_timeout);
|
||||
break;
|
||||
case PROP_SCHEDULE_TIMEOUT:
|
||||
self->prop_schedule_timeout = g_value_get_uint64 (value);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
|
@ -1166,6 +1195,9 @@ gst_cc_combiner_get_property (GObject * object, guint prop_id, GValue * value,
|
|||
case PROP_CEA608_VALID_PADDING_TIMEOUT:
|
||||
g_value_set_uint64 (value, self->prop_cea608_valid_padding_timeout);
|
||||
break;
|
||||
case PROP_SCHEDULE_TIMEOUT:
|
||||
g_value_set_uint64 (value, self->prop_schedule_timeout);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
|
@ -1294,6 +1326,24 @@ gst_cc_combiner_class_init (GstCCCombinerClass * klass)
|
|||
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
|
||||
GST_PARAM_MUTABLE_PLAYING));
|
||||
|
||||
/**
|
||||
* GstCCCombiner:schedule-timeout:
|
||||
*
|
||||
* Timeout to apply when the caption pad is EOS and schedule=true. On
|
||||
* reaching the timeout, no caption data will be placed on the outgoing
|
||||
* buffers until receiving a new stream.
|
||||
*
|
||||
* Since: 1.26
|
||||
*/
|
||||
g_object_class_install_property (G_OBJECT_CLASS (klass),
|
||||
PROP_SCHEDULE_TIMEOUT,
|
||||
g_param_spec_uint64 ("schedule-timeout",
|
||||
"Schedule Timeout",
|
||||
"How long after not receiving caption data on the caption pad to continue adding (padding) caption data on output buffers",
|
||||
0, G_MAXUINT64, DEFAULT_SCHEDULE_TIMEOUT,
|
||||
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
|
||||
GST_PARAM_MUTABLE_PLAYING));
|
||||
|
||||
gst_element_class_add_static_pad_template_with_gtype (gstelement_class,
|
||||
&sinktemplate, GST_TYPE_AGGREGATOR_PAD);
|
||||
gst_element_class_add_static_pad_template_with_gtype (gstelement_class,
|
||||
|
@ -1347,8 +1397,10 @@ gst_cc_combiner_init (GstCCCombiner * self)
|
|||
self->prop_cea608_padding_strategy = DEFAULT_CEA608_PADDING_STRATEGY;
|
||||
self->prop_cea608_valid_padding_timeout =
|
||||
DEFAULT_CEA608_VALID_PADDING_TIMEOUT;
|
||||
self->prop_schedule_timeout = DEFAULT_SCHEDULE_TIMEOUT;
|
||||
self->cdp_hdr_sequence_cntr = 0;
|
||||
self->cdp_fps_entry = &null_fps_entry;
|
||||
self->last_caption_ts = GST_CLOCK_TIME_NONE;
|
||||
|
||||
self->cc_buffer = cc_buffer_new ();
|
||||
cc_buffer_set_max_buffer_time (self->cc_buffer, GST_CLOCK_TIME_NONE);
|
||||
|
|
|
@ -61,11 +61,13 @@ struct _GstCCCombiner
|
|||
gboolean prop_output_padding;
|
||||
CCBufferCea608PaddingStrategy prop_cea608_padding_strategy;
|
||||
GstClockTime prop_cea608_valid_padding_timeout;
|
||||
GstClockTime prop_schedule_timeout;
|
||||
|
||||
gboolean schedule;
|
||||
guint max_scheduled;
|
||||
gboolean output_padding;
|
||||
guint current_scheduled;
|
||||
GstClockTime last_caption_ts;
|
||||
|
||||
CCBuffer *cc_buffer;
|
||||
guint16 cdp_hdr_sequence_cntr;
|
||||
|
|
Loading…
Reference in a new issue