@@ -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