qTox  Version: nightly | Commit: bc751c8e1cac455f9690654fcfe0f560d2d7dfdd
videoframe.h
Go to the documentation of this file.
1 /*
2  Copyright © 2014-2019 by The qTox Project Contributors
3 
4  This file is part of qTox, a Qt-based graphical interface for Tox.
5 
6  qTox is libre software: you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation, either version 3 of the License, or
9  (at your option) any later version.
10 
11  qTox is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  GNU General Public License for more details.
15 
16  You should have received a copy of the GNU General Public License
17  along with qTox. If not, see <http://www.gnu.org/licenses/>.
18 */
19 
20 #pragma once
21 
22 #include <QImage>
23 #include <QMutex>
24 #include <QReadWriteLock>
25 #include <QRect>
26 #include <QSize>
27 
28 extern "C" {
29 #pragma GCC diagnostic push
30 #pragma GCC diagnostic ignored "-Wold-style-cast"
31 #include <libavcodec/avcodec.h>
32 #pragma GCC diagnostic pop
33 }
34 
35 #include <atomic>
36 #include <cstdint>
37 #include <functional>
38 #include <memory>
39 #include <unordered_map>
40 
42 {
43 public:
44  bool isValid() const;
45  explicit operator bool() const;
46 
47  const std::uint16_t width;
48  const std::uint16_t height;
49 
50  const uint8_t* y;
51  const uint8_t* u;
52  const uint8_t* v;
53 };
54 
56 {
57 public:
58  // Declare type aliases
59  using IDType = std::uint_fast64_t;
60  using AtomicIDType = std::atomic_uint_fast64_t;
61 
62 public:
63  VideoFrame(IDType sourceID, AVFrame* sourceFrame, QRect dimensions, int pixFmt,
64  bool freeSourceFrame = false);
65  VideoFrame(IDType sourceID, AVFrame* sourceFrame, bool freeSourceFrame = false);
66 
67  ~VideoFrame();
68 
69  // Copy/Move operations are disabled for the VideoFrame, encapsulate with a std::shared_ptr to
70  // manage.
71 
72  VideoFrame(const VideoFrame& other) = delete;
73  VideoFrame(VideoFrame&& other) = delete;
74 
75  const VideoFrame& operator=(const VideoFrame& other) = delete;
76  const VideoFrame& operator=(VideoFrame&& other) = delete;
77 
78  bool isValid();
79 
80  std::shared_ptr<VideoFrame> trackFrame();
81  static void untrackFrames(const IDType& sourceID, bool releaseFrames = false);
82 
83  void releaseFrame();
84 
85  const AVFrame* getAVFrame(QSize frameSize, const int pixelFormat, const bool requireAligned);
86  QImage toQImage(QSize frameSize = {});
87  ToxYUVFrame toToxYUVFrame(QSize frameSize = {});
88 
89  IDType getFrameID() const;
90  IDType getSourceID() const;
91  QRect getSourceDimensions() const;
92  int getSourcePixelFormat() const;
93 
94  static constexpr int dataAlignment = 32;
95 
96 private:
98  {
99  public:
100  FrameBufferKey(const int width, const int height, const int pixFmt, const bool lineAligned);
101 
102  // Explictly state default constructor/destructor
103 
104  FrameBufferKey(const FrameBufferKey&) = default;
105  FrameBufferKey(FrameBufferKey&&) = default;
106  ~FrameBufferKey() = default;
107 
108  // Assignment operators are disabled for the FrameBufferKey
109 
110  const FrameBufferKey& operator=(const FrameBufferKey&) = delete;
111  const FrameBufferKey& operator=(FrameBufferKey&&) = delete;
112 
113  bool operator==(const FrameBufferKey& other) const;
114  bool operator!=(const FrameBufferKey& other) const;
115 
116  static size_t hash(const FrameBufferKey& key);
117 
118  public:
119  const int frameWidth;
120  const int frameHeight;
121  const int pixelFormat;
122  const bool linesizeAligned;
123  };
124 
125 private:
126  static FrameBufferKey getFrameKey(const QSize& frameSize, const int pixFmt, const int linesize);
127  static FrameBufferKey getFrameKey(const QSize& frameSize, const int pixFmt,
128  const bool frameAligned);
129 
130  AVFrame* retrieveAVFrame(const QSize& dimensions, const int pixelFormat, const bool requireAligned);
131  AVFrame* generateAVFrame(const QSize& dimensions, const int pixelFormat, const bool requireAligned);
132  AVFrame* storeAVFrame(AVFrame* frame, const QSize& dimensions, const int pixelFormat);
133 
134  void deleteFrameBuffer();
135 
136  template <typename T>
137  T toGenericObject(const QSize& dimensions, const int pixelFormat, const bool requireAligned,
138  const std::function<T(AVFrame* const)>& objectConstructor, const T& nullObject);
139 
140 private:
141  // ID
144 
145  // Main framebuffer store
146  std::unordered_map<FrameBufferKey, AVFrame*, std::function<decltype(FrameBufferKey::hash)>>
148 
149  // Source frame
150  const QRect sourceDimensions;
153  const bool freeSourceFrame;
154 
155  // Reference store
157 
158  static std::unordered_map<IDType, QMutex> mutexMap;
159  static std::unordered_map<IDType, std::unordered_map<IDType, std::weak_ptr<VideoFrame>>> refsMap;
160 
161  // Concurrency
162  QReadWriteLock frameLock{};
163  static QReadWriteLock refsLock;
164 };
VideoFrame::mutexMap
static std::unordered_map< IDType, QMutex > mutexMap
Definition: videoframe.h:158
VideoFrame::refsLock
static QReadWriteLock refsLock
Definition: videoframe.h:163
VideoFrame::refsMap
static std::unordered_map< IDType, std::unordered_map< IDType, std::weak_ptr< VideoFrame > > > refsMap
Definition: videoframe.h:159
VideoFrame::FrameBufferKey::frameHeight
const int frameHeight
Definition: videoframe.h:120
VideoFrame::~VideoFrame
~VideoFrame()
Destructor for VideoFrame.
Definition: videoframe.cpp:152
VideoFrame::FrameBufferKey
Definition: videoframe.h:97
VideoFrame::retrieveAVFrame
AVFrame * retrieveAVFrame(const QSize &dimensions, const int pixelFormat, const bool requireAligned)
Retrieves an AVFrame derived from the source based on the given parameters without obtaining a lock.
Definition: videoframe.cpp:523
VideoFrame::toToxYUVFrame
ToxYUVFrame toToxYUVFrame(QSize frameSize={})
Converts this VideoFrame to a ToxAVFrame that shares this VideoFrame's buffer.
Definition: videoframe.cpp:352
VideoFrame::IDType
std::uint_fast64_t IDType
Definition: videoframe.h:59
ToxYUVFrame::isValid
bool isValid() const
Returns whether the given ToxYUVFrame represents a valid frame or not.
Definition: videoframe.cpp:779
VideoFrame::sourceFrameKey
const FrameBufferKey sourceFrameKey
Definition: videoframe.h:152
VideoFrame::freeSourceFrame
const bool freeSourceFrame
Definition: videoframe.h:153
VideoFrame::getSourcePixelFormat
int getSourcePixelFormat() const
Retrieves a copy of the source VideoFormat's pixel format.
Definition: videoframe.cpp:408
VideoFrame::getSourceDimensions
QRect getSourceDimensions() const
Retrieves a copy of the source VideoFrame's dimensions.
Definition: videoframe.cpp:398
VideoFrame::FrameBufferKey::operator=
const FrameBufferKey & operator=(const FrameBufferKey &)=delete
VideoFrame::FrameBufferKey::operator==
bool operator==(const FrameBufferKey &other) const
Comparison operator for FrameBufferKey.
Definition: videoframe.cpp:437
VideoFrame::getFrameID
IDType getFrameID() const
Returns the ID for the given frame.
Definition: videoframe.cpp:378
VideoFrame::frameIDs
static AtomicIDType frameIDs
Definition: videoframe.h:156
VideoFrame::sourceID
const IDType sourceID
Definition: videoframe.h:143
VideoFrame::VideoFrame
VideoFrame(IDType sourceID, AVFrame *sourceFrame, QRect dimensions, int pixFmt, bool freeSourceFrame=false)
Constructs a new instance of a VideoFrame, sourced by a given AVFrame pointer.
Definition: videoframe.cpp:93
ToxYUVFrame::u
const uint8_t * u
Definition: videoframe.h:51
VideoFrame::trackFrame
std::shared_ptr< VideoFrame > trackFrame()
Causes the VideoFrame class to maintain an internal reference for the frame.
Definition: videoframe.cpp:200
VideoFrame::getFrameKey
static FrameBufferKey getFrameKey(const QSize &frameSize, const int pixFmt, const int linesize)
Generates a key object based on given parameters.
Definition: videoframe.cpp:488
VideoFrame::deleteFrameBuffer
void deleteFrameBuffer()
Releases all frames within the frame buffer.
Definition: videoframe.cpp:670
VideoFrame::generateAVFrame
AVFrame * generateAVFrame(const QSize &dimensions, const int pixelFormat, const bool requireAligned)
Generates an AVFrame based on the given specifications.
Definition: videoframe.cpp:557
ToxYUVFrame::height
const std::uint16_t height
Definition: videoframe.h:48
VideoFrame::frameBuffer
std::unordered_map< FrameBufferKey, AVFrame *, std::function< decltype(FrameBufferKey::hash)> > frameBuffer
Definition: videoframe.h:147
VideoFrame::FrameBufferKey::~FrameBufferKey
~FrameBufferKey()=default
VideoFrame::isValid
bool isValid()
Returns the validity of this VideoFrame.
Definition: videoframe.cpp:183
ToxYUVFrame::v
const uint8_t * v
Definition: videoframe.h:52
ToxYUVFrame::width
const std::uint16_t width
Definition: videoframe.h:47
VideoFrame::releaseFrame
void releaseFrame()
Releases all frames managed by this VideoFrame and invalidates it.
Definition: videoframe.cpp:274
VideoFrame::operator=
const VideoFrame & operator=(const VideoFrame &other)=delete
VideoFrame::FrameBufferKey::hash
static size_t hash(const FrameBufferKey &key)
Hash function for FrameBufferKey.
Definition: videoframe.cpp:462
VideoFrame
An ownernship and management class for AVFrames.
Definition: videoframe.h:55
VideoFrame::FrameBufferKey::linesizeAligned
const bool linesizeAligned
Definition: videoframe.h:122
VideoFrame::sourceDimensions
const QRect sourceDimensions
Definition: videoframe.h:150
VideoFrame::FrameBufferKey::FrameBufferKey
FrameBufferKey(const int width, const int height, const int pixFmt, const bool lineAligned)
Constructs a new FrameBufferKey with the given attributes.
Definition: videoframe.cpp:422
VideoFrame::sourcePixelFormat
int sourcePixelFormat
Definition: videoframe.h:151
VideoFrame::getAVFrame
const AVFrame * getAVFrame(QSize frameSize, const int pixelFormat, const bool requireAligned)
Retrieves an AVFrame derived from the source based on the given parameters.
Definition: videoframe.cpp:296
VideoFrame::toQImage
QImage toQImage(QSize frameSize={})
Converts this VideoFrame to a QImage that shares this VideoFrame's buffer.
Definition: videoframe.cpp:325
VideoFrame::toGenericObject
T toGenericObject(const QSize &dimensions, const int pixelFormat, const bool requireAligned, const std::function< T(AVFrame *const)> &objectConstructor, const T &nullObject)
Converts this VideoFrame to a generic type T based on the given parameters and supplied converter fun...
Definition: videoframe.cpp:722
ToxYUVFrame::y
const uint8_t * y
Definition: videoframe.h:50
VideoFrame::dataAlignment
static constexpr int dataAlignment
Data alignment parameter used to populate AVFrame buffers.
Definition: videoframe.h:94
ToxYUVFrame
A simple structure to represent a ToxYUV video frame (corresponds to a frame encoded under format: AV...
Definition: videoframe.h:41
VideoFrame::FrameBufferKey::pixelFormat
const int pixelFormat
Definition: videoframe.h:121
VideoFrame::AtomicIDType
std::atomic_uint_fast64_t AtomicIDType
Definition: videoframe.h:60
VideoFrame::getSourceID
IDType getSourceID() const
Returns the ID for the VideoSource which created this frame.
Definition: videoframe.cpp:388
VideoFrame::untrackFrames
static void untrackFrames(const IDType &sourceID, bool releaseFrames=false)
Untracks all the frames for the given VideoSource, releasing them if specified.
Definition: videoframe.cpp:236
VideoFrame::frameID
const IDType frameID
Definition: videoframe.h:142
VideoFrame::frameLock
QReadWriteLock frameLock
Definition: videoframe.h:162
VideoFrame::FrameBufferKey::frameWidth
const int frameWidth
Definition: videoframe.h:119
VideoFrame::storeAVFrame
AVFrame * storeAVFrame(AVFrame *frame, const QSize &dimensions, const int pixelFormat)
Stores a given AVFrame within the frameBuffer map.
Definition: videoframe.cpp:642
VideoFrame::FrameBufferKey::operator!=
bool operator!=(const FrameBufferKey &other) const
Not equal to operator for FrameBufferKey.
Definition: videoframe.cpp:449