mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-27 18:50:48 +00:00
videorate: fix dynamically changing average period
The average_period_set variable can be accessed in different threads, so always lock it when reading. Furthermore when switching to averaging mode we should make sure we don't have cached buffers that aren't used in that mode. And any modeswitch will cause the latency to change, so we should post a NewLatency message
This commit is contained in:
parent
ea46b3c706
commit
08ac05a06c
1 changed files with 30 additions and 12 deletions
|
@ -645,10 +645,14 @@ gst_video_rate_query (GstBaseTransform * trans, GstPadDirection direction,
|
|||
GstClockTime min, max;
|
||||
gboolean live;
|
||||
guint64 latency;
|
||||
guint64 avg_period;
|
||||
GstPad *peer;
|
||||
|
||||
if (videorate->average_period == 0
|
||||
&& (peer = gst_pad_get_peer (otherpad))) {
|
||||
GST_OBJECT_LOCK (videorate);
|
||||
avg_period = videorate->average_period_set;
|
||||
GST_OBJECT_UNLOCK (videorate);
|
||||
|
||||
if (avg_period == 0 && (peer = gst_pad_get_peer (otherpad))) {
|
||||
if ((res = gst_pad_query (peer, query))) {
|
||||
gst_query_parse_latency (query, &live, &min, &max);
|
||||
|
||||
|
@ -682,8 +686,10 @@ gst_video_rate_query (GstBaseTransform * trans, GstPadDirection direction,
|
|||
gst_query_set_latency (query, live, min, max);
|
||||
}
|
||||
gst_object_unref (peer);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
/* Simple fallthrough if we don't have a latency or not a peer that we
|
||||
* can't ask about its latency yet.. */
|
||||
}
|
||||
default:
|
||||
res = parent_class->query (trans, direction, query);
|
||||
|
@ -783,17 +789,25 @@ gst_video_rate_transform_ip (GstBaseTransform * trans, GstBuffer * buffer)
|
|||
|
||||
/* MT-safe switching between modes */
|
||||
if (G_UNLIKELY (avg_period != videorate->average_period)) {
|
||||
gboolean switch_mode = (avg_period == 0 || videorate->average_period == 0);
|
||||
videorate->average_period = avg_period;
|
||||
videorate->last_ts = GST_CLOCK_TIME_NONE;
|
||||
if (avg_period && !videorate->average) {
|
||||
/* enabling average mode */
|
||||
videorate->average = 0;
|
||||
} else {
|
||||
/* enable regular mode */
|
||||
gst_video_rate_swap_prev (videorate, NULL, 0);
|
||||
/* arrange for skip-to-first behaviour */
|
||||
videorate->next_ts = GST_CLOCK_TIME_NONE;
|
||||
skip = TRUE;
|
||||
|
||||
if (switch_mode) {
|
||||
if (avg_period) {
|
||||
/* enabling average mode */
|
||||
videorate->average = 0;
|
||||
/* make sure no cached buffers from regular mode are left */
|
||||
gst_video_rate_swap_prev (videorate, NULL, 0);
|
||||
} else {
|
||||
/* enable regular mode */
|
||||
videorate->next_ts = GST_CLOCK_TIME_NONE;
|
||||
skip = TRUE;
|
||||
}
|
||||
|
||||
/* max averaging mode has a no latency, normal mode does */
|
||||
gst_element_post_message (GST_ELEMENT (videorate),
|
||||
gst_message_new_latency (GST_OBJECT (videorate)));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -980,7 +994,9 @@ gst_video_rate_set_property (GObject * object,
|
|||
videorate->drop_only = g_value_get_boolean (value);
|
||||
break;
|
||||
case ARG_AVERAGE_PERIOD:
|
||||
GST_OBJECT_LOCK (videorate);
|
||||
videorate->average_period_set = g_value_get_uint64 (value);
|
||||
GST_OBJECT_UNLOCK (videorate);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
|
@ -1022,7 +1038,9 @@ gst_video_rate_get_property (GObject * object,
|
|||
g_value_set_boolean (value, videorate->drop_only);
|
||||
break;
|
||||
case ARG_AVERAGE_PERIOD:
|
||||
GST_OBJECT_LOCK (videorate);
|
||||
g_value_set_uint64 (value, videorate->average_period_set);
|
||||
GST_OBJECT_UNLOCK (videorate);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
|
|
Loading…
Reference in a new issue