- enforce locking before getting.
- explicitly keep track of last now time to determine max delta. - refactoring. git-svn-id: https://gambatte.svn.sourceforge.net/svnroot/gambatte@306 9dfb2916-2d38-0410-aef4-c5fe6c9ffc24
This commit is contained in:
parent
9118428047
commit
ae91cda89f
@ -24,10 +24,8 @@
|
||||
#include <QtGlobal> // for Q_WS_WIN define
|
||||
|
||||
MainWindow::FrameBuffer::Locked::Locked(FrameBuffer fb) : mw(0), pb() {
|
||||
if (fb.mw->tryLockFrameBuf()) {
|
||||
if (fb.mw->tryLockFrameBuf(pb))
|
||||
mw = fb.mw;
|
||||
pb = fb.mw->frameBuf();
|
||||
}
|
||||
}
|
||||
|
||||
MainWindow::FrameBuffer::Locked::~Locked() {
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include "mediawidget.h"
|
||||
#include <QEvent>
|
||||
#include <QKeyEvent>
|
||||
#include <QMutexLocker>
|
||||
#include <QCoreApplication>
|
||||
#include <QtGlobal> // for Q_WS_WIN define
|
||||
#include "adaptivesleep.h"
|
||||
@ -130,11 +131,17 @@ public:
|
||||
bool cancelBlit();
|
||||
void paused();
|
||||
void audioEngineFailure();
|
||||
bool tryLockVideoBuffer() { return mw.vbmut.tryLock(); }
|
||||
void unlockVideoBuffer() { mw.vbmut.unlock(); }
|
||||
const PixelBuffer& videoBuffer() {
|
||||
return mw.blitterContainer->blitter()->inBuffer();
|
||||
|
||||
bool tryLockVideoBuffer(PixelBuffer &pb) {
|
||||
if (mw.vbmut.tryLock()) {
|
||||
pb = mw.blitterContainer->blitter()->inBuffer();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void unlockVideoBuffer() { mw.vbmut.unlock(); }
|
||||
|
||||
void consumeBlitRequest();
|
||||
};
|
||||
@ -364,13 +371,13 @@ void MediaWidget::setBlitter(BlitterWidget *const blitter) {
|
||||
|
||||
void MediaWidget::setVideo(const unsigned w, const unsigned h, BlitterWidget *const blitter) {
|
||||
if (QSize(w, h) != blitterContainer->sourceSize() || blitter != blitterContainer->blitter()) {
|
||||
vbmut.lock();
|
||||
setBlitter(blitter);
|
||||
{
|
||||
const QMutexLocker vblock(&vbmut);
|
||||
setBlitter(blitter);
|
||||
|
||||
if (running)
|
||||
blitterContainer->blitter()->setVideoFormat(w, h);
|
||||
|
||||
vbmut.unlock();
|
||||
if (running)
|
||||
blitterContainer->blitter()->setVideoFormat(w, h);
|
||||
}
|
||||
|
||||
blitterContainer->setSourceSize(QSize(w, h));
|
||||
}
|
||||
|
@ -120,9 +120,16 @@ public:
|
||||
void keyPressEvent(QKeyEvent*);
|
||||
void keyReleaseEvent(QKeyEvent*);
|
||||
|
||||
bool tryLockFrameBuf() { return vbmut.tryLock(); }
|
||||
bool tryLockFrameBuf(PixelBuffer &pb) {
|
||||
if (vbmut.tryLock()) {
|
||||
pb = running ? blitterContainer->blitter()->inBuffer() : PixelBuffer();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void unlockFrameBuf() { vbmut.unlock(); }
|
||||
const PixelBuffer frameBuf() const { return running ? blitterContainer->blitter()->inBuffer() : PixelBuffer(); }
|
||||
|
||||
const QSize& videoSize() const { return blitterContainer->sourceSize(); }
|
||||
|
||||
|
@ -311,11 +311,9 @@ long MediaWorker::sourceUpdate() {
|
||||
Callback *cb;
|
||||
PixelBuffer pb;
|
||||
public:
|
||||
VidBuf(Callback *cb) : cb(cb), pb(cb->videoBuffer()) {
|
||||
if (!cb->tryLockVideoBuffer()) {
|
||||
pb.data = 0;
|
||||
explicit VidBuf(Callback *cb) : cb(cb), pb() {
|
||||
if (!cb->tryLockVideoBuffer(pb))
|
||||
this->cb = 0;
|
||||
}
|
||||
}
|
||||
|
||||
~VidBuf() { if (cb) cb->unlockVideoBuffer(); }
|
||||
@ -335,23 +333,29 @@ void MediaWorker::adjustResamplerRate(const long outRate) {
|
||||
sndOutBuffer.reset(sz);
|
||||
}
|
||||
|
||||
static usec_t frameWait(const usec_t base, const usec_t syncft, const usec_t usecsFromUnderrun, SyncVar &waitingForSync) {
|
||||
const usec_t now = getusecs();
|
||||
namespace {
|
||||
struct NowDelta { usec_t now, inc;
|
||||
NowDelta(usec_t now, usec_t inc) : now(now), inc(inc) {} };
|
||||
}
|
||||
|
||||
if (base + syncft - now < syncft * 2) {
|
||||
if (base + syncft - now >= usecsFromUnderrun - (usecsFromUnderrun >> 2))
|
||||
return base;
|
||||
static const NowDelta frameWait(const NowDelta basetime,
|
||||
const usec_t syncft, const usec_t usecsFromUnderrun, SyncVar &waitingForSync) {
|
||||
const usec_t now = getusecs();
|
||||
const usec_t target = basetime.now + basetime.inc + syncft;
|
||||
|
||||
if (target - now < basetime.inc + syncft) {
|
||||
if (target - now >= usecsFromUnderrun - (usecsFromUnderrun >> 2))
|
||||
return basetime;
|
||||
|
||||
SyncVar::Locked wfs(waitingForSync);
|
||||
|
||||
/*while*/if (!wfs.get() && /*wfs.wait(now, base + syncft - now)*/ wfs.wait((base + syncft - now) / 1000)) {
|
||||
;
|
||||
}
|
||||
|
||||
return base + syncft;
|
||||
|
||||
if (!wfs.get())
|
||||
wfs.wait((target - now) / 1000);
|
||||
|
||||
return NowDelta(now, target - now);
|
||||
}
|
||||
|
||||
return now;
|
||||
|
||||
return NowDelta(now, 0);
|
||||
}
|
||||
|
||||
static void blitWait(MediaWorker::Callback *const cb, SyncVar &waitingForSync) {
|
||||
@ -410,7 +414,7 @@ void MediaWorker::run() {
|
||||
|
||||
SkipSched skipSched;
|
||||
bool audioBufLow = false;
|
||||
usec_t base = 0;
|
||||
NowDelta basetime(0, 0);
|
||||
|
||||
for (;;) {
|
||||
pauseVar.waitWhilePaused(callback.get(), *ao_);
|
||||
@ -428,7 +432,7 @@ void MediaWorker::run() {
|
||||
const bool blit = blitSamples >= 0 && !skipSched.skipNext(audioBufLow);
|
||||
|
||||
if (blit)
|
||||
callback->blit(base, syncft);
|
||||
callback->blit(basetime.now, basetime.inc + syncft);
|
||||
|
||||
const long outsamples = sampleBuffer.read(
|
||||
blit ? blitSamples : sampleBuffer.samplesBuffered(),
|
||||
@ -446,7 +450,8 @@ void MediaWorker::run() {
|
||||
audioBufLow = audioBufIsLow(bstate, outsamples);
|
||||
|
||||
if (blit) {
|
||||
base = frameWait(base, syncft, usecsFromUnderrun(bstate, outsamples, ao_->estimatedRate()), waitingForSync_);
|
||||
basetime = frameWait(basetime, syncft, usecsFromUnderrun(
|
||||
bstate, outsamples, ao_->estimatedRate()), waitingForSync_);
|
||||
blitWait(callback.get(), waitingForSync_);
|
||||
}
|
||||
}
|
||||
|
@ -40,9 +40,8 @@ public:
|
||||
virtual bool cancelBlit() = 0;
|
||||
// virtual void sync() = 0;
|
||||
virtual void audioEngineFailure() = 0;
|
||||
virtual bool tryLockVideoBuffer() = 0;
|
||||
virtual bool tryLockVideoBuffer(PixelBuffer &pb) = 0;
|
||||
virtual void unlockVideoBuffer() = 0;
|
||||
virtual const PixelBuffer& videoBuffer() = 0;
|
||||
virtual ~Callback() {}
|
||||
};
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user