Skip to content

Commit b2f86fa

Browse files
authored
Integer scale half scaling improvements (#17976)
1 parent 2899bd1 commit b2f86fa

File tree

1 file changed

+63
-24
lines changed

1 file changed

+63
-24
lines changed

gfx/video_driver.c

Lines changed: 63 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -2548,9 +2548,12 @@ void video_viewport_get_scaled_integer(struct video_viewport *vp,
25482548
float underscale_ratio = 0;
25492549
float overscale_ratio = 0;
25502550
uint16_t content_width_ar = content_width;
2551+
uint16_t height_threshold = height * 1.12f;
25512552
uint8_t overscale_w = 0;
25522553
uint8_t overscale_h = 0;
25532554
uint8_t i = 0;
2555+
bool hires_w = false;
2556+
bool hires_h = false;
25542557

25552558
/* Reset width to exact width */
25562559
content_width = (rotation % 2)
@@ -2573,7 +2576,7 @@ void video_viewport_get_scaled_integer(struct video_viewport *vp,
25732576
}
25742577

25752578
if (scaling == VIDEO_SCALE_INTEGER_SCALING_SMART)
2576-
max_scale_h = ((int)(height - content_height * overscale_h) < -(int)(height * 0.20f))
2579+
max_scale_h = ((content_height * overscale_h) > height_threshold)
25772580
? overscale_h - 1
25782581
: overscale_h;
25792582
else if (scaling == VIDEO_SCALE_INTEGER_SCALING_OVERSCALE)
@@ -2601,46 +2604,82 @@ void video_viewport_get_scaled_integer(struct video_viewport *vp,
26012604
else if (i > 1)
26022605
max_scale_w = i - 1;
26032606

2604-
/* Special half width scale for hi-res */
2605-
if ( axis == VIDEO_SCALE_INTEGER_AXIS_Y_XHALF
2606-
|| axis == VIDEO_SCALE_INTEGER_AXIS_YHALF_XHALF
2607-
|| axis == VIDEO_SCALE_INTEGER_AXIS_XHALF)
2608-
{
2609-
float scale_w_ratio = (float)(content_width * max_scale_w) / (float)(content_height * max_scale_h);
2610-
uint8_t hires_w = content_width / 512;
2611-
int content_width_diff = content_width_ar - (content_width / (hires_w + 1));
2612-
2613-
if ( content_width_ar - content_width_diff == (int)content_width / 2
2614-
&& content_width_diff < 20
2615-
&& scale_w_ratio - target_ratio > 0.25f)
2616-
half_w = -1;
2617-
}
2607+
/* Decide hi-res source */
2608+
hires_w = content_width / 512;
2609+
hires_h = content_height / ((rotation % 2) ? 288 : 300);
26182610

26192611
/* Special half height scale for hi-res */
2620-
if ( axis == VIDEO_SCALE_INTEGER_AXIS_YHALF_XHALF
2621-
|| axis == VIDEO_SCALE_INTEGER_AXIS_XHALF)
2612+
if ( (hires_h)
2613+
&& (axis == VIDEO_SCALE_INTEGER_AXIS_YHALF_XHALF)
2614+
&& (scaling != VIDEO_SCALE_INTEGER_SCALING_UNDERSCALE))
26222615
{
26232616
if ( max_scale_h == (height / content_height)
2624-
&& content_height / ((rotation % 2) ? 288 : 300)
26252617
&& content_height * max_scale_h < height * 0.90f
2618+
&& content_height * (max_scale_h + 0.5f) < height_threshold
26262619
)
2620+
half_h = 1;
2621+
}
2622+
2623+
/* Special half width scale for hi-res */
2624+
if ( (hires_w || hires_h)
2625+
&& ( axis == VIDEO_SCALE_INTEGER_AXIS_Y_XHALF
2626+
|| axis == VIDEO_SCALE_INTEGER_AXIS_YHALF_XHALF
2627+
|| axis == VIDEO_SCALE_INTEGER_AXIS_XHALF))
2628+
{
2629+
float diff = 1.0f;
2630+
uint8_t mode = 0;
2631+
2632+
/* Reset current target ratio for stable width matching */
2633+
if (!hires_w && half_h)
2634+
target_ratio = (float)(content_width * max_scale_w) / (float)(content_height * max_scale_h);
2635+
2636+
/* Find the nearest ratio */
2637+
for (i = 0; i < 4; i++)
26272638
{
2628-
float halfstep_prev_ratio = (float)(content_width * max_scale_w) / (float)(content_height * max_scale_h);
2629-
float halfstep_next_ratio = (float)(content_width * max_scale_w) / (float)(content_height * (max_scale_h + 0.5f));
2639+
float diff_mode = content_width;
2640+
2641+
/* Skip half scales with lo-res width */
2642+
if (!hires_w && !(i % 2))
2643+
continue;
26302644

2631-
if (content_height * (max_scale_h + 0.5f) < height * 1.12f)
2645+
switch (i)
26322646
{
2633-
half_h = 1;
2647+
case 0: diff_mode *= (max_scale_w - 0.5f); break;
2648+
case 1: diff_mode *= (max_scale_w); break;
2649+
case 2: diff_mode *= (max_scale_w + 0.5f); break;
2650+
case 3: diff_mode *= (max_scale_w + 1.0f); break;
2651+
}
2652+
2653+
diff_mode /= (content_height * (max_scale_h + (half_h * 0.5f)));
2654+
diff_mode = fabsf(diff_mode - target_ratio);
26342655

2635-
if (halfstep_next_ratio - target_ratio <= target_ratio - halfstep_prev_ratio)
2636-
half_w = 1;
2656+
if (diff_mode <= diff)
2657+
{
2658+
diff = diff_mode;
2659+
mode = i;
26372660
}
26382661
}
2662+
2663+
switch (mode)
2664+
{
2665+
case 0: half_w = -1; break;
2666+
case 1: half_w = 0; break;
2667+
case 2: half_w = 1; break;
2668+
case 3: half_w = 2; break;
2669+
}
26392670
}
26402671
}
26412672

26422673
padding_x = width - content_width * (max_scale_w + (half_w * 0.5f));
26432674
padding_y = height - content_height * (max_scale_h + (half_h * 0.5f));
2675+
2676+
/* Use regular scaling if overscale is unreasonable */
2677+
if ( padding_x <= (int)-video_st->av_info.geometry.base_width
2678+
|| padding_y <= (int)-video_st->av_info.geometry.base_height)
2679+
{
2680+
video_viewport_get_scaled_aspect(vp, width, height, y_down);
2681+
return;
2682+
}
26442683
}
26452684
else
26462685
{

0 commit comments

Comments
 (0)