@@ -39,7 +39,29 @@ void settings_reconcile_refresh_rate(app_settings_t *config) {
3939#if defined(TARGET_WEBOS )
4040 int ntsc = settings_ntsc_refresh_rate_x100_for_fps (config -> stream .fps );
4141 if (ntsc > 0 ) {
42- config -> client_refresh_rate_x100 = ntsc ;
42+ if (config -> use_ntsc_refresh ) {
43+ /* Auto NTSC for presets; keep a user Custom FPS fractional rate if present. */
44+ if (config -> client_refresh_rate_x100 == 0 ||
45+ config -> client_refresh_rate_x100 == ntsc ) {
46+ config -> client_refresh_rate_x100 = ntsc ;
47+ return ;
48+ }
49+ int implied = (config -> client_refresh_rate_x100 + 50 ) / 100 ;
50+ if (implied != config -> stream .fps ) {
51+ config -> client_refresh_rate_x100 = ntsc ;
52+ }
53+ return ;
54+ }
55+ /* Integer presets: clear auto-NTSC; keep a distinct Custom FPS fractional rate. */
56+ if (config -> client_refresh_rate_x100 == 0 ||
57+ config -> client_refresh_rate_x100 == ntsc ) {
58+ config -> client_refresh_rate_x100 = 0 ;
59+ return ;
60+ }
61+ int implied = (config -> client_refresh_rate_x100 + 50 ) / 100 ;
62+ if (implied != config -> stream .fps ) {
63+ config -> client_refresh_rate_x100 = 0 ;
64+ }
4365 return ;
4466 }
4567#endif
@@ -77,7 +99,16 @@ int settings_ntsc_refresh_rate_x100_for_fps(int nominal_fps)
7799void settings_apply_ntsc_preset_refresh (app_settings_t * config , int nominal_fps )
78100{
79101#if defined(TARGET_WEBOS )
102+ if (!config ) {
103+ return ;
104+ }
80105 (void ) nominal_fps ;
106+ int ntsc = settings_ntsc_refresh_rate_x100_for_fps (config -> stream .fps );
107+ if (ntsc > 0 ) {
108+ /* Preset selection / NTSC checkbox: force auto NTSC or integer (clears Custom). */
109+ config -> client_refresh_rate_x100 = config -> use_ntsc_refresh ? ntsc : 0 ;
110+ return ;
111+ }
81112 settings_reconcile_refresh_rate (config );
82113#else
83114 (void ) config ;
@@ -128,11 +159,17 @@ void settings_initialize(app_settings_t *config, char *conf_dir) {
128159 config -> hdr = false;
129160 config -> force_full_color_range = false;
130161 config -> hevc = true;
131- config -> idr_refresh_interval_sec = 0 ;
162+ config -> idr_refresh_interval_ms = 0 ;
132163 config -> show_stats_on_start = false;
133164 config -> show_stats_compact = false;
134165 config -> stick_deadzone = 7 ;
135166 config -> client_refresh_rate_x100 = 0 ;
167+ config -> use_ntsc_refresh = false;
168+ #if defined(TARGET_WEBOS )
169+ config -> smooth_frame_pacing = true;
170+ #else
171+ config -> smooth_frame_pacing = false;
172+ #endif
136173 config -> auto_adjust_bitrate = false;
137174 config -> abr_mode = 0 ;
138175
@@ -199,10 +236,12 @@ bool settings_save(app_settings_t *config) {
199236 ini_write_bool (fp , "hdr" , config -> hdr );
200237 ini_write_bool (fp , "force_full_color_range" , config -> force_full_color_range );
201238 ini_write_bool (fp , "hevc" , config -> hevc );
202- ini_write_int (fp , "idr_refresh_interval_sec " , config -> idr_refresh_interval_sec );
239+ ini_write_int (fp , "idr_refresh_interval_ms " , config -> idr_refresh_interval_ms );
203240 ini_write_bool (fp , "show_stats_on_start" , config -> show_stats_on_start );
204241 ini_write_bool (fp , "show_stats_compact" , config -> show_stats_compact );
205242 ini_write_int (fp , "client_refresh_rate_x100" , config -> client_refresh_rate_x100 );
243+ ini_write_bool (fp , "use_ntsc_refresh" , config -> use_ntsc_refresh );
244+ ini_write_bool (fp , "smooth_frame_pacing" , config -> smooth_frame_pacing );
206245
207246 ini_write_section (fp , "audio" );
208247 ini_write_string (fp , "backend" , config -> audio_backend );
@@ -297,14 +336,33 @@ static int settings_parse(app_settings_t *config, const char *section, const cha
297336 if (config -> abr_mode < 0 || config -> abr_mode > 2 ) {
298337 config -> abr_mode = 0 ;
299338 }
339+ } else if (INI_FULL_MATCH ("video" , "idr_refresh_interval_ms" )) {
340+ set_int (& config -> idr_refresh_interval_ms , value );
341+ if (config -> idr_refresh_interval_ms < 0 ) {
342+ config -> idr_refresh_interval_ms = 0 ;
343+ } else if (config -> idr_refresh_interval_ms > 0 && config -> idr_refresh_interval_ms < 500 ) {
344+ config -> idr_refresh_interval_ms = 500 ;
345+ } else if (config -> idr_refresh_interval_ms > 60000 ) {
346+ config -> idr_refresh_interval_ms = 60000 ;
347+ } else if (config -> idr_refresh_interval_ms > 0 ) {
348+ config -> idr_refresh_interval_ms = ((config -> idr_refresh_interval_ms + 250 ) / 500 ) * 500 ;
349+ if (config -> idr_refresh_interval_ms < 500 ) {
350+ config -> idr_refresh_interval_ms = 500 ;
351+ }
352+ }
300353 } else if (INI_FULL_MATCH ("video" , "idr_refresh_interval_sec" )) {
301- set_int (& config -> idr_refresh_interval_sec , value );
302- if (config -> idr_refresh_interval_sec < 0 ) {
303- config -> idr_refresh_interval_sec = 0 ;
304- } else if (config -> idr_refresh_interval_sec > 60 ) {
305- config -> idr_refresh_interval_sec = 60 ;
306- } else if (config -> idr_refresh_interval_sec == 1 ) {
307- config -> idr_refresh_interval_sec = 2 ;
354+ /* Legacy seconds key → milliseconds */
355+ int sec = 0 ;
356+ set_int (& sec , value );
357+ if (sec < 0 ) {
358+ config -> idr_refresh_interval_ms = 0 ;
359+ } else if (sec == 0 ) {
360+ config -> idr_refresh_interval_ms = 0 ;
361+ } else {
362+ if (sec > 60 ) {
363+ sec = 60 ;
364+ }
365+ config -> idr_refresh_interval_ms = sec * 1000 ;
308366 }
309367 } else if (INI_NAME_MATCH ("hevc" )) {
310368 config -> hevc = INI_IS_TRUE (value );
@@ -325,6 +383,10 @@ static int settings_parse(app_settings_t *config, const char *section, const cha
325383 } else if (config -> client_refresh_rate_x100 > 24000 ) {
326384 config -> client_refresh_rate_x100 = 24000 ;
327385 }
386+ } else if (INI_FULL_MATCH ("video" , "use_ntsc_refresh" )) {
387+ config -> use_ntsc_refresh = INI_IS_TRUE (value );
388+ } else if (INI_FULL_MATCH ("video" , "smooth_frame_pacing" )) {
389+ config -> smooth_frame_pacing = INI_IS_TRUE (value );
328390 } else if (INI_FULL_MATCH ("video" , "force_full_color_range" )) {
329391 config -> force_full_color_range = INI_IS_TRUE (value );
330392 } else if (INI_NAME_MATCH ("surround" )) {
0 commit comments