mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-22 14:06:23 +00:00
videoencoder: add qos property
This new property control if the encoder base class should gather QoS stats and if subclasses should use them by dropping late frames. https://bugzilla.gnome.org/show_bug.cgi?id=789467
This commit is contained in:
parent
346c24dc4b
commit
7950a4614c
3 changed files with 113 additions and 0 deletions
|
@ -79,6 +79,13 @@
|
|||
* * Accept data in @handle_frame and provide encoded results to
|
||||
* @gst_video_encoder_finish_frame.
|
||||
*
|
||||
*
|
||||
* The #GstVideoEncoder:qos property will enable the Quality-of-Service
|
||||
* features of the encoder which gather statistics about the real-time
|
||||
* performance of the downstream elements. If enabled, subclasses can
|
||||
* use gst_video_encoder_get_max_encode_time() to check if input frames
|
||||
* are already late and drop them right away to give a chance to the
|
||||
* pipeline to catch up.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
|
@ -108,6 +115,17 @@ GST_DEBUG_CATEGORY (videoencoder_debug);
|
|||
(G_TYPE_INSTANCE_GET_PRIVATE ((obj), GST_TYPE_VIDEO_ENCODER, \
|
||||
GstVideoEncoderPrivate))
|
||||
|
||||
/* properties */
|
||||
|
||||
#define DEFAULT_QOS FALSE
|
||||
|
||||
enum
|
||||
{
|
||||
PROP_0,
|
||||
PROP_QOS,
|
||||
PROP_LAST
|
||||
};
|
||||
|
||||
struct _GstVideoEncoderPrivate
|
||||
{
|
||||
guint64 presentation_frame_number;
|
||||
|
@ -154,6 +172,7 @@ struct _GstVideoEncoderPrivate
|
|||
GstClockTime time_adjustment;
|
||||
|
||||
/* QoS properties */
|
||||
gint qos_enabled; /* ATOMIC */
|
||||
gdouble proportion; /* OBJECT_LOCK */
|
||||
GstClockTime earliest_time; /* OBJECT_LOCK */
|
||||
GstClockTime qos_frame_duration; /* OBJECT_LOCK */
|
||||
|
@ -273,6 +292,38 @@ gst_video_encoder_get_type (void)
|
|||
return type;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_video_encoder_set_property (GObject * object, guint prop_id,
|
||||
const GValue * value, GParamSpec * pspec)
|
||||
{
|
||||
GstVideoEncoder *sink = GST_VIDEO_ENCODER (object);
|
||||
|
||||
switch (prop_id) {
|
||||
case PROP_QOS:
|
||||
gst_video_encoder_set_qos_enabled (sink, g_value_get_boolean (value));
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gst_video_encoder_get_property (GObject * object, guint prop_id, GValue * value,
|
||||
GParamSpec * pspec)
|
||||
{
|
||||
GstVideoEncoder *sink = GST_VIDEO_ENCODER (object);
|
||||
|
||||
switch (prop_id) {
|
||||
case PROP_QOS:
|
||||
g_value_set_boolean (value, gst_video_encoder_is_qos_enabled (sink));
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gst_video_encoder_class_init (GstVideoEncoderClass * klass)
|
||||
{
|
||||
|
@ -289,6 +340,8 @@ gst_video_encoder_class_init (GstVideoEncoderClass * klass)
|
|||
|
||||
g_type_class_add_private (klass, sizeof (GstVideoEncoderPrivate));
|
||||
|
||||
gobject_class->set_property = gst_video_encoder_set_property;
|
||||
gobject_class->get_property = gst_video_encoder_get_property;
|
||||
gobject_class->finalize = gst_video_encoder_finalize;
|
||||
|
||||
gstelement_class->change_state =
|
||||
|
@ -302,6 +355,11 @@ gst_video_encoder_class_init (GstVideoEncoderClass * klass)
|
|||
klass->sink_query = gst_video_encoder_sink_query_default;
|
||||
klass->src_query = gst_video_encoder_src_query_default;
|
||||
klass->transform_meta = gst_video_encoder_transform_meta_default;
|
||||
|
||||
g_object_class_install_property (gobject_class, PROP_QOS,
|
||||
g_param_spec_boolean ("qos", "Qos",
|
||||
"Handle Quality-of-Service events from downstream", DEFAULT_QOS,
|
||||
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||
}
|
||||
|
||||
static GList *
|
||||
|
@ -1196,6 +1254,9 @@ gst_video_encoder_src_event_default (GstVideoEncoder * encoder,
|
|||
GstClockTimeDiff diff;
|
||||
GstClockTime timestamp;
|
||||
|
||||
if (!g_atomic_int_get (&priv->qos_enabled))
|
||||
break;
|
||||
|
||||
gst_event_parse_qos (event, &type, &proportion, &diff, ×tamp);
|
||||
|
||||
GST_OBJECT_LOCK (encoder);
|
||||
|
@ -2585,6 +2646,9 @@ gst_video_encoder_set_min_pts (GstVideoEncoder * encoder, GstClockTime min_pts)
|
|||
* In particular, a negative result means encoding in time is no longer possible
|
||||
* and should therefore occur as soon/skippy as possible.
|
||||
*
|
||||
* If no QoS events have been received from downstream, or if
|
||||
* #GstVideoEncoder:qos is disabled this function returns #G_MAXINT64.
|
||||
*
|
||||
* Returns: max decoding time.
|
||||
* Since: 1.14
|
||||
*/
|
||||
|
@ -2595,6 +2659,9 @@ gst_video_encoder_get_max_encode_time (GstVideoEncoder *
|
|||
GstClockTimeDiff deadline;
|
||||
GstClockTime earliest_time;
|
||||
|
||||
if (!g_atomic_int_get (&encoder->priv->qos_enabled))
|
||||
return G_MAXINT64;
|
||||
|
||||
GST_OBJECT_LOCK (encoder);
|
||||
earliest_time = encoder->priv->earliest_time;
|
||||
if (GST_CLOCK_TIME_IS_VALID (earliest_time)
|
||||
|
@ -2612,3 +2679,41 @@ gst_video_encoder_get_max_encode_time (GstVideoEncoder *
|
|||
|
||||
return deadline;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_video_encoder_set_qos_enabled:
|
||||
* @encoder: the encoder
|
||||
* @enabled: the new qos value.
|
||||
*
|
||||
* Configures @encoder to handle Quality-of-Service events from downstream.
|
||||
* Since: 1.14
|
||||
*/
|
||||
void
|
||||
gst_video_encoder_set_qos_enabled (GstVideoEncoder * encoder, gboolean enabled)
|
||||
{
|
||||
g_return_if_fail (GST_IS_VIDEO_ENCODER (encoder));
|
||||
|
||||
g_atomic_int_set (&encoder->priv->qos_enabled, enabled);
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_video_encoder_is_qos_enabled:
|
||||
* @encoder: the encoder
|
||||
*
|
||||
* Checks if @encoder is currently configured to handle Quality-of-Service
|
||||
* events from downstream.
|
||||
*
|
||||
* Returns: %TRUE if the encoder is configured to perform Quality-of-Service.
|
||||
* Since: 1.14
|
||||
*/
|
||||
gboolean
|
||||
gst_video_encoder_is_qos_enabled (GstVideoEncoder * encoder)
|
||||
{
|
||||
gboolean res;
|
||||
|
||||
g_return_val_if_fail (GST_IS_VIDEO_ENCODER (encoder), FALSE);
|
||||
|
||||
res = g_atomic_int_get (&encoder->priv->qos_enabled);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
|
|
@ -368,6 +368,12 @@ void gst_video_encoder_get_allocator (GstVideoEncoder *encoder,
|
|||
GST_EXPORT
|
||||
void gst_video_encoder_set_min_pts(GstVideoEncoder *encoder, GstClockTime min_pts);
|
||||
|
||||
GST_EXPORT
|
||||
void gst_video_encoder_set_qos_enabled (GstVideoEncoder * encoder, gboolean enabled);
|
||||
|
||||
GST_EXPORT
|
||||
gboolean gst_video_encoder_is_qos_enabled (GstVideoEncoder * encoder);
|
||||
|
||||
GST_EXPORT
|
||||
GstClockTimeDiff gst_video_encoder_get_max_encode_time (GstVideoEncoder *encoder, GstVideoCodecFrame * frame);
|
||||
|
||||
|
|
|
@ -552,6 +552,8 @@ GST_START_TEST (videoencoder_qos)
|
|||
|
||||
setup_videoencodertester ();
|
||||
|
||||
gst_video_encoder_set_qos_enabled (GST_VIDEO_ENCODER (enc), TRUE);
|
||||
|
||||
gst_pad_set_active (mysrcpad, TRUE);
|
||||
gst_element_set_state (enc, GST_STATE_PLAYING);
|
||||
gst_pad_set_active (mysinkpad, TRUE);
|
||||
|
|
Loading…
Reference in a new issue