2 * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
3 * 2000 Wim Taymans <wtay@chello.be>
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Library General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Library General Public License for more details.
17 * You should have received a copy of the GNU Library General Public
18 * License along with this library; if not, write to the
19 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 * Boston, MA 02111-1307, USA.
24 #include <gststatistics.h>
27 GstElementDetails gst_statistics_details = {
31 "Statistics on buffers/bytes/events",
33 "David I. Lehn <dlehn@users.sourceforge.net>",
38 /* Statistics signals and args */
49 ARG_BUFFER_UPDATE_FREQ,
50 ARG_BYTES_UPDATE_FREQ,
51 ARG_EVENT_UPDATE_FREQ,
58 static void gst_statistics_class_init (GstStatisticsClass *klass);
59 static void gst_statistics_init (GstStatistics *statistics);
61 static void gst_statistics_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec);
62 static void gst_statistics_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec);
64 static void gst_statistics_chain (GstPad *pad, GstBuffer *buf);
65 static void gst_statistics_reset (GstStatistics *statistics);
66 static void gst_statistics_print (GstStatistics *statistics);
68 static GstElementClass *parent_class = NULL;
69 static guint gst_statistics_signals[LAST_SIGNAL] = { 0, };
71 static stats zero_stats = { 0, };
74 gst_statistics_get_type (void)
76 static GType statistics_type = 0;
78 if (!statistics_type) {
79 static const GTypeInfo statistics_info = {
80 sizeof(GstStatisticsClass), NULL,
82 (GClassInitFunc)gst_statistics_class_init,
85 sizeof(GstStatistics),
87 (GInstanceInitFunc)gst_statistics_init,
89 statistics_type = g_type_register_static (GST_TYPE_ELEMENT, "GstStatistics", &statistics_info, 0);
91 return statistics_type;
95 gst_statistics_class_init (GstStatisticsClass *klass)
97 GObjectClass *gobject_class;
99 gobject_class = (GObjectClass*)klass;
101 parent_class = g_type_class_ref (GST_TYPE_ELEMENT);
103 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_BUFFERS,
104 g_param_spec_int64 ("buffers", "buffers", "total buffers count",
105 0, G_MAXINT64, 0, G_PARAM_READABLE));
106 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_BYTES,
107 g_param_spec_int64 ("bytes", "bytes", "total bytes count",
108 0, G_MAXINT64, 0, G_PARAM_READABLE));
109 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_EVENTS,
110 g_param_spec_int64 ("events", "events", "total event count",
111 0, G_MAXINT64, 0, G_PARAM_READABLE));
112 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_BUFFER_UPDATE_FREQ,
113 g_param_spec_int64 ("buffer_update_freq", "buffer update freq", "buffer update frequency",
114 0, G_MAXINT64, 0, G_PARAM_READWRITE));
115 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_BYTES_UPDATE_FREQ,
116 g_param_spec_int64 ("bytes_update_freq", "bytes update freq", "bytes update frequency",
117 0, G_MAXINT64, 0, G_PARAM_READWRITE));
118 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_EVENT_UPDATE_FREQ,
119 g_param_spec_int64 ("event_update_freq", "event update freq", "event update frequency",
120 0, G_MAXINT64, 0, G_PARAM_READWRITE));
121 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_UPDATE_ON_EOS,
122 g_param_spec_boolean ("update_on_eos", "update on EOS", "update on EOS event",
123 TRUE,G_PARAM_READWRITE));
124 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_UPDATE,
125 g_param_spec_boolean ("update", "update", "update",
126 TRUE,G_PARAM_READWRITE));
127 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_SILENT,
128 g_param_spec_boolean ("silent", "silent", "silent",
129 TRUE,G_PARAM_READWRITE));
131 gst_statistics_signals[SIGNAL_UPDATE] =
132 g_signal_new ("update", G_TYPE_FROM_CLASS(klass), G_SIGNAL_RUN_LAST,
133 G_STRUCT_OFFSET (GstStatisticsClass, update), NULL, NULL,
134 g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
136 gobject_class->set_property = GST_DEBUG_FUNCPTR (gst_statistics_set_property);
137 gobject_class->get_property = GST_DEBUG_FUNCPTR (gst_statistics_get_property);
140 static GstBufferPool*
141 gst_statistics_get_bufferpool (GstPad *pad)
143 GstStatistics *statistics;
145 statistics = GST_STATISTICS (gst_pad_get_parent (pad));
147 return gst_pad_get_bufferpool (statistics->srcpad);
151 gst_statistics_init (GstStatistics *statistics)
153 statistics->sinkpad = gst_pad_new ("sink", GST_PAD_SINK);
154 gst_element_add_pad (GST_ELEMENT (statistics), statistics->sinkpad);
155 gst_pad_set_chain_function (statistics->sinkpad, GST_DEBUG_FUNCPTR (gst_statistics_chain));
156 gst_pad_set_bufferpool_function (statistics->sinkpad, GST_DEBUG_FUNCPTR (gst_statistics_get_bufferpool));
158 statistics->srcpad = gst_pad_new ("src", GST_PAD_SRC);
159 gst_element_add_pad (GST_ELEMENT (statistics), statistics->srcpad);
161 statistics->timer = NULL;
162 statistics->last_timer = NULL;
163 gst_statistics_reset(statistics);
167 gst_statistics_reset (GstStatistics *statistics)
169 g_return_if_fail (statistics != NULL);
170 g_return_if_fail (GST_IS_STATISTICS (statistics));
172 statistics->stats.buffers = 0;
173 statistics->stats.bytes = 0;
174 statistics->stats.events = 0;
176 statistics->last_stats.buffers = 0;
177 statistics->last_stats.bytes = 0;
178 statistics->last_stats.events = 0;
180 statistics->update_count.buffers = 0;
181 statistics->update_count.bytes = 0;
182 statistics->update_count.events = 0;
184 statistics->update_freq.buffers = 0;
185 statistics->update_freq.bytes = 0;
186 statistics->update_freq.events = 0;
188 statistics->update_on_eos = TRUE;
189 statistics->update = TRUE;
190 statistics->silent = FALSE;
192 if (!statistics->timer) {
193 statistics->timer = g_timer_new();
195 if (!statistics->last_timer) {
196 statistics->last_timer = g_timer_new();
201 print_stats(gboolean first, const gchar *name, const gchar *type, stats *base, stats *final, double time)
203 const gchar *header0 = "statistics";
204 const gchar *headerN = " ";
207 delta.buffers = final->buffers - base->buffers;
208 delta.bytes = final->bytes - base->bytes;
209 delta.events = final->events - base->events;
211 g_print("%s: (%s) %s: s:%g buffers:%lld bytes:%lld events:%lld\n",
212 first ? header0 : headerN,
217 g_print("%s: (%s) %s: buf/s:%g B/s:%g e/s:%g B/buf:%g\n",
223 ((double)delta.bytes/(double)delta.buffers));
227 gst_statistics_print (GstStatistics *statistics)
233 g_return_if_fail (statistics != NULL);
234 g_return_if_fail (GST_IS_STATISTICS (statistics));
236 name = gst_object_get_name(GST_OBJECT(statistics));
241 elapsed = g_timer_elapsed(statistics->timer, NULL);
242 last_elapsed = g_timer_elapsed(statistics->last_timer, NULL);
244 print_stats(1, name, "total", &zero_stats, &statistics->stats, elapsed);
245 print_stats(0, name, "last", &statistics->last_stats, &statistics->stats, last_elapsed);
246 statistics->last_stats = statistics->stats;
247 g_timer_reset(statistics->last_timer);
251 gst_statistics_chain (GstPad *pad, GstBuffer *buf)
253 GstStatistics *statistics;
254 gboolean update = FALSE;
256 g_return_if_fail (pad != NULL);
257 g_return_if_fail (GST_IS_PAD (pad));
258 g_return_if_fail (buf != NULL);
260 statistics = GST_STATISTICS (gst_pad_get_parent (pad));
262 if (GST_IS_EVENT(buf)) {
263 GstEvent *event = GST_EVENT (buf);
264 statistics->stats.events += 1;
265 if (GST_EVENT_TYPE(event) == GST_EVENT_EOS) {
266 gst_element_set_eos (GST_ELEMENT (statistics));
267 if (statistics->update_on_eos) {
271 if (statistics->update_freq.events) {
272 statistics->update_count.events += 1;
273 if (statistics->update_count.events == statistics->update_freq.events) {
274 statistics->update_count.events = 0;
279 statistics->stats.buffers += 1;
280 if (statistics->update_freq.buffers) {
281 statistics->update_count.buffers += 1;
282 if (statistics->update_count.buffers == statistics->update_freq.buffers) {
283 statistics->update_count.buffers = 0;
288 statistics->stats.bytes += GST_BUFFER_SIZE(buf);
289 if (statistics->update_freq.bytes) {
290 statistics->update_count.bytes += GST_BUFFER_SIZE(buf);
291 if (statistics->update_count.bytes >= statistics->update_freq.bytes) {
292 statistics->update_count.bytes = 0;
299 if (statistics->update) {
300 GST_DEBUG_ELEMENT (GST_CAT_DATAFLOW, statistics, "pre update emit\n");
301 g_signal_emit (G_OBJECT (statistics), gst_statistics_signals[SIGNAL_UPDATE], 0);
302 GST_DEBUG_ELEMENT (GST_CAT_DATAFLOW, statistics, "post update emit\n");
304 if (!statistics->silent) {
305 gst_statistics_print(statistics);
308 gst_pad_push (statistics->srcpad, buf);
312 gst_statistics_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
314 GstStatistics *statistics;
316 /* it's not null if we got it, but it might not be ours */
317 g_return_if_fail (GST_IS_STATISTICS (object));
319 statistics = GST_STATISTICS (object);
322 case ARG_BUFFER_UPDATE_FREQ:
323 statistics->update_freq.buffers = g_value_get_int64 (value);
325 case ARG_BYTES_UPDATE_FREQ:
326 statistics->update_freq.bytes = g_value_get_int64 (value);
328 case ARG_EVENT_UPDATE_FREQ:
329 statistics->update_freq.events = g_value_get_int64 (value);
331 case ARG_UPDATE_ON_EOS:
332 statistics->update_on_eos = g_value_get_boolean (value);
335 statistics->update = g_value_get_boolean (value);
338 statistics->silent = g_value_get_boolean (value);
341 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
346 static void gst_statistics_get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) {
347 GstStatistics *statistics;
349 /* it's not null if we got it, but it might not be ours */
350 g_return_if_fail (GST_IS_STATISTICS (object));
352 statistics = GST_STATISTICS (object);
356 g_value_set_int64 (value, statistics->stats.buffers);
359 g_value_set_int64 (value, statistics->stats.bytes);
362 g_value_set_int64 (value, statistics->stats.events);
364 case ARG_BUFFER_UPDATE_FREQ:
365 g_value_set_int64 (value, statistics->update_freq.buffers);
367 case ARG_BYTES_UPDATE_FREQ:
368 g_value_set_int64 (value, statistics->update_freq.bytes);
370 case ARG_EVENT_UPDATE_FREQ:
371 g_value_set_int64 (value, statistics->update_freq.events);
373 case ARG_UPDATE_ON_EOS:
374 g_value_set_boolean (value, statistics->update_on_eos);
377 g_value_set_boolean (value, statistics->update);
380 g_value_set_boolean (value, statistics->silent);
383 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);