Polish and fix qmlvideofx example
[qt:qtmultimedia.git] / examples / multimedia / video / snippets / frequencymonitor / frequencymonitor.cpp
1 /****************************************************************************
2 **
3 ** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/legal
5 **
6 ** This file is part of the Qt Mobility Components.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.  For licensing terms and
14 ** conditions see http://qt.digia.com/licensing.  For further information
15 ** use the contact form at http://qt.digia.com/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file.  Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 **
25 ** In addition, as a special exception, Digia gives you certain additional
26 ** rights.  These rights are described in the Digia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 **
29 ** GNU General Public License Usage
30 ** Alternatively, this file may be used under the terms of the GNU
31 ** General Public License version 3.0 as published by the Free Software
32 ** Foundation and appearing in the file LICENSE.GPL included in the
33 ** packaging of this file.  Please review the following information to
34 ** ensure the GNU General Public License version 3.0 requirements will be
35 ** met: http://www.gnu.org/copyleft/gpl.html.
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42 #include "frequencymonitor.h"
43 #include <QDebug>
44 #include <QElapsedTimer>
45 #include <QString>
46 #include <QTime>
47 #include <QTimer>
48
49 //#define VERBOSE_TRACE
50
51 inline QDebug qtTrace() { return qDebug() << "[frequencymonitor]"; }
52 #ifdef VERBOSE_TRACE
53 inline QDebug qtVerboseTrace() { return qtTrace(); }
54 #else
55 inline QNoDebug qtVerboseTrace() { return QNoDebug(); }
56 #endif
57
58 static const int DefaultSamplingInterval = 100;
59 static const int DefaultTraceInterval = 0;
60
61 class FrequencyMonitorPrivate : public QObject
62 {
63     Q_OBJECT
64
65 public:
66     FrequencyMonitorPrivate(FrequencyMonitor *parent);
67     void calculateInstantaneousFrequency();
68
69 private slots:
70     void calculateAverageFrequency();
71     void stalled();
72
73 public:
74     FrequencyMonitor *const q_ptr;
75     QString m_label;
76     bool m_active;
77     qreal m_instantaneousFrequency;
78     QElapsedTimer m_instantaneousElapsed;
79     QTimer *m_averageTimer;
80     QElapsedTimer m_averageElapsed;
81     int m_count;
82     qreal m_averageFrequency;
83     QTimer *m_traceTimer;
84     QTimer *m_stalledTimer;
85 };
86
87 FrequencyMonitorPrivate::FrequencyMonitorPrivate(FrequencyMonitor *parent)
88 :   QObject(parent)
89 ,   q_ptr(parent)
90 ,   m_active(false)
91 ,   m_instantaneousFrequency(0)
92 ,   m_averageTimer(new QTimer(this))
93 ,   m_count(0)
94 ,   m_averageFrequency(0)
95 ,   m_traceTimer(new QTimer(this))
96 ,   m_stalledTimer(new QTimer(this))
97 {
98     m_instantaneousElapsed.start();
99     connect(m_averageTimer, SIGNAL(timeout()),
100             this, SLOT(calculateAverageFrequency()));
101     if (DefaultSamplingInterval)
102         m_averageTimer->start(DefaultSamplingInterval);
103     m_averageElapsed.start();
104     connect(m_traceTimer, SIGNAL(timeout()),
105             q_ptr, SLOT(trace()));
106     if (DefaultTraceInterval)
107         m_traceTimer->start(DefaultTraceInterval);
108     m_stalledTimer->setSingleShot(true);
109     connect(m_stalledTimer, SIGNAL(timeout()),
110             this, SLOT(stalled()));
111 }
112
113 void FrequencyMonitorPrivate::calculateInstantaneousFrequency()
114 {
115     const qint64 ms = m_instantaneousElapsed.restart();
116     m_instantaneousFrequency = ms ? qreal(1000) / ms : 0;
117     m_stalledTimer->start(3 * ms);
118     if (m_instantaneousFrequency)
119         q_ptr->setActive(true);
120     emit q_ptr->instantaneousFrequencyChanged(m_instantaneousFrequency);
121     emit q_ptr->frequencyChanged();
122 }
123
124 void FrequencyMonitorPrivate::calculateAverageFrequency()
125 {
126     const qint64 ms = m_averageElapsed.restart();
127     m_averageFrequency = qreal(m_count * 1000) / ms;
128     emit q_ptr->averageFrequencyChanged(m_averageFrequency);
129     emit q_ptr->frequencyChanged();
130     m_count = 0;
131 }
132
133 void FrequencyMonitorPrivate::stalled()
134 {
135     if (m_instantaneousFrequency) {
136         qtVerboseTrace() << "FrequencyMonitor::stalled";
137         m_instantaneousFrequency = 0;
138         emit q_ptr->instantaneousFrequencyChanged(m_instantaneousFrequency);
139         emit q_ptr->frequencyChanged();
140     }
141 }
142
143 FrequencyMonitor::FrequencyMonitor(QObject *parent)
144 :   QObject(parent)
145 {
146     d_ptr = new FrequencyMonitorPrivate(this);
147     qtTrace() << "FrequencyMonitor::FrequencyMonitor";
148 }
149
150 FrequencyMonitor::~FrequencyMonitor()
151 {
152
153 }
154
155 QString FrequencyMonitor::label() const
156 {
157     return d_func()->m_label;
158 }
159
160 bool FrequencyMonitor::active() const
161 {
162     return d_func()->m_active;
163 }
164
165 int FrequencyMonitor::samplingInterval() const
166 {
167     return d_ptr->m_averageTimer->isActive() ? d_ptr->m_averageTimer->interval() : 0;
168 }
169
170 int FrequencyMonitor::traceInterval() const
171 {
172     return d_ptr->m_traceTimer->isActive() ? d_ptr->m_traceTimer->interval() : 0;
173 }
174
175 qreal FrequencyMonitor::instantaneousFrequency() const
176 {
177     return d_func()->m_instantaneousFrequency;
178 }
179
180 qreal FrequencyMonitor::averageFrequency() const
181 {
182     return d_func()->m_averageFrequency;
183 }
184
185 void FrequencyMonitor::notify()
186 {
187     Q_D(FrequencyMonitor);
188     ++(d->m_count);
189     d->calculateInstantaneousFrequency();
190 }
191
192 void FrequencyMonitor::trace()
193 {
194     Q_D(FrequencyMonitor);
195     const QString value = QString::fromLatin1("instant %1 average %2")
196                             .arg(d->m_instantaneousFrequency, 0, 'f', 2)
197                             .arg(d->m_averageFrequency, 0, 'f', 2);
198     if (d->m_label.isEmpty())
199         qtTrace() << "FrequencyMonitor::trace" << value;
200     else
201         qtTrace() << "FrequencyMonitor::trace" << "label" << d->m_label << value;
202 }
203
204 void FrequencyMonitor::setLabel(const QString &value)
205 {
206     Q_D(FrequencyMonitor);
207     if (d->m_label != value) {
208         d->m_label = value;
209         emit labelChanged(d->m_label);
210     }
211 }
212
213 void FrequencyMonitor::setActive(bool value)
214 {
215     Q_D(FrequencyMonitor);
216     if (d->m_active != value) {
217         d->m_active = value;
218         emit activeChanged(d->m_active);
219     }
220 }
221
222 void FrequencyMonitor::setSamplingInterval(int value)
223 {
224     Q_D(FrequencyMonitor);
225     if (samplingInterval() != value) {
226         if (value) {
227             d->m_averageTimer->setInterval(value);
228             d->m_averageTimer->start();
229         } else {
230             d->m_averageTimer->stop();
231         }
232         emit samplingIntervalChanged(value);
233     }
234 }
235
236 void FrequencyMonitor::setTraceInterval(int value)
237 {
238     Q_D(FrequencyMonitor);
239     if (traceInterval() != value) {
240         if (value) {
241             d->m_traceTimer->setInterval(value);
242             d->m_traceTimer->start();
243         } else {
244             d->m_traceTimer->stop();
245         }
246         emit traceIntervalChanged(value);
247     }
248 }
249
250 #include "frequencymonitor.moc"