blob: 15bbb0bbf10bdf09696689a4c57ffa6350170785 [file] [log] [blame]
#pragma once
#include "ikvm_input.hpp"
#include <mutex>
#include <string>
#include <vector>
namespace ikvm
{
/*
* @class Video
* @brief Sets up the V4L2 video device and performs read operations
*/
class Video
{
public:
/*
* @brief Constructs Video object
*
* @param[in] p - Path to the V4L2 video device
* @param[in] input - Reference to the Input object
* @param[in] fr - desired frame rate of the video
*/
Video(const std::string& p, Input& input, int fr = 30, int sub = 0);
~Video();
Video(const Video&) = default;
Video& operator=(const Video&) = default;
Video(Video&&) = default;
Video& operator=(Video&&) = default;
/*
* @brief Gets the video frame data
*
* @return Pointer to the video frame data
*/
char* getData();
/* @brief Performs read to grab latest video frame */
void getFrame();
/*
* @brief Gets whether or not the video frame needs to be resized
*
* @return Boolean indicating if the frame needs to be resized
*/
bool needsResize();
/* @brief Performs the resize and re-allocates framebuffer */
void resize();
/* @brief Starts streaming from the video device */
void start();
/* @brief Stops streaming from the video device */
void stop();
/* @brief Restarts streaming from the video device */
void restart()
{
stop();
start();
}
/*
* @brief Gets the desired video frame rate in frames per second
*
* @return Value of the desired frame rate
*/
inline int getFrameRate() const
{
return frameRate;
}
/*
* @brief Gets the size of the video frame data
*
* @return Value of the size of the video frame data in bytes
*/
inline size_t getFrameSize() const
{
return buffers[lastFrameIndex].payload;
}
/*
* @brief Gets the height of the video frame
*
* @return Value of the height of video frame in pixels
*/
inline size_t getHeight() const
{
return height;
}
/*
* @brief Gets the pixel format of the video frame
*
* @return Value of the pixel format of video frame */
inline uint32_t getPixelformat() const
{
return pixelformat;
}
/*
* @brief Gets the width of the video frame
*
* @return Value of the width of video frame in pixels
*/
inline size_t getWidth() const
{
return width;
}
/*
* @brief Gets the subsampling of the video frame
*
* @return Value of the subsampling of video frame, 1:420/0:444
*/
inline int getSubsampling() const
{
return subSampling;
}
/*
* @brief Sets the subsampling of the video frame
*
* @return Value of the subsampling of video frame, 1:420/0:444
*/
inline void setSubsampling(int _sub)
{
subSampling = _sub;
}
/* @brief Number of bits per component of a pixel */
static const int bitsPerSample;
/* @brief Number of bytes of storage for a pixel */
static const int bytesPerPixel;
/* @brief Number of components in a pixel (i.e. 3 for RGB pixel) */
static const int samplesPerPixel;
private:
/*
* @struct Buffer
* @brief Store the address and size of frame data from streaming
* operations
*/
struct Buffer
{
Buffer() : data(nullptr), queued(false), payload(0), size(0) {}
~Buffer() = default;
Buffer(const Buffer&) = default;
Buffer& operator=(const Buffer&) = default;
Buffer(Buffer&&) = default;
Buffer& operator=(Buffer&&) = default;
void* data;
bool queued;
size_t payload;
size_t size;
};
/*
* @brief Boolean to indicate whether the resize was triggered during
* the open operation
*/
bool resizeAfterOpen;
/* @brief Indicates whether or not timings query was last sucessful */
bool timingsError;
/* @brief File descriptor for the V4L2 video device */
int fd;
/* @brief Desired frame rate of video stream in frames per second */
int frameRate;
/* @brief Buffer index for the last video frame */
int lastFrameIndex;
/* @brief Height in pixels of the video frame */
size_t height;
/* @brief Width in pixels of the video frame */
size_t width;
/* @brief jpeg's subsampling, 1:420/0:444 */
int subSampling;
/* @brief Reference to the Input object */
Input& input;
/* @brief Path to the V4L2 video device */
const std::string path;
/* @brief Streaming buffer storage */
std::vector<Buffer> buffers;
/* @brief Pixel Format */
uint32_t pixelformat;
};
} // namespace ikvm