remove all global var

This commit is contained in:
pigeatgarlic 2023-10-28 00:14:35 +07:00
parent 1a0a3f9105
commit 1262ee2706
8 changed files with 200 additions and 222 deletions

View File

@ -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)

View File

@ -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);
}

View File

@ -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;
}

View File

@ -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

View File

@ -573,6 +573,5 @@ namespace platf {
typedef deinit_t client_input_t;
[[nodiscard]] std::unique_ptr<deinit_t>
init();
bool init();
} // namespace platf

View File

@ -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

View File

@ -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

View File

@ -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;