urisourcebin: add a statistics property for queueing
It contains the minimum/maximum/average byte and time levels of the queues inside this urisourcebin https://gitlab.freedesktop.org/gstreamer/gst-plugins-base/issues/60
This commit is contained in:
parent
81e00791bf
commit
af166b5b22
@ -229,6 +229,7 @@ enum
|
|||||||
PROP_RING_BUFFER_MAX_SIZE,
|
PROP_RING_BUFFER_MAX_SIZE,
|
||||||
PROP_LOW_WATERMARK,
|
PROP_LOW_WATERMARK,
|
||||||
PROP_HIGH_WATERMARK,
|
PROP_HIGH_WATERMARK,
|
||||||
|
PROP_STATISTICS,
|
||||||
};
|
};
|
||||||
|
|
||||||
#define CUSTOM_EOS_QUARK _custom_eos_quark_get ()
|
#define CUSTOM_EOS_QUARK _custom_eos_quark_get ()
|
||||||
@ -279,6 +280,7 @@ static GstPad *create_output_pad (GstURISourceBin * urisrc, GstPad * pad);
|
|||||||
static void remove_buffering_msgs (GstURISourceBin * bin, GstObject * src);
|
static void remove_buffering_msgs (GstURISourceBin * bin, GstObject * src);
|
||||||
|
|
||||||
static void update_queue_values (GstURISourceBin * urisrc);
|
static void update_queue_values (GstURISourceBin * urisrc);
|
||||||
|
static GstStructure *get_queue_statistics (GstURISourceBin * urisrc);
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gst_uri_source_bin_class_init (GstURISourceBinClass * klass)
|
gst_uri_source_bin_class_init (GstURISourceBinClass * klass)
|
||||||
@ -384,6 +386,25 @@ gst_uri_source_bin_class_init (GstURISourceBinClass * klass)
|
|||||||
0.0, 1.0, DEFAULT_HIGH_WATERMARK,
|
0.0, 1.0, DEFAULT_HIGH_WATERMARK,
|
||||||
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GstURISourceBin::statistics
|
||||||
|
*
|
||||||
|
* A GStructure containing the following values based on the values from
|
||||||
|
* all the queue's contained in this urisourcebin.
|
||||||
|
*
|
||||||
|
* "minimum-byte-level" G_TYPE_UINT Minimum of the current byte levels
|
||||||
|
* "maximum-byte-level" G_TYPE_UINT Maximum of the current byte levels
|
||||||
|
* "average-byte-level" G_TYPE_UINT Average of the current byte levels
|
||||||
|
* "minimum-time-level" G_TYPE_UINT64 Minimum of the current time levels
|
||||||
|
* "maximum-time-level" G_TYPE_UINT64 Maximum of the current time levels
|
||||||
|
* "average-time-level" G_TYPE_UINT64 Average of the current time levels
|
||||||
|
*/
|
||||||
|
g_object_class_install_property (gobject_class, PROP_STATISTICS,
|
||||||
|
g_param_spec_boxed ("statistics", "Queue Statistics",
|
||||||
|
"A set of statistics over all the queue-like elements contained in "
|
||||||
|
"this element", GST_TYPE_STRUCTURE,
|
||||||
|
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* GstURISourceBin::drained:
|
* GstURISourceBin::drained:
|
||||||
*
|
*
|
||||||
@ -580,6 +601,9 @@ gst_uri_source_bin_get_property (GObject * object, guint prop_id,
|
|||||||
case PROP_HIGH_WATERMARK:
|
case PROP_HIGH_WATERMARK:
|
||||||
g_value_set_double (value, urisrc->high_watermark);
|
g_value_set_double (value, urisrc->high_watermark);
|
||||||
break;
|
break;
|
||||||
|
case PROP_STATISTICS:
|
||||||
|
g_value_take_boxed (value, get_queue_statistics (dec));
|
||||||
|
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;
|
||||||
@ -892,6 +916,53 @@ pre_queue_event_probe (GstPad * pad, GstPadProbeInfo * info, gpointer user_data)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static GstStructure *
|
||||||
|
get_queue_statistics (GstURISourceBin * urisrc)
|
||||||
|
{
|
||||||
|
GstStructure *ret = NULL;
|
||||||
|
guint min_byte_level = 0, max_byte_level = 0;
|
||||||
|
guint64 min_time_level = 0, max_time_level = 0;
|
||||||
|
gdouble avg_byte_level = 0., avg_time_level = 0.;
|
||||||
|
guint i = 0;
|
||||||
|
GSList *cur;
|
||||||
|
|
||||||
|
GST_URI_SOURCE_BIN_LOCK (urisrc);
|
||||||
|
|
||||||
|
for (cur = urisrc->out_slots; cur != NULL; cur = g_slist_next (cur)) {
|
||||||
|
OutputSlotInfo *slot = (OutputSlotInfo *) (cur->data);
|
||||||
|
guint byte_limit = 0;
|
||||||
|
guint64 time_limit = 0;
|
||||||
|
|
||||||
|
g_object_get (slot->queue, "current-level-bytes", &byte_limit,
|
||||||
|
"current-level-time", &time_limit, NULL);
|
||||||
|
|
||||||
|
if (byte_limit < min_byte_level)
|
||||||
|
min_byte_level = byte_limit;
|
||||||
|
if (byte_limit > max_byte_level)
|
||||||
|
max_byte_level = byte_limit;
|
||||||
|
avg_byte_level = (avg_byte_level * i + byte_limit) / (gdouble) (i + 1);
|
||||||
|
|
||||||
|
if (time_limit < min_time_level)
|
||||||
|
min_time_level = time_limit;
|
||||||
|
if (time_limit > max_time_level)
|
||||||
|
max_time_level = time_limit;
|
||||||
|
avg_time_level = (avg_time_level * i + time_limit) / (gdouble) (i + 1);
|
||||||
|
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
GST_URI_SOURCE_BIN_UNLOCK (urisrc);
|
||||||
|
|
||||||
|
ret = gst_structure_new ("application/x-urisourcebin-stats",
|
||||||
|
"minimum-byte-level", G_TYPE_UINT, (guint) min_byte_level,
|
||||||
|
"maximum-byte-level", G_TYPE_UINT, (guint) max_byte_level,
|
||||||
|
"average-byte-level", G_TYPE_UINT, (guint) avg_byte_level,
|
||||||
|
"minimum-time-level", G_TYPE_UINT64, (guint64) min_time_level,
|
||||||
|
"maximum-time-level", G_TYPE_UINT64, (guint64) max_time_level,
|
||||||
|
"average-time-level", G_TYPE_UINT64, (guint64) avg_time_level, NULL);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
update_queue_values (GstURISourceBin * urisrc)
|
update_queue_values (GstURISourceBin * urisrc)
|
||||||
{
|
{
|
||||||
|
@ -103,7 +103,8 @@ endif
|
|||||||
if USE_PLUGIN_PLAYBACK
|
if USE_PLUGIN_PLAYBACK
|
||||||
check_playback = elements/decodebin elements/playbin \
|
check_playback = elements/decodebin elements/playbin \
|
||||||
elements/playbin-complex elements/streamsynchronizer \
|
elements/playbin-complex elements/streamsynchronizer \
|
||||||
elements/playsink
|
elements/playsink \
|
||||||
|
elements/urisourcebin
|
||||||
else
|
else
|
||||||
check_playback =
|
check_playback =
|
||||||
endif
|
endif
|
||||||
@ -712,6 +713,9 @@ elements_playbin_CFLAGS = $(GST_BASE_CFLAGS) $(AM_CFLAGS)
|
|||||||
elements_playbin_complex_LDADD = $(top_builddir)/gst-libs/gst/audio/libgstaudio-@GST_API_VERSION@.la $(top_builddir)/gst-libs/gst/video/libgstvideo-@GST_API_VERSION@.la $(GST_BASE_LIBS) $(LDADD)
|
elements_playbin_complex_LDADD = $(top_builddir)/gst-libs/gst/audio/libgstaudio-@GST_API_VERSION@.la $(top_builddir)/gst-libs/gst/video/libgstvideo-@GST_API_VERSION@.la $(GST_BASE_LIBS) $(LDADD)
|
||||||
elements_playbin_complex_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) $(GST_BASE_CFLAGS) $(AM_CFLAGS)
|
elements_playbin_complex_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) $(GST_BASE_CFLAGS) $(AM_CFLAGS)
|
||||||
|
|
||||||
|
elements_urisourcebin_LDADD = $(GST_BASE_LIBS) $(LDADD)
|
||||||
|
elements_urisourcebin_CFLAGS = $(GST_BASE_CFLAGS) $(AM_CFLAGS)
|
||||||
|
|
||||||
elements_decodebin_LDADD = $(GST_BASE_LIBS) $(LDADD)
|
elements_decodebin_LDADD = $(GST_BASE_LIBS) $(LDADD)
|
||||||
elements_decodebin_CFLAGS = $(GST_BASE_CFLAGS) $(AM_CFLAGS)
|
elements_decodebin_CFLAGS = $(GST_BASE_CFLAGS) $(AM_CFLAGS)
|
||||||
|
|
||||||
|
1
tests/check/elements/.gitignore
vendored
1
tests/check/elements/.gitignore
vendored
@ -36,3 +36,4 @@ streamsynchronizer
|
|||||||
subparse
|
subparse
|
||||||
rawaudioparse
|
rawaudioparse
|
||||||
rawvideoparse
|
rawvideoparse
|
||||||
|
urisourcebin
|
||||||
|
84
tests/check/elements/urisourcebin.c
Normal file
84
tests/check/elements/urisourcebin.c
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
/* GStreamer unit tests for playsink
|
||||||
|
* Copyright (C) 2015 Matthew Waters <matthew@centricular.com>
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Library General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Library General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Library General Public
|
||||||
|
* License along with this library; if not, write to the
|
||||||
|
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||||
|
* Boston, MA 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
# include <config.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <gst/check/gstcheck.h>
|
||||||
|
|
||||||
|
|
||||||
|
GST_START_TEST (test_initial_statistics)
|
||||||
|
{
|
||||||
|
GstElement *urisrc;
|
||||||
|
GstStructure *stats = NULL;
|
||||||
|
guint min_bytes, max_bytes, avg_bytes;
|
||||||
|
guint64 min_time, max_time, avg_time;
|
||||||
|
|
||||||
|
urisrc = gst_element_factory_make ("urisourcebin", NULL);
|
||||||
|
fail_unless (urisrc != NULL);
|
||||||
|
|
||||||
|
g_object_get (urisrc, "statistics", &stats, NULL);
|
||||||
|
|
||||||
|
fail_unless (stats != NULL);
|
||||||
|
fail_unless (g_strcmp0 (gst_structure_get_name (stats),
|
||||||
|
"application/x-urisourcebin-stats") == 0);
|
||||||
|
fail_unless_equals_int (6, gst_structure_n_fields (stats));
|
||||||
|
|
||||||
|
fail_unless_equals_int (TRUE, gst_structure_get_uint (stats,
|
||||||
|
"minimum-byte-level", &min_bytes));
|
||||||
|
fail_unless_equals_int (0, min_bytes);
|
||||||
|
fail_unless_equals_int (TRUE, gst_structure_get_uint (stats,
|
||||||
|
"maximum-byte-level", &max_bytes));
|
||||||
|
fail_unless_equals_int (0, max_bytes);
|
||||||
|
fail_unless_equals_int (TRUE, gst_structure_get_uint (stats,
|
||||||
|
"average-byte-level", &avg_bytes));
|
||||||
|
fail_unless_equals_int (0, avg_bytes);
|
||||||
|
|
||||||
|
fail_unless_equals_int (TRUE, gst_structure_get_uint64 (stats,
|
||||||
|
"minimum-time-level", &min_time));
|
||||||
|
fail_unless_equals_int (0, min_time);
|
||||||
|
fail_unless_equals_int (TRUE, gst_structure_get_uint64 (stats,
|
||||||
|
"maximum-time-level", &max_time));
|
||||||
|
fail_unless_equals_int (0, max_time);
|
||||||
|
fail_unless_equals_int (TRUE, gst_structure_get_uint64 (stats,
|
||||||
|
"average-time-level", &avg_time));
|
||||||
|
fail_unless_equals_int (0, avg_time);
|
||||||
|
|
||||||
|
gst_structure_free (stats);
|
||||||
|
gst_object_unref (urisrc);
|
||||||
|
}
|
||||||
|
|
||||||
|
GST_END_TEST;
|
||||||
|
|
||||||
|
|
||||||
|
static Suite *
|
||||||
|
urisourcebin_suite (void)
|
||||||
|
{
|
||||||
|
Suite *s = suite_create ("urisourcebin");
|
||||||
|
TCase *tc_chain = tcase_create ("general");
|
||||||
|
|
||||||
|
suite_add_tcase (s, tc_chain);
|
||||||
|
|
||||||
|
tcase_add_test (tc_chain, test_initial_statistics);
|
||||||
|
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
GST_CHECK_MAIN (urisourcebin);
|
@ -51,6 +51,7 @@ base_tests = [
|
|||||||
[ 'elements/streamsynchronizer.c' ],
|
[ 'elements/streamsynchronizer.c' ],
|
||||||
[ 'elements/subparse.c' ],
|
[ 'elements/subparse.c' ],
|
||||||
[ 'elements/textoverlay.c', not pango_dep.found() ],
|
[ 'elements/textoverlay.c', not pango_dep.found() ],
|
||||||
|
[ 'elements/urisourcebin.c' ],
|
||||||
[ 'elements/videoconvert.c' ],
|
[ 'elements/videoconvert.c' ],
|
||||||
[ 'elements/videorate.c' ],
|
[ 'elements/videorate.c' ],
|
||||||
[ 'elements/videoscale.c' ],
|
[ 'elements/videoscale.c' ],
|
||||||
|
Loading…
x
Reference in New Issue
Block a user