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:%" G_GINT64_FORMAT
212 " bytes:%" G_GINT64_FORMAT
213 " events:%" G_GINT64_FORMAT "\n",
214 first ? header0 : headerN,
219 g_print("%s: (%s) %s: buf/s:%g B/s:%g e/s:%g B/buf:%g\n",
225 ((double)delta.bytes/(double)delta.buffers));
229 gst_statistics_print (GstStatistics *statistics)
235 g_return_if_fail (statistics != NULL);
236 g_return_if_fail (GST_IS_STATISTICS (statistics));
238 name = gst_object_get_name(GST_OBJECT(statistics));
243 elapsed = g_timer_elapsed(statistics->timer, NULL);
244 last_elapsed = g_timer_elapsed(statistics->last_timer, NULL);
246 print_stats(1, name, "total", &zero_stats, &statistics->stats, elapsed);
247 print_stats(0, name, "last", &statistics->last_stats, &statistics->stats, last_elapsed);
248 statistics->last_stats = statistics->stats;
249 g_timer_reset(statistics->last_timer);
253 gst_statistics_chain (GstPad *pad, GstBuffer *buf)
255 GstStatistics *statistics;
256 gboolean update = FALSE;
258 g_return_if_fail (pad != NULL);
259 g_return_if_fail (GST_IS_PAD (pad));
260 g_return_if_fail (buf != NULL);
262 statistics = GST_STATISTICS (gst_pad_get_parent (pad));
264 if (GST_IS_EVENT(buf)) {
265 GstEvent *event = GST_EVENT (buf);
266 statistics->stats.events += 1;
267 if (GST_EVENT_TYPE(event) == GST_EVENT_EOS) {
268 gst_element_set_eos (GST_ELEMENT (statistics));
269 if (statistics->update_on_eos) {
273 if (statistics->update_freq.events) {
274 statistics->update_count.events += 1;
275 if (statistics->update_count.events == statistics->update_freq.events) {
276 statistics->update_count.events = 0;
281 statistics->stats.buffers += 1;
282 if (statistics->update_freq.buffers) {
283 statistics->update_count.buffers += 1;
284 if (statistics->update_count.buffers == statistics->update_freq.buffers) {
285 statistics->update_count.buffers = 0;
290 statistics->stats.bytes += GST_BUFFER_SIZE(buf);
291 if (statistics->update_freq.bytes) {
292 statistics->update_count.bytes += GST_BUFFER_SIZE(buf);
293 if (statistics->update_count.bytes >= statistics->update_freq.bytes) {
294 statistics->update_count.bytes = 0;
301 if (statistics->update) {
302 GST_DEBUG_ELEMENT (GST_CAT_DATAFLOW, statistics, "pre update emit\n");
303 g_signal_emit (G_OBJECT (statistics), gst_statistics_signals[SIGNAL_UPDATE], 0);
304 GST_DEBUG_ELEMENT (GST_CAT_DATAFLOW, statistics, "post update emit\n");
306 if (!statistics->silent) {
307 gst_statistics_print(statistics);
310 gst_pad_push (statistics->srcpad, buf);
314 gst_statistics_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
316 GstStatistics *statistics;
318 /* it's not null if we got it, but it might not be ours */
319 g_return_if_fail (GST_IS_STATISTICS (object));
321 statistics = GST_STATISTICS (object);
324 case ARG_BUFFER_UPDATE_FREQ:
325 statistics->update_freq.buffers = g_value_get_int64 (value);
327 case ARG_BYTES_UPDATE_FREQ:
328 statistics->update_freq.bytes = g_value_get_int64 (value);
330 case ARG_EVENT_UPDATE_FREQ:
331 statistics->update_freq.events = g_value_get_int64 (value);
333 case ARG_UPDATE_ON_EOS:
334 statistics->update_on_eos = g_value_get_boolean (value);
337 statistics->update = g_value_get_boolean (value);
340 statistics->silent = g_value_get_boolean (value);
343 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
348 static void gst_statistics_get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) {
349 GstStatistics *statistics;
351 /* it's not null if we got it, but it might not be ours */
352 g_return_if_fail (GST_IS_STATISTICS (object));
354 statistics = GST_STATISTICS (object);
358 g_value_set_int64 (value, statistics->stats.buffers);
361 g_value_set_int64 (value, statistics->stats.bytes);
364 g_value_set_int64 (value, statistics->stats.events);
366 case ARG_BUFFER_UPDATE_FREQ:
367 g_value_set_int64 (value, statistics->update_freq.buffers);
369 case ARG_BYTES_UPDATE_FREQ:
370 g_value_set_int64 (value, statistics->update_freq.bytes);
372 case ARG_EVENT_UPDATE_FREQ:
373 g_value_set_int64 (value, statistics->update_freq.events);
375 case ARG_UPDATE_ON_EOS:
376 g_value_set_boolean (value, statistics->update_on_eos);
379 g_value_set_boolean (value, statistics->update);
382 g_value_set_boolean (value, statistics->silent);
385 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);