blob: 23c58a74ce214085f1da71aad2e2a82d39baf1c1 [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 /*
88 * @brief Gets the width of the video frame
89 *
90 * @return Value of the width of video frame in pixels
91 */
92 inline size_t getWidth() const
93 {
94 return width;
95 }
Jammy Huanga4f63b32022-02-14 14:43:21 +080096 /*
97 * @brief Gets the subsampling of the video frame
98 *
99 * @return Value of the subsampling of video frame, 1:420/0:444
100 */
101 inline int getSubsampling() const
102 {
103 return subSampling;
104 }
105 /*
106 * @brief Sets the subsampling of the video frame
107 *
108 * @return Value of the subsampling of video frame, 1:420/0:444
109 */
110 inline void setSubsampling(int _sub)
111 {
112 subSampling = _sub;
113 }
Eddie James21b177e2018-12-11 13:14:46 -0600114
Eddie James90d49582018-12-11 13:22:00 -0600115 /* @brief Number of bits per component of a pixel */
116 static const int bitsPerSample;
117 /* @brief Number of bytes of storage for a pixel */
118 static const int bytesPerPixel;
119 /* @brief Number of components in a pixel (i.e. 3 for RGB pixel) */
120 static const int samplesPerPixel;
121
Eddie James21b177e2018-12-11 13:14:46 -0600122 private:
Eddie James90d49582018-12-11 13:22:00 -0600123 /*
124 * @struct Buffer
125 * @brief Store the address and size of frame data from streaming
126 * operations
127 */
128 struct Buffer
129 {
130 Buffer() : data(nullptr), queued(false), payload(0), size(0)
131 {
132 }
133 ~Buffer() = default;
134 Buffer(const Buffer&) = default;
135 Buffer& operator=(const Buffer&) = default;
136 Buffer(Buffer&&) = default;
137 Buffer& operator=(Buffer&&) = default;
138
139 void* data;
140 bool queued;
141 size_t payload;
142 size_t size;
143 };
144
145 /*
146 * @brief Boolean to indicate whether the resize was triggered during
147 * the open operation
148 */
149 bool resizeAfterOpen;
Eddie James23135dd2019-08-09 15:41:37 -0500150 /* @brief Indicates whether or not timings query was last sucessful */
151 bool timingsError;
Eddie James90d49582018-12-11 13:22:00 -0600152 /* @brief File descriptor for the V4L2 video device */
153 int fd;
154 /* @brief Desired frame rate of video stream in frames per second */
155 int frameRate;
156 /* @brief Buffer index for the last video frame */
157 int lastFrameIndex;
Eddie James21b177e2018-12-11 13:14:46 -0600158 /* @brief Height in pixels of the video frame */
159 size_t height;
160 /* @brief Width in pixels of the video frame */
161 size_t width;
Jammy Huanga4f63b32022-02-14 14:43:21 +0800162 /* @brief jpeg's subsampling, 1:420/0:444 */
163 int subSampling;
Eddie James21b177e2018-12-11 13:14:46 -0600164 /* @brief Reference to the Input object */
165 Input& input;
166 /* @brief Path to the V4L2 video device */
167 const std::string path;
Eddie James90d49582018-12-11 13:22:00 -0600168 /* @brief Streaming buffer storage */
169 std::vector<Buffer> buffers;
Eddie James21b177e2018-12-11 13:14:46 -0600170};
171
172} // namespace ikvm