5#ifndef PONYPLAYER_VIDEOWORKER_H
6#define PONYPLAYER_VIDEOWORKER_H
11#include <QCoreApplication>
25 QThread *m_affinityThread;
31 std::atomic<bool> m_isInterrupt;
32 std::atomic<bool> m_isPlaying;
33 std::mutex m_interruptMutex;
34 std::mutex m_workMutex;
35 std::condition_variable m_interruptCond;
38 qreal m_speedFactor = 1.0;
40 std::atomic<qreal> m_preferablePos = 0.0;
47 inline void syncTo(qreal current) {
56 if (isnan(pos)) {
return; }
57 m_preferablePos = current;
60 duration = (current - pos) / m_audioSink->
speed();
62 if (m_audioSink->
speed() > 2 - 1e-5) {
64 m_demuxer->
skipPicture([
this, backward](qreal framePos) {
68 m_demuxer->
skipPicture([
this, backward](qreal framePos) {
75 if (backward) { duration = -duration; }
79 qWarning() <<
"Sleep long duration" << duration <<
"s";
81 std::unique_lock lock(m_interruptMutex);
83 m_interruptCond.wait_for(lock, std::chrono::duration<double>(duration));
86 qWarning() <<
"Sleep negative duration" << duration <<
"s";
90 inline bool writeAudio(
int batch) {
91 if (m_audioSink->
isBlock()) {
return true; }
94 if (!sample.
isValid()) {
return false; }
103 if (cacheVideoFrame.
isValid()) {
105 cacheVideoFrame = {};
114 m_affinityThread =
new QThread;
116 this->moveToThread(m_affinityThread);
123 m_speedFactor = speed;
126 if (this->m_audioSink->
isBlock()) { return; }
128 this->m_audioSink->setBlockState(
true);
131 if (!this->m_audioSink->
isBlock()) { return; }
133 this->m_audioSink->setBlockState(
false);
138 if (!cacheVideoFrame.
isValid()) { cacheVideoFrame = m_demuxer->getPicture(); }
142 cacheVideoFrame = {};
145 connect(m_affinityThread, &QThread::started, [
this] {
151 }, Qt::QueuedConnection);
159 m_affinityThread->start();
163 return m_preferablePos;
167 std::unique_lock lock(m_workMutex);
189 m_affinityThread->quit();
234 m_isInterrupt =
false;
236 qDebug() <<
"SetStartPoint" << startPoint;
245 m_isInterrupt =
false;
260 std::unique_lock cond_lock(m_interruptMutex);
261 m_isInterrupt =
true;
262 m_interruptCond.notify_all();
264 std::unique_lock lock(m_workMutex);
271 std::unique_lock cond_lock(m_interruptMutex);
272 m_isInterrupt =
true;
273 m_interruptCond.notify_all();
275 std::unique_lock lock(m_workMutex);
292 std::unique_lock lock(m_workMutex, std::defer_lock);
293 if (!lock.try_lock()) {
return; }
296 m_audioSink->
start();
297 while (!m_isInterrupt) {
306 if (!writeAudio(
static_cast<int>(10 * m_audioSink->
speed()))) {
311 QCoreApplication::processEvents();
314 m_audioSink->
pause();
Definition: frame.hpp:145
int getDataLen() const
Definition: frame.hpp:163
std::byte * getSampleData() const
Definition: frame.hpp:159
bool isValid()
Definition: frame.hpp:155
Definition: demuxer.hpp:14
PONY_THREAD_SAFE int skipPicture(const std::function< bool(qreal)> &predicate)
Definition: demuxer.hpp:53
qreal frontPicture()
Definition: demuxer.hpp:48
AudioFrame getSample()
Definition: demuxer.hpp:60
PONY_THREAD_SAFE bool isBackward()
Definition: demuxer.hpp:108
VideoFrameRef getPicture()
Definition: demuxer.hpp:41
PONY_THREAD_SAFE bool hasVideo()
Definition: demuxer.hpp:114
负责输出视频和音频(不含视频预览).
Definition: playback.hpp:22
void pause()
Definition: playback.hpp:259
bool isPlaying()
Definition: playback.hpp:225
void start()
Definition: playback.hpp:243
void setSpeed(qreal speed)
Definition: playback.hpp:201
void signalDeviceSwitched()
void setAudioVolume(qreal volume, QPrivateSignal)
qreal getPitch()
Definition: playback.hpp:283
QString getSelectedAudioOutputDevice()
Definition: playback.hpp:209
void stop()
Definition: playback.hpp:270
void stateChanged(bool isPlaying)
void showFirstVideoFrame(QPrivateSignal)
PONY_THREAD_SAFE qreal getPreferablePos()
Definition: playback.hpp:162
void stopWork(QPrivateSignal)
void clearCacheVideoFrame(QPrivateSignal)
qreal getAudioPos(bool backward) const
Definition: playback.hpp:171
void clearCacheFrame()
Definition: playback.hpp:217
Playback(Demuxer *demuxer, QObject *parent)
Definition: playback.hpp:113
void startWork(QPrivateSignal)
bool isInterrupted()
Definition: playback.hpp:231
QStringList getAudioDeviceList()
Definition: playback.hpp:281
void setAudioPitch(qreal pitch, QPrivateSignal)
void clear()
Definition: playback.hpp:252
void setPitch(qreal pitch)
Definition: playback.hpp:197
void signalSetSelectedAudioOutputDevice(QString)
void setDesiredFormat(const PonyAudioFormat &format)
Definition: playback.hpp:180
void setSelectedAudioOutputDevice(QString deviceName)
Definition: playback.hpp:205
void setAudioStartPoint(qreal startPoint, QPrivateSignal)
virtual ~Playback()
Definition: playback.hpp:188
void requestResynchronization(bool enableAudio, bool updateAudioFormat)
void setPicture(VideoFrameRef pic)
PonyAudioFormat getDeviceFormat()
Definition: playback.hpp:166
void setVolume(qreal volume)
Definition: playback.hpp:192
void clearRingBuffer(QPrivateSignal)
void signalAudioOutputDevicesListChanged()
void showFrame()
Definition: playback.hpp:213
void setStartPoint(qreal startPoint)
Definition: playback.hpp:233
void setAudioSpeed(qreal speed, QPrivateSignal)
播放音频裸流, 用于代替QAudioSink.
Definition: audiosink.hpp:38
void pause()
Definition: audiosink.hpp:303
void setVolume(qreal newVolume)
Definition: audiosink.hpp:452
void setSpeed(qreal newSpeed)
Definition: audiosink.hpp:470
qreal pitch() const
Definition: audiosink.hpp:487
int64_t freeByte() const
Definition: audiosink.hpp:357
PonyAudioFormat getCurrentDeviceFormat()
Definition: audiosink.hpp:584
void stop()
Definition: audiosink.hpp:326
QStringList getAudioDeviceList()
Definition: audiosink.hpp:533
void requestDeviceSwitch(const QString &device)
Definition: audiosink.hpp:567
void start()
Definition: audiosink.hpp:281
void signalDeviceSwitched()
qreal speed() const
Definition: audiosink.hpp:483
void setPitch(qreal newPitch)
Definition: audiosink.hpp:461
void waitComplete()
Definition: audiosink.hpp:317
qreal getProcessSecs(bool backward) const
Definition: audiosink.hpp:421
size_t clear()
Definition: audiosink.hpp:407
bool isBlock()
Definition: audiosink.hpp:341
constexpr static const qreal MAX_SPEED_FACTOR
Definition: audiosink.hpp:230
void setStartPoint(double t=0.0)
Definition: audiosink.hpp:435
void setFormat(const PonyAudioFormat &format)
Definition: audiosink.hpp:537
void signalAudioOutputDeviceListChanged()
QString getSelectedOutputDevice()
Definition: audiosink.hpp:506
bool write(const char *buf, qint32 origLen)
Definition: audiosink.hpp:369
bool isValid() const
Definition: frame.hpp:97
double getPTS() const
Definition: frame.hpp:102
const int MAX_AUDIO_FRAME_SIZE
Definition: helper.hpp:15
const PonyAudioFormat DEFAULT_AUDIO_FORMAT
Definition: audioformat.hpp:164
constexpr PonyThread PLAYBACK
Definition: ponyplayer.h:45
#define ILLEGAL_STATE(msg)
Definition: ponyplayer.h:40
#define PONY_GUARD_BY(...)
Definition: ponyplayer.h:89