1
0
mirror of https://github.com/qTox/qTox.git synced 2024-03-22 14:00:36 +08:00

CoreVideoSource: Replace insane spinlock by QMutex

What was I thinking.
This commit is contained in:
tux3 2015-10-24 04:38:00 +02:00
parent c0d8703368
commit e1c61cd207
No known key found for this signature in database
GPG Key ID: 7E086DD661263264
2 changed files with 15 additions and 36 deletions

View File

@ -26,7 +26,7 @@ extern "C" {
CoreVideoSource::CoreVideoSource()
: subscribers{0}, deleteOnClose{false},
biglock{false}, stopped{false}
stopped{false}
{
}
@ -35,12 +35,7 @@ void CoreVideoSource::pushFrame(const vpx_image_t* vpxframe)
if (stopped)
return;
// Fast lock
{
bool expected = false;
while (!biglock.compare_exchange_weak(expected, true))
expected = false;
}
QMutexLocker locker(&biglock);
std::shared_ptr<VideoFrame> vframe;
AVFrame* avframe;
@ -49,11 +44,11 @@ void CoreVideoSource::pushFrame(const vpx_image_t* vpxframe)
int dstStride, srcStride, minStride;
if (subscribers <= 0)
goto end;
return;
avframe = av_frame_alloc();
if (!avframe)
goto end;
return;
avframe->width = width;
avframe->height = height;
avframe->format = AV_PIX_FMT_YUV420P;
@ -62,7 +57,7 @@ void CoreVideoSource::pushFrame(const vpx_image_t* vpxframe)
if (!buf)
{
av_frame_free(&avframe);
goto end;
return;
}
avframe->opaque = buf;
@ -80,63 +75,46 @@ void CoreVideoSource::pushFrame(const vpx_image_t* vpxframe)
vframe = std::make_shared<VideoFrame>(avframe);
emit frameAvailable(vframe);
end:
biglock = false;
}
bool CoreVideoSource::subscribe()
{
// Fast lock
{
bool expected = false;
while (!biglock.compare_exchange_weak(expected, true))
expected = false;
}
QMutexLocker locker(&biglock);
++subscribers;
biglock = false;
return true;
}
void CoreVideoSource::unsubscribe()
{
// Fast lock
{
bool expected = false;
while (!biglock.compare_exchange_weak(expected, true))
expected = false;
}
biglock.lock();
if (--subscribers == 0)
{
if (deleteOnClose)
{
biglock = false;
biglock.unlock();
// DANGEROUS: No member access after this point, that's why we manually unlock
delete this;
return;
}
}
biglock = false;
biglock.unlock();
}
void CoreVideoSource::setDeleteOnClose(bool newstate)
{
// Fast lock
{
bool expected = false;
while (!biglock.compare_exchange_weak(expected, true))
expected = false;
}
QMutexLocker locker(&biglock);
deleteOnClose = newstate;
biglock = false;
}
void CoreVideoSource::stopSource()
{
QMutexLocker locker(&biglock);
stopped = true;
emit sourceStopped();
}
void CoreVideoSource::restartSource()
{
QMutexLocker locker(&biglock);
stopped = false;
}

View File

@ -24,6 +24,7 @@
#include <vpx/vpx_image.h>
#include <atomic>
#include "videosource.h"
#include <QMutex>
/// A VideoSource that emits frames received by Core
class CoreVideoSource : public VideoSource
@ -52,7 +53,7 @@ private:
private:
std::atomic_int subscribers; ///< Number of suscribers
std::atomic_bool deleteOnClose; ///< If true, self-delete after the last suscriber is gone
std::atomic_bool biglock; ///< Fast lock
QMutex biglock;
std::atomic_bool stopped;
friend class CoreAV;