gstvideoaggregator: expose max-last-buffer-repeat property on pads
This can be used to have compositor display either the background or a stream on a lower zorder after a live input stream freezes for a certain amount of time, for example because of network issues.
This commit is contained in:
parent
caca46e0e6
commit
fb1c284026
@ -55,11 +55,13 @@ static void gst_video_aggregator_reset_qos (GstVideoAggregator * vagg);
|
|||||||
|
|
||||||
#define DEFAULT_PAD_ZORDER 0
|
#define DEFAULT_PAD_ZORDER 0
|
||||||
#define DEFAULT_PAD_REPEAT_AFTER_EOS FALSE
|
#define DEFAULT_PAD_REPEAT_AFTER_EOS FALSE
|
||||||
|
#define DEFAULT_PAD_MAX_LAST_BUFFER_REPEAT GST_CLOCK_TIME_NONE
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
PROP_PAD_0,
|
PROP_PAD_0,
|
||||||
PROP_PAD_ZORDER,
|
PROP_PAD_ZORDER,
|
||||||
PROP_PAD_REPEAT_AFTER_EOS,
|
PROP_PAD_REPEAT_AFTER_EOS,
|
||||||
|
PROP_PAD_MAX_LAST_BUFFER_REPEAT,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -71,6 +73,7 @@ struct _GstVideoAggregatorPadPrivate
|
|||||||
/* properties */
|
/* properties */
|
||||||
guint zorder;
|
guint zorder;
|
||||||
gboolean repeat_after_eos;
|
gboolean repeat_after_eos;
|
||||||
|
GstClockTime max_last_buffer_repeat;
|
||||||
|
|
||||||
/* Subclasses can force an alpha channel in the (input thus output)
|
/* Subclasses can force an alpha channel in the (input thus output)
|
||||||
* colorspace format */
|
* colorspace format */
|
||||||
@ -99,6 +102,9 @@ gst_video_aggregator_pad_get_property (GObject * object, guint prop_id,
|
|||||||
case PROP_PAD_REPEAT_AFTER_EOS:
|
case PROP_PAD_REPEAT_AFTER_EOS:
|
||||||
g_value_set_boolean (value, pad->priv->repeat_after_eos);
|
g_value_set_boolean (value, pad->priv->repeat_after_eos);
|
||||||
break;
|
break;
|
||||||
|
case PROP_PAD_MAX_LAST_BUFFER_REPEAT:
|
||||||
|
g_value_set_uint64 (value, pad->priv->max_last_buffer_repeat);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
break;
|
break;
|
||||||
@ -131,6 +137,9 @@ gst_video_aggregator_pad_set_property (GObject * object, guint prop_id,
|
|||||||
case PROP_PAD_REPEAT_AFTER_EOS:
|
case PROP_PAD_REPEAT_AFTER_EOS:
|
||||||
pad->priv->repeat_after_eos = g_value_get_boolean (value);
|
pad->priv->repeat_after_eos = g_value_get_boolean (value);
|
||||||
break;
|
break;
|
||||||
|
case PROP_PAD_MAX_LAST_BUFFER_REPEAT:
|
||||||
|
pad->priv->max_last_buffer_repeat = g_value_get_uint64 (value);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
break;
|
break;
|
||||||
@ -218,6 +227,36 @@ gst_video_aggregator_pad_class_init (GstVideoAggregatorPadClass * klass)
|
|||||||
DEFAULT_PAD_REPEAT_AFTER_EOS,
|
DEFAULT_PAD_REPEAT_AFTER_EOS,
|
||||||
G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE | G_PARAM_STATIC_STRINGS));
|
G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE | G_PARAM_STATIC_STRINGS));
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* GstVideoAggregator:max-last-buffer-repeat:
|
||||||
|
*
|
||||||
|
* Repeat last buffer for time (in ns, -1 = until EOS).
|
||||||
|
* The default behaviour is for the last buffer received on a pad to be
|
||||||
|
* aggregated until a new buffer is received.
|
||||||
|
*
|
||||||
|
* Setting this property causes the last buffer to be discarded once the
|
||||||
|
* running time of the output buffer is `max-last-buffer-repeat` nanoseconds
|
||||||
|
* past its end running time. When the buffer didn't have a duration, the
|
||||||
|
* comparison is made against its running start time.
|
||||||
|
*
|
||||||
|
* This is useful in live scenarios: when a stream encounters a temporary
|
||||||
|
* networking problem, a #GstVideoAggregator subclass can then fall back to
|
||||||
|
* displaying a lower z-order stream, or the background.
|
||||||
|
*
|
||||||
|
* Setting this property doesn't affect the behaviour on EOS.
|
||||||
|
*
|
||||||
|
* Since: 1.18
|
||||||
|
*/
|
||||||
|
g_object_class_install_property (gobject_class,
|
||||||
|
PROP_PAD_MAX_LAST_BUFFER_REPEAT,
|
||||||
|
g_param_spec_uint64 ("max-last-buffer-repeat", "Max Last Buffer Repeat",
|
||||||
|
"Repeat last buffer for time (in ns, -1=until EOS), "
|
||||||
|
"behaviour on EOS is not affected", 0, G_MAXUINT64,
|
||||||
|
DEFAULT_PAD_MAX_LAST_BUFFER_REPEAT,
|
||||||
|
G_PARAM_READWRITE | GST_PARAM_MUTABLE_PLAYING |
|
||||||
|
G_PARAM_STATIC_STRINGS));
|
||||||
|
|
||||||
aggpadclass->flush = GST_DEBUG_FUNCPTR (_flush_pad);
|
aggpadclass->flush = GST_DEBUG_FUNCPTR (_flush_pad);
|
||||||
aggpadclass->skip_buffer =
|
aggpadclass->skip_buffer =
|
||||||
GST_DEBUG_FUNCPTR (gst_video_aggregator_pad_skip_buffer);
|
GST_DEBUG_FUNCPTR (gst_video_aggregator_pad_skip_buffer);
|
||||||
@ -233,6 +272,7 @@ gst_video_aggregator_pad_init (GstVideoAggregatorPad * vaggpad)
|
|||||||
|
|
||||||
vaggpad->priv->zorder = DEFAULT_PAD_ZORDER;
|
vaggpad->priv->zorder = DEFAULT_PAD_ZORDER;
|
||||||
vaggpad->priv->repeat_after_eos = DEFAULT_PAD_REPEAT_AFTER_EOS;
|
vaggpad->priv->repeat_after_eos = DEFAULT_PAD_REPEAT_AFTER_EOS;
|
||||||
|
vaggpad->priv->max_last_buffer_repeat = DEFAULT_PAD_MAX_LAST_BUFFER_REPEAT;
|
||||||
memset (&vaggpad->priv->prepared_frame, 0, sizeof (GstVideoFrame));
|
memset (&vaggpad->priv->prepared_frame, 0, sizeof (GstVideoFrame));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1459,6 +1499,7 @@ gst_video_aggregator_fill_queues (GstVideoAggregator * vagg,
|
|||||||
}
|
}
|
||||||
gst_buffer_unref (buf);
|
gst_buffer_unref (buf);
|
||||||
gst_aggregator_pad_drop_buffer (bpad);
|
gst_aggregator_pad_drop_buffer (bpad);
|
||||||
|
pad->priv->start_time = start_time;
|
||||||
need_more_data = TRUE;
|
need_more_data = TRUE;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -1470,7 +1511,8 @@ gst_video_aggregator_fill_queues (GstVideoAggregator * vagg,
|
|||||||
need_reconfigure = TRUE;
|
need_reconfigure = TRUE;
|
||||||
pad->priv->pending_vinfo.finfo = NULL;
|
pad->priv->pending_vinfo.finfo = NULL;
|
||||||
}
|
}
|
||||||
/* FIXME: Set start_time and end_time to something here? */
|
/* FIXME: Set end_time to something here? */
|
||||||
|
pad->priv->start_time = start_time;
|
||||||
gst_buffer_unref (buf);
|
gst_buffer_unref (buf);
|
||||||
GST_DEBUG_OBJECT (pad, "buffer duration is -1");
|
GST_DEBUG_OBJECT (pad, "buffer duration is -1");
|
||||||
continue;
|
continue;
|
||||||
@ -1568,18 +1610,41 @@ gst_video_aggregator_fill_queues (GstVideoAggregator * vagg,
|
|||||||
|
|
||||||
if (pad->priv->end_time != -1) {
|
if (pad->priv->end_time != -1) {
|
||||||
if (pad->priv->end_time <= output_start_running_time) {
|
if (pad->priv->end_time <= output_start_running_time) {
|
||||||
pad->priv->start_time = pad->priv->end_time = -1;
|
|
||||||
if (!is_eos) {
|
if (!is_eos) {
|
||||||
GST_DEBUG ("I just need more data");
|
GST_DEBUG_OBJECT (pad, "I just need more data");
|
||||||
|
if (GST_CLOCK_TIME_IS_VALID (pad->priv->max_last_buffer_repeat)) {
|
||||||
|
if (output_start_running_time - pad->priv->end_time >
|
||||||
|
pad->priv->max_last_buffer_repeat) {
|
||||||
|
pad->priv->start_time = pad->priv->end_time = -1;
|
||||||
|
gst_buffer_replace (&pad->priv->buffer, NULL);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
pad->priv->start_time = pad->priv->end_time = -1;
|
||||||
|
}
|
||||||
need_more_data = TRUE;
|
need_more_data = TRUE;
|
||||||
} else {
|
} else {
|
||||||
gst_buffer_replace (&pad->priv->buffer, NULL);
|
gst_buffer_replace (&pad->priv->buffer, NULL);
|
||||||
|
pad->priv->start_time = pad->priv->end_time = -1;
|
||||||
}
|
}
|
||||||
} else if (is_eos) {
|
} else if (is_eos) {
|
||||||
eos = FALSE;
|
eos = FALSE;
|
||||||
}
|
}
|
||||||
} else if (is_eos) {
|
} else if (is_eos) {
|
||||||
gst_buffer_replace (&pad->priv->buffer, NULL);
|
gst_buffer_replace (&pad->priv->buffer, NULL);
|
||||||
|
} else if (pad->priv->start_time != -1) {
|
||||||
|
/* When the current buffer didn't have a duration, but
|
||||||
|
* max-last-buffer-repeat was set, we use start_time as
|
||||||
|
* the comparison point
|
||||||
|
*/
|
||||||
|
if (pad->priv->start_time <= output_start_running_time) {
|
||||||
|
if (GST_CLOCK_TIME_IS_VALID (pad->priv->max_last_buffer_repeat)) {
|
||||||
|
if (output_start_running_time - pad->priv->start_time >
|
||||||
|
pad->priv->max_last_buffer_repeat) {
|
||||||
|
pad->priv->start_time = pad->priv->end_time = -1;
|
||||||
|
gst_buffer_replace (&pad->priv->buffer, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user