blob: 15bbb0bbf10bdf09696689a4c57ffa6350170785 [file] [log] [blame]
Eddie James21b177e2018-12-11 13:14:46 -06001#pragma once
2
3#include "ikvm_input.hpp"
4
Eddie James90d49582018-12-11 13:22:00 -06005#include <mutex>
Eddie James21b177e2018-12-11 13:14:46 -06006#include <string>
Eddie James90d49582018-12-11 13:22:00 -06007#include <vector>
Eddie James21b177e2018-12-11 13:14:46 -06008
9namespace ikvm
10{
11
12/*
13 * @class Video
14 * @brief Sets up the V4L2 video device and performs read operations
15 */
16class Video
17{
18 public:
19 /*
20 * @brief Constructs Video object
21 *
22 * @param[in] p - Path to the V4L2 video device
23 * @param[in] input - Reference to the Input object
24 * @param[in] fr - desired frame rate of the video
25 */
Jammy Huanga4f63b32022-02-14 14:43:21 +080026 Video(const std::string& p, Input& input, int fr = 30, int sub = 0);
Eddie James21b177e2018-12-11 13:14:46 -060027 ~Video();
28 Video(const Video&) = default;
29 Video& operator=(const Video&) = default;
30 Video(Video&&) = default;
31 Video& operator=(Video&&) = default;
32
33 /*
Eddie James90d49582018-12-11 13:22:00 -060034 * @brief Gets the video frame data
35 *
36 * @return Pointer to the video frame data
37 */
38 char* getData();
39 /* @brief Performs read to grab latest video frame */
40 void getFrame();
41 /*
42 * @brief Gets whether or not the video frame needs to be resized
43 *
44 * @return Boolean indicating if the frame needs to be resized
45 */
46 bool needsResize();
47 /* @brief Performs the resize and re-allocates framebuffer */
48 void resize();
49 /* @brief Starts streaming from the video device */
50 void start();
51 /* @brief Stops streaming from the video device */
52 void stop();
Jae Hyun Yoof6ed0e72019-03-15 15:21:51 -070053 /* @brief Restarts streaming from the video device */
54 void restart()
55 {
56 stop();
57 start();
58 }
Eddie James90d49582018-12-11 13:22:00 -060059
60 /*
61 * @brief Gets the desired video frame rate in frames per second
62 *
63 * @return Value of the desired frame rate
64 */
65 inline int getFrameRate() const
66 {
67 return frameRate;
68 }
69 /*
70 * @brief Gets the size of the video frame data
71 *
72 * @return Value of the size of the video frame data in bytes
73 */
74 inline size_t getFrameSize() const
75 {
76 return buffers[lastFrameIndex].payload;
77 }
78 /*
Eddie James21b177e2018-12-11 13:14:46 -060079 * @brief Gets the height of the video frame
80 *
81 * @return Value of the height of video frame in pixels
82 */
83 inline size_t getHeight() const
84 {
85 return height;
86 }
87 /*
Charles Kearney8e909b72023-03-29 21:11:23 +000088 * @brief Gets the pixel format of the video frame
89 *
90 * @return Value of the pixel format of video frame */
91 inline uint32_t getPixelformat() const
92 {
93 return pixelformat;
94 }
95 /*
Eddie James21b177e2018-12-11 13:14:46 -060096 * @brief Gets the width of the video frame
97 *
98 * @return Value of the width of video frame in pixels
99 */
100 inline size_t getWidth() const
101 {
102 return width;
103 }
Jammy Huanga4f63b32022-02-14 14:43:21 +0800104 /*
105 * @brief Gets the subsampling of the video frame
106 *
107 * @return Value of the subsampling of video frame, 1:420/0:444
108 */
109 inline int getSubsampling() const
110 {
111 return subSampling;
112 }
113 /*
114 * @brief Sets the subsampling of the video frame
115 *
116 * @return Value of the subsampling of video frame, 1:420/0:444
117 */
118 inline void setSubsampling(int _sub)
119 {
120 subSampling = _sub;
121 }
Eddie James21b177e2018-12-11 13:14:46 -0600122
Eddie James90d49582018-12-11 13:22:00 -0600123 /* @brief Number of bits per component of a pixel */
124 static const int bitsPerSample;
125 /* @brief Number of bytes of storage for a pixel */
126 static const int bytesPerPixel;
127 /* @brief Number of components in a pixel (i.e. 3 for RGB pixel) */
128 static const int samplesPerPixel;
129
Eddie James21b177e2018-12-11 13:14:46 -0600130 private:
Eddie James90d49582018-12-11 13:22:00 -0600131 /*
132 * @struct Buffer
133 * @brief Store the address and size of frame data from streaming
134 * operations
135 */
136 struct Buffer
137 {
Patrick Williams3c110332023-05-10 07:51:28 -0500138 Buffer() : data(nullptr), queued(false), payload(0), size(0) {}
Eddie James90d49582018-12-11 13:22:00 -0600139 ~Buffer() = default;
140 Buffer(const Buffer&) = default;
141 Buffer& operator=(const Buffer&) = default;
142 Buffer(Buffer&&) = default;
143 Buffer& operator=(Buffer&&) = default;
144
145 void* data;
146 bool queued;
147 size_t payload;
148 size_t size;
149 };
150
151 /*
152 * @brief Boolean to indicate whether the resize was triggered during
153 * the open operation
154 */
155 bool resizeAfterOpen;
Eddie James23135dd2019-08-09 15:41:37 -0500156 /* @brief Indicates whether or not timings query was last sucessful */
157 bool timingsError;
Eddie James90d49582018-12-11 13:22:00 -0600158 /* @brief File descriptor for the V4L2 video device */
159 int fd;
160 /* @brief Desired frame rate of video stream in frames per second */
161 int frameRate;
162 /* @brief Buffer index for the last video frame */
163 int lastFrameIndex;
Eddie James21b177e2018-12-11 13:14:46 -0600164 /* @brief Height in pixels of the video frame */
165 size_t height;
166 /* @brief Width in pixels of the video frame */
167 size_t width;
Jammy Huanga4f63b32022-02-14 14:43:21 +0800168 /* @brief jpeg's subsampling, 1:420/0:444 */
169 int subSampling;
Eddie James21b177e2018-12-11 13:14:46 -0600170 /* @brief Reference to the Input object */
171 Input& input;
172 /* @brief Path to the V4L2 video device */
173 const std::string path;
Eddie James90d49582018-12-11 13:22:00 -0600174 /* @brief Streaming buffer storage */
175 std::vector<Buffer> buffers;
Charles Kearney8e909b72023-03-29 21:11:23 +0000176
177 /* @brief Pixel Format */
178 uint32_t pixelformat;
Eddie James21b177e2018-12-11 13:14:46 -0600179};
180
181} // namespace ikvm