Skip to content
Snippets Groups Projects
Commit 64496d22 authored by Emmanuel Lepage Vallee's avatar Emmanuel Lepage Vallee
Browse files

video: Cosmetic

Refs #70057
parent 7005452a
No related branches found
No related tags found
No related merge requests found
...@@ -85,7 +85,7 @@ void Video::DirectRenderer::onNewFrame(const QByteArray& frame) ...@@ -85,7 +85,7 @@ void Video::DirectRenderer::onNewFrame(const QByteArray& frame)
return; return;
} }
Video::Renderer::d_ptr->m_framePtr = const_cast<char*>(frame.data()); Video::Renderer::d_ptr->m_pFrame = const_cast<char*>(frame.data());
emit frameUpdated(); emit frameUpdated();
} }
......
...@@ -54,17 +54,17 @@ ...@@ -54,17 +54,17 @@
*/ */
struct SHMHeader { struct SHMHeader {
sem_t mutex; // Lock it before any operations on following fields. sem_t mutex ; /*!< Lock it before any operations on following fields. */
sem_t frameGenMutex; // unlocked by producer when frameGen modified sem_t frameGenMutex; /*!< unlocked by producer when frameGen modified */
unsigned frameGen; // monotonically incremented when a producer changes readOffset unsigned frameGen ; /*!< monotonically incremented when a producer changes readOffset */
unsigned frameSize; // size in bytes of 1 frame unsigned frameSize ; /*!< size in bytes of 1 frame */
unsigned mapSize; // size to map if you need to see all data unsigned mapSize ; /*!< size to map if you need to see all data */
unsigned readOffset; // offset of readable frame in data unsigned readOffset ; /*!< offset of readable frame in data */
unsigned writeOffset; // offset of writable frame in data unsigned writeOffset ; /*!< offset of writable frame in data */
#pragma GCC diagnostic push #pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-pedantic" #pragma GCC diagnostic ignored "-pedantic"
char data[]; // the whole shared memory char data[]; /*!< the whole shared memory */
#pragma GCC diagnostic pop #pragma GCC diagnostic pop
}; };
...@@ -72,59 +72,61 @@ namespace Video { ...@@ -72,59 +72,61 @@ namespace Video {
class ShmRendererPrivate : public QObject class ShmRendererPrivate : public QObject
{ {
Q_OBJECT Q_OBJECT
public: public:
ShmRendererPrivate(ShmRenderer* parent); ShmRendererPrivate(ShmRenderer* parent);
// Attributes //Types
QString m_ShmPath ; using TimePoint = std::chrono::time_point<std::chrono::system_clock>;
int m_fd ;
SHMHeader* m_pShmArea ; // Attributes
unsigned m_ShmAreaLen ; QString m_ShmPath ;
uint m_FrameGen ; int m_fd ;
QTimer* m_pTimer ; SHMHeader* m_pShmArea ;
int m_fpsC ; unsigned m_ShmAreaLen ;
int m_Fps ; uint m_FrameGen ;
std::chrono::time_point<std::chrono::system_clock> m_lastFrameDebug; QTimer* m_pTimer ;
int m_fpsC ;
// Constants int m_Fps ;
static const int FPS_RATE_SEC = 1; TimePoint m_lastFrameDebug;
static const int FRAME_CHECK_RATE_HZ = 120;
// Constants
// Helpers constexpr static const int FPS_RATE_SEC = 1 ;
timespec createTimeout(); constexpr static const int FRAME_CHECK_RATE_HZ = 120;
bool shmLock();
void shmUnlock(); // Helpers
bool getNewFrame(bool wait); timespec createTimeout( );
bool remapShm(); bool shmLock ( );
void shmUnlock ( );
private: bool getNewFrame ( bool wait );
Video::ShmRenderer* q_ptr; bool remapShm ( );
private:
Video::ShmRenderer* q_ptr;
}; };
ShmRendererPrivate::ShmRendererPrivate(ShmRenderer* parent) ShmRendererPrivate::ShmRendererPrivate(ShmRenderer* parent)
: QObject(parent) : QObject ( parent )
, q_ptr(parent) , q_ptr ( parent )
, m_fd(-1) , m_fd ( -1 )
, m_fpsC(0) , m_fpsC ( 0 )
, m_Fps(0) , m_Fps ( 0 )
, m_pShmArea((SHMHeader*)MAP_FAILED) , m_pShmArea ( (SHMHeader*)MAP_FAILED )
, m_ShmAreaLen(0) , m_ShmAreaLen( 0 )
, m_FrameGen(0) , m_FrameGen ( 0 )
, m_pTimer(nullptr) , m_pTimer ( nullptr )
#ifdef DEBUG_FPS #ifdef DEBUG_FPS
, m_frameCount(0) , m_frameCount( 0 )
, m_lastFrameDebug(std::chrono::system_clock::now()) , m_lastFrameDebug(std::chrono::system_clock::now() )
#endif #endif
{ {
} }
/// Constructor /// Constructor
ShmRenderer::ShmRenderer(const QByteArray& id, const QString& shmPath, ShmRenderer::ShmRenderer(const QByteArray& id, const QString& shmPath, const QSize& res)
const QSize& res) : Renderer(id, res)
: Renderer(id, res) , d_ptr(new ShmRendererPrivate(this))
, d_ptr(new ShmRendererPrivate(this))
{ {
d_ptr->m_ShmPath = shmPath; d_ptr->m_ShmPath = shmPath;
setObjectName("Video::Renderer:"+id); setObjectName("Video::Renderer:"+id);
...@@ -139,89 +141,91 @@ ShmRenderer::~ShmRenderer() ...@@ -139,89 +141,91 @@ ShmRenderer::~ShmRenderer()
/// Wait new frame data from shared memory and save pointer /// Wait new frame data from shared memory and save pointer
bool ShmRendererPrivate::getNewFrame(bool wait) bool ShmRendererPrivate::getNewFrame(bool wait)
{ {
if (!shmLock()) if (!shmLock())
return false; return false;
if (m_FrameGen == m_pShmArea->frameGen) { if (m_FrameGen == m_pShmArea->frameGen) {
shmUnlock(); shmUnlock();
if (not wait) if (not wait)
return false; return false;
// wait for a new frame, max 33ms // wait for a new frame, max 33ms
static const struct timespec timeout = {0, 33000000}; static const struct timespec timeout = {0, 33000000};
if (::sem_timedwait(&m_pShmArea->frameGenMutex, &timeout) < 0) if (::sem_timedwait(&m_pShmArea->frameGenMutex, &timeout) < 0)
return false; return false;
if (!shmLock()) if (!shmLock())
return false; return false;
}
}
// valid frame to render (daemon may have stopped)?
if (! m_pShmArea->frameSize) { // valid frame to render (daemon may have stopped)?
shmUnlock(); if (! m_pShmArea->frameSize) {
return false; shmUnlock();
} return false;
}
// map frame data
if (!remapShm()) { // map frame data
qDebug() << "Could not resize shared memory"; if (!remapShm()) {
return false; qDebug() << "Could not resize shared memory";
} return false;
}
q_ptr->Video::Renderer::d_ptr->m_framePtr = (char*)(m_pShmArea->data + m_pShmArea->readOffset);
m_FrameGen = m_pShmArea->frameGen; q_ptr->Video::Renderer::d_ptr->m_pFrame = (char*)(m_pShmArea->data + m_pShmArea->readOffset);
q_ptr->Video::Renderer::d_ptr->m_FrameSize = m_pShmArea->frameSize; m_FrameGen = m_pShmArea->frameGen;
q_ptr->Video::Renderer::d_ptr->m_FrameSize = m_pShmArea->frameSize;
shmUnlock();
shmUnlock();
++m_fpsC;
++m_fpsC;
// Compute the FPS shown to the client
auto currentTime = std::chrono::system_clock::now(); // Compute the FPS shown to the client
const std::chrono::duration<double> seconds = currentTime - m_lastFrameDebug; auto currentTime = std::chrono::system_clock::now();
if (seconds.count() >= FPS_RATE_SEC) { const std::chrono::duration<double> seconds = currentTime - m_lastFrameDebug;
m_Fps = m_fpsC / seconds.count(); if (seconds.count() >= FPS_RATE_SEC) {
m_fpsC = 0; m_Fps = m_fpsC / seconds.count();
m_lastFrameDebug = currentTime; m_fpsC = 0;
m_lastFrameDebug = currentTime;
#ifdef DEBUG_FPS #ifdef DEBUG_FPS
qDebug() << this << ": FPS " << m_fps; qDebug() << this << ": FPS " << m_fps;
#endif #endif
} }
emit q_ptr->frameUpdated(); emit q_ptr->frameUpdated();
return true; return true;
} }
/// Remap the shared memory /// Remap the shared memory
/// Shared memory in unlocked state if returns false (resize failed). /// Shared memory in unlocked state if returns false (resize failed).
bool ShmRendererPrivate::remapShm() bool ShmRendererPrivate::remapShm()
{ {
// This loop handles case where deamon resize shared memory // This loop handles case where deamon resize shared memory
// during time we unlock it for remapping. // during time we unlock it for remapping.
while (m_ShmAreaLen != m_pShmArea->mapSize) { while (m_ShmAreaLen != m_pShmArea->mapSize) {
auto mapSize = m_pShmArea->mapSize; auto mapSize = m_pShmArea->mapSize;
shmUnlock(); shmUnlock();
if (::munmap(m_pShmArea, m_ShmAreaLen)) { if (::munmap(m_pShmArea, m_ShmAreaLen)) {
qDebug() << "Could not unmap shared area: " << strerror(errno); qDebug() << "Could not unmap shared area: " << strerror(errno);
return false; return false;
} }
m_pShmArea = (SHMHeader*) ::mmap(nullptr, mapSize, PROT_READ | PROT_WRITE, m_pShmArea = (SHMHeader*) ::mmap(nullptr, mapSize, PROT_READ | PROT_WRITE,
MAP_SHARED, m_fd, 0); MAP_SHARED, m_fd, 0);
if (m_pShmArea == MAP_FAILED) {
qDebug() << "Could not remap shared area: " << strerror(errno); if (m_pShmArea == MAP_FAILED) {
return false; qDebug() << "Could not remap shared area: " << strerror(errno);
} return false;
}
if (!shmLock())
return false; if (!shmLock())
return false;
m_ShmAreaLen = mapSize;
} m_ShmAreaLen = mapSize;
}
return true;
return true;
} }
/// Connect to the shared memory /// Connect to the shared memory
...@@ -233,20 +237,23 @@ bool ShmRenderer::startShm() ...@@ -233,20 +237,23 @@ bool ShmRenderer::startShm()
} }
d_ptr->m_fd = ::shm_open(d_ptr->m_ShmPath.toLatin1(), O_RDWR, 0); d_ptr->m_fd = ::shm_open(d_ptr->m_ShmPath.toLatin1(), O_RDWR, 0);
if (d_ptr->m_fd < 0) { if (d_ptr->m_fd < 0) {
qDebug() << "could not open shm area " << d_ptr->m_ShmPath qDebug() << "could not open shm area" << d_ptr->m_ShmPath
<< ", shm_open failed:" << strerror(errno); << ", shm_open failed:" << strerror(errno);
return false; return false;
} }
// Map only header data // Map only header data
const auto mapSize = sizeof(SHMHeader); const auto mapSize = sizeof(SHMHeader);
d_ptr->m_pShmArea = (SHMHeader*) ::mmap(nullptr, mapSize, d_ptr->m_pShmArea = (SHMHeader*) ::mmap(nullptr, mapSize,
PROT_READ | PROT_WRITE, PROT_READ | PROT_WRITE,
MAP_SHARED, d_ptr->m_fd, 0); MAP_SHARED, d_ptr->m_fd, 0
);
if (d_ptr->m_pShmArea == MAP_FAILED) { if (d_ptr->m_pShmArea == MAP_FAILED) {
qDebug() << "Could not remap shared area"; qDebug() << "Could not remap shared area";
return false; return false;
} }
d_ptr->m_ShmAreaLen = mapSize; d_ptr->m_ShmAreaLen = mapSize;
...@@ -257,13 +264,13 @@ bool ShmRenderer::startShm() ...@@ -257,13 +264,13 @@ bool ShmRenderer::startShm()
void ShmRenderer::stopShm() void ShmRenderer::stopShm()
{ {
if (d_ptr->m_fd < 0) if (d_ptr->m_fd < 0)
return; return;
::close(d_ptr->m_fd); ::close(d_ptr->m_fd);
d_ptr->m_fd = -1; d_ptr->m_fd = -1;
if (d_ptr->m_pShmArea == MAP_FAILED) if (d_ptr->m_pShmArea == MAP_FAILED)
return; return;
::munmap(d_ptr->m_pShmArea, d_ptr->m_ShmAreaLen); ::munmap(d_ptr->m_pShmArea, d_ptr->m_ShmAreaLen);
d_ptr->m_ShmAreaLen = 0; d_ptr->m_ShmAreaLen = 0;
...@@ -273,13 +280,13 @@ void ShmRenderer::stopShm() ...@@ -273,13 +280,13 @@ void ShmRenderer::stopShm()
/// Lock the memory while the copy is being made /// Lock the memory while the copy is being made
bool ShmRendererPrivate::shmLock() bool ShmRendererPrivate::shmLock()
{ {
return ::sem_wait(&m_pShmArea->mutex) >= 0; return ::sem_wait(&m_pShmArea->mutex) >= 0;
} }
/// Remove the lock, allow a new frame to be drawn /// Remove the lock, allow a new frame to be drawn
void ShmRendererPrivate::shmUnlock() void ShmRendererPrivate::shmUnlock()
{ {
::sem_post(&m_pShmArea->mutex); ::sem_post(&m_pShmArea->mutex);
} }
/***************************************************************************** /*****************************************************************************
...@@ -291,23 +298,23 @@ void ShmRendererPrivate::shmUnlock() ...@@ -291,23 +298,23 @@ void ShmRendererPrivate::shmUnlock()
/// Start the rendering loop /// Start the rendering loop
void ShmRenderer::startRendering() void ShmRenderer::startRendering()
{ {
QMutexLocker locker {mutex()}; QMutexLocker locker {mutex()};
if (!startShm()) if (!startShm())
return; return;
Video::Renderer::d_ptr->m_isRendering = true; Video::Renderer::d_ptr->m_isRendering = true;
emit started(); emit started();
} }
/// Stop the rendering loop /// Stop the rendering loop
void ShmRenderer::stopRendering() void ShmRenderer::stopRendering()
{ {
QMutexLocker locker {mutex()}; QMutexLocker locker {mutex()};
Video::Renderer::d_ptr->m_isRendering = false; Video::Renderer::d_ptr->m_isRendering = false;
emit stopped(); emit stopped();
stopShm(); stopShm();
} }
/***************************************************************************** /*****************************************************************************
...@@ -319,18 +326,18 @@ void ShmRenderer::stopRendering() ...@@ -319,18 +326,18 @@ void ShmRenderer::stopRendering()
/// Get the current frame rate of this renderer /// Get the current frame rate of this renderer
int ShmRenderer::fps() const int ShmRenderer::fps() const
{ {
return d_ptr->m_Fps; return d_ptr->m_Fps;
} }
/// Get frame data pointer from shared memory /// Get frame data pointer from shared memory
const QByteArray& ShmRenderer::currentFrame() const const QByteArray& ShmRenderer::currentFrame() const
{ {
if (!isRendering()) if (!isRendering())
return {}; return Renderer::currentFrame();
QMutexLocker lk {mutex()}; QMutexLocker lk {mutex()};
d_ptr->getNewFrame(false); d_ptr->getNewFrame(false);
return Renderer::currentFrame(); return Renderer::currentFrame();
} }
/***************************************************************************** /*****************************************************************************
...@@ -341,7 +348,7 @@ const QByteArray& ShmRenderer::currentFrame() const ...@@ -341,7 +348,7 @@ const QByteArray& ShmRenderer::currentFrame() const
void ShmRenderer::setShmPath(const QString& path) void ShmRenderer::setShmPath(const QString& path)
{ {
d_ptr->m_ShmPath = path; d_ptr->m_ShmPath = path;
} }
} // namespace Video } // namespace Video
......
...@@ -44,29 +44,29 @@ class LIB_EXPORT ShmRenderer : public Renderer { ...@@ -44,29 +44,29 @@ class LIB_EXPORT ShmRenderer : public Renderer {
friend class VideoRendererManagerPrivate ; friend class VideoRendererManagerPrivate ;
public: public:
//Constructor //Constructor
ShmRenderer (const QByteArray& id, const QString& shmPath, const QSize& res); ShmRenderer (const QByteArray& id, const QString& shmPath, const QSize& res);
virtual ~ShmRenderer(); virtual ~ShmRenderer();
//Mutators //Mutators
void stopShm (); void stopShm ();
bool startShm (); bool startShm ();
//Getters //Getters
virtual int fps() const; virtual int fps() const;
virtual const QByteArray& currentFrame() const override; virtual const QByteArray& currentFrame() const override;
//Setters //Setters
void setShmPath(const QString& path); void setShmPath(const QString& path);
private: private:
QScopedPointer<ShmRendererPrivate> d_ptr; QScopedPointer<ShmRendererPrivate> d_ptr;
Q_DECLARE_PRIVATE(ShmRenderer) Q_DECLARE_PRIVATE(ShmRenderer)
public Q_SLOTS: public Q_SLOTS:
void startRendering(); void startRendering();
void stopRendering (); void stopRendering ();
}; };
} }
......
...@@ -41,7 +41,7 @@ public: ...@@ -41,7 +41,7 @@ public:
QMutex* m_pMutex ; QMutex* m_pMutex ;
QString m_Id ; QString m_Id ;
QSize m_pSize ; QSize m_pSize ;
char* m_framePtr ; char* m_pFrame ;
QByteArray m_Content ; QByteArray m_Content ;
unsigned int m_FrameSize ; unsigned int m_FrameSize ;
......
...@@ -24,8 +24,8 @@ ...@@ -24,8 +24,8 @@
#include <QtCore/QMutex> #include <QtCore/QMutex>
Video::RendererPrivate::RendererPrivate(Video::Renderer* parent) Video::RendererPrivate::RendererPrivate(Video::Renderer* parent)
: QObject(parent), q_ptr(parent) : QObject(parent), q_ptr(parent)
, m_pMutex(new QMutex()),m_framePtr(nullptr),m_FrameSize(0) , m_pMutex(new QMutex()),m_pFrame(nullptr),m_FrameSize(0),m_isRendering(false)
{ {
} }
...@@ -33,8 +33,8 @@ Video::Renderer::Renderer(const QByteArray& id, const QSize& res) : d_ptr(new Re ...@@ -33,8 +33,8 @@ Video::Renderer::Renderer(const QByteArray& id, const QSize& res) : d_ptr(new Re
{ {
setObjectName("Renderer:"+id); setObjectName("Renderer:"+id);
d_ptr->m_FrameSize = res.width() * res.height() * 4; d_ptr->m_FrameSize = res.width() * res.height() * 4;
d_ptr->m_pSize = res; d_ptr->m_pSize = res;
d_ptr->m_Id = id; d_ptr->m_Id = id;
} }
Video::Renderer::~Renderer() Video::Renderer::~Renderer()
...@@ -68,8 +68,8 @@ QSize Video::Renderer::size() const ...@@ -68,8 +68,8 @@ QSize Video::Renderer::size() const
const QByteArray& Video::Renderer::currentFrame() const const QByteArray& Video::Renderer::currentFrame() const
{ {
if (d_ptr->m_framePtr && d_ptr->m_FrameSize) if (d_ptr->m_pFrame && d_ptr->m_FrameSize)
d_ptr->m_Content.setRawData(d_ptr->m_framePtr,d_ptr->m_FrameSize); d_ptr->m_Content.setRawData(d_ptr->m_pFrame,d_ptr->m_FrameSize);
return d_ptr->m_Content; return d_ptr->m_Content;
} }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment