mirror of
https://github.com/Armored-Dragon/overte.git
synced 2025-03-11 16:13:16 +01:00
Fixing race condition on seek, correcting some issues with frame timing
This commit is contained in:
parent
900f425f35
commit
48b0465e56
3 changed files with 59 additions and 23 deletions
|
@ -47,19 +47,19 @@ RecordingScriptingInterface::RecordingScriptingInterface() {
|
|||
connect(audioClient.data(), &AudioClient::inputReceived, this, &RecordingScriptingInterface::processAudioInput);
|
||||
}
|
||||
|
||||
bool RecordingScriptingInterface::isPlaying() {
|
||||
bool RecordingScriptingInterface::isPlaying() const {
|
||||
return _player->isPlaying();
|
||||
}
|
||||
|
||||
bool RecordingScriptingInterface::isPaused() {
|
||||
bool RecordingScriptingInterface::isPaused() const {
|
||||
return _player->isPaused();
|
||||
}
|
||||
|
||||
float RecordingScriptingInterface::playerElapsed() {
|
||||
float RecordingScriptingInterface::playerElapsed() const {
|
||||
return _player->position();
|
||||
}
|
||||
|
||||
float RecordingScriptingInterface::playerLength() {
|
||||
float RecordingScriptingInterface::playerLength() const {
|
||||
return _player->length();
|
||||
}
|
||||
|
||||
|
@ -103,6 +103,10 @@ void RecordingScriptingInterface::setPlayerAudioOffset(float audioOffset) {
|
|||
}
|
||||
|
||||
void RecordingScriptingInterface::setPlayerTime(float time) {
|
||||
if (QThread::currentThread() != thread()) {
|
||||
QMetaObject::invokeMethod(this, "setPlayerTime", Qt::BlockingQueuedConnection, Q_ARG(float, time));
|
||||
return;
|
||||
}
|
||||
_player->seek(time);
|
||||
}
|
||||
|
||||
|
@ -130,23 +134,27 @@ void RecordingScriptingInterface::setPlayerUseSkeletonModel(bool useSkeletonMode
|
|||
_useSkeletonModel = useSkeletonModel;
|
||||
}
|
||||
|
||||
void RecordingScriptingInterface::play() {
|
||||
_player->play();
|
||||
}
|
||||
|
||||
void RecordingScriptingInterface::pausePlayer() {
|
||||
if (QThread::currentThread() != thread()) {
|
||||
QMetaObject::invokeMethod(this, "pausePlayer", Qt::BlockingQueuedConnection);
|
||||
return;
|
||||
}
|
||||
_player->pause();
|
||||
}
|
||||
|
||||
void RecordingScriptingInterface::stopPlaying() {
|
||||
if (QThread::currentThread() != thread()) {
|
||||
QMetaObject::invokeMethod(this, "stopPlaying", Qt::BlockingQueuedConnection);
|
||||
return;
|
||||
}
|
||||
_player->stop();
|
||||
}
|
||||
|
||||
bool RecordingScriptingInterface::isRecording() {
|
||||
bool RecordingScriptingInterface::isRecording() const {
|
||||
return _recorder->isRecording();
|
||||
}
|
||||
|
||||
float RecordingScriptingInterface::recorderElapsed() {
|
||||
float RecordingScriptingInterface::recorderElapsed() const {
|
||||
return _recorder->position();
|
||||
}
|
||||
|
||||
|
|
|
@ -25,12 +25,17 @@ public:
|
|||
RecordingScriptingInterface();
|
||||
|
||||
public slots:
|
||||
bool isPlaying();
|
||||
bool isPaused();
|
||||
float playerElapsed();
|
||||
float playerLength();
|
||||
void loadRecording(const QString& filename);
|
||||
|
||||
void startPlaying();
|
||||
void pausePlayer();
|
||||
void stopPlaying();
|
||||
bool isPlaying() const;
|
||||
bool isPaused() const;
|
||||
|
||||
float playerElapsed() const;
|
||||
float playerLength() const;
|
||||
|
||||
void setPlayerVolume(float volume);
|
||||
void setPlayerAudioOffset(float audioOffset);
|
||||
void setPlayerTime(float time);
|
||||
|
@ -40,13 +45,13 @@ public slots:
|
|||
void setPlayerUseAttachments(bool useAttachments);
|
||||
void setPlayerUseHeadModel(bool useHeadModel);
|
||||
void setPlayerUseSkeletonModel(bool useSkeletonModel);
|
||||
void play();
|
||||
void pausePlayer();
|
||||
void stopPlaying();
|
||||
bool isRecording();
|
||||
float recorderElapsed();
|
||||
|
||||
void startRecording();
|
||||
void stopRecording();
|
||||
bool isRecording() const;
|
||||
|
||||
float recorderElapsed() const;
|
||||
|
||||
void saveRecording(const QString& filename);
|
||||
void loadLastRecording();
|
||||
|
||||
|
|
|
@ -8,6 +8,8 @@
|
|||
|
||||
#include "Deck.h"
|
||||
|
||||
#include <QtCore/QThread>
|
||||
|
||||
#include <NumericalConstants.h>
|
||||
#include <SharedUtil.h>
|
||||
|
||||
|
@ -101,9 +103,13 @@ float Deck::position() const {
|
|||
}
|
||||
|
||||
static const Frame::Time MIN_FRAME_WAIT_INTERVAL = Frame::secondsToFrameTime(0.001f);
|
||||
static const Frame::Time MAX_FRAME_PROCESSING_TIME = Frame::secondsToFrameTime(0.002f);
|
||||
static const Frame::Time MAX_FRAME_PROCESSING_TIME = Frame::secondsToFrameTime(0.004f);
|
||||
|
||||
void Deck::processFrames() {
|
||||
if (qApp->thread() != QThread::currentThread()) {
|
||||
qWarning() << "Processing frames must only happen on the main thread.";
|
||||
return;
|
||||
}
|
||||
Locker lock(_mutex);
|
||||
if (_pause) {
|
||||
return;
|
||||
|
@ -115,10 +121,17 @@ void Deck::processFrames() {
|
|||
// FIXME add code to start dropping frames if we fall behind.
|
||||
// Alternatively, add code to cache frames here and then process only the last frame of a given type
|
||||
// ... the latter will work for Avatar, but not well for audio I suspect.
|
||||
bool overLimit = false;
|
||||
for (nextClip = getNextClip(); nextClip; nextClip = getNextClip()) {
|
||||
auto currentPosition = Frame::frameTimeFromEpoch(_startEpoch);
|
||||
if ((currentPosition - startingPosition) >= MAX_FRAME_PROCESSING_TIME) {
|
||||
qCWarning(recordingLog) << "Exceeded maximum frame processing time, breaking early";
|
||||
#ifdef WANT_RECORDING_DEBUG
|
||||
qCDebug(recordingLog) << "Starting: " << currentPosition;
|
||||
qCDebug(recordingLog) << "Current: " << startingPosition;
|
||||
qCDebug(recordingLog) << "Trigger: " << triggerPosition;
|
||||
#endif
|
||||
overLimit = true;
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -150,9 +163,19 @@ void Deck::processFrames() {
|
|||
|
||||
// If we have more clip frames available, set the timer for the next one
|
||||
_position = Frame::frameTimeFromEpoch(_startEpoch);
|
||||
auto nextFrameTime = nextClip->positionFrameTime();
|
||||
auto interval = Frame::frameTimeToMilliseconds(nextFrameTime - _position);
|
||||
_timer.singleShot(interval, [this] {
|
||||
int nextInterval = 1;
|
||||
if (!overLimit) {
|
||||
auto nextFrameTime = nextClip->positionFrameTime();
|
||||
nextInterval = (int)Frame::frameTimeToMilliseconds(nextFrameTime - _position);
|
||||
#ifdef WANT_RECORDING_DEBUG
|
||||
qCDebug(recordingLog) << "Now " << _position;
|
||||
qCDebug(recordingLog) << "Next frame time " << nextInterval;
|
||||
#endif
|
||||
}
|
||||
#ifdef WANT_RECORDING_DEBUG
|
||||
qCDebug(recordingLog) << "Setting timer for next processing " << nextInterval;
|
||||
#endif
|
||||
_timer.singleShot(nextInterval, [this] {
|
||||
processFrames();
|
||||
});
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue