diff --git a/smemory.h b/smemory.h index 15afd971..c1ba3be5 100644 --- a/smemory.h +++ b/smemory.h @@ -1,4 +1,7 @@ -#define QUEUE_SIZE 64 +#define OUT_QUEUE_SIZE 8 +#define IN_QUEUE_SIZE 8 + +#define TAG_SIZE 8192 #define PACKET_SIZE 5 * 1024 * 1024 typedef struct { @@ -21,9 +24,20 @@ typedef struct { typedef struct _Queue{ int inindex; int outindex; - void* handle; - QueueMetadata metadata; + Packet incoming[IN_QUEUE_SIZE]; + Packet outgoing[OUT_QUEUE_SIZE]; +}Queue; - Packet incoming[QUEUE_SIZE]; - Packet outcoming[QUEUE_SIZE]; -}Queue; \ No newline at end of file +typedef struct _DisplayQueue{ + Queue internal; + QueueMetadata metadata; +}DisplayQueue; + +typedef struct _Memory { + DisplayQueue video; + Queue audio; + Queue data; + + + char worker_info[TAG_SIZE]; +}Memory; \ No newline at end of file diff --git a/src/interprocess.cpp b/src/interprocess.cpp index 0441f60d..56ef5257 100644 --- a/src/interprocess.cpp +++ b/src/interprocess.cpp @@ -30,7 +30,6 @@ IVSHMEM::IVSHMEM() : m_initialized(false), m_handle(INVALID_HANDLE_VALUE), m_gotSize(false), - m_gotPeerID(false), m_gotMemory(false) { @@ -112,7 +111,7 @@ void IVSHMEM::DeInitialize() if (m_gotMemory) { if (!DeviceIoControl(m_handle, IOCTL_IVSHMEM_RELEASE_MMAP, NULL, 0, NULL, 0, NULL, NULL)) - printf("DeviceIoControl failed: %d", (int)GetLastError()); + printf("Deintialize DeviceIoControl failed: %d", (int)GetLastError()); m_memory = NULL; } @@ -122,7 +121,6 @@ void IVSHMEM::DeInitialize() m_initialized = false; m_handle = INVALID_HANDLE_VALUE; m_gotSize = false; - m_gotPeerID = false; m_gotMemory = false; } @@ -142,7 +140,7 @@ UINT64 IVSHMEM::GetSize() IVSHMEM_SIZE size; if (!DeviceIoControl(m_handle, IOCTL_IVSHMEM_REQUEST_SIZE, NULL, 0, &size, sizeof(IVSHMEM_SIZE), NULL, NULL)) { - printf("DeviceIoControl Failed: %d", (int)GetLastError()); + printf("GetSize DeviceIoControl Failed: %d", (int)GetLastError()); return 0; } @@ -151,25 +149,7 @@ UINT64 IVSHMEM::GetSize() return m_size; } -UINT16 IVSHMEM::GetPeerID() -{ - if (!m_initialized) - return 0; - if (m_gotPeerID) - return m_peerID; - - IVSHMEM_PEERID peerID; - if (!DeviceIoControl(m_handle, IOCTL_IVSHMEM_REQUEST_SIZE, NULL, 0, &peerID, sizeof(IVSHMEM_PEERID), NULL, NULL)) - { - printf("DeviceIoControl Failed: %d", (int)GetLastError()); - return 0; - } - - m_gotPeerID = true; - m_peerID = static_cast(peerID); - return m_peerID; -} void * IVSHMEM::GetMemory() @@ -201,15 +181,13 @@ void * IVSHMEM::GetMemory() &map , sizeof(IVSHMEM_MMAP ), NULL, NULL)) { - printf("DeviceIoControl Failed: %d", (int)GetLastError()); + printf("GetMemory DeviceIoControl Failed: %d", (int)GetLastError()); return NULL; } m_gotSize = true; - m_gotPeerID = true; m_gotMemory = true; m_size = static_cast(map.size ); - m_peerID = static_cast(map.peerID ); m_memory = map.ptr; return m_memory; diff --git a/src/interprocess.h b/src/interprocess.h index 27634a6f..dbc40219 100644 --- a/src/interprocess.h +++ b/src/interprocess.h @@ -110,7 +110,6 @@ public: bool IsInitialized(); UINT64 GetSize(); - UINT16 GetPeerID(); void * GetMemory(); HANDLE getHandle(); @@ -122,6 +121,5 @@ private: bool m_initialized; HANDLE m_handle; UINT64 m_size ; bool m_gotSize ; - UINT16 m_peerID ; bool m_gotPeerID; void * m_memory ; bool m_gotMemory; }; diff --git a/src/main.cpp b/src/main.cpp index d110ea44..6948e85a 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -137,71 +137,64 @@ main(int argc, char *argv[]) { ivshmem->DeInitialize(); }); - int queuetype = QueueType::Video; - std::stringstream ss0; ss0 << argv[1]; - std::string target; ss0 >> target; - if (target == "audio") - queuetype = QueueType::Audio; - int codec = 0; - if (argc == 3) { - std::stringstream ss1; ss1 << argv[2]; - std::string codecs; ss1 >> codecs; - if (codecs == "h265") - codec = 1; - else if (codecs == "av1") - codec = 2; - } + std::stringstream ss1; ss1 << argv[1]; + std::string codecs; ss1 >> codecs; + if (codecs == "h265") + codec = 1; + else if (codecs == "av1") + codec = 2; - if(queuetype == QueueType::Video) { -#ifdef _WIN32 - // Modify relevant NVIDIA control panel settings if the system has corresponding gpu - if (nvprefs_instance.load()) { - // Restore global settings to the undo file left by improper termination of sunshine.exe - nvprefs_instance.restore_from_and_delete_undo_file_if_exists(); - // Modify application settings for sunshine.exe - nvprefs_instance.modify_application_profile(); - // Modify global settings, undo file is produced in the process to restore after improper termination - nvprefs_instance.modify_global_profile(); - // Unload dynamic library to survive driver re-installation - nvprefs_instance.unload(); - } - - // Wait as long as possible to terminate Sunshine.exe during logoff/shutdown - SetProcessShutdownParameters(0x100, SHUTDOWN_NORETRY); - - // We must create a hidden window to receive shutdown notifications since we load gdi32.dll - std::promise session_monitor_hwnd_promise; - auto session_monitor_hwnd_future = session_monitor_hwnd_promise.get_future(); - std::promise session_monitor_join_thread_promise; - auto session_monitor_join_thread_future = session_monitor_join_thread_promise.get_future(); -#endif + // Modify relevant NVIDIA control panel settings if the system has corresponding gpu + if (nvprefs_instance.load()) { + // Restore global settings to the undo file left by improper termination of sunshine.exe + nvprefs_instance.restore_from_and_delete_undo_file_if_exists(); + // Modify application settings for sunshine.exe + nvprefs_instance.modify_application_profile(); + // Modify global settings, undo file is produced in the process to restore after improper termination + nvprefs_instance.modify_global_profile(); + // Unload dynamic library to survive driver re-installation + nvprefs_instance.unload(); } + // Wait as long as possible to terminate Sunshine.exe during logoff/shutdown + SetProcessShutdownParameters(0x100, SHUTDOWN_NORETRY); + + // We must create a hidden window to receive shutdown notifications since we load gdi32.dll + std::promise session_monitor_hwnd_promise; + auto session_monitor_hwnd_future = session_monitor_hwnd_promise.get_future(); + std::promise session_monitor_join_thread_promise; + auto session_monitor_join_thread_future = session_monitor_join_thread_promise.get_future(); + auto platf_deinit_guard = platf::init(); - if (ivshmem->GetSize() != (UINT64)sizeof(Queue)) { - BOOST_LOG(error) << "Invalid ivshmem size: "sv << ivshmem->GetSize(); + Memory* memory = NULL; + if (ivshmem->GetSize() < (UINT64)sizeof(Memory)) { + BOOST_LOG(error) << "Invalid ivshmem size: "sv << ivshmem->GetSize(); + BOOST_LOG(error) << "Expected ivshmem size: "sv << sizeof(Memory); + memory = (Memory*)malloc(sizeof(Memory)); + } else { + BOOST_LOG(info) << "Found ivshmem shared memory"sv; + memory = (Memory*)ivshmem->GetMemory(); + } + + if (memory == NULL) { + BOOST_LOG(error) << "Failed to allocate shared memory"sv; return StatusCode::INVALID_IVSHMEM; } - auto queue = (Queue*)ivshmem->GetMemory(); if (!platf_deinit_guard) { BOOST_LOG(error) << "Platform failed to initialize"sv; return StatusCode::NO_ENCODER_AVAILABLE; - } else if(queuetype == QueueType::Video && video::probe_encoders()) { + } else if(video::probe_encoders()) { BOOST_LOG(error) << "Video failed to find working encoder"sv; return StatusCode::NO_ENCODER_AVAILABLE; - } else if (queue == nullptr) { - BOOST_LOG(error) << "Failed to find shared memory"sv; - queue = (Queue*)malloc(sizeof(Queue)); } - memset(queue,0,sizeof(Queue)); auto video_capture = [&](safe::mail_t mail, std::string displayin,int codec){ video::capture(mail,video::config_t{ displayin, 1920, 1080, 60, 6000, 1, 0, 1, codec, 0 @@ -218,7 +211,7 @@ main(int argc, char *argv[]) { auto mail = std::make_shared(); - auto pull = [process_shutdown_event,queue,mail](){ + auto pull = [process_shutdown_event,mail](Queue* queue){ auto timer = platf::create_high_precision_timer(); auto local_shutdown= mail->event(mail::shutdown); auto bitrate = mail->event(mail::bitrate); @@ -233,12 +226,12 @@ main(int argc, char *argv[]) { timer->sleep_for(1ms); memcpy(buffer, - queue->outcoming[expected_index].data, - queue->outcoming[expected_index].size + queue->outgoing[expected_index].data, + queue->outgoing[expected_index].size ); expected_index++; - if (expected_index >= QUEUE_SIZE) + if (expected_index >= OUT_QUEUE_SIZE) expected_index = 0; switch (buffer[0]) { @@ -281,7 +274,7 @@ main(int argc, char *argv[]) { }; - auto push = [process_shutdown_event](safe::mail_t mail, Queue* queue, QueueType queue_type){ + auto push_video = [process_shutdown_event](safe::mail_t mail, Queue* queue){ auto video_packets = mail->queue(mail::video_packets); auto audio_packets = mail->queue(mail::audio_packets); auto local_shutdown= mail->event(mail::shutdown); @@ -294,54 +287,70 @@ main(int argc, char *argv[]) { uint32_t findex = 0; while (!process_shutdown_event->peek() && !local_shutdown->peek()) { - if (queue_type == QueueType::Video) { - do { - auto packet = video_packets->pop(); - char* ptr = (char*)packet->data(); - size_t size = packet->data_size(); - uint64_t utimestamp = packet->frame_timestamp.value().time_since_epoch().count(); + do { + auto packet = video_packets->pop(); + char* ptr = (char*)packet->data(); + size_t size = packet->data_size(); + uint64_t utimestamp = packet->frame_timestamp.value().time_since_epoch().count(); - auto updated = queue->inindex + 1; - if (updated >= QUEUE_SIZE) - updated = 0; + auto updated = queue->inindex + 1; + if (updated >= IN_QUEUE_SIZE) + updated = 0; - findex++; - uint16_t sum = 0; - queue->incoming[updated].size = 0; - copy_to_packet(&queue->incoming[updated],&findex,sizeof(uint32_t)); - copy_to_packet(&queue->incoming[updated],&utimestamp,sizeof(uint64_t)); - copy_to_packet(&queue->incoming[updated],&sum,sizeof(uint16_t)); - copy_to_packet(&queue->incoming[updated],ptr,size); - queue->inindex = updated; - } while (video_packets->peek()); - } else if (queue_type == QueueType::Audio) { - do { - auto packet = audio_packets->pop(); - char* ptr = (char*)packet->second.begin(); - size_t size = packet->second.size(); - uint64_t utimestamp = std::chrono::steady_clock::now().time_since_epoch().count(); - - auto updated = queue->inindex + 1; - if (updated >= QUEUE_SIZE) - updated = 0; - - findex++; - uint16_t sum = 0; - queue->incoming[updated].size = 0; - copy_to_packet(&queue->incoming[updated],&findex,sizeof(uint32_t)); - copy_to_packet(&queue->incoming[updated],&utimestamp,sizeof(uint64_t)); - copy_to_packet(&queue->incoming[updated],&sum,sizeof(uint16_t)); - copy_to_packet(&queue->incoming[updated],ptr,size); - queue->inindex = updated; - } while (audio_packets->peek()); - } + findex++; + uint16_t sum = 0; + queue->incoming[updated].size = 0; + copy_to_packet(&queue->incoming[updated],&findex,sizeof(uint32_t)); + copy_to_packet(&queue->incoming[updated],&utimestamp,sizeof(uint64_t)); + copy_to_packet(&queue->incoming[updated],&sum,sizeof(uint16_t)); + copy_to_packet(&queue->incoming[updated],ptr,size); + queue->inindex = updated; + } while (video_packets->peek()); } if (!local_shutdown->peek()) local_shutdown->raise(true); }; - auto touch_fun = [mail,process_shutdown_event](Queue* queue){ + auto push_audio = [process_shutdown_event](safe::mail_t mail, Queue* queue){ + auto video_packets = mail->queue(mail::video_packets); + auto audio_packets = mail->queue(mail::audio_packets); + auto local_shutdown= mail->event(mail::shutdown); + auto touch_port = mail->event(mail::touch_port); + + +#ifdef _WIN32 + platf::adjust_thread_priority(platf::thread_priority_e::critical); +#endif + + uint32_t findex = 0; + while (!process_shutdown_event->peek() && !local_shutdown->peek()) { + do { + auto packet = audio_packets->pop(); + char* ptr = (char*)packet->second.begin(); + size_t size = packet->second.size(); + uint64_t utimestamp = std::chrono::steady_clock::now().time_since_epoch().count(); + + auto updated = queue->inindex + 1; + if (updated >= IN_QUEUE_SIZE) + updated = 0; + + findex++; + uint16_t sum = 0; + queue->incoming[updated].size = 0; + copy_to_packet(&queue->incoming[updated],&findex,sizeof(uint32_t)); + copy_to_packet(&queue->incoming[updated],&utimestamp,sizeof(uint64_t)); + copy_to_packet(&queue->incoming[updated],&sum,sizeof(uint16_t)); + copy_to_packet(&queue->incoming[updated],ptr,size); + queue->inindex = updated; + } while (audio_packets->peek()); + } + + if (!local_shutdown->peek()) + local_shutdown->raise(true); + }; + + auto touch_fun = [mail,process_shutdown_event](DisplayQueue* queue){ auto timer = platf::create_high_precision_timer(); auto local_shutdown= mail->event(mail::shutdown); auto touch_port = mail->event(mail::touch_port); @@ -371,19 +380,20 @@ main(int argc, char *argv[]) { }; - BOOST_LOG(info) << "Starting capture on channel " << queuetype; - if (queuetype == QueueType::Video) { - auto capture = std::thread{video_capture,mail,target,codec}; - auto forward = std::thread{push,mail,queue,(QueueType)queuetype}; - auto touch_thread = std::thread{touch_fun,queue}; - auto receive = std::thread{pull}; + { + auto capture = std::thread{video_capture,mail,"TODO",codec}; + auto forward = std::thread{push_video,mail,&memory->video.internal}; + auto touch_thread = std::thread{touch_fun,&memory->video}; + auto receive = std::thread{pull,&memory->video.internal}; receive.detach(); touch_thread.detach(); capture.detach(); forward.detach(); - } else if (queuetype == QueueType::Audio) { + } + + { auto capture = std::thread{audio_capture,mail}; - auto forward = std::thread{push,mail,queue,(QueueType)queuetype}; + auto forward = std::thread{push_audio,mail,&memory->audio}; capture.detach(); forward.detach(); } diff --git a/third-party/Simple-Web-Server b/third-party/Simple-Web-Server new file mode 160000 index 00000000..187f798d --- /dev/null +++ b/third-party/Simple-Web-Server @@ -0,0 +1 @@ +Subproject commit 187f798d54a9c6cee742f2eb2c54e9ba26f5a385 diff --git a/third-party/ViGEmClient b/third-party/ViGEmClient new file mode 160000 index 00000000..8d71f674 --- /dev/null +++ b/third-party/ViGEmClient @@ -0,0 +1 @@ +Subproject commit 8d71f6740ffff4671cdadbca255ce528e3cd3fef diff --git a/third-party/doxyconfig b/third-party/doxyconfig new file mode 160000 index 00000000..a73f908f --- /dev/null +++ b/third-party/doxyconfig @@ -0,0 +1 @@ +Subproject commit a73f908fb70fac4f6076a28f0a751239ea5ac2d3 diff --git a/third-party/googletest b/third-party/googletest new file mode 160000 index 00000000..52eb8108 --- /dev/null +++ b/third-party/googletest @@ -0,0 +1 @@ +Subproject commit 52eb8108c5bdec04579160ae17225d66034bd723 diff --git a/third-party/inputtino b/third-party/inputtino new file mode 160000 index 00000000..83cf70ef --- /dev/null +++ b/third-party/inputtino @@ -0,0 +1 @@ +Subproject commit 83cf70ef33196a2a022671ccf8a686fc8f67ae8e diff --git a/third-party/libdisplaydevice b/third-party/libdisplaydevice new file mode 160000 index 00000000..f31e46d8 --- /dev/null +++ b/third-party/libdisplaydevice @@ -0,0 +1 @@ +Subproject commit f31e46d8736fa6932d34c1417111e60ca507b29f diff --git a/third-party/moonlight-common-c b/third-party/moonlight-common-c new file mode 160000 index 00000000..5f228018 --- /dev/null +++ b/third-party/moonlight-common-c @@ -0,0 +1 @@ +Subproject commit 5f2280183cb62cba1052894d76e64e5f4153377d diff --git a/third-party/nanors b/third-party/nanors new file mode 160000 index 00000000..19f07b51 --- /dev/null +++ b/third-party/nanors @@ -0,0 +1 @@ +Subproject commit 19f07b513e924e471cadd141943c1ec4adc8d0e0 diff --git a/third-party/tray b/third-party/tray new file mode 160000 index 00000000..0309a7cb --- /dev/null +++ b/third-party/tray @@ -0,0 +1 @@ +Subproject commit 0309a7cb84aad25079b60c40d1eae0bacd05b26d