ACMX 2.139.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 {
12
13 void LatestCameraFrame::start(mxvk::VK_Capture &source) {
14 stop();
15 {
16 std::lock_guard<std::mutex> lock(frame_mutex);
17 capture_source = &source;
18 stopping = false;
19 latest_frame.release();
22 }
24 }
25
26 void LatestCameraFrame::stop() noexcept {
27 {
28 std::lock_guard<std::mutex> lock(frame_mutex);
29 stopping = true;
30 }
31 frame_condition.notify_all();
32 if (capture_thread.joinable()) {
33 capture_thread.join();
34 }
35 std::lock_guard<std::mutex> lock(frame_mutex);
36 capture_source = nullptr;
37 latest_frame.release();
40 }
41
42 bool LatestCameraFrame::takeLatest(cv::Mat &frame, bool wait_for_first) {
43 std::unique_lock<std::mutex> lock(frame_mutex);
44 if (wait_for_first && published_generation == 0 && !stopping) {
45 frame_condition.wait_for(lock, std::chrono::seconds(3), [&] { return stopping || published_generation > 0; });
46 }
48 return false;
49 }
50 frame = latest_frame;
52 return true;
53 }
54
56 while (true) {
57 mxvk::VK_Capture *source = nullptr;
58 {
59 std::lock_guard<std::mutex> lock(frame_mutex);
60 if (stopping) {
61 return;
62 }
63 source = capture_source;
64 }
65 if (source == nullptr) {
66 return;
67 }
68
69 cv::Mat captured;
70 bool read_frame = false;
71 try {
72 read_frame = source->read(captured);
73 } catch (const std::exception &error) {
74 std::cerr << "acmxvk: asynchronous camera read failed: " << error.what() << '\n';
75 } catch (...) {
76 std::cerr << "acmxvk: asynchronous camera read failed\n";
77 }
78 if (!read_frame || captured.empty()) {
79 std::this_thread::sleep_for(std::chrono::milliseconds(5));
80 continue;
81 }
82
83 {
84 std::lock_guard<std::mutex> lock(frame_mutex);
85 if (stopping) {
86 return;
87 }
88 latest_frame = std::move(captured);
90 }
91 frame_condition.notify_one();
92 }
93 }
94} // 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