parent library

This commit is contained in:
pigeatgarlic 2024-04-04 07:32:31 -07:00
parent 0aa1dabf2f
commit 4b3d8dddf3
4 changed files with 172 additions and 93 deletions

View File

@ -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
View 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
View 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();

View File

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