Miam-Player  0.8.0
A nice music player
AVClock.h
Go to the documentation of this file.
1 /******************************************************************************
2  QtAV: Multimedia framework based on Qt and FFmpeg
3  Copyright (C) 2012-2016 Wang Bin <wbsecg1@gmail.com>
4 
5 * This file is part of QtAV
6 
7  This library is free software; you can redistribute it and/or
8  modify it under the terms of the GNU Lesser General Public
9  License as published by the Free Software Foundation; either
10  version 2.1 of the License, or (at your option) any later version.
11 
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  Lesser General Public License for more details.
16 
17  You should have received a copy of the GNU Lesser General Public
18  License along with this library; if not, write to the Free Software
19  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 ******************************************************************************/
21 
22 #ifndef QTAV_AVCLOCK_H
23 #define QTAV_AVCLOCK_H
24 
25 #include <QtAV/QtAV_Global.h>
26 #include <QtCore/QAtomicInt>
27 #include <QtCore/QBasicTimer>
28 #include <QtCore/QObject>
29 #if QT_VERSION >= QT_VERSION_CHECK(4, 7, 0)
30 #include <QtCore/QElapsedTimer>
31 #else
32 #include <QtCore/QTime>
33 typedef QTime QElapsedTimer;
34 #endif
35 
36 /*
37  * AVClock is created by AVPlayer. The only way to access AVClock is through AVPlayer::masterClock()
38  * The default clock type is Audio's clock, i.e. vedio synchronizes to audio. If audio stream is not
39  * detected, then the clock will set to External clock automatically.
40  * I name it ExternalClock because the clock can be corrected outside, though it is a clock inside AVClock
41  */
42 namespace QtAV {
43 
44 static const double kThousandth = 0.001;
45 
46 class Q_AV_EXPORT AVClock : public QObject
47 {
48  Q_OBJECT
49 public:
50  typedef enum {
53  VideoClock //sync to video timestamp
54  } ClockType;
55 
56  AVClock(ClockType c, QObject* parent = 0);
57  AVClock(QObject* parent = 0);
58  void setClockType(ClockType ct);
59  ClockType clockType() const;
60  bool isActive() const;
65  void setInitialValue(double v);
66  double initialValue() const;
67  /*
68  * auto clock: use audio clock if audio stream found, otherwise use external clock
69  */
70  void setClockAuto(bool a);
71  bool isClockAuto() const;
72  /*in seconds*/
73  inline double pts() const;
79  inline double value() const;
80  inline void updateValue(double pts); //update the pts
81  /*used when seeking and correcting from external*/
82  void updateExternalClock(qint64 msecs);
83  /*external clock outside still running, so it's more accurate for syncing multiple clocks serially*/
84  void updateExternalClock(const AVClock& clock);
85 
86  inline void updateVideoTime(double pts);
87  inline double videoTime() const;
88  inline double delay() const; //playing audio spends some time
89  inline void updateDelay(double delay);
90  inline qreal diff() const;
91 
92  void setSpeed(qreal speed);
93  inline qreal speed() const;
94 
95  bool isPaused() const;
96 
104  int syncStart(int count);
105  int syncId() const {return sync_id;}
111  bool syncEndOnce(int id);
112 
113 signals:
114  void paused(bool);
115  void paused(); //equals to paused(true)
116  void resumed();//equals to paused(false)
117  void started();
118  void resetted();
119 public slots:
120  //these slots are not frequently used. so not inline
121  /*start the external clock*/
122  void start();
123  /*pause external clock*/
124  void pause(bool p);
125  /*reset clock intial value and external clock parameters (and stop timer). keep speed() and isClockAuto()*/
126  void reset();
127 
128 protected:
129  virtual void timerEvent(QTimerEvent *event);
130 private Q_SLOTS:
132  void restartCorrectionTimer();
133  void stopCorrectionTimer();
134 private:
135  bool auto_clock;
136  int m_state;
137  ClockType clock_type;
138  mutable double pts_;
139  mutable double pts_v;
140  double delay_;
141  mutable QElapsedTimer timer;
142  qreal mSpeed;
143  double value0;
151  QBasicTimer correction_schedule_timer;
152  qint64 t; // absolute time for elapsed timer correction
153  static const int kCorrectionInterval = 1; // 1000ms
154  double last_pts;
155  double avg_err; // average error of restart()
156  mutable int nb_restarted;
157  QAtomicInt nb_sync;
158  int sync_id;
159 };
160 
161 double AVClock::value() const
162 {
163  if (clock_type == AudioClock) {
164  // TODO: audio clock need a timer too
165  // timestamp from media stream is >= value0
166  return pts_ == 0 ? value0 : pts_ + delay_;
167  } else if (clock_type == ExternalClock) {
168  if (timer.isValid()) {
169  ++nb_restarted;
170  pts_ += (double(timer.restart()) * kThousandth + avg_err)* speed();
171  } else {//timer is paused
172  //qDebug("clock is paused. return the last value %f", pts_);
173  }
174  return pts_ + value0;
175  } else {
176  if (timer.isValid()) {
177  ++nb_restarted;
178  pts_v += (double(timer.restart()) * kThousandth + avg_err)* speed();
179  }
180  return pts_v; // value0 is 1st video pts_v already
181  }
182 }
183 
184 void AVClock::updateValue(double pts)
185 {
186  if (clock_type == AudioClock)
187  pts_ = pts;
188 }
189 
190 void AVClock::updateVideoTime(double pts)
191 {
192  pts_v = pts;
193  if (clock_type == VideoClock)
194  timer.restart();
195 }
196 
197 double AVClock::videoTime() const
198 {
199  return pts_v;
200 }
201 
202 double AVClock::delay() const
203 {
204  return delay_;
205 }
206 
207 void AVClock::updateDelay(double delay)
208 {
209  delay_ = delay;
210 }
211 
212 qreal AVClock::diff() const
213 {
214  return value() - videoTime();
215 }
216 
217 qreal AVClock::speed() const
218 {
219  return mSpeed;
220 }
221 
222 } //namespace QtAV
223 #endif // QTAV_AVCLOCK_H
int syncId() const
Definition: AVClock.h:105
#define Q_AV_EXPORT
Definition: QtAV_Global.h:40
Definition: AVClock.h:51
ClockType
Definition: AVClock.h:50
double delay() const
Definition: AVClock.h:202
qreal speed() const
Definition: AVClock.h:217
Definition: AVClock.h:46
void updateValue(double pts)
Definition: AVClock.h:184
double value() const
value the real timestamp in seconds: pts + delay
Definition: AVClock.h:161
void updateDelay(double delay)
Definition: AVClock.h:207
qreal diff() const
Definition: AVClock.h:212
AudioOutput ao; ao.setAudioFormat(fmt); ao.open(); while (has_data) { data = read_data(ao->bufferSize...
Definition: AudioDecoder.h:31
Definition: AVClock.h:52
double videoTime() const
Definition: AVClock.h:197
void updateVideoTime(double pts)
Definition: AVClock.h:190