ACMX 2.136.0
Dual-Backend Real-Time GPU Video Synthesis
Loading...
Searching...
No Matches
media_helpers.cpp
Go to the documentation of this file.
1#include "media_helpers.hpp"
2
3#include <mxvk/mxvk_cv.hpp>
4
5#include <chrono>
6#include <exception>
7#include <iostream>
8#include <utility>
9
10namespace acmxvk {
14
15 void LatestCameraFrame::start(mxvk::VK_Capture &source) {
16 stop();
17 {
18 std::lock_guard<std::mutex> lock(frame_mutex);
19 capture_source = &source;
20 stopping = false;
21 latest_frame.release();
24 }
26 }
27
28 void LatestCameraFrame::stop() noexcept {
29 {
30 std::lock_guard<std::mutex> lock(frame_mutex);
31 stopping = true;
32 }
33 frame_condition.notify_all();
34 if (capture_thread.joinable()) {
35 capture_thread.join();
36 }
37 std::lock_guard<std::mutex> lock(frame_mutex);
38 capture_source = nullptr;
39 latest_frame.release();
42 }
43
44 bool LatestCameraFrame::takeLatest(cv::Mat &frame, bool wait_for_first) {
45 std::unique_lock<std::mutex> lock(frame_mutex);
46 if (wait_for_first && published_generation == 0 && !stopping) {
47 frame_condition.wait_for(lock, std::chrono::seconds(3), [&] {
48 return stopping || published_generation > 0;
49 });
50 }
52 latest_frame.empty()) {
53 return false;
54 }
55 frame = latest_frame;
57 return true;
58 }
59
61 while (true) {
62 mxvk::VK_Capture *source = nullptr;
63 {
64 std::lock_guard<std::mutex> lock(frame_mutex);
65 if (stopping) {
66 return;
67 }
68 source = capture_source;
69 }
70 if (source == nullptr) {
71 return;
72 }
73
74 cv::Mat captured;
75 bool read_frame = false;
76 try {
77 read_frame = source->read(captured);
78 } catch (const std::exception &error) {
79 std::cerr << "acmxvk: asynchronous camera read failed: "
80 << error.what() << '\n';
81 } catch (...) {
82 std::cerr << "acmxvk: asynchronous camera read failed\n";
83 }
84 if (!read_frame || captured.empty()) {
85 std::this_thread::sleep_for(std::chrono::milliseconds(5));
86 continue;
87 }
88
89 {
90 std::lock_guard<std::mutex> lock(frame_mutex);
91 if (stopping) {
92 return;
93 }
94 latest_frame = std::move(captured);
96 }
97 frame_condition.notify_one();
98 }
99 }
100} // namespace acmxvk
std::uint64_t published_generation
bool takeLatest(cv::Mat &frame, bool wait_for_first)
void start(mxvk::VK_Capture &source)
std::condition_variable frame_condition
std::uint64_t consumed_generation
mxvk::VK_Capture * capture_source