MXVK Vulkan Framework 0.24.0
C++20 Vulkan rendering framework for practical 2D and 3D application development with SDL3.
Loading...
Searching...
No Matches
mxvk_cv.hpp
Go to the documentation of this file.
1/**
2 * @file mxvk_cv.hpp
3 * @brief OpenCV video-capture integration for the Vulkan backend.
4 *
5 * mxvk::VK_Capture (Vulkan variant) wraps cv::VideoCapture and feeds decoded
6 * frames into a VK_Sprite for display within a VK_Window.
7 */
8#pragma once
9
10#include "mxvk.hpp"
11#include "mxvk_sprite.hpp"
12#include <memory>
13#include <opencv2/opencv.hpp>
14#ifdef MXVK_CUDA
15#include <opencv2/core/cuda.hpp>
16#include <opencv2/cudaarithm.hpp>
17#include <opencv2/cudaimgproc.hpp>
18#endif
19
20namespace mxvk {
21 class VKAbstractModel;
22
23 /**
24 * @class VK_Capture
25 * @brief Vulkan OpenCV video capture source.
26 *
27 * Opens a video file or camera, decodes frames, and uploads them to a
28 * VKSprite texture for Vulkan-accelerated rendering inside a VKWindow.
29 */
30 class VK_Capture {
31 public:
32 /** @brief Default constructor. */
33 VK_Capture() = default;
34 /** @brief Destructor. */
35 ~VK_Capture() = default;
36 VK_Capture &operator=(const VK_Capture &) = delete;
38 VK_Capture(const VK_Capture &) = delete;
39 VK_Capture(VK_Capture &&) = delete;
40
41 /**
42 * @brief Open a video file.
43 * @param filename Path to the video file.
44 * @return @c true on success.
45 */
46 bool open(const std::string &filename);
47
48 /**
49 * @brief Open a camera device.
50 * @param id Camera index.
51 * @param mode Backend hint (0 = auto).
52 * @return @c true on success.
53 */
54 bool open(int id, int mode = 0);
55
56 /** @brief Close the capture device. */
57 void close();
58
59 /**
60 * @brief Destroy the current sprite and its Vulkan resources.
61 *
62 * Call this before swapchain/command-pool teardown to avoid destroying
63 * sprite staging command buffers against an invalid command pool.
64 */
65 void resetSprite();
66
67 /**
68 * @brief Check whether the capture device is open.
69 * @return @c true if the VideoCapture is opened.
70 */
71 bool is_open() const { return cap.isOpened(); }
72
73 /**
74 * @brief Allocate the VKSprite and upload the initial texture.
75 * @param device Logical Vulkan device.
76 * @param physDev Physical device.
77 * @param gQueue Graphics queue.
78 * @param cmdPool Command pool.
79 * @param width Display width.
80 * @param height Display height.
81 * @param vert Vertex shader path.
82 * @param frag Fragment shader path.
83 * @return @c true on success.
84 */
85 bool createImage(VkDevice device, VkPhysicalDevice physDev, VkQueue gQueue,
86 VkCommandPool cmdPool, size_t width, size_t height,
87 const std::string &vert, const std::string &frag);
88
89 /**
90 * @brief Access the backing sprite.
91 * @return Pointer to the VKSprite (may be null before createImage).
92 */
93 VK_Sprite *getSprite() { return sprite.get(); }
94
95 /**
96 * @brief Draw the current frame at a specified position and size.
97 * @param x Width destination X.
98 * @param y Width destination Y.
99 * @param width Display width.
100 * @param height Display height.
101 */
102 void draw(int x, int y, int width, int height);
103
104 /**
105 * @brief Draw using the sprite's native dimensions.
106 * @param x Destination X.
107 * @param y Destination Y.
108 */
109 void draw(int x, int y);
110
111 /**
112 * @brief Replace the vertex/fragment shaders.
113 * @param width Display width.
114 * @param height Display height.
115 * @param vert New vertex shader path.
116 * @param frag New fragment shader path.
117 * @return @c true on success.
118 */
119 bool reload(size_t width, size_t height, const std::string &vert, const std::string &frag);
120
121 /**
122 * @brief Capture and upload the next video frame.
123 * @return @c true if a frame was available.
124 */
125 bool read();
126 bool readRgba(cv::Mat &rgba, bool flipY = false);
127 bool readToSprite(VK_Sprite &targetSprite);
128 bool readToSprite(VK_Sprite &targetSprite, bool flipY);
129 bool readToModelTexture(VKAbstractModel &model, bool flipY = false);
130#ifdef MXVK_CUDA
131 bool readGpuRgba(cv::cuda::GpuMat &rgba, bool flipY = false);
132 cv::cuda::Stream &cudaStream() { return cuda_stream; }
133#endif
134
135 /**
136 * @brief Capture the next frame into a cv::Mat.
137 * @param frame Output matrix.
138 * @return @c true if a frame was available.
139 */
140 bool read(cv::Mat &frame);
141
142 /**
143 * @brief Set a VideoCapture property.
144 * @param option cv::VideoCaptureProperties constant.
145 * @param value Desired value.
146 */
147 void set(unsigned int option, double value);
148
149 /**
150 * @brief Query a VideoCapture property.
151 * @param option cv::VideoCaptureProperties constant.
152 * @return Current value.
153 */
154 double get(unsigned int option);
155
156 private:
157#ifdef MXVK_CUDA
158 bool initializeCuda();
159 bool readCuda();
160#endif
161
162 std::unique_ptr<VK_Sprite> sprite; ///< Backing Vulkan sprite (owned).
163 cv::VideoCapture cap; ///< OpenCV capture device.
164 cv::Mat frame; ///< Most recent decoded frame.
165#ifdef MXVK_CUDA
166 bool cudaChecked = false;
167 bool cudaAvailable = false;
168 bool cudaMappedInput = false;
169 bool cudaPipelineLogged = false;
170 bool cudaFlipYForVulkan = true;
171 cv::cuda::Stream cuda_stream{};
172 cv::cuda::GpuMat gpuFrame{};
173 cv::cuda::GpuMat gpuRgba{};
174 cv::cuda::GpuMat gpuVulkanRgba{};
175 cv::cuda::HostMem mappedFrame{cv::cuda::HostMem::SHARED};
176 cv::cuda::HostMem pinnedRgba{cv::cuda::HostMem::PAGE_LOCKED};
177 cv::Mat pinnedRgbaMat{};
178#endif
179 };
180} // namespace mxvk
Convenience wrapper that owns mesh, textures, descriptors, and pipeline state.
VK_Capture(VK_Capture &&)=delete
VK_Capture()=default
Default constructor.
~VK_Capture()=default
Destructor.
VK_Capture & operator=(const VK_Capture &)=delete
bool readToModelTexture(VKAbstractModel &model, bool flipY=false)
Definition mxvk_cv.cpp:298
bool open(const std::string &filename)
Open a video file.
Definition mxvk_cv.cpp:14
VK_Capture & operator=(VK_Capture &&)=delete
bool reload(size_t width, size_t height, const std::string &vert, const std::string &frag)
Replace the vertex/fragment shaders.
Definition mxvk_cv.cpp:57
void resetSprite()
Destroy the current sprite and its Vulkan resources.
Definition mxvk_cv.cpp:42
VK_Sprite * getSprite()
Access the backing sprite.
Definition mxvk_cv.hpp:93
VK_Capture(const VK_Capture &)=delete
void close()
Close the capture device.
Definition mxvk_cv.cpp:37
double get(unsigned int option)
Query a VideoCapture property.
Definition mxvk_cv.cpp:485
bool readToSprite(VK_Sprite &targetSprite)
Definition mxvk_cv.cpp:369
bool readRgba(cv::Mat &rgba, bool flipY=false)
Definition mxvk_cv.cpp:74
bool createImage(VkDevice device, VkPhysicalDevice physDev, VkQueue gQueue, VkCommandPool cmdPool, size_t width, size_t height, const std::string &vert, const std::string &frag)
Allocate the VKSprite and upload the initial texture.
Definition mxvk_cv.cpp:46
void draw(int x, int y, int width, int height)
Draw the current frame at a specified position and size.
Definition mxvk_cv.cpp:471
bool is_open() const
Check whether the capture device is open.
Definition mxvk_cv.hpp:71
bool read()
Capture and upload the next video frame.
Definition mxvk_cv.cpp:456
void set(unsigned int option, double value)
Set a VideoCapture property.
Definition mxvk_cv.cpp:481
Vulkan 2-D sprite renderer with optional custom shaders and instancing.
Utilities for loading and saving PNG images.
Definition mxvk.hpp:30