mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-21 13:36:39 +00:00
gst/: Move latency query from GstPipeline to GstBin so that we can also use it when async-handling is enabled on bins.
Original commit message from CVS: * gst/gstbin.c: (gst_bin_class_init), (clear_queue), (do_bin_latency), (gst_bin_change_state_func): * gst/gstpipeline.c: (gst_pipeline_change_state): Move latency query from GstPipeline to GstBin so that we can also use it when async-handling is enabled on bins.
This commit is contained in:
parent
2a94dbb663
commit
b155f59d19
3 changed files with 77 additions and 40 deletions
|
@ -1,3 +1,11 @@
|
||||||
|
2007-09-13 Wim Taymans <wim.taymans@gmail.com>
|
||||||
|
|
||||||
|
* gst/gstbin.c: (gst_bin_class_init), (clear_queue),
|
||||||
|
(do_bin_latency), (gst_bin_change_state_func):
|
||||||
|
* gst/gstpipeline.c: (gst_pipeline_change_state):
|
||||||
|
Move latency query from GstPipeline to GstBin so that we can also
|
||||||
|
use it when async-handling is enabled on bins.
|
||||||
|
|
||||||
2007-09-13 Wim Taymans <wim.taymans@gmail.com>
|
2007-09-13 Wim Taymans <wim.taymans@gmail.com>
|
||||||
|
|
||||||
* libs/gst/base/gstbasesrc.c: (gst_base_src_query_latency),
|
* libs/gst/base/gstbasesrc.c: (gst_base_src_query_latency),
|
||||||
|
|
72
gst/gstbin.c
72
gst/gstbin.c
|
@ -395,7 +395,7 @@ gst_bin_class_init (GstBinClass * klass)
|
||||||
*
|
*
|
||||||
* If set to #TRUE, the bin will handle asynchronous state changes.
|
* If set to #TRUE, the bin will handle asynchronous state changes.
|
||||||
* This should be used only if the bin subclass is modifying the state
|
* This should be used only if the bin subclass is modifying the state
|
||||||
* of its childs on its own.
|
* of its children on its own.
|
||||||
*
|
*
|
||||||
* Since: 0.10.13
|
* Since: 0.10.13
|
||||||
*/
|
*/
|
||||||
|
@ -1603,7 +1603,6 @@ clear_queue (GQueue * queue)
|
||||||
|
|
||||||
while ((p = g_queue_pop_head (queue)))
|
while ((p = g_queue_pop_head (queue)))
|
||||||
gst_object_unref (p);
|
gst_object_unref (p);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* set all degrees to 0. Elements marked as a sink are
|
/* set all degrees to 0. Elements marked as a sink are
|
||||||
|
@ -2017,6 +2016,58 @@ failed:
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
do_bin_latency (GstElement * element)
|
||||||
|
{
|
||||||
|
GstQuery *query;
|
||||||
|
GstClockTime min_latency, max_latency;
|
||||||
|
gboolean res;
|
||||||
|
|
||||||
|
GST_DEBUG_OBJECT (element, "querying latency");
|
||||||
|
|
||||||
|
query = gst_query_new_latency ();
|
||||||
|
if ((res = gst_element_query (element, query))) {
|
||||||
|
gboolean live;
|
||||||
|
|
||||||
|
gst_query_parse_latency (query, &live, &min_latency, &max_latency);
|
||||||
|
|
||||||
|
GST_DEBUG_OBJECT (element,
|
||||||
|
"got min latency %" GST_TIME_FORMAT ", max latency %"
|
||||||
|
GST_TIME_FORMAT ", live %d", GST_TIME_ARGS (min_latency),
|
||||||
|
GST_TIME_ARGS (max_latency), live);
|
||||||
|
|
||||||
|
if (max_latency < min_latency) {
|
||||||
|
/* this is an impossible situation, some parts of the pipeline might not
|
||||||
|
* work correctly. We post a warning for now. */
|
||||||
|
GST_ELEMENT_WARNING (element, CORE, CLOCK, (NULL),
|
||||||
|
("Impossible to configure latency: max %" GST_TIME_FORMAT " < min %"
|
||||||
|
GST_TIME_FORMAT ". Add queues or other buffering elements.",
|
||||||
|
GST_TIME_ARGS (max_latency), GST_TIME_ARGS (min_latency)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* configure latency on elements */
|
||||||
|
res = gst_element_send_event (element, gst_event_new_latency (min_latency));
|
||||||
|
if (res) {
|
||||||
|
GST_INFO_OBJECT (element, "configured latency of %" GST_TIME_FORMAT,
|
||||||
|
GST_TIME_ARGS (min_latency));
|
||||||
|
} else {
|
||||||
|
GST_WARNING_OBJECT (element,
|
||||||
|
"failed to configure latency of %" GST_TIME_FORMAT,
|
||||||
|
GST_TIME_ARGS (min_latency));
|
||||||
|
GST_ELEMENT_WARNING (element, CORE, CLOCK, (NULL),
|
||||||
|
("Failed to configure latency of %" GST_TIME_FORMAT,
|
||||||
|
GST_TIME_ARGS (min_latency)));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* this is not a real problem, we just don't configure any latency. */
|
||||||
|
GST_WARNING_OBJECT (element, "failed to query latency");
|
||||||
|
}
|
||||||
|
gst_query_unref (query);
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
static GstStateChangeReturn
|
static GstStateChangeReturn
|
||||||
gst_bin_change_state_func (GstElement * element, GstStateChange transition)
|
gst_bin_change_state_func (GstElement * element, GstStateChange transition)
|
||||||
{
|
{
|
||||||
|
@ -2040,6 +2091,18 @@ gst_bin_change_state_func (GstElement * element, GstStateChange transition)
|
||||||
bin = GST_BIN_CAST (element);
|
bin = GST_BIN_CAST (element);
|
||||||
|
|
||||||
switch (next) {
|
switch (next) {
|
||||||
|
case GST_STATE_PLAYING:
|
||||||
|
{
|
||||||
|
gboolean toplevel;
|
||||||
|
|
||||||
|
GST_OBJECT_LOCK (bin);
|
||||||
|
toplevel = BIN_IS_TOPLEVEL (bin);
|
||||||
|
GST_OBJECT_UNLOCK (bin);
|
||||||
|
|
||||||
|
if (toplevel)
|
||||||
|
do_bin_latency (element);
|
||||||
|
break;
|
||||||
|
}
|
||||||
case GST_STATE_PAUSED:
|
case GST_STATE_PAUSED:
|
||||||
/* Clear EOS list on next PAUSED */
|
/* Clear EOS list on next PAUSED */
|
||||||
GST_OBJECT_LOCK (bin);
|
GST_OBJECT_LOCK (bin);
|
||||||
|
@ -2350,6 +2413,7 @@ bin_push_state_continue (BinContinueData * data)
|
||||||
|
|
||||||
/* an element started an async state change, if we were not busy with a state
|
/* an element started an async state change, if we were not busy with a state
|
||||||
* change, we perform a lost state.
|
* change, we perform a lost state.
|
||||||
|
* This function is called with the OBJECT lock.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
bin_handle_async_start (GstBin * bin, gboolean new_base_time)
|
bin_handle_async_start (GstBin * bin, gboolean new_base_time)
|
||||||
|
@ -2433,7 +2497,9 @@ was_no_preroll:
|
||||||
}
|
}
|
||||||
|
|
||||||
/* this function is called when there are no more async elements in the bin. We
|
/* this function is called when there are no more async elements in the bin. We
|
||||||
* post a state changed message and an ASYNC_DONE message. */
|
* post a state changed message and an ASYNC_DONE message.
|
||||||
|
* This function is called with the OBJECT lock.
|
||||||
|
*/
|
||||||
static void
|
static void
|
||||||
bin_handle_async_done (GstBin * bin, GstStateChangeReturn ret)
|
bin_handle_async_done (GstBin * bin, GstStateChangeReturn ret)
|
||||||
{
|
{
|
||||||
|
|
|
@ -371,11 +371,8 @@ gst_pipeline_change_state (GstElement * element, GstStateChange transition)
|
||||||
case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
|
case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
|
||||||
{
|
{
|
||||||
GstClockTime new_base_time;
|
GstClockTime new_base_time;
|
||||||
GstQuery *query;
|
|
||||||
GstClockTime min_latency, max_latency;
|
|
||||||
GstClockTime start_time, stream_time, delay;
|
GstClockTime start_time, stream_time, delay;
|
||||||
gboolean new_clock, update_stream_time, update_clock;
|
gboolean new_clock, update_stream_time, update_clock;
|
||||||
gboolean res;
|
|
||||||
GstClock *cur_clock;
|
GstClock *cur_clock;
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (element, "selecting clock and base_time");
|
GST_DEBUG_OBJECT (element, "selecting clock and base_time");
|
||||||
|
@ -457,40 +454,6 @@ gst_pipeline_change_state (GstElement * element, GstStateChange transition)
|
||||||
|
|
||||||
if (cur_clock)
|
if (cur_clock)
|
||||||
gst_object_unref (cur_clock);
|
gst_object_unref (cur_clock);
|
||||||
|
|
||||||
/* determine latency in this pipeline */
|
|
||||||
GST_DEBUG_OBJECT (element, "querying pipeline latency");
|
|
||||||
query = gst_query_new_latency ();
|
|
||||||
if (gst_element_query (element, query)) {
|
|
||||||
gboolean live;
|
|
||||||
|
|
||||||
gst_query_parse_latency (query, &live, &min_latency, &max_latency);
|
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (element,
|
|
||||||
"configuring min latency %" GST_TIME_FORMAT ", max latency %"
|
|
||||||
GST_TIME_FORMAT ", live %d", GST_TIME_ARGS (min_latency),
|
|
||||||
GST_TIME_ARGS (max_latency), live);
|
|
||||||
|
|
||||||
/* configure latency on elements */
|
|
||||||
res =
|
|
||||||
gst_element_send_event (element,
|
|
||||||
gst_event_new_latency (min_latency));
|
|
||||||
if (res) {
|
|
||||||
GST_INFO_OBJECT (element, "configured latency of %" GST_TIME_FORMAT,
|
|
||||||
GST_TIME_ARGS (min_latency));
|
|
||||||
} else {
|
|
||||||
GST_WARNING_OBJECT (element,
|
|
||||||
"failed to configure latency of %" GST_TIME_FORMAT,
|
|
||||||
GST_TIME_ARGS (min_latency));
|
|
||||||
GST_ELEMENT_WARNING (element, CORE, CLOCK, (NULL),
|
|
||||||
("Failed to configure latency of %" GST_TIME_FORMAT,
|
|
||||||
GST_TIME_ARGS (min_latency)));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
/* this is not a real problem, we just don't configure any latency. */
|
|
||||||
GST_WARNING_OBJECT (element, "failed to query pipeline latency");
|
|
||||||
}
|
|
||||||
gst_query_unref (query);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
|
case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
|
||||||
|
|
Loading…
Reference in a new issue