[x264-devel] commit: Really fix fittobox resize rounding code (Anton Mitrofanov )
git at videolan.org
git at videolan.org
Tue Dec 7 09:15:48 CET 2010
x264 | branch: master | Anton Mitrofanov <BugMaster at narod.ru> | Sat Nov 27 15:54:39 2010 -0800| [f6482d8c07754c8703a090a5bd8d1683179b65e2] | committer: Jason Garrett-Glaser
Really fix fittobox resize rounding code
> http://git.videolan.org/gitweb.cgi/x264.git/?a=commit;h=f6482d8c07754c8703a090a5bd8d1683179b65e2
---
filters/video/resize.c | 78 +++++++++++++++++++++---------------------------
1 files changed, 34 insertions(+), 44 deletions(-)
diff --git a/filters/video/resize.c b/filters/video/resize.c
index aec53e1..48f22cf 100644
--- a/filters/video/resize.c
+++ b/filters/video/resize.c
@@ -203,14 +203,6 @@ static int pick_closest_supported_csp( int csp )
}
}
-static int round_dbl( double val, int precision, int b_truncate )
-{
- if( b_truncate )
- return trunc(val / precision) * precision;
- else
- return round(val / precision) * precision;
-}
-
static int handle_opts( const char **optlist, char **opts, video_info_t *info, resizer_hnd_t *h )
{
uint32_t out_sar_w, out_sar_h;
@@ -266,56 +258,48 @@ static int handle_opts( const char **optlist, char **opts, video_info_t *info, r
if( fittobox )
{
/* resize the video to fit the box as much as possible */
- double box_width = width;
- double box_height = height;
if( !strcasecmp( fittobox, "both" ) )
{
- FAIL_IF_ERROR( box_width <= 0 || box_height <= 0, "invalid box resolution %sx%s\n",
- x264_otos( str_width, "unset" ), x264_otos( str_height, "unset" ) )
+ FAIL_IF_ERROR( width <= 0 || height <= 0, "invalid box resolution %sx%s\n",
+ x264_otos( str_width, "<unset>" ), x264_otos( str_height, "<unset>" ) )
}
else if( !strcasecmp( fittobox, "width" ) )
{
- FAIL_IF_ERROR( box_width <= 0, "invalid box width `%s'\n", x264_otos( str_width, "unset" ) )
- box_height = INT_MAX;
+ FAIL_IF_ERROR( width <= 0, "invalid box width `%s'\n", x264_otos( str_width, "<unset>" ) )
+ height = INT_MAX;
}
else if( !strcasecmp( fittobox, "height" ) )
{
- FAIL_IF_ERROR( box_height <= 0, "invalid box height `%s'\n", x264_otos( str_height, "unset" ) )
- box_width = INT_MAX;
+ FAIL_IF_ERROR( height <= 0, "invalid box height `%s'\n", x264_otos( str_height, "<unset>" ) )
+ width = INT_MAX;
}
else FAIL_IF_ERROR( 1, "invalid fittobox mode `%s'\n", fittobox )
- /* we now have the requested bounding box display dimensions, now adjust them for output sar */
- if( out_sar_w > out_sar_h ) // SAR is wide, decrease width
- box_width *= (double)out_sar_h / out_sar_w;
- else // SAR is thin, decrease height
- box_height *= (double)out_sar_w / out_sar_h;
-
- /* get the display resolution of the clip as it is now */
- double d_width = info->width;
- double d_height = info->height;
- if( in_sar_w > in_sar_h )
- d_width *= (double)in_sar_w / in_sar_h;
- else
- d_height *= (double)in_sar_h / in_sar_w;
- /* now convert it to the coded resolution in accordance with the output sar */
- if( out_sar_w > out_sar_h )
- d_width *= (double)out_sar_h / out_sar_w;
- else
- d_height *= (double)out_sar_w / out_sar_h;
-
/* maximally fit the new coded resolution to the box */
- double scale = X264_MIN( box_width / d_width, box_height / d_height );
const x264_cli_csp_t *csp = x264_cli_get_csp( h->dst_csp );
- width = round_dbl( scale * d_width, csp->mod_width, 1 );
- height = round_dbl( scale * d_height, csp->mod_height, 1 );
+ double width_units = (double)info->height * in_sar_h * out_sar_w;
+ double height_units = (double)info->width * in_sar_w * out_sar_h;
+ width = width / csp->mod_width * csp->mod_width;
+ height = height / csp->mod_height * csp->mod_height;
+ if( width * width_units > height * height_units )
+ {
+ int new_width = round( height * height_units / (width_units * csp->mod_width) );
+ new_width *= csp->mod_width;
+ width = X264_MIN( new_width, width );
+ }
+ else
+ {
+ int new_height = round( width * width_units / (height_units * csp->mod_height) );
+ new_height *= csp->mod_height;
+ height = X264_MIN( new_height, height );
+ }
}
else
{
if( str_width || str_height )
{
FAIL_IF_ERROR( width <= 0 || height <= 0, "invalid resolution %sx%s\n",
- x264_otos( str_width, "unset" ), x264_otos( str_height, "unset" ) )
+ x264_otos( str_width, "<unset>" ), x264_otos( str_height, "<unset>" ) )
if( !str_sar ) /* res only -> adjust sar */
{
/* new_sar = (new_h * old_w * old_sar_w) / (old_h * new_w * old_sar_h) */
@@ -330,14 +314,20 @@ static int handle_opts( const char **optlist, char **opts, video_info_t *info, r
else if( str_sar ) /* sar only -> adjust res */
{
const x264_cli_csp_t *csp = x264_cli_get_csp( h->dst_csp );
+ double width_units = (double)in_sar_h * out_sar_w;
+ double height_units = (double)in_sar_w * out_sar_h;
width = info->width;
height = info->height;
- if( (out_sar_w * in_sar_h) > (out_sar_h * in_sar_w) ) // SAR got wider, decrease width
- width = round_dbl( (double)info->width * in_sar_w * out_sar_h
- / in_sar_h / out_sar_w, csp->mod_width, 0 );
+ if( width_units > height_units ) // SAR got wider, decrease width
+ {
+ width = round( info->width * height_units / (width_units * csp->mod_width) );
+ width *= csp->mod_width;
+ }
else // SAR got thinner, decrease height
- height = round_dbl( (double)info->height * in_sar_h * out_sar_w
- / in_sar_w / out_sar_h, csp->mod_height, 0 );
+ {
+ height = round( info->height * width_units / (height_units * csp->mod_height) );
+ height *= csp->mod_height;
+ }
}
else /* csp only */
{
More information about the x264-devel
mailing list