@@ -367,17 +367,34 @@ static const char *get_encoder_id(obs_data_t *settings)
367
367
return enc_id ;
368
368
}
369
369
370
+ static bool (* obs_encoder_set_frame_rate_divisor_func )(obs_encoder_t * , uint32_t ) = NULL ;
371
+
370
372
static void update_video_encoder (struct source_record_filter_context * filter , obs_data_t * settings )
371
373
{
372
374
if (obs_encoder_video (filter -> encoder ) != filter -> video_output ) {
373
375
if (obs_encoder_active (filter -> encoder )) {
374
376
obs_encoder_release (filter -> encoder );
375
377
const char * enc_id = get_encoder_id (settings );
376
378
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 );
378
379
}
379
380
obs_encoder_set_video (filter -> encoder , filter -> video_output );
380
381
}
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
+ }
381
398
if (filter -> fileOutput && obs_output_get_video_encoder (filter -> fileOutput ) != filter -> encoder )
382
399
obs_output_set_video_encoder (filter -> fileOutput , filter -> encoder );
383
400
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
548
565
static void source_record_filter_update (void * data , obs_data_t * settings )
549
566
{
550
567
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
+ }
551
583
filter -> remove_after_record = obs_data_get_bool (settings , "remove_after_record" );
552
584
filter -> record_max_seconds = obs_data_get_int (settings , "record_max_seconds" );
553
585
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)
560
592
obs_encoder_release (filter -> encoder );
561
593
filter -> encoder = obs_video_encoder_create (enc_id , obs_source_get_name (filter -> source ), settings , NULL );
562
594
563
- obs_encoder_set_scaled_size (filter -> encoder , 0 , 0 );
564
595
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
+ }
565
612
if (filter -> fileOutput && obs_output_get_video_encoder (filter -> fileOutput ) != filter -> encoder )
566
613
obs_output_set_video_encoder (filter -> fileOutput , filter -> encoder );
567
614
if (filter -> streamOutput && obs_output_get_video_encoder (filter -> streamOutput ) != filter -> encoder )
@@ -884,7 +931,9 @@ static void source_record_filter_destroy(void *data)
884
931
da_erase_item (source_record_filters , & context -> source );
885
932
context -> closing = true;
886
933
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 );
888
937
context -> output_active = false;
889
938
}
890
939
obs_frontend_remove_event_callback (frontend_event , context );
@@ -1166,14 +1215,43 @@ static obs_properties_t *source_record_filter_properties(void *data)
1166
1215
1167
1216
obs_properties_add_group (props , "different_audio" , obs_module_text ("DifferentAudio" ), OBS_GROUP_CHECKABLE , audio );
1168
1217
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
+
1169
1247
p = obs_properties_add_list (props , "encoder" , obs_module_text ("Encoder" ), OBS_COMBO_TYPE_LIST , OBS_COMBO_FORMAT_STRING );
1170
1248
1171
1249
obs_property_list_add_string (p , obs_module_text ("Software" ), "x264" );
1172
1250
if (EncoderAvailable ("obs_qsv11" ))
1173
1251
obs_property_list_add_string (p , obs_module_text ("QSV.H264" ), "qsv" );
1174
1252
if (EncoderAvailable ("obs_qsv11_av1" ))
1175
1253
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" ) )
1177
1255
obs_property_list_add_string (p , obs_module_text ("NVENC.H264" ), "nvenc" );
1178
1256
if (EncoderAvailable ("jim_av1_nvenc" ))
1179
1257
obs_property_list_add_string (p , obs_module_text ("NVENC.AV1" ), "nvenc_av1" );
@@ -1778,6 +1856,16 @@ bool obs_module_load(void)
1778
1856
return true;
1779
1857
}
1780
1858
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
+
1781
1869
void obs_module_unload (void )
1782
1870
{
1783
1871
da_free (source_record_filters );
0 commit comments