diff --git a/src/capture.c b/src/capture.c index f985d69..dc9ca74 100644 --- a/src/capture.c +++ b/src/capture.c @@ -28,6 +28,9 @@ with this program. If not, see #include #include #include +#include +#include +#include static struct { int connfd; @@ -113,6 +116,11 @@ void capture_init() { memset(&data, 0, sizeof(data)); data.connfd = -1; + + if(sem_open(CAPTURE_STATS_SEM, O_CREAT, 0644, 0) == SEM_FAILED) + { + hlog("sem_open error %s", strerror(errno)); + } } void capture_update_socket() diff --git a/src/capture.h b/src/capture.h index d8e4b4d..194b948 100644 --- a/src/capture.h +++ b/src/capture.h @@ -89,6 +89,14 @@ struct capture_control_data { #define CAPTURE_CONTROL_DATA_SIZE 32 static_assert(sizeof(struct capture_control_data) == CAPTURE_CONTROL_DATA_SIZE, "size mismatch"); +struct capture_stats_data +{ + uint32_t time; + uint64_t bytes; +}; +#define CAPTURE_STATS_SHM "/com_obsproject_vkcapture_CaptureStats" +#define CAPTURE_STATS_SEM "/com_obsproject_vkcapture_CaptureStatsSem" + void capture_init(); void capture_update_socket(); void capture_init_shtex( diff --git a/src/vkcapture.c b/src/vkcapture.c index 31e65b7..301b020 100644 --- a/src/vkcapture.c +++ b/src/vkcapture.c @@ -20,6 +20,7 @@ with this program. If not, see #include #include +#include #include #include @@ -33,6 +34,7 @@ with this program. If not, see #include #include #include +#include #include "utils.h" #include "capture.h" @@ -83,6 +85,11 @@ static struct { pthread_mutex_t mutex; DARRAY(struct pollfd) fds; DARRAY(vkcapture_client_t) clients; + bool recording, consumed; + struct obs_output* output; + struct capture_stats_data* sdata; + double time_hires; + sem_t* capture_stats_sem; } server; static int source_instances = 0; @@ -520,10 +527,16 @@ static void vkcapture_source_video_tick(void *data, float seconds) ctx->client_id = client->id; } } + + if(server.recording && server.sdata) + { + server.time_hires += seconds; + server.sdata->time = server.time_hires; + } pthread_mutex_unlock(&server.mutex); - UNUSED_PARAMETER(seconds); + /*UNUSED_PARAMETER(seconds);*/ } static void vkcapture_source_render(void *data, gs_effect_t *effect) @@ -605,6 +618,12 @@ static void vkcapture_source_render(void *data, gs_effect_t *effect) } } + if(server.recording && server.sdata) + { + server.consumed = true; + server.sdata->bytes = obs_output_get_total_bytes(server.output); + /*printf("%lu %u\n", server.sdata->bytes, server.sdata->time);*/ + } gs_enable_framebuffer_srgb(previous); } @@ -713,6 +732,59 @@ static struct obs_source_info vkcapture_input = { .video_get_color_space = vkcapture_get_color_space, }; + +void vkcapture_frontend_event_callback(enum obs_frontend_event event, void* private_data) +{ + switch (event) { + + case OBS_FRONTEND_EVENT_RECORDING_STARTING: + { + /* afaict refs seem to persist */ + if(!server.output) + server.output = obs_frontend_get_recording_output(); + server.recording = true; + server.consumed = false; + server.time_hires = 0; + server.sdata = NULL; + + int fd_shm; + if((fd_shm = shm_open(CAPTURE_STATS_SHM, O_CREAT | O_RDWR, 0666)) < 0) + { + hlog("shm_open error %s", strerror(errno)); + } + if(fd_shm > 0 && ftruncate(fd_shm, sizeof(struct capture_stats_data)) < 0) + { + hlog("ftruncate error %s", strerror(errno)); + } + + if((server.sdata = mmap(NULL, sizeof(struct capture_stats_data), PROT_READ | PROT_WRITE, MAP_SHARED, fd_shm, 0))) + { + memset(server.sdata, 0, sizeof(struct capture_stats_data)); + close(fd_shm); + } + + if((server.capture_stats_sem = sem_open(CAPTURE_STATS_SEM, O_CREAT, 0644, 0)) == SEM_FAILED) + { + hlog("sem_open error %s", strerror(errno)); + } + + sem_post(server.capture_stats_sem); + } + + case OBS_FRONTEND_EVENT_RECORDING_STOPPING: + { + if(server.consumed){ + sem_post(server.capture_stats_sem); + shm_unlink(CAPTURE_STATS_SHM); + server.recording = false; + } + } + + default: + break; + } +} + static bool server_wakeup() { uint64_t q = 1; @@ -945,6 +1017,8 @@ static void *server_thread_run(void *data) return NULL; } + + bool obs_module_load(void) { enum obs_nix_platform_type platform = obs_get_nix_platform(); @@ -968,8 +1042,8 @@ bool obs_module_load(void) blog(LOG_ERROR, "Failed to create thread"); return false; } - pthread_setname_np(server.thread, PLUGIN_NAME); - + pthread_setname_np(server.thread, PLUGIN_NAME); + obs_frontend_add_event_callback(vkcapture_frontend_event_callback, NULL); obs_register_source(&vkcapture_input); blog(LOG_INFO, "plugin loaded successfully (version %s)", PLUGIN_VERSION); @@ -982,7 +1056,7 @@ void obs_module_unload() if (server_wakeup()) { pthread_join(server.thread, NULL); } - + obs_output_release(server.output); blog(LOG_INFO, "plugin unloaded"); }