From a59049cbdf10b38d8d73bbd9a809b8394b36774c Mon Sep 17 00:00:00 2001 From: Mike Odom Date: Sat, 13 Jan 2018 18:38:39 -0800 Subject: [PATCH 1/9] Actually pausing AVPlayer on stepBackward --- src/AVPlayer.cpp | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/AVPlayer.cpp b/src/AVPlayer.cpp index d1f0ebf78..f1bdfa153 100644 --- a/src/AVPlayer.cpp +++ b/src/AVPlayer.cpp @@ -1545,11 +1545,8 @@ void AVPlayer::stepForward() void AVPlayer::stepBackward() { - d->clock->pause(true); - d->state = PausedState; - Q_EMIT stateChanged(d->state); - Q_EMIT paused(true); - d->read_thread->stepBackward(); + pause(true); + d->read_thread->stepBackward(); } void AVPlayer::seek(qreal r) From b1c4a6ded359fa649fc66f6a901bb352c5b22c6b Mon Sep 17 00:00:00 2001 From: Mike Odom <5105729+ThatOdieGuy@users.noreply.github.com> Date: Tue, 9 Jul 2019 16:05:40 -0700 Subject: [PATCH 2/9] Adding displayPosition to AVPlayer This remembers the last seek pos of the player. Prevents the display position from jumping around wildly as we seek. --- src/AVDemuxThread.cpp | 12 ++++++++++++ src/AVDemuxThread.h | 1 + src/AVPlayer.cpp | 21 +++++++++++++++++++++ src/AVPlayerPrivate.cpp | 1 + src/AVPlayerPrivate.h | 1 + src/QtAV/AVPlayer.h | 3 ++- 6 files changed, 38 insertions(+), 1 deletion(-) diff --git a/src/AVDemuxThread.cpp b/src/AVDemuxThread.cpp index 6eee37d94..cbc68b623 100644 --- a/src/AVDemuxThread.cpp +++ b/src/AVDemuxThread.cpp @@ -82,6 +82,7 @@ AVDemuxThread::AVDemuxThread(QObject *parent) : , audio_thread(0) , video_thread(0) , clock_type(-1) + , last_seek_pos(0) { seek_tasks.setCapacity(1); seek_tasks.blockFull(false); @@ -95,6 +96,7 @@ AVDemuxThread::AVDemuxThread(AVDemuxer *dmx, QObject *parent) : , m_buffer(0) , audio_thread(0) , video_thread(0) + , last_seek_pos(0) { setDemuxer(dmx); seek_tasks.setCapacity(1); @@ -278,6 +280,7 @@ void AVDemuxThread::seekInternal(qint64 pos, SeekType type, qint64 external_pos) if (external_pos != std::numeric_limits < qint64 >::min() ) t->clock()->updateExternalClock(qMax(qint64(0), external_pos)); t->clock()->updateValue(double(pos)/1000.0); + last_seek_pos = pos; t->requestSeek(); // TODO: the first frame (key frame) will not be decoded correctly if flush() is called. //PacketBuffer *pb = t->packetQueue(); @@ -323,6 +326,11 @@ void AVDemuxThread::processNextSeekTask() delete task; } +qint64 AVDemuxThread::lastSeekPos() +{ + return last_seek_pos; +} + void AVDemuxThread::pauseInternal(bool value) { paused = value; @@ -486,6 +494,10 @@ void AVDemuxThread::frameDeliveredOnStepForward() clock_type = -1; thread->clock()->updateExternalClock((thread->previousHistoryPts() - thread->clock()->initialValue())*1000.0); } + + // Fudge the bit at the end + 33ms so that step forward and step backwards present different values + last_seek_pos = (thread->previousHistoryPts() - thread->clock()->initialValue())*1000.0 + 33; + Q_EMIT stepFinished(); } diff --git a/src/AVDemuxThread.h b/src/AVDemuxThread.h index f2a9080b9..aca42b610 100644 --- a/src/AVDemuxThread.h +++ b/src/AVDemuxThread.h @@ -100,6 +100,7 @@ private slots: QMutex buffer_mutex; QWaitCondition cond; BlockingQueue seek_tasks; + qint64 last_seek_pos; QSemaphore sem; QMutex next_frame_mutex; diff --git a/src/AVPlayer.cpp b/src/AVPlayer.cpp index f1bdfa153..8a7f8c163 100644 --- a/src/AVPlayer.cpp +++ b/src/AVPlayer.cpp @@ -848,6 +848,27 @@ qint64 AVPlayer::position() const return pts; } +qint64 AVPlayer::displayPosition() const +{ + //return d->read_thread->lastSeekPos(); + + // Return a cached value if there are seek tasks + if (d->seeking || (d->read_thread->buffer() && d->read_thread->buffer()->isBuffering())) { + //return d->last_known_good_pts; + return d->last_known_good_pts = d->read_thread->lastSeekPos(); + } + + // TODO: videoTime()? + qint64 pts = d->clock->videoTime()*1000.0; + + if (pts < 0) { + return d->last_known_good_pts; + } + d->last_known_good_pts = pts; + + return pts; +} + void AVPlayer::setPosition(qint64 position) { // FIXME: strange things happen if seek out of eof diff --git a/src/AVPlayerPrivate.cpp b/src/AVPlayerPrivate.cpp index 84f079ef2..f8d815791 100644 --- a/src/AVPlayerPrivate.cpp +++ b/src/AVPlayerPrivate.cpp @@ -111,6 +111,7 @@ AVPlayer::Private::Private() , status(NoMedia) , state(AVPlayer::StoppedState) , end_action(MediaEndAction_Default) + , last_known_good_pts(0) { demuxer.setInterruptTimeout(interrupt_timeout); /* diff --git a/src/AVPlayerPrivate.h b/src/AVPlayerPrivate.h index e404b9bff..7aa532f5a 100644 --- a/src/AVPlayerPrivate.h +++ b/src/AVPlayerPrivate.h @@ -111,6 +111,7 @@ class AVPlayer::Private bool reset_state; qint64 start_position, stop_position; qint64 start_position_norm, stop_position_norm; // real position + qint64 last_known_good_pts; int repeat_max, repeat_current; int timer_id; //notify position change and check AB repeat range. active when playing diff --git a/src/QtAV/AVPlayer.h b/src/QtAV/AVPlayer.h index e297b0370..11ae4d6a5 100644 --- a/src/QtAV/AVPlayer.h +++ b/src/QtAV/AVPlayer.h @@ -178,7 +178,8 @@ class Q_AV_EXPORT AVPlayer : public QObject */ qint64 stopPosition() const; //unit: ms qint64 position() const; //unit: ms - //0: play once. N: play N+1 times. <0: infinity + qint64 displayPosition() const; + //0: play once. N: play N+1 times. <0: infinity int repeat() const; //or repeatMax()? /*! * \brief currentRepeat From 5501862af3cb3d5f55b59ce00a8d82f074d460c9 Mon Sep 17 00:00:00 2001 From: Mike Odom <5105729+ThatOdieGuy@users.noreply.github.com> Date: Tue, 9 Jul 2019 16:06:43 -0700 Subject: [PATCH 3/9] Adding displayPosition to AVPlayer --- src/AVDemuxThread.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/AVDemuxThread.h b/src/AVDemuxThread.h index aca42b610..93bf915f8 100644 --- a/src/AVDemuxThread.h +++ b/src/AVDemuxThread.h @@ -59,6 +59,7 @@ class AVDemuxThread : public QThread MediaEndAction mediaEndAction() const; void setMediaEndAction(MediaEndAction value); bool waitForStarted(int msec = -1); + qint64 lastSeekPos(); Q_SIGNALS: void requestClockPause(bool value); void mediaStatusChanged(QtAV::MediaStatus); From 12da5dd2aa7dab2b51b39e3c29f8174e1c726667 Mon Sep 17 00:00:00 2001 From: Mike Odom <5105729+ThatOdieGuy@users.noreply.github.com> Date: Tue, 9 Jul 2019 18:55:42 -0700 Subject: [PATCH 4/9] Preventing double stepping --- src/AVDemuxThread.cpp | 79 +++++++++++++++++++++++++++++++++++++---- src/AVDemuxThread.h | 9 ++++- src/AVPlayer.cpp | 21 ++++++++--- src/AVPlayerPrivate.cpp | 1 + src/AVPlayerPrivate.h | 1 + 5 files changed, 100 insertions(+), 11 deletions(-) diff --git a/src/AVDemuxThread.cpp b/src/AVDemuxThread.cpp index cbc68b623..db8abbaaf 100644 --- a/src/AVDemuxThread.cpp +++ b/src/AVDemuxThread.cpp @@ -27,6 +27,7 @@ #include "VideoThread.h" #include #include "utils/Logger.h" +#include #define RESUME_ONCE_ON_SEEK 0 @@ -83,6 +84,8 @@ AVDemuxThread::AVDemuxThread(QObject *parent) : , video_thread(0) , clock_type(-1) , last_seek_pos(0) + , current_seek_task(nullptr) + , stepping(false) { seek_tasks.setCapacity(1); seek_tasks.blockFull(false); @@ -97,6 +100,8 @@ AVDemuxThread::AVDemuxThread(AVDemuxer *dmx, QObject *parent) : , audio_thread(0) , video_thread(0) , last_seek_pos(0) + , current_seek_task(nullptr) + , stepping(false) { setDemuxer(dmx); seek_tasks.setCapacity(1); @@ -155,6 +160,8 @@ void AVDemuxThread::stepBackward() { if (!video_thread) return; + if (hasSeekTasks() || m_buffering) + return; AVThread *t = video_thread; const qreal pre_pts = video_thread->previousHistoryPts(); if (pre_pts == 0.0) { @@ -176,6 +183,10 @@ void AVDemuxThread::stepBackward() void run() { AVThread *avt = demux_thread->videoThread(); avt->packetQueue()->clear(); // clear here + + connect(avt, SIGNAL(frameDelivered()), demux_thread, SLOT(finishedStepBackward()), Qt::DirectConnection); + connect(avt, SIGNAL(eofDecoded()), demux_thread, SLOT(finishedStepBackward()), Qt::DirectConnection); + if (pts <= 0) { demux_thread->demuxer->seek(qint64(-pts*1000.0) - 500LL); QVector ts; @@ -195,6 +206,7 @@ void AVDemuxThread::stepBackward() pts -= dt/2.0; } qDebug("step backward: %lld, %f", qint64(pts*1000.0), pts); + demux_thread->video_thread->setDropFrameOnSeek(false); demux_thread->seekInternal(qint64(pts*1000.0), AccurateSeek); } @@ -204,6 +216,14 @@ void AVDemuxThread::stepBackward() }; pause(true); + stepping = true; + + // In case we never get a frame, set a timeout. + auto timer = new QTimer(this); + connect(timer, SIGNAL(timeout()), this, SLOT(finishedStepBackward())); + timer->start(200); + step_timeout_timer = timer; + t->packetQueue()->clear(); // will put new packets before task run t->packetQueue(); Packet pkt; @@ -213,6 +233,19 @@ void AVDemuxThread::stepBackward() newSeekRequest(new stepBackwardTask(this, pre_pts)); } +void AVDemuxThread::finishedStepBackward() +{ + disconnect(video_thread, SIGNAL(frameDelivered()), this, SLOT(finishedStepBackward())); + disconnect(video_thread, SIGNAL(eofDecoded()), this, SLOT(finishedStepBackward())); + + if (step_timeout_timer) { + step_timeout_timer->stop(); + step_timeout_timer = nullptr; + } + + stepping = false; +} + void AVDemuxThread::seek(qint64 external_pos, qint64 pos, SeekType type) { class SeekTask : public QRunnable { @@ -318,12 +351,20 @@ void AVDemuxThread::processNextSeekTask() { if (seek_tasks.isEmpty()) return; - QRunnable *task = seek_tasks.take(); - if (!task) + + current_seek_task = seek_tasks.take(); + if (!current_seek_task) return; - task->run(); - if (task->autoDelete()) - delete task; + current_seek_task->run(); + + if (current_seek_task->autoDelete()) + delete current_seek_task; + current_seek_task = nullptr; +} + +bool AVDemuxThread::hasSeekTasks() +{ + return !seek_tasks.isEmpty() || current_seek_task || stepping; } qint64 AVDemuxThread::lastSeekPos() @@ -428,6 +469,11 @@ void AVDemuxThread::stepForward() { if (end) return; + if (hasSeekTasks() || m_buffering) + return; + + stepping = true; + // clock type will be wrong if no lock because slot frameDeliveredOnStepForward() is in video thread QMutexLocker locker(&next_frame_mutex); Q_UNUSED(locker); @@ -448,6 +494,13 @@ void AVDemuxThread::stepForward() if (!connected) { connect(t, SIGNAL(frameDelivered()), this, SLOT(frameDeliveredOnStepForward()), Qt::DirectConnection); connect(t, SIGNAL(eofDecoded()), this, SLOT(eofDecodedOnStepForward()), Qt::DirectConnection); + + // In case we never get a frame, set a timeout. + auto timer = new QTimer(this); + connect(timer, SIGNAL(timeout()), this, SLOT(frameDeliveredOnStepForward())); + timer->start(200); + step_timeout_timer = timer; + connected = true; } } @@ -497,7 +550,9 @@ void AVDemuxThread::frameDeliveredOnStepForward() // Fudge the bit at the end + 33ms so that step forward and step backwards present different values last_seek_pos = (thread->previousHistoryPts() - thread->clock()->initialValue())*1000.0 + 33; - + + stepForwardDone(); + Q_EMIT stepFinished(); } @@ -516,9 +571,21 @@ void AVDemuxThread::eofDecodedOnStepForward() thread->clock()->setClockType(AVClock::ClockType(clock_type/2)); clock_type = -1; } + + stepForwardDone(); + Q_EMIT stepFinished(); } +void AVDemuxThread::stepForwardDone() +{ + if (step_timeout_timer) { + step_timeout_timer->stop(); + step_timeout_timer = nullptr; + } + stepping = false; +} + void AVDemuxThread::onAVThreadQuit() { AVThread* av[] = { audio_thread, video_thread}; diff --git a/src/AVDemuxThread.h b/src/AVDemuxThread.h index 93bf915f8..6c05942fe 100644 --- a/src/AVDemuxThread.h +++ b/src/AVDemuxThread.h @@ -27,6 +27,7 @@ #include #include #include "PacketBuffer.h" +#include namespace QtAV { @@ -60,6 +61,7 @@ class AVDemuxThread : public QThread void setMediaEndAction(MediaEndAction value); bool waitForStarted(int msec = -1); qint64 lastSeekPos(); + bool hasSeekTasks(); Q_SIGNALS: void requestClockPause(bool value); void mediaStatusChanged(QtAV::MediaStatus); @@ -68,9 +70,11 @@ class AVDemuxThread : public QThread void stepFinished(); void internalSubtitlePacketRead(int index, const QtAV::Packet& packet); private slots: + void finishedStepBackward(); void seekOnPauseFinished(); void frameDeliveredOnStepForward(); void eofDecodedOnStepForward(); + void stepForwardDone(); void onAVThreadQuit(); protected: @@ -102,7 +106,10 @@ private slots: QWaitCondition cond; BlockingQueue seek_tasks; qint64 last_seek_pos; - + QRunnable *current_seek_task; + bool stepping; + QTimer *step_timeout_timer; + QSemaphore sem; QMutex next_frame_mutex; int clock_type; // change happens in different threads(direct connection) diff --git a/src/AVPlayer.cpp b/src/AVPlayer.cpp index 8a7f8c163..94a16b7cd 100644 --- a/src/AVPlayer.cpp +++ b/src/AVPlayer.cpp @@ -583,6 +583,12 @@ void AVPlayer::pause(bool p) return; if (isPaused() == p) return; + + if (!p) { + // TODO: If was stepping, skip our position a little bit behind us. + d->was_stepping = false; + } + audio()->pause(p); //pause thread. check pause state? d->read_thread->pause(p); @@ -850,17 +856,19 @@ qint64 AVPlayer::position() const qint64 AVPlayer::displayPosition() const { - //return d->read_thread->lastSeekPos(); - // Return a cached value if there are seek tasks - if (d->seeking || (d->read_thread->buffer() && d->read_thread->buffer()->isBuffering())) { - //return d->last_known_good_pts; + if (d->seeking || d->read_thread->hasSeekTasks() || (d->read_thread->buffer() && d->read_thread->buffer()->isBuffering())) { return d->last_known_good_pts = d->read_thread->lastSeekPos(); } // TODO: videoTime()? qint64 pts = d->clock->videoTime()*1000.0; + // If we are stepping around, we want the lastSeekPos. + /// But if we're just paused by the user... we want another value. + if (d->was_stepping) { + pts = d->read_thread->lastSeekPos(); + } if (pts < 0) { return d->last_known_good_pts; } @@ -1279,6 +1287,9 @@ void AVPlayer::playInternal() else setPosition((qint64)(d->start_position_norm)); } + + d->was_stepping = false; + Q_EMIT stateChanged(PlayingState); Q_EMIT started(); //we called stop(), so must emit started() } @@ -1561,12 +1572,14 @@ void AVPlayer::stepForward() { // pause clock pause(true); // must pause AVDemuxThread (set user_paused true) + d->was_stepping = true; d->read_thread->stepForward(); } void AVPlayer::stepBackward() { pause(true); + d->was_stepping = true; d->read_thread->stepBackward(); } diff --git a/src/AVPlayerPrivate.cpp b/src/AVPlayerPrivate.cpp index f8d815791..9b9014f43 100644 --- a/src/AVPlayerPrivate.cpp +++ b/src/AVPlayerPrivate.cpp @@ -112,6 +112,7 @@ AVPlayer::Private::Private() , state(AVPlayer::StoppedState) , end_action(MediaEndAction_Default) , last_known_good_pts(0) + , was_stepping(false) { demuxer.setInterruptTimeout(interrupt_timeout); /* diff --git a/src/AVPlayerPrivate.h b/src/AVPlayerPrivate.h index 7aa532f5a..e7be85807 100644 --- a/src/AVPlayerPrivate.h +++ b/src/AVPlayerPrivate.h @@ -112,6 +112,7 @@ class AVPlayer::Private qint64 start_position, stop_position; qint64 start_position_norm, stop_position_norm; // real position qint64 last_known_good_pts; + bool was_stepping; int repeat_max, repeat_current; int timer_id; //notify position change and check AB repeat range. active when playing From cfb454a088df0ce529ceb338edc1b2d30164f890 Mon Sep 17 00:00:00 2001 From: Mike Odom <5105729+ThatOdieGuy@users.noreply.github.com> Date: Tue, 9 Jul 2019 18:59:38 -0700 Subject: [PATCH 5/9] Seeking backwards a bit if we were stepping --- src/AVPlayer.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/AVPlayer.cpp b/src/AVPlayer.cpp index 94a16b7cd..8bef91aad 100644 --- a/src/AVPlayer.cpp +++ b/src/AVPlayer.cpp @@ -585,8 +585,12 @@ void AVPlayer::pause(bool p) return; if (!p) { - // TODO: If was stepping, skip our position a little bit behind us. - d->was_stepping = false; + if (d->was_stepping) { + d->was_stepping = false; + // If was stepping, skip our position a little bit behind us. + // This fixes an issue with the audio timer + seek(position() - 100); + } } audio()->pause(p); From a1a435bd57d3ab96c0f50c6281e4090d5b50fc75 Mon Sep 17 00:00:00 2001 From: Mike Odom <5105729+ThatOdieGuy@users.noreply.github.com> Date: Tue, 9 Jul 2019 21:34:15 -0700 Subject: [PATCH 6/9] Removing the check for buffering on steps Buffering state seems to get stuck, we don't need to check it for stepping. --- src/AVDemuxThread.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/AVDemuxThread.cpp b/src/AVDemuxThread.cpp index db8abbaaf..51af2f240 100644 --- a/src/AVDemuxThread.cpp +++ b/src/AVDemuxThread.cpp @@ -160,7 +160,7 @@ void AVDemuxThread::stepBackward() { if (!video_thread) return; - if (hasSeekTasks() || m_buffering) + if (hasSeekTasks()) return; AVThread *t = video_thread; const qreal pre_pts = video_thread->previousHistoryPts(); @@ -469,7 +469,7 @@ void AVDemuxThread::stepForward() { if (end) return; - if (hasSeekTasks() || m_buffering) + if (hasSeekTasks()) return; stepping = true; From 6f0f7fc09f57b424c0cea4e7901d1ce83c1b9a28 Mon Sep 17 00:00:00 2001 From: Mike Odom <5105729+ThatOdieGuy@users.noreply.github.com> Date: Wed, 10 Jul 2019 00:35:29 -0700 Subject: [PATCH 7/9] Fixing the step backwards seek timeout --- src/AVDemuxThread.cpp | 42 ++++++++++++++++-------------------------- src/AVDemuxThread.h | 2 +- 2 files changed, 17 insertions(+), 27 deletions(-) diff --git a/src/AVDemuxThread.cpp b/src/AVDemuxThread.cpp index 51af2f240..995c035f6 100644 --- a/src/AVDemuxThread.cpp +++ b/src/AVDemuxThread.cpp @@ -86,6 +86,7 @@ AVDemuxThread::AVDemuxThread(QObject *parent) : , last_seek_pos(0) , current_seek_task(nullptr) , stepping(false) + , stepping_timeout_time(0) { seek_tasks.setCapacity(1); seek_tasks.blockFull(false); @@ -102,6 +103,7 @@ AVDemuxThread::AVDemuxThread(AVDemuxer *dmx, QObject *parent) : , last_seek_pos(0) , current_seek_task(nullptr) , stepping(false) + , stepping_timeout_time(0) { setDemuxer(dmx); seek_tasks.setCapacity(1); @@ -174,13 +176,18 @@ void AVDemuxThread::stepBackward() audio_thread->packetQueue()->clear(); // will put new packets before task run } - class stepBackwardTask : public QRunnable { + class stepBackwardTask : public QObject, public QRunnable { public: + QTimer timeout_timer; + stepBackwardTask(AVDemuxThread *dt, qreal t) : demux_thread(dt) , pts(t) {} void run() { + demux_thread->stepping = true; + demux_thread->stepping_timeout_time = QDateTime::currentMSecsSinceEpoch() + 200; + AVThread *avt = demux_thread->videoThread(); avt->packetQueue()->clear(); // clear here @@ -216,13 +223,6 @@ void AVDemuxThread::stepBackward() }; pause(true); - stepping = true; - - // In case we never get a frame, set a timeout. - auto timer = new QTimer(this); - connect(timer, SIGNAL(timeout()), this, SLOT(finishedStepBackward())); - timer->start(200); - step_timeout_timer = timer; t->packetQueue()->clear(); // will put new packets before task run t->packetQueue(); @@ -238,12 +238,8 @@ void AVDemuxThread::finishedStepBackward() disconnect(video_thread, SIGNAL(frameDelivered()), this, SLOT(finishedStepBackward())); disconnect(video_thread, SIGNAL(eofDecoded()), this, SLOT(finishedStepBackward())); - if (step_timeout_timer) { - step_timeout_timer->stop(); - step_timeout_timer = nullptr; - } - stepping = false; + stepping_timeout_time = 0; } void AVDemuxThread::seek(qint64 external_pos, qint64 pos, SeekType type) @@ -364,6 +360,10 @@ void AVDemuxThread::processNextSeekTask() bool AVDemuxThread::hasSeekTasks() { + // This is not great. But I couldn't figure out how to get QTimers and stepBackwardTask working + if (stepping && stepping_timeout_time > 0 && stepping_timeout_time < QDateTime::currentMSecsSinceEpoch()) { + finishedStepBackward(); + } return !seek_tasks.isEmpty() || current_seek_task || stepping; } @@ -495,12 +495,6 @@ void AVDemuxThread::stepForward() connect(t, SIGNAL(frameDelivered()), this, SLOT(frameDeliveredOnStepForward()), Qt::DirectConnection); connect(t, SIGNAL(eofDecoded()), this, SLOT(eofDecodedOnStepForward()), Qt::DirectConnection); - // In case we never get a frame, set a timeout. - auto timer = new QTimer(this); - connect(timer, SIGNAL(timeout()), this, SLOT(frameDeliveredOnStepForward())); - timer->start(200); - step_timeout_timer = timer; - connected = true; } } @@ -551,7 +545,7 @@ void AVDemuxThread::frameDeliveredOnStepForward() // Fudge the bit at the end + 33ms so that step forward and step backwards present different values last_seek_pos = (thread->previousHistoryPts() - thread->clock()->initialValue())*1000.0 + 33; - stepForwardDone(); + stepping = false; Q_EMIT stepFinished(); } @@ -572,18 +566,14 @@ void AVDemuxThread::eofDecodedOnStepForward() clock_type = -1; } - stepForwardDone(); + stepping = false; Q_EMIT stepFinished(); } void AVDemuxThread::stepForwardDone() { - if (step_timeout_timer) { - step_timeout_timer->stop(); - step_timeout_timer = nullptr; - } - stepping = false; + } void AVDemuxThread::onAVThreadQuit() diff --git a/src/AVDemuxThread.h b/src/AVDemuxThread.h index 6c05942fe..624b3c0d4 100644 --- a/src/AVDemuxThread.h +++ b/src/AVDemuxThread.h @@ -108,7 +108,7 @@ private slots: qint64 last_seek_pos; QRunnable *current_seek_task; bool stepping; - QTimer *step_timeout_timer; + qint64 stepping_timeout_time; QSemaphore sem; QMutex next_frame_mutex; From 75a0c1ef6930796880f3d474865d59528be56421 Mon Sep 17 00:00:00 2001 From: Mike Odom <5105729+ThatOdieGuy@users.noreply.github.com> Date: Sat, 5 Oct 2019 13:36:13 -0700 Subject: [PATCH 8/9] Replacing tabs with spaces I don't know what editor I was using that put tabs in! --- src/AVDemuxThread.cpp | 2 +- src/AVPlayer.cpp | 26 +++++++++++++------------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/AVDemuxThread.cpp b/src/AVDemuxThread.cpp index 995c035f6..552da2295 100644 --- a/src/AVDemuxThread.cpp +++ b/src/AVDemuxThread.cpp @@ -364,7 +364,7 @@ bool AVDemuxThread::hasSeekTasks() if (stepping && stepping_timeout_time > 0 && stepping_timeout_time < QDateTime::currentMSecsSinceEpoch()) { finishedStepBackward(); } - return !seek_tasks.isEmpty() || current_seek_task || stepping; + return !seek_tasks.isEmpty() || current_seek_task || stepping; } qint64 AVDemuxThread::lastSeekPos() diff --git a/src/AVPlayer.cpp b/src/AVPlayer.cpp index 8bef91aad..b5e05136b 100644 --- a/src/AVPlayer.cpp +++ b/src/AVPlayer.cpp @@ -860,25 +860,25 @@ qint64 AVPlayer::position() const qint64 AVPlayer::displayPosition() const { - // Return a cached value if there are seek tasks - if (d->seeking || d->read_thread->hasSeekTasks() || (d->read_thread->buffer() && d->read_thread->buffer()->isBuffering())) { - return d->last_known_good_pts = d->read_thread->lastSeekPos(); - } + // Return a cached value if there are seek tasks + if (d->seeking || d->read_thread->hasSeekTasks() || (d->read_thread->buffer() && d->read_thread->buffer()->isBuffering())) { + return d->last_known_good_pts = d->read_thread->lastSeekPos(); + } - // TODO: videoTime()? - qint64 pts = d->clock->videoTime()*1000.0; + // TODO: videoTime()? + qint64 pts = d->clock->videoTime()*1000.0; // If we are stepping around, we want the lastSeekPos. /// But if we're just paused by the user... we want another value. if (d->was_stepping) { pts = d->read_thread->lastSeekPos(); } - if (pts < 0) { - return d->last_known_good_pts; - } - d->last_known_good_pts = pts; + if (pts < 0) { + return d->last_known_good_pts; + } + d->last_known_good_pts = pts; - return pts; + return pts; } void AVPlayer::setPosition(qint64 position) @@ -1582,9 +1582,9 @@ void AVPlayer::stepForward() void AVPlayer::stepBackward() { - pause(true); + pause(true); d->was_stepping = true; - d->read_thread->stepBackward(); + d->read_thread->stepBackward(); } void AVPlayer::seek(qreal r) From cf06dbbed3dfd42c17634ac011e4110191381e08 Mon Sep 17 00:00:00 2001 From: Mike Odom <5105729+ThatOdieGuy@users.noreply.github.com> Date: Sat, 5 Oct 2019 13:40:30 -0700 Subject: [PATCH 9/9] Replacing tabs with spaces --- src/AVDemuxThread.cpp | 2 +- src/AVDemuxThread.h | 4 ++-- src/AVPlayerPrivate.h | 2 +- src/QtAV/AVPlayer.h | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/AVDemuxThread.cpp b/src/AVDemuxThread.cpp index 552da2295..432cee641 100644 --- a/src/AVDemuxThread.cpp +++ b/src/AVDemuxThread.cpp @@ -272,7 +272,7 @@ void AVDemuxThread::seek(qint64 external_pos, qint64 pos, SeekType type) }; end = false; - // queue maybe blocked by put() + // queue maybe blocked by put() // These must be here or seeking while paused will not update the video frame if (audio_thread) { audio_thread->packetQueue()->clear(); diff --git a/src/AVDemuxThread.h b/src/AVDemuxThread.h index 624b3c0d4..6d9953783 100644 --- a/src/AVDemuxThread.h +++ b/src/AVDemuxThread.h @@ -60,8 +60,8 @@ class AVDemuxThread : public QThread MediaEndAction mediaEndAction() const; void setMediaEndAction(MediaEndAction value); bool waitForStarted(int msec = -1); - qint64 lastSeekPos(); - bool hasSeekTasks(); + qint64 lastSeekPos(); + bool hasSeekTasks(); Q_SIGNALS: void requestClockPause(bool value); void mediaStatusChanged(QtAV::MediaStatus); diff --git a/src/AVPlayerPrivate.h b/src/AVPlayerPrivate.h index e7be85807..77e45f06a 100644 --- a/src/AVPlayerPrivate.h +++ b/src/AVPlayerPrivate.h @@ -111,7 +111,7 @@ class AVPlayer::Private bool reset_state; qint64 start_position, stop_position; qint64 start_position_norm, stop_position_norm; // real position - qint64 last_known_good_pts; + qint64 last_known_good_pts; bool was_stepping; int repeat_max, repeat_current; int timer_id; //notify position change and check AB repeat range. active when playing diff --git a/src/QtAV/AVPlayer.h b/src/QtAV/AVPlayer.h index 11ae4d6a5..368cdbfe6 100644 --- a/src/QtAV/AVPlayer.h +++ b/src/QtAV/AVPlayer.h @@ -178,8 +178,8 @@ class Q_AV_EXPORT AVPlayer : public QObject */ qint64 stopPosition() const; //unit: ms qint64 position() const; //unit: ms - qint64 displayPosition() const; - //0: play once. N: play N+1 times. <0: infinity + qint64 displayPosition() const; + //0: play once. N: play N+1 times. <0: infinity int repeat() const; //or repeatMax()? /*! * \brief currentRepeat