// Copyright (c) 2012-2017 VideoStitch SAS // Copyright (c) 2018 stitchEm #pragma once #include "common-config.hpp" #include #include #include /** * High precision date or time interval * * Store a high precision date or time interval. The maximum precision is the * microsecond, and a 64 bits integer is used to avoid overflows (maximum * time interval is then 292271 years, which should be long enough for any * video). Dates are stored as microseconds since a common date (eg. the epoch for * the system clock). Note that date and time intervals can be manipulated using * regular arithmetic operators, and that no special functions are required. */ typedef int64_t mtime_t; /** * @brief The Frame class * * It is a Qt-friendly frame buffer, that can be passed through * a shared pointer between video players callbacks (output writers) * and widgets. * * Aside from that, just a lockable wrapper around a pixel buffer. */ class VS_COMMON_EXPORT Frame { public: Frame(char* buffer, unsigned w, unsigned h) : buf(buffer), date(0), width(w), height(h) {} Frame(unsigned w, unsigned h) : buf(nullptr), date(0), width(w), height(h) {} virtual ~Frame() {} char* buffer() { return buf; } void setDate(mtime_t d) { date = d; } mtime_t getDate() const { return date; } unsigned getWidth() const { return width; } unsigned getHeight() const { return height; } virtual void readLock() = 0; virtual void writeLock() = 0; virtual void unlock() = 0; protected: char* buf; mtime_t date; unsigned width; unsigned height; Frame(const Frame& o) { buf = o.buf; width = o.width; height = o.height; date = o.date; } Frame& operator=(const Frame&); }; class VS_COMMON_EXPORT PanoFrame : public Frame { public: PanoFrame(unsigned w, unsigned h) : Frame(new char[w * h * 4], w, h) {} virtual ~PanoFrame() { delete[] buf; } virtual void readLock() { mutex.lock(); } virtual void writeLock() { mutex.lock(); } virtual void unlock() { mutex.unlock(); } private: QMutex mutex; PanoFrame(const PanoFrame&); PanoFrame& operator=(const PanoFrame&); }; class VS_COMMON_EXPORT EyeFrame : public Frame { public: EyeFrame(char* buf, QReadWriteLock& lk, unsigned w, unsigned h) : Frame(buf, w, h), rwLk(lk) {} EyeFrame(const EyeFrame& o) : Frame(o), rwLk(o.rwLk) {} virtual void readLock() { rwLk.lockForRead(); } virtual void writeLock() { rwLk.lockForWrite(); } virtual void unlock() { rwLk.unlock(); } private: QReadWriteLock& rwLk; EyeFrame& operator=(const EyeFrame&); }; class VS_COMMON_EXPORT StereoFrame : public Frame { public: StereoFrame(unsigned w, unsigned h) : Frame(new char[w * h * 4], w, h), leftFrame(buf, rwLk, width, height / 2), rightFrame(buf + width * height * 2, rwLk, width, height / 2) {} ~StereoFrame() { delete[] buf; } EyeFrame& getLeftFrame() { return leftFrame; } EyeFrame& getRightFrame() { return rightFrame; } virtual void readLock() { rwLk.lockForRead(); } virtual void writeLock() { rwLk.lockForWrite(); } virtual void unlock() { rwLk.unlock(); } private: EyeFrame leftFrame; EyeFrame rightFrame; QReadWriteLock rwLk; StereoFrame(const StereoFrame&); StereoFrame& operator=(const StereoFrame&); };