Skip to content

Commit 7a8e57d

Browse files
committed
Add scaling and frame rate divisor
1 parent adf46a6 commit 7a8e57d

File tree

1 file changed

+92
-4
lines changed

1 file changed

+92
-4
lines changed

source-record.c

Lines changed: 92 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -367,17 +367,34 @@ static const char *get_encoder_id(obs_data_t *settings)
367367
return enc_id;
368368
}
369369

370+
static bool (*obs_encoder_set_frame_rate_divisor_func)(obs_encoder_t *, uint32_t) = NULL;
371+
370372
static void update_video_encoder(struct source_record_filter_context *filter, obs_data_t *settings)
371373
{
372374
if (obs_encoder_video(filter->encoder) != filter->video_output) {
373375
if (obs_encoder_active(filter->encoder)) {
374376
obs_encoder_release(filter->encoder);
375377
const char *enc_id = get_encoder_id(settings);
376378
filter->encoder = obs_video_encoder_create(enc_id, obs_source_get_name(filter->source), settings, NULL);
377-
obs_encoder_set_scaled_size(filter->encoder, 0, 0);
378379
}
379380
obs_encoder_set_video(filter->encoder, filter->video_output);
380381
}
382+
uint32_t divisor = (uint32_t)obs_data_get_int(settings, "frame_rate_divisor");
383+
if (divisor > 1 && obs_encoder_set_frame_rate_divisor_func)
384+
obs_encoder_set_frame_rate_divisor_func(filter->encoder, divisor);
385+
bool scale = obs_data_get_bool(settings, "scale");
386+
if (scale) {
387+
uint32_t width = (uint32_t)obs_data_get_int(settings, "width");
388+
uint32_t height = (uint32_t)obs_data_get_int(settings, "height");
389+
if (width > 0 && height > 0) {
390+
obs_encoder_set_scaled_size(filter->encoder, width, height);
391+
} else {
392+
obs_encoder_set_scaled_size(filter->encoder, 0, 0);
393+
}
394+
//obs_encoder_set_gpu_scale_type(filter->encoder, (enum obs_scale_type)obs_data_get_int(settings, "scale_type"));
395+
} else {
396+
obs_encoder_set_scaled_size(filter->encoder, 0, 0);
397+
}
381398
if (filter->fileOutput && obs_output_get_video_encoder(filter->fileOutput) != filter->encoder)
382399
obs_output_set_video_encoder(filter->fileOutput, filter->encoder);
383400
if (filter->streamOutput && obs_output_get_video_encoder(filter->streamOutput) != filter->encoder)
@@ -548,6 +565,21 @@ static void start_replay_output(struct source_record_filter_context *filter, obs
548565
static void source_record_filter_update(void *data, obs_data_t *settings)
549566
{
550567
struct source_record_filter_context *filter = data;
568+
if (obs_data_get_bool(settings, "scale")) {
569+
const char *res = obs_data_get_string(settings, "resolution");
570+
uint32_t width, height;
571+
if (sscanf(res, "%dx%d", &width, &height) == 2 && width > 0 && height > 0) {
572+
obs_data_set_int(settings, "width", width);
573+
obs_data_set_int(settings, "height", height);
574+
} else {
575+
struct dstr str;
576+
dstr_init(&str);
577+
dstr_printf(&str, "%dx%d", (int)obs_data_get_int(settings, "width"),
578+
(int)obs_data_get_int(settings, "height"));
579+
obs_data_set_string(settings, "resolution", str.array);
580+
dstr_free(&str);
581+
}
582+
}
551583
filter->remove_after_record = obs_data_get_bool(settings, "remove_after_record");
552584
filter->record_max_seconds = obs_data_get_int(settings, "record_max_seconds");
553585
const long long record_mode = obs_data_get_int(settings, "record_mode");
@@ -560,8 +592,23 @@ static void source_record_filter_update(void *data, obs_data_t *settings)
560592
obs_encoder_release(filter->encoder);
561593
filter->encoder = obs_video_encoder_create(enc_id, obs_source_get_name(filter->source), settings, NULL);
562594

563-
obs_encoder_set_scaled_size(filter->encoder, 0, 0);
564595
obs_encoder_set_video(filter->encoder, filter->video_output);
596+
uint32_t divisor = (uint32_t)obs_data_get_int(settings, "frame_rate_divisor");
597+
if (divisor > 1 && obs_encoder_set_frame_rate_divisor_func)
598+
obs_encoder_set_frame_rate_divisor_func(filter->encoder, divisor);
599+
bool scale = obs_data_get_bool(settings, "scale");
600+
if (scale) {
601+
uint32_t width = (uint32_t)obs_data_get_int(settings, "width");
602+
uint32_t height = (uint32_t)obs_data_get_int(settings, "height");
603+
if (width > 0 && height > 0) {
604+
obs_encoder_set_scaled_size(filter->encoder, width, height);
605+
} else {
606+
obs_encoder_set_scaled_size(filter->encoder, 0, 0);
607+
}
608+
//obs_encoder_set_gpu_scale_type(filter->encoder, (enum obs_scale_type)obs_data_get_int(settings, "scale_type"));
609+
} else {
610+
obs_encoder_set_scaled_size(filter->encoder, 0, 0);
611+
}
565612
if (filter->fileOutput && obs_output_get_video_encoder(filter->fileOutput) != filter->encoder)
566613
obs_output_set_video_encoder(filter->fileOutput, filter->encoder);
567614
if (filter->streamOutput && obs_output_get_video_encoder(filter->streamOutput) != filter->encoder)
@@ -884,7 +931,9 @@ static void source_record_filter_destroy(void *data)
884931
da_erase_item(source_record_filters, &context->source);
885932
context->closing = true;
886933
if (context->output_active) {
887-
obs_source_dec_showing(obs_filter_get_parent(context->source));
934+
obs_source_t *parent = obs_filter_get_parent(context->source);
935+
if (parent)
936+
obs_source_dec_showing(parent);
888937
context->output_active = false;
889938
}
890939
obs_frontend_remove_event_callback(frontend_event, context);
@@ -1166,14 +1215,43 @@ static obs_properties_t *source_record_filter_properties(void *data)
11661215

11671216
obs_properties_add_group(props, "different_audio", obs_module_text("DifferentAudio"), OBS_GROUP_CHECKABLE, audio);
11681217

1218+
obs_properties_t *scale = obs_properties_create();
1219+
p = obs_properties_add_list(scale, "resolution", obs_module_text("Resolution"), OBS_COMBO_TYPE_EDITABLE,
1220+
OBS_COMBO_FORMAT_STRING);
1221+
1222+
obs_property_list_add_string(p, "640x480", "640x480");
1223+
obs_property_list_add_string(p, "800x600", "800x600");
1224+
obs_property_list_add_string(p, "1280x720", "1280x720");
1225+
obs_property_list_add_string(p, "1920x1080", "1920x1080");
1226+
obs_property_list_add_string(p, "2560x1440", "2560x1440");
1227+
1228+
obs_properties_add_group(props, "scale", obs_module_text("Scale"), OBS_GROUP_CHECKABLE, scale);
1229+
1230+
if (obs_encoder_set_frame_rate_divisor_func) {
1231+
p = obs_properties_add_list(props, "frame_rate_divisor", obs_module_text("FrameRate"), OBS_COMBO_TYPE_LIST,
1232+
OBS_COMBO_FORMAT_INT);
1233+
struct obs_video_info ovi;
1234+
obs_get_video_info(&ovi);
1235+
float fps = ovi.fps_den > 0 ? (float)ovi.fps_num / (float)ovi.fps_den : 0.0f;
1236+
struct dstr str;
1237+
dstr_init(&str);
1238+
dstr_printf(&str, "%.2f fps", fps);
1239+
obs_property_list_add_int(p, str.array, 0);
1240+
for (int i = 2; i <= 10; i++) {
1241+
dstr_printf(&str, "%.2f fps (/%d)", fps / (float)i, i);
1242+
obs_property_list_add_int(p, str.array, i);
1243+
}
1244+
dstr_free(&str);
1245+
}
1246+
11691247
p = obs_properties_add_list(props, "encoder", obs_module_text("Encoder"), OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_STRING);
11701248

11711249
obs_property_list_add_string(p, obs_module_text("Software"), "x264");
11721250
if (EncoderAvailable("obs_qsv11"))
11731251
obs_property_list_add_string(p, obs_module_text("QSV.H264"), "qsv");
11741252
if (EncoderAvailable("obs_qsv11_av1"))
11751253
obs_property_list_add_string(p, obs_module_text("QSV.AV1"), "qsv_av1");
1176-
if (EncoderAvailable("ffmpeg_nvenc"))
1254+
if (EncoderAvailable("ffmpeg_nvenc") || EncoderAvailable("jim_nvenc"))
11771255
obs_property_list_add_string(p, obs_module_text("NVENC.H264"), "nvenc");
11781256
if (EncoderAvailable("jim_av1_nvenc"))
11791257
obs_property_list_add_string(p, obs_module_text("NVENC.AV1"), "nvenc_av1");
@@ -1778,6 +1856,16 @@ bool obs_module_load(void)
17781856
return true;
17791857
}
17801858

1859+
void obs_module_post_load(void)
1860+
{
1861+
void *handle = os_dlopen("obs");
1862+
if (handle) {
1863+
obs_encoder_set_frame_rate_divisor_func =
1864+
(bool (*)(obs_encoder_t *, uint32_t))os_dlsym(handle, "obs_encoder_set_frame_rate_divisor");
1865+
os_dlclose(handle);
1866+
}
1867+
}
1868+
17811869
void obs_module_unload(void)
17821870
{
17831871
da_free(source_record_filters);

0 commit comments

Comments
 (0)