ACMX 2.136.0
Dual-Backend Real-Time GPU Video Synthesis
Loading...
Searching...
No Matches
ACMXVK/acmx.cpp
Go to the documentation of this file.
1/**
2 * @file acmx.cpp
3 * @brief ACMXVK real-time Vulkan video shader application.
4 */
5
6#include <mxvk/mxvk_exception.hpp>
7
8#ifdef AUDIO_ENABLED
9#include "audio.hpp"
10#endif
11#ifdef MIDI_ENABLED
12#include "midi.hpp"
13#endif
14#ifdef ACMXVK_WITH_CUDA
15#include "gpu_filters.hpp"
16#endif
17#ifdef ACMXVK_WITH_DEEP_DREAM
18#include "deep_dream.hpp"
19#endif
20#include "app/camera_probe.hpp"
21#include "app/media_utils.hpp"
22#include "app/options.hpp"
24#include "main_window.hpp"
25
26#include <csignal>
27#include <cstdlib>
28#include <iostream>
29#include <opencv2/core.hpp>
30#include <opencv2/imgcodecs.hpp>
31#include <stdexcept>
32#include <string_view>
33#include <utility>
34
35int main(int argc, char **argv) {
36 try {
37 for (int index = 1; index < argc; ++index) {
38 if (argv[index] != nullptr &&
39 (std::string_view(argv[index]) == "--unbuffered" ||
40 std::string_view(argv[index]) == "--silent" ||
41 std::string_view(argv[index]) == "--headless")) {
42 std::cout << std::unitbuf;
43 std::cerr << std::unitbuf;
44 break;
45 }
46 }
47 acmxvk::Options options = acmxvk::parseOptions(argc, argv);
48 if (options.show_help) {
49 acmxvk::printHelp(std::cout);
50 return EXIT_SUCCESS;
51 }
52 if (!options.build_manifest.empty()) {
53 return acmxvk::buildShaderLibrary(options);
54 }
55 if (options.enumerate_camera_device >= 0) {
57 std::cout, std::cerr)
58 ? EXIT_SUCCESS
59 : EXIT_FAILURE;
60 }
61 if (options.list_camera_devices) {
62 return acmxvk::listCameraDevices(std::cout, std::cerr)
63 ? EXIT_SUCCESS
64 : EXIT_FAILURE;
65 }
66 if (options.check_audio) {
67#ifdef AUDIO_ENABLED
68 std::cout << "AUDIO: enabled\n";
69#else
70 std::cout << "AUDIO: disabled\n";
71#endif
72 return EXIT_SUCCESS;
73 }
74 if (options.check_midi) {
75#ifdef MIDI_ENABLED
76 std::cout << "MIDI: enabled\n";
77#else
78 std::cout << "MIDI: disabled\n";
79#endif
80 return EXIT_SUCCESS;
81 }
82 if (options.check_cuda) {
83#ifdef ACMXVK_WITH_MXVK_CUDA
84 std::cout << "MXVK CUDA interop: enabled\n";
85#else
86 std::cout << "MXVK CUDA interop: disabled\n";
87#endif
88#ifdef ACMXVK_WITH_CUDA
89 std::cout << "acidcam-gpu filters: enabled\n";
90#else
91 std::cout << "acidcam-gpu filters: disabled\n";
92#endif
93 return EXIT_SUCCESS;
94 }
95 if (options.check_dnn) {
96#ifdef ACMXVK_WITH_DNN
97 std::cout << "OpenCV DNN effects: enabled\n";
98#else
99 std::cout << "OpenCV DNN effects: disabled\n";
100#endif
101 return EXIT_SUCCESS;
102 }
103 if (options.check_deep_dream) {
104#ifdef ACMXVK_WITH_DEEP_DREAM
106 options.cuda_device, options.dream_model,
107 options.dream_layer, options.dream_iterations,
108 static_cast<float>(options.dream_strength),
109 static_cast<float>(options.dream_feedback),
110 static_cast<float>(options.dream_zoom),
111 static_cast<float>(options.dream_rotation),
112 options.dream_size, options.dream_fp16,
113 options.dream_channel, options.dream_octaves,
114 static_cast<float>(options.dream_octave_scale),
115 options.dream_jitter, options.dream_smoothing,
116 std::cout, std::cerr)
117 ? EXIT_SUCCESS
118 : EXIT_FAILURE;
119#else
120 if (!options.dream_model.empty()) {
121 std::cerr << "Deep Dream model inspection requires an ACMXVK "
122 "build configured with -DWITH_DEEP_DREAM=ON\n";
123 return EXIT_FAILURE;
124 }
125 std::cout << "Deep Dream: disabled\n";
126 return EXIT_SUCCESS;
127#endif
128 }
129 if (!options.probe_hdr_file.empty()) {
130 const acmxvk::VideoHdrInfo info =
132 if (!info.valid) {
133 std::cerr << "acmxvk: unable to probe HDR metadata: "
134 << options.probe_hdr_file << '\n';
135 return EXIT_FAILURE;
136 }
137 std::cout << "acmxvk: HDR probe: " << options.probe_hdr_file
138 << '\n';
139 acmxvk::printVideoHdrInfo(info, std::cout);
140 return EXIT_SUCCESS;
141 }
142 if (options.list_audio_devices) {
143#ifdef AUDIO_ENABLED
145 return EXIT_SUCCESS;
146#else
147 throw std::runtime_error(
148 "--list-devices requires an ACMXVK build configured with -DAUDIO=ON");
149#endif
150 }
151 if (options.list_midi_devices) {
152#ifdef MIDI_ENABLED
154 return EXIT_SUCCESS;
155#else
156 throw std::runtime_error(
157 "--list-midi requires an ACMXVK build configured with -DMIDI=ON");
158#endif
159 }
160 if (options.list_gpu_filters) {
161#ifdef ACMXVK_WITH_CUDA
163 return EXIT_SUCCESS;
164#else
165 throw std::runtime_error(
166 "--list-filters requires an ACMXVK build configured with "
167 "-DWITH_CUDA=ON");
168#endif
169 }
170 if (options.list_cuda_devices) {
171#ifdef ACMXVK_WITH_MXVK_CUDA
172 acmxvk::list_cuda_devices(std::cout);
173 return EXIT_SUCCESS;
174#else
175 throw std::runtime_error(
176 "--list-cuda-devices requires a CUDA-enabled MXVK installation");
177#endif
178 }
179#ifndef AUDIO_ENABLED
180 if (options.enable_audio) {
181 throw std::runtime_error(
182 "--enable-audio requires an ACMXVK build configured with -DAUDIO=ON");
183 }
184#endif
185#ifndef MIDI_ENABLED
186 if (options.midi_device_specified || options.midi_monitor ||
187 !options.midi_map_file.empty() || !options.midi_cc_mappings.empty()) {
188 throw std::runtime_error(
189 "MIDI input requires an ACMXVK build configured with -DMIDI=ON");
190 }
191#endif
192#ifndef ACMXVK_WITH_DEEP_DREAM
193 if (!options.dream_model.empty()) {
194 throw std::runtime_error(
195 "--dream-model requires an ACMXVK build configured with "
196 "-DWITH_DEEP_DREAM=ON");
197 }
198#endif
199#ifndef ACMXVK_WITH_CUDA
200 if (!options.gpu_filter_indices.empty()) {
201 throw std::runtime_error(
202 "CUDA filters require an ACMXVK build configured with "
203 "-DWITH_CUDA=ON");
204 }
205#endif
206#ifndef ACMXVK_WITH_MXVK_CUDA
207 if (options.cuda_device_specified && options.dream_model.empty()) {
208 throw std::runtime_error(
209 "--cuda-device requires a CUDA-enabled MXVK installation");
210 }
211#endif
212#ifndef ACMXVK_WITH_DNN
213 if (!options.edge_model.empty() || !options.human_model.empty() ||
214 !options.onnx_configuration.empty() ||
215 options.human_background || options.human_black_specified ||
216 options.human_white_specified) {
217 throw std::runtime_error(
218 "DNN effects require an ACMXVK build configured with "
219 "-DWITH_OPENCV_DNN=ON");
220 }
221#endif
222 if (options.list_encoders) {
223 acmxvk::printEncoders(std::cout);
224 return EXIT_SUCCESS;
225 }
226 if (!options.list_encoder_options.empty()) {
227 return acmxvk::printEncoderOptions(options.list_encoder_options, std::cout,
228 std::cerr)
229 ? EXIT_SUCCESS
230 : EXIT_FAILURE;
231 }
232
233 if (options.headless &&
234 std::signal(SIGINT, acmxvk::request_headless_shutdown) ==
235 SIG_ERR) {
236 throw std::runtime_error(
237 "unable to install Ctrl+C handler for headless mode");
238 }
239
240#ifdef ACMXVK_WITH_CUDA
241 if (!options.gpu_filter_indices.empty()) {
243 options.gpu_filter_indices);
244 }
245#endif
246#ifdef ACMXVK_WITH_MXVK_CUDA
247 if (!options.gpu_filter_indices.empty() || options.cuda_device_specified) {
248 acmxvk::select_cuda_device(options.cuda_device);
249 }
250#endif
251
252 if (!options.graphic_file.empty() && !options.resolution_specified) {
253 const cv::Mat image = cv::imread(options.graphic_file, cv::IMREAD_UNCHANGED);
254 if (!image.empty()) {
255 options.width = image.cols;
256 options.height = image.rows;
258 std::swap(options.width, options.height);
259 }
260 }
261 }
262
263 acmxvk::MainWindow main_window(std::move(options));
264 main_window.loop();
265 } catch (const mxvk::Exception &error) {
266 std::cerr << "acmxvk: MXVK exception: " << error.text() << '\n';
267 return EXIT_FAILURE;
268 } catch (const std::exception &error) {
269 std::cerr << "acmxvk: exception: " << error.what() << '\n';
270 return EXIT_FAILURE;
271 }
272 return EXIT_SUCCESS;
273}
int main(int argc, char **argv)
Application entry point.
static void validate_filter_indices(const std::vector< int > &filter_indices)
static void list_filters(std::ostream &output)
static void list_ports(std::ostream &output)
Definition midi.cpp:295
bool probe(int cuda_device, std::string_view model_file, std::string_view layer, int iterations, float strength, float feedback, float zoom, float rotation_degrees, int max_dimension, bool use_half, int target_channel, int octaves, float octave_scale, int jitter, int smoothing, std::ostream &output, std::ostream &error)
void printEncoders(std::ostream &output)
Definition options.cpp:1584
bool rotationSwapsDimensions(FrameRotation rotation)
void printHelp(std::ostream &output)
Definition options.cpp:1382
void printVideoHdrInfo(const VideoHdrInfo &info, std::ostream &output)
void request_headless_shutdown(int signal_number) noexcept
bool printEncoderOptions(std::string_view encoder_name, std::ostream &output, std::ostream &error_output)
Definition options.cpp:1596
VideoHdrInfo probeVideoHdrInfo(const std::string &filename)
bool listCameraDevices(std::ostream &output, std::ostream &error)
Print native camera device indices and names as tab-separated records.
Options parseOptions(int argc, char **argv)
Definition options.cpp:382
bool probeCameraDevice(int device_index, std::ostream &output, std::ostream &error)
Print the native capture formats, resolutions, and frame rates exposed by a camera device.
int buildShaderLibrary(const Options &options)
std::string edge_model
Definition options.hpp:186
bool midi_device_specified
Definition options.hpp:119
double dream_octave_scale
Definition options.hpp:84
std::string dream_layer
Definition options.hpp:190
bool cuda_device_specified
Definition options.hpp:124
std::string build_manifest
Definition options.hpp:171
std::string dream_model
Definition options.hpp:189
double dream_rotation
Definition options.hpp:83
bool human_background
Definition options.hpp:146
FrameRotation frame_rotation
Definition options.hpp:159
bool list_camera_devices
Definition options.hpp:117
std::string midi_map_file
Definition options.hpp:185
std::vector< int > gpu_filter_indices
Definition options.hpp:164
double dream_feedback
Definition options.hpp:81
std::vector< std::string > midi_cc_mappings
Definition options.hpp:163
std::string graphic_file
Definition options.hpp:166
double dream_strength
Definition options.hpp:80
bool list_cuda_devices
Definition options.hpp:126
std::string onnx_configuration
Definition options.hpp:188
std::string human_model
Definition options.hpp:187
bool list_audio_devices
Definition options.hpp:116
double dream_zoom
Definition options.hpp:82
int enumerate_camera_device
Definition options.hpp:46
bool check_deep_dream
Definition options.hpp:129
std::string list_encoder_options
Definition options.hpp:181
bool list_midi_devices
Definition options.hpp:121
bool resolution_specified
Definition options.hpp:86
std::string probe_hdr_file
Definition options.hpp:182
bool human_white_specified
Definition options.hpp:148
bool list_gpu_filters
Definition options.hpp:125
bool human_black_specified
Definition options.hpp:147