-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathapp.cpp
118 lines (96 loc) · 4.25 KB
/
app.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
#include <atomic>
#include <csignal>
#include <cstddef>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <map>
#ifdef _WIN32
#ifdef _WIN64
#pragma comment(lib, "Processing.NDI.Lib.x64.lib")
#else // _WIN64
#pragma comment(lib, "Processing.NDI.Lib.x86.lib")
#endif // _WIN64
#include <windows.h>
#endif
#include "lib/NDI SDK for Linux/include/Processing.NDI.Lib.h"
#include "lib/screen_capture_lite/include/ScreenCapture.h"
std::map<int, void *> frame_buffers;
std::map<int, NDIlib_video_frame_v2_t> frames;
std::map<int, NDIlib_send_instance_t> senders;
void ExtractAndConvertToRGBA(const SL::Screen_Capture::Image &img, unsigned char *dst, size_t dst_size) {
assert(dst_size >= static_cast<size_t>(SL::Screen_Capture::Width(img) * SL::Screen_Capture::Height(img) * sizeof(SL::Screen_Capture::ImageBGRA)));
auto imgsrc = StartSrc(img);
auto imgdist = dst;
for (auto h = 0; h < Height(img); h++) {
auto startimgsrc = imgsrc;
for (auto w = 0; w < Width(img); w++, imgsrc++) {
*imgdist++ = imgsrc->B;
*imgdist++ = imgsrc->G;
*imgdist++ = imgsrc->R;
*imgdist++ = 0;
}
imgsrc = SL::Screen_Capture::GotoNextRow(img, startimgsrc);
}
}
using namespace std::chrono_literals;
std::shared_ptr<SL::Screen_Capture::IScreenCaptureManager> dispCapture;
// static std::atomic<bool> exit_loop(false);
// static void sigint_handler(int) {
// exit_loop = true;
// }
int main(int argc, char *argv[]) {
if (!NDIlib_initialize()) { // Cannot run NDI. Most likely because the CPU is not sufficient (see SDK documentation).
printf("Cannot run NDI.");
return 0;
}
// signal(SIGINT, sigint_handler);
std::srand(std::time(nullptr));
std::cout << "Running display capture" << std::endl;
dispCapture = nullptr;
dispCapture =
SL::Screen_Capture::CreateCaptureConfiguration([]() {
auto mons = SL::Screen_Capture::GetMonitors();
std::cout << "Library is requesting the list of monitors to capture!" << std::endl;
for (auto &m : mons) {
NDIlib_send_create_t NDI_send_create_desc;
NDI_send_create_desc.p_ndi_name = m.Name;
NDIlib_send_instance_t pNDI_send = NDIlib_send_create(&NDI_send_create_desc);
if (!pNDI_send) {
std::cout << "Error?" << std::endl;
continue;
}
// We are going to create a 1920x1080 interlaced frame at 29.97Hz.
NDIlib_video_frame_v2_t NDI_video_frame;
NDI_video_frame.xres = m.Width;
NDI_video_frame.yres = m.Height;
NDI_video_frame.FourCC = NDIlib_FourCC_type_BGRX;
NDI_video_frame.line_stride_in_bytes = m.Width * 4;
// NDI_video_frame.frame_rate_N = 60000;
// NDI_video_frame.frame_rate_D = 1200;
senders[m.Id] = pNDI_send;
frames[m.Id] = NDI_video_frame;
frame_buffers[m.Id] = malloc(m.Width * m.Height * 4);
std::cout << m.Name << std::endl;
// free(p_frame_buffers[]);
// NDIlib_send_destroy(pNDI_send);
// NDIlib_destroy();
// std::cout << m.Name << std::endl;
}
return mons;
})
->onNewFrame([&](const SL::Screen_Capture::Image &img, const SL::Screen_Capture::Monitor &monitor) {
if (!NDIlib_send_get_no_connections(senders[monitor.Id], 0)) {
return;
}
ExtractAndConvertToRGBA(img, (unsigned char *)frame_buffers[monitor.Id], monitor.Width * monitor.Height * 4);
frames[monitor.Id].p_data = (uint8_t *)frame_buffers[monitor.Id];
NDIlib_send_send_video_v2(senders[monitor.Id], &frames[monitor.Id]);
// NDIlib_send_send_video_async_v2(senders[monitor.Id], &frames[monitor.Id]);
})
->start_capturing();
dispCapture->setFrameChangeInterval(std::chrono::milliseconds(1));
std::this_thread::sleep_until(std::chrono::system_clock::now() + std::chrono::hours(std::numeric_limits<int>::max()));
return 0;
}