#include #include #include "shared-memory-queue.h" struct virtualcam_data { obs_output_t *output; video_queue_t *vq; }; static const char *virtualcam_name(void *unused) { UNUSED_PARAMETER(unused); return "Virtual Camera Output"; } static void virtualcam_destroy(void *data) { struct virtualcam_data *vcam = (struct virtualcam_data *)data; video_queue_close(vcam->vq); bfree(data); } static void *virtualcam_create(obs_data_t *settings, obs_output_t *output) { struct virtualcam_data *vcam = (struct virtualcam_data *)bzalloc(sizeof(*vcam)); vcam->output = output; UNUSED_PARAMETER(settings); return vcam; } static bool virtualcam_start(void *data) { struct virtualcam_data *vcam = (struct virtualcam_data *)data; uint32_t width = obs_output_get_width(vcam->output); uint32_t height = obs_output_get_height(vcam->output); struct obs_video_info ovi; obs_get_video_info(&ovi); uint64_t interval = ovi.fps_den * 10000000ULL / ovi.fps_num; char res[64]; snprintf(res, sizeof(res), "%dx%dx%lld", (int)width, (int)height, (long long)interval); char *res_file = os_get_config_path_ptr("obs-virtualcam.txt"); os_quick_write_utf8_file_safe(res_file, res, strlen(res), false, "tmp", NULL); bfree(res_file); vcam->vq = video_queue_create(width, height, interval); if (!vcam->vq) { blog(LOG_WARNING, "starting virtual-output failed"); return false; } struct video_scale_info vsi = {0}; vsi.format = VIDEO_FORMAT_NV12; vsi.width = width; vsi.height = height; obs_output_set_video_conversion(vcam->output, &vsi); blog(LOG_INFO, "Virtual output started"); obs_output_begin_data_capture(vcam->output, 0); return true; } static void virtualcam_stop(void *data, uint64_t ts) { struct virtualcam_data *vcam = (struct virtualcam_data *)data; obs_output_end_data_capture(vcam->output); video_queue_close(vcam->vq); vcam->vq = NULL; blog(LOG_INFO, "Virtual output stopped"); UNUSED_PARAMETER(ts); } static void virtual_video(void *param, struct video_data *frame) { struct virtualcam_data *vcam = (struct virtualcam_data *)param; if (!vcam->vq) return; video_queue_write(vcam->vq, frame->data, frame->linesize, frame->timestamp); } struct obs_output_info virtualcam_info = { .id = "virtualcam_output", .flags = OBS_OUTPUT_VIDEO, .get_name = virtualcam_name, .create = virtualcam_create, .destroy = virtualcam_destroy, .start = virtualcam_start, .stop = virtualcam_stop, .raw_video = virtual_video, };