mirror of
https://github.com/thinkonmay/sunshine-sdk.git
synced 2026-08-17 22:30:54 +00:00
parent library
This commit is contained in:
parent
0aa1dabf2f
commit
4b3d8dddf3
@ -5,10 +5,9 @@ add_executable(sunshine ${SUNSHINE_TARGET_FILES})
|
||||
|
||||
|
||||
|
||||
add_executable(parent
|
||||
"${CMAKE_SOURCE_DIR}/src/parent.cpp"
|
||||
"${CMAKE_SOURCE_DIR}/src/interprocess.h"
|
||||
"${CMAKE_SOURCE_DIR}/src/interprocess.cpp"
|
||||
add_library(parent SHARED
|
||||
"${CMAKE_SOURCE_DIR}/lib/interprocess.h"
|
||||
"${CMAKE_SOURCE_DIR}/lib/interprocess.cpp"
|
||||
)
|
||||
set_target_properties(parent PROPERTIES CXX_STANDARD 17)
|
||||
target_link_libraries(parent
|
||||
|
||||
108
lib/interprocess.cpp
Normal file
108
lib/interprocess.cpp
Normal file
@ -0,0 +1,108 @@
|
||||
/**
|
||||
* @file globals.cpp
|
||||
* @brief Implementation for globally accessible variables and functions.
|
||||
*/
|
||||
#include "interprocess.h"
|
||||
|
||||
#include <thread>
|
||||
#include <stdio.h>
|
||||
#include <iostream>
|
||||
|
||||
#include <boost/interprocess/sync/scoped_lock.hpp>
|
||||
#include <boost/interprocess/sync/interprocess_mutex.hpp>
|
||||
#include <boost/interprocess/managed_shared_memory.hpp>
|
||||
|
||||
#include <thread>
|
||||
#include <ctime>
|
||||
#include <unistd.h>
|
||||
|
||||
using namespace boost::interprocess;
|
||||
using namespace std::literals;
|
||||
|
||||
|
||||
typedef struct {
|
||||
Packet audio[QUEUE_SIZE];
|
||||
Packet video[QUEUE_SIZE];
|
||||
int audio_order[QUEUE_SIZE];
|
||||
int video_order[QUEUE_SIZE];
|
||||
|
||||
|
||||
Event events[EVENT_TYPE_MAX];
|
||||
interprocess_mutex lock;
|
||||
}SharedMemoryInternal;
|
||||
|
||||
|
||||
void lock_shared_memory(SharedMemory* memory){
|
||||
SharedMemoryInternal* internal = (SharedMemoryInternal*) memory;
|
||||
internal->lock.lock();
|
||||
}
|
||||
void unlock_shared_memory(SharedMemory* memory){
|
||||
SharedMemoryInternal* internal = (SharedMemoryInternal*) memory;
|
||||
internal->lock.unlock();
|
||||
}
|
||||
|
||||
|
||||
std::string gen_random(const int len) {
|
||||
static const char alphanum[] =
|
||||
"0123456789"
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||
"abcdefghijklmnopqrstuvwxyz";
|
||||
std::string tmp_s;
|
||||
tmp_s.reserve(len);
|
||||
|
||||
for (int i = 0; i < len; ++i) {
|
||||
tmp_s += alphanum[rand() % (sizeof(alphanum) - 1)];
|
||||
}
|
||||
|
||||
return tmp_s;
|
||||
}
|
||||
|
||||
std::string random = gen_random(12);
|
||||
managed_shared_memory segment(create_only, random.c_str(), 2 * sizeof(SharedMemory));
|
||||
|
||||
|
||||
|
||||
void
|
||||
init_shared_memory(SharedMemory* memory){
|
||||
for (int i = 0; i < QUEUE_SIZE; i++) {
|
||||
memory->audio_order[i] = -1;
|
||||
memory->video_order[i] = -1;
|
||||
}
|
||||
|
||||
for (int i = 0; i < EventType::EVENT_TYPE_MAX; i++)
|
||||
memory->events[i].read = 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
deinit_shared_memory() {
|
||||
shared_memory_object::remove(random.c_str());
|
||||
}
|
||||
|
||||
|
||||
SharedMemory*
|
||||
allocate_shared_memory(long long* handle) {
|
||||
//Allocate a portion of the segment (raw memory)
|
||||
std::size_t free_memory = segment.get_free_memory();
|
||||
SharedMemory* memory = (SharedMemory*)segment.allocate(sizeof(SharedMemory));
|
||||
init_shared_memory(memory);
|
||||
|
||||
//Check invariant
|
||||
if(free_memory <= segment.get_free_memory())
|
||||
return NULL;
|
||||
|
||||
//An handle from the base address can identify any byte of the shared
|
||||
//memory segment even if it is mapped in different base addresses
|
||||
managed_shared_memory::handle_t hnd = segment.get_handle_from_address((void*)memory);
|
||||
*handle = hnd;
|
||||
|
||||
// thread_test.join();
|
||||
return memory;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
free_shared_memory(SharedMemory* buffer) {
|
||||
segment.deallocate(buffer);
|
||||
}
|
||||
61
lib/interprocess.h
Normal file
61
lib/interprocess.h
Normal file
@ -0,0 +1,61 @@
|
||||
/**
|
||||
* @file globals.h
|
||||
* @brief Header for globally accessible variables and functions.
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#define QUEUE_SIZE 16
|
||||
#define PACKET_SIZE 32 * 1024
|
||||
|
||||
typedef struct {
|
||||
int is_idr;
|
||||
}VideoMetadata;
|
||||
|
||||
typedef struct {
|
||||
int size;
|
||||
VideoMetadata metadata;
|
||||
char data[PACKET_SIZE];
|
||||
} Packet;
|
||||
|
||||
typedef enum _EventType {
|
||||
POINTER_VISIBLE,
|
||||
CHANGE_BITRATE,
|
||||
CHANGE_FRAMERATE,
|
||||
CHANGE_DISPLAY,
|
||||
IDR_FRAME,
|
||||
|
||||
STOP,
|
||||
HDR_CALLBACK,
|
||||
EVENT_TYPE_MAX
|
||||
} EventType;
|
||||
|
||||
typedef enum _DataType {
|
||||
HDR_INFO,
|
||||
} DataType;
|
||||
|
||||
typedef struct {
|
||||
int value_number;
|
||||
char value_raw[PACKET_SIZE];
|
||||
int data_size;
|
||||
|
||||
DataType type;
|
||||
|
||||
int read;
|
||||
} Event;
|
||||
|
||||
typedef struct {
|
||||
Packet audio[QUEUE_SIZE];
|
||||
Packet video[QUEUE_SIZE];
|
||||
int audio_order[QUEUE_SIZE];
|
||||
int video_order[QUEUE_SIZE];
|
||||
|
||||
|
||||
Event events[EVENT_TYPE_MAX];
|
||||
}SharedMemory;
|
||||
|
||||
|
||||
SharedMemory* allocate_shared_memory(long long* handle) ;
|
||||
void lock_shared_memory(SharedMemory* memory);
|
||||
void unlock_shared_memory(SharedMemory* memory);
|
||||
void free_shared_memory(SharedMemory* buffer);
|
||||
void deinit_shared_memory();
|
||||
@ -1,89 +0,0 @@
|
||||
|
||||
#include <boost/interprocess/managed_shared_memory.hpp>
|
||||
#include <cstdlib> //std::system
|
||||
#include <thread>
|
||||
#include <sstream>
|
||||
|
||||
#include <iostream>
|
||||
#include <thread>
|
||||
|
||||
#include "interprocess.h"
|
||||
|
||||
|
||||
using namespace boost::interprocess;
|
||||
using namespace std::literals;
|
||||
int main (int argc, char *argv[]) {
|
||||
|
||||
//Remove shared memory on construction and destruction
|
||||
struct shm_remove {
|
||||
shm_remove() { shared_memory_object::remove("MySharedMemory"); }
|
||||
~shm_remove(){ shared_memory_object::remove("MySharedMemory"); }
|
||||
} remover;
|
||||
|
||||
//Create a managed shared memory segment
|
||||
managed_shared_memory segment(create_only, "MySharedMemory", 2 * sizeof(SharedMemory));
|
||||
|
||||
//Allocate a portion of the segment (raw memory)
|
||||
std::size_t free_memory = segment.get_free_memory();
|
||||
SharedMemory* memory = (SharedMemory*)segment.allocate(sizeof(SharedMemory));
|
||||
init_shared_memory(memory);
|
||||
|
||||
//Check invariant
|
||||
if(free_memory <= segment.get_free_memory())
|
||||
return 1;
|
||||
|
||||
auto running = true;
|
||||
auto thread = std::thread{[&](){
|
||||
int size;
|
||||
char buffer[PACKET_SIZE] = {0};
|
||||
while (running) {
|
||||
while(peek_audio_packet(memory)) {
|
||||
pop_audio_packet(memory,buffer,&size);
|
||||
std::cout << "Audio buffer received : " << size << "\n";
|
||||
}
|
||||
while(peek_video_packet(memory)) {
|
||||
pop_video_packet(memory,buffer,&size);
|
||||
std::cout << "Video buffer received : " << size << "\n";
|
||||
}
|
||||
std::this_thread::sleep_for(1ms);
|
||||
}
|
||||
}};
|
||||
|
||||
// auto thread_test = std::thread{[&](){
|
||||
// int size = 120;
|
||||
// char buffer[PACKET_SIZE] = {0};
|
||||
// while (running) {
|
||||
// std::this_thread::sleep_for(1ms);
|
||||
// push_audio_packet(memory,buffer,size);
|
||||
// push_video_packet(memory,buffer,size,VideoMetadata{0});
|
||||
// size++;
|
||||
// }
|
||||
// }};
|
||||
|
||||
// while (running)
|
||||
// std::this_thread::sleep_for(1s);
|
||||
|
||||
|
||||
//An handle from the base address can identify any byte of the shared
|
||||
//memory segment even if it is mapped in different base addresses
|
||||
managed_shared_memory::handle_t handle = segment.get_handle_from_address((void*)memory);
|
||||
|
||||
#ifdef _WIN32
|
||||
auto binary = "sunshine.exe";
|
||||
#else
|
||||
auto binary = "./sunshine";
|
||||
#endif
|
||||
|
||||
std::stringstream s; s << binary << " " << handle; s << std::ends;
|
||||
|
||||
//Launch child process
|
||||
if(0 != std::system(s.str().c_str()))
|
||||
return 1;
|
||||
if(free_memory != segment.get_free_memory())
|
||||
return 1;
|
||||
|
||||
running = false;
|
||||
thread.join();
|
||||
// thread_test.join();
|
||||
return 0;
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user