mirror of
https://github.com/thinkonmay/sunshine-sdk.git
synced 2026-08-08 11:19:19 +00:00
remove all global var
This commit is contained in:
parent
1a0a3f9105
commit
1262ee2706
@ -1,8 +1,8 @@
|
||||
# common target definitions
|
||||
# this file will also load platform specific macros
|
||||
|
||||
# add_library(sunshine SHARED ${SUNSHINE_TARGET_FILES})
|
||||
add_executable(sunshine ${SUNSHINE_TARGET_FILES})
|
||||
add_library(sunshine SHARED ${SUNSHINE_TARGET_FILES})
|
||||
# add_executable(sunshine ${SUNSHINE_TARGET_FILES})
|
||||
|
||||
# platform specific target definitions
|
||||
if(WIN32)
|
||||
|
||||
42
src/dll.h
42
src/dll.h
@ -2,18 +2,36 @@
|
||||
*/
|
||||
|
||||
extern "C" {
|
||||
__declspec(dllexport) int __cdecl Init(
|
||||
int video_width,
|
||||
int video_height,
|
||||
int video_bitrate,
|
||||
int video_framerate,
|
||||
int video_codec
|
||||
);
|
||||
|
||||
__declspec(dllexport) int __cdecl StartQueue(int media_type);
|
||||
__declspec(dllexport) int __cdecl PopFromQueue(int media_type, void* data,int* duration);
|
||||
__declspec(dllexport) void __cdecl RaiseEvent(int event_id,int value);
|
||||
|
||||
__declspec(dllexport) void __cdecl Wait();
|
||||
__declspec(dllexport) void __cdecl Stop();
|
||||
typedef struct _VideoPipeline VideoPipeline;
|
||||
|
||||
|
||||
typedef enum _EventType {
|
||||
POINTER_VISIBLE,
|
||||
CHANGE_BITRATE,
|
||||
IDR_FRAME,
|
||||
|
||||
STOP
|
||||
}EventType;
|
||||
|
||||
__declspec(dllexport) VideoPipeline* __cdecl StartQueue( int video_width,
|
||||
int video_height,
|
||||
int video_bitrate,
|
||||
int video_framerate,
|
||||
int video_codec);
|
||||
|
||||
__declspec(dllexport) int __cdecl PopFromQueue(VideoPipeline* pipeline,
|
||||
void* data,
|
||||
int* duration);
|
||||
|
||||
__declspec(dllexport) void __cdecl RaiseEvent(VideoPipeline* pipeline,
|
||||
EventType event,
|
||||
int value);
|
||||
|
||||
__declspec(dllexport) void __cdecl WaitEvent(VideoPipeline* pipeline,
|
||||
EventType event,
|
||||
int* value);
|
||||
|
||||
|
||||
}
|
||||
283
src/main.cpp
283
src/main.cpp
@ -10,7 +10,6 @@
|
||||
#include <iostream>
|
||||
#include <thread>
|
||||
|
||||
|
||||
// local includes
|
||||
#include "config.h"
|
||||
#include "main.h"
|
||||
@ -18,188 +17,152 @@
|
||||
#include "platform/common.h"
|
||||
#include "video.h"
|
||||
|
||||
struct _VideoPipeline
|
||||
{
|
||||
std::chrono::steady_clock::time_point start;
|
||||
video::config_t monitor;
|
||||
safe::mail_t mail;
|
||||
};
|
||||
|
||||
extern VideoPipeline *__cdecl StartQueue(int video_width,
|
||||
int video_height,
|
||||
int video_bitrate,
|
||||
int video_framerate,
|
||||
int video_codec)
|
||||
{
|
||||
static bool init = false;
|
||||
if (!init)
|
||||
{
|
||||
// If any of the following fail, we log an error and continue event though sunshine will not function correctly.
|
||||
// This allows access to the UI to fix configuration problems or view the logs.
|
||||
if (platf::init())
|
||||
{
|
||||
// BOOST_LOG(error) << "Platform failed to initialize"sv;
|
||||
return NULL;
|
||||
}
|
||||
else if (video::probe_encoders())
|
||||
{
|
||||
// BOOST_LOG(error) << "Video failed to find working encoder"sv;
|
||||
return NULL;
|
||||
}
|
||||
init = true;
|
||||
}
|
||||
|
||||
safe::mail_t mail::man;
|
||||
static VideoPipeline pipeline = {};
|
||||
auto mail = std::make_shared<safe::mail_raw_t>();
|
||||
pipeline.mail = mail;
|
||||
pipeline.monitor = {1920, 1080, 60, 6000, 1, 0, 1, 0, 0};
|
||||
pipeline.start = std::chrono::steady_clock::now();
|
||||
|
||||
using namespace std::literals;
|
||||
switch (video_codec)
|
||||
{
|
||||
case 2: // h265
|
||||
pipeline.monitor.videoFormat = 1;
|
||||
config::video.hevc_mode = 1;
|
||||
config::video.av1_mode = 0;
|
||||
break;
|
||||
case 3: // av1
|
||||
pipeline.monitor.videoFormat = 2;
|
||||
config::video.hevc_mode = 0;
|
||||
config::video.av1_mode = 1;
|
||||
break;
|
||||
default:
|
||||
pipeline.monitor.videoFormat = 0;
|
||||
config::video.hevc_mode = 0;
|
||||
config::video.av1_mode = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
bool display_cursor = true;
|
||||
auto thread = std::thread{[&](){ video::capture(pipeline.mail, pipeline.monitor, NULL); }};
|
||||
thread.detach();
|
||||
|
||||
|
||||
static video::config_t monitor = { 1920, 1080, 60, 6000, 1, 0, 1, 0, 0 };
|
||||
static std::shared_ptr<safe::mail_raw_t> privatemail;
|
||||
static std::chrono::steady_clock::time_point start;
|
||||
extern int __cdecl
|
||||
Init(
|
||||
int width,
|
||||
int height,
|
||||
int bitrate,
|
||||
int framerate,
|
||||
int codec
|
||||
) {
|
||||
start = std::chrono::steady_clock::now();
|
||||
monitor.width = width;
|
||||
monitor.height = height;
|
||||
monitor.framerate = framerate;
|
||||
|
||||
switch (codec)
|
||||
{
|
||||
case 2: // h265
|
||||
monitor.videoFormat = 1;
|
||||
config::video.hevc_mode = 1;
|
||||
config::video.av1_mode = 0;
|
||||
break;
|
||||
case 3: // av1
|
||||
monitor.videoFormat = 2;
|
||||
config::video.hevc_mode = 0;
|
||||
config::video.av1_mode = 1;
|
||||
break;
|
||||
default:
|
||||
monitor.videoFormat = 0;
|
||||
config::video.hevc_mode = 0;
|
||||
config::video.av1_mode = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
|
||||
mail::man = std::make_shared<safe::mail_raw_t>();
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// If any of the following fail, we log an error and continue event though sunshine will not function correctly.
|
||||
// This allows access to the UI to fix configuration problems or view the logs.
|
||||
auto deinit_guard = platf::init();
|
||||
if (!deinit_guard) {
|
||||
// BOOST_LOG(error) << "Platform failed to initialize"sv;
|
||||
return 1;
|
||||
} else if (video::probe_encoders()) {
|
||||
// BOOST_LOG(error) << "Video failed to find working encoder"sv;
|
||||
return 1;
|
||||
} else {
|
||||
// BOOST_LOG(error) << "Hello from thinkmay."sv;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// auto mic = control->microphone(stream->mapping, stream->channelCount, stream->sampleRate, frame_size);
|
||||
|
||||
// Create signal handler after logging has been initialized
|
||||
mail::man->event<bool>(mail::shutdown)->view();
|
||||
}
|
||||
|
||||
|
||||
|
||||
extern void __cdecl
|
||||
Wait(){
|
||||
mail::man->event<bool>(mail::shutdown)->view();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief Main application entry point.
|
||||
* @param argc The number of arguments.
|
||||
* @param argv The arguments.
|
||||
*
|
||||
* EXAMPLES:
|
||||
* ```cpp
|
||||
* main(1, const char* args[] = {"sunshine", nullptr});
|
||||
* ```
|
||||
*/
|
||||
extern int __cdecl
|
||||
StartQueue() {
|
||||
void* null = 0;
|
||||
privatemail = std::make_shared<safe::mail_raw_t>();
|
||||
auto capture = std::thread {[&](){video::capture(privatemail, monitor, (void*)null);}};
|
||||
|
||||
// Create signal handler after logging has been initialized
|
||||
mail::man->event<bool>(mail::shutdown)->view();
|
||||
return 0;
|
||||
return &pipeline;
|
||||
}
|
||||
|
||||
int __cdecl
|
||||
PopFromQueue(void* data,int* duration)
|
||||
PopFromQueue(VideoPipeline *pipeline,
|
||||
void *data,
|
||||
int *duration)
|
||||
{
|
||||
auto packets = mail::man->queue<video::packet_t>(mail::video_packets);
|
||||
auto packet = packets->pop();
|
||||
auto packets = pipeline->mail->queue<video::packet_t>(mail::video_packets);
|
||||
auto packet = packets->pop();
|
||||
|
||||
if(packet->frame_timestamp) {
|
||||
auto duration_to_latency = [](const std::chrono::steady_clock::duration &duration) {
|
||||
const auto duration_ns = std::chrono::duration_cast<std::chrono::nanoseconds>(duration).count();
|
||||
return std::clamp<decltype(duration_ns)>((duration_ns + 50) / 100, 0, std::numeric_limits<int>::max());
|
||||
};
|
||||
if (packet->frame_timestamp)
|
||||
{
|
||||
auto duration_to_latency = [](const std::chrono::steady_clock::duration &duration)
|
||||
{
|
||||
const auto duration_ns = std::chrono::duration_cast<std::chrono::nanoseconds>(duration).count();
|
||||
return std::clamp<decltype(duration_ns)>((duration_ns + 50) / 100, 0, std::numeric_limits<int>::max());
|
||||
};
|
||||
|
||||
*duration = duration_to_latency(*packet->frame_timestamp - pipeline->start);
|
||||
pipeline->start = *packet->frame_timestamp;
|
||||
}
|
||||
|
||||
*duration = duration_to_latency(*packet->frame_timestamp - start);
|
||||
start = *packet->frame_timestamp;
|
||||
}
|
||||
|
||||
// packet->
|
||||
memcpy(data,packet->data(),packet->data_size());
|
||||
return packet->data_size();
|
||||
memcpy(data, packet->data(), packet->data_size());
|
||||
return packet->data_size();
|
||||
}
|
||||
|
||||
void __cdecl
|
||||
RaiseEvent(int event_id, int value)
|
||||
RaiseEvent(VideoPipeline *pipeline,
|
||||
EventType event,
|
||||
int value)
|
||||
{
|
||||
switch (event_id)
|
||||
{
|
||||
case 1: // IDR FRAME
|
||||
if (privatemail)
|
||||
privatemail->event<bool>(mail::idr)->raise(true);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
switch (event)
|
||||
{
|
||||
case IDR_FRAME: // IDR FRAME
|
||||
pipeline->mail->event<bool>(mail::idr)->raise(true);
|
||||
break;
|
||||
case STOP: // IDR FRAME
|
||||
pipeline->mail->event<bool>(mail::shutdown)->raise(true);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
DecodeCallbackEx(void* data, int size) {
|
||||
printf("received packet with size %d\n",size);
|
||||
void __cdecl
|
||||
WaitEvent(VideoPipeline* pipeline,
|
||||
EventType event,
|
||||
int* value)
|
||||
{
|
||||
switch (event)
|
||||
{
|
||||
case STOP: // IDR FRAME
|
||||
pipeline->mail->event<bool>(mail::shutdown)->pop();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Main application entry point.
|
||||
* @param argc The number of arguments.
|
||||
* @param argv The arguments.
|
||||
*
|
||||
* EXAMPLES:
|
||||
* ```cpp
|
||||
* main(1, const char* args[] = {"sunshine", nullptr});
|
||||
* ```
|
||||
*/
|
||||
int
|
||||
main(int argc, char *argv[]) {
|
||||
Init(1920,1080,6000,60,1);
|
||||
// StartCallback(DecodeCallbackEx);
|
||||
|
||||
auto video = std::thread {[](){
|
||||
auto shutdown_event = mail::man->event<bool>(mail::broadcast_shutdown);
|
||||
// Video traffic is sent on this thread
|
||||
platf::adjust_thread_priority(platf::thread_priority_e::high);
|
||||
|
||||
int duration = 0;
|
||||
void* data = malloc(100 * 1000 * 1000);
|
||||
while (true) {
|
||||
int size = PopFromQueue(data,&duration);
|
||||
if (shutdown_event->peek()) {
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
|
||||
DecodeCallbackEx(data,size);
|
||||
}
|
||||
VideoPipeline *pipeline = StartQueue(1920, 1080, 6000, 60, 1);
|
||||
auto video = std::thread{[&]() {
|
||||
// Video traffic is sent on this thread
|
||||
platf::adjust_thread_priority(platf::thread_priority_e::high);
|
||||
int duration = 0;
|
||||
void *data = malloc(100 * 1000 * 1000);
|
||||
|
||||
shutdown_event->raise(true);
|
||||
}};
|
||||
int count = 0;
|
||||
while (true) {
|
||||
int size = PopFromQueue(pipeline, data, &duration);
|
||||
if (pipeline->mail->event<bool>(mail::shutdown)->peek() || count == 10) {
|
||||
break;
|
||||
}
|
||||
|
||||
StartQueue();
|
||||
return 0;
|
||||
printf("received packet with size %d\n", size);
|
||||
count++;
|
||||
}
|
||||
|
||||
RaiseEvent(pipeline,STOP,0);
|
||||
}};
|
||||
|
||||
int val;
|
||||
WaitEvent(pipeline,STOP,&val);
|
||||
return 0;
|
||||
}
|
||||
26
src/main.h
26
src/main.h
@ -19,33 +19,23 @@
|
||||
// local includes
|
||||
#include "thread_safe.h"
|
||||
|
||||
extern bool display_cursor;
|
||||
|
||||
|
||||
|
||||
|
||||
// namespaces
|
||||
namespace mail {
|
||||
#define MAIL(x) \
|
||||
constexpr auto x = std::string_view { \
|
||||
#x \
|
||||
}
|
||||
#define MAIL(x) constexpr auto x = std::string_view { #x }
|
||||
|
||||
extern safe::mail_t man;
|
||||
|
||||
// Global mail
|
||||
MAIL(shutdown);
|
||||
MAIL(broadcast_shutdown);
|
||||
//queue
|
||||
MAIL(video_packets);
|
||||
MAIL(audio_packets);
|
||||
MAIL(switch_display);
|
||||
|
||||
// Local mail
|
||||
MAIL(touch_port);
|
||||
//event
|
||||
MAIL(shutdown);
|
||||
MAIL(switch_display);
|
||||
MAIL(toggle_cursor);
|
||||
MAIL(idr);
|
||||
MAIL(invalidate_ref_frames);
|
||||
MAIL(gamepad_feedback);
|
||||
MAIL(hdr);
|
||||
MAIL(invalidate_ref_frames);
|
||||
|
||||
#undef MAIL
|
||||
|
||||
} // namespace mail
|
||||
@ -573,6 +573,5 @@ namespace platf {
|
||||
|
||||
typedef deinit_t client_input_t;
|
||||
|
||||
[[nodiscard]] std::unique_ptr<deinit_t>
|
||||
init();
|
||||
bool init();
|
||||
} // namespace platf
|
||||
|
||||
@ -659,13 +659,14 @@ namespace platf {
|
||||
|
||||
if (sources.none()) {
|
||||
BOOST_LOG(error) << "Unable to initialize capture method"sv;
|
||||
return nullptr;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!gladLoaderLoadEGL(EGL_NO_DISPLAY) || !eglGetPlatformDisplay) {
|
||||
BOOST_LOG(warning) << "Couldn't load EGL library"sv;
|
||||
return true;
|
||||
}
|
||||
|
||||
return std::make_unique<deinit_t>();
|
||||
return false;
|
||||
}
|
||||
} // namespace platf
|
||||
|
||||
@ -413,11 +413,8 @@ namespace platf {
|
||||
init();
|
||||
}
|
||||
|
||||
std::unique_ptr<deinit_t>
|
||||
bool
|
||||
init() {
|
||||
if (dxgi::init()) {
|
||||
return nullptr;
|
||||
}
|
||||
return std::make_unique<deinit_t>();
|
||||
return dxgi::init() != 0;
|
||||
}
|
||||
} // namespace platf
|
||||
|
||||
@ -518,6 +518,8 @@ namespace video {
|
||||
safe::mail_raw_t::event_t<bool> shutdown_event;
|
||||
safe::mail_raw_t::queue_t<packet_t> packets;
|
||||
safe::mail_raw_t::event_t<bool> idr_events;
|
||||
safe::mail_raw_t::event_t<int> switch_display;
|
||||
safe::mail_raw_t::event_t<bool> toggle_cursor;
|
||||
safe::mail_raw_t::event_t<hdr_info_t> hdr_events;
|
||||
|
||||
config_t config;
|
||||
@ -534,6 +536,8 @@ namespace video {
|
||||
using encode_e = platf::capture_e;
|
||||
|
||||
struct capture_ctx_t {
|
||||
safe::mail_raw_t::event_t<int> switch_display;
|
||||
safe::mail_raw_t::event_t<bool> toggle_cursor;
|
||||
img_event_t images;
|
||||
config_t config;
|
||||
};
|
||||
@ -1032,7 +1036,6 @@ namespace video {
|
||||
}
|
||||
});
|
||||
|
||||
auto switch_display_event = mail::man->event<int>(mail::switch_display);
|
||||
|
||||
// Get all the monitor names now, rather than at boot, to
|
||||
// get the most up-to-date list available monitors
|
||||
@ -1163,6 +1166,7 @@ namespace video {
|
||||
// Capture takes place on this thread
|
||||
platf::adjust_thread_priority(platf::thread_priority_e::critical);
|
||||
|
||||
bool display_cursor = false;
|
||||
while (capture_ctx_queue->running()) {
|
||||
bool artificial_reinit = false;
|
||||
|
||||
@ -1172,6 +1176,13 @@ namespace video {
|
||||
capture_ctx = capture_ctxs.erase(capture_ctx);
|
||||
|
||||
continue;
|
||||
} else if (capture_ctx->switch_display->peek()) {
|
||||
artificial_reinit = true;
|
||||
|
||||
display_p = std::clamp(*capture_ctx->switch_display->pop(), 0, (int) display_names.size() - 1);
|
||||
return false;
|
||||
} else if (capture_ctx->toggle_cursor->peek()) {
|
||||
display_cursor = capture_ctx->toggle_cursor->pop();
|
||||
}
|
||||
|
||||
if (frame_captured) {
|
||||
@ -1189,13 +1200,6 @@ namespace video {
|
||||
capture_ctxs.emplace_back(std::move(*capture_ctx_queue->pop()));
|
||||
}
|
||||
|
||||
if (switch_display_event->peek()) {
|
||||
artificial_reinit = true;
|
||||
|
||||
display_p = std::clamp(*switch_display_event->pop(), 0, (int) display_names.size() - 1);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
@ -1745,9 +1749,9 @@ namespace video {
|
||||
return;
|
||||
}
|
||||
|
||||
auto shutdown_event = mail->event<bool>(mail::shutdown);
|
||||
auto packets = mail::man->queue<packet_t>(mail::video_packets);
|
||||
auto idr_events = mail->event<bool>(mail::idr);
|
||||
auto shutdown_event = mail->event<bool>(mail::shutdown);
|
||||
auto packets = mail->queue<packet_t>(mail::video_packets);
|
||||
auto idr_events = mail->event<bool>(mail::idr);
|
||||
auto invalidate_ref_frames_events = mail->event<std::pair<int64_t, int64_t>>(mail::invalidate_ref_frames);
|
||||
|
||||
{
|
||||
@ -1891,7 +1895,6 @@ namespace video {
|
||||
|
||||
std::shared_ptr<platf::display_t> disp;
|
||||
|
||||
auto switch_display_event = mail::man->event<int>(mail::switch_display);
|
||||
|
||||
if (synced_session_ctxs.empty()) {
|
||||
auto ctx = encode_session_ctx_queue.pop();
|
||||
@ -1929,6 +1932,7 @@ namespace video {
|
||||
synced_sessions.emplace_back(std::move(*synced_session));
|
||||
}
|
||||
|
||||
bool display_cursor = false;
|
||||
auto ec = platf::capture_e::ok;
|
||||
while (encode_session_ctx_queue.running()) {
|
||||
auto push_captured_image_callback = [&](std::shared_ptr<platf::img_t> &&img, bool frame_captured) -> bool {
|
||||
@ -1965,6 +1969,12 @@ namespace video {
|
||||
}
|
||||
|
||||
continue;
|
||||
} else if (ctx->switch_display->peek()) {
|
||||
ec = platf::capture_e::reinit;
|
||||
display_p = std::clamp(*ctx->switch_display->pop(), 0, (int) display_names.size() - 1);
|
||||
return false;
|
||||
} else if (ctx->toggle_cursor->peek()) {
|
||||
display_cursor = ctx->toggle_cursor->pop();
|
||||
}
|
||||
|
||||
if (ctx->idr_events->peek()) {
|
||||
@ -1997,12 +2007,6 @@ namespace video {
|
||||
++pos;
|
||||
})
|
||||
|
||||
if (switch_display_event->peek()) {
|
||||
ec = platf::capture_e::reinit;
|
||||
|
||||
display_p = std::clamp(*switch_display_event->pop(), 0, (int) display_names.size() - 1);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
@ -2072,7 +2076,10 @@ namespace video {
|
||||
return;
|
||||
}
|
||||
|
||||
ref->capture_ctx_queue->raise(capture_ctx_t { images, config });
|
||||
ref->capture_ctx_queue->raise(capture_ctx_t {
|
||||
mail->event<int>(mail::switch_display),
|
||||
mail->event<bool>(mail::toggle_cursor),
|
||||
images, config });
|
||||
|
||||
if (!ref->capture_ctx_queue->running()) {
|
||||
return;
|
||||
@ -2149,8 +2156,10 @@ namespace video {
|
||||
ref->encode_session_ctx_queue.raise(sync_session_ctx_t {
|
||||
&join_event,
|
||||
mail->event<bool>(mail::shutdown),
|
||||
mail::man->queue<packet_t>(mail::video_packets),
|
||||
mail->queue<packet_t>(mail::video_packets),
|
||||
std::move(idr_events),
|
||||
mail->event<int>(mail::switch_display),
|
||||
mail->event<bool>(mail::toggle_cursor),
|
||||
mail->event<hdr_info_t>(mail::hdr),
|
||||
config,
|
||||
1,
|
||||
@ -2193,7 +2202,8 @@ namespace video {
|
||||
|
||||
session->request_idr_frame();
|
||||
|
||||
auto packets = mail::man->queue<packet_t>(mail::video_packets);
|
||||
auto localmail = std::make_shared<safe::mail_raw_t>();
|
||||
auto packets = localmail->queue<packet_t>(mail::video_packets);
|
||||
while (!packets->peek()) {
|
||||
if (encode(1, *session, packets, nullptr, {})) {
|
||||
return -1;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user