[vlc-commits] transcode: rework the encoding size computing

Steve Lhomme git at videolan.org
Mon Jan 18 08:08:31 UTC 2021


vlc | branch: master | Steve Lhomme <robux4 at ycbcr.xyz> | Wed Jan 13 16:06:59 2021 +0100| [fe7b7f153d10da4c82a932850c4746d963bbfed2] | committer: Steve Lhomme

transcode: rework the encoding size computing

The transcode_video_size_config_apply() and transcode_video_scale_apply() calls
should give consistent results regardless of what width/height were previously
set on the output video_format_t.

The 16 pixels horizontal alignment was never done since the i_visible_width/height
was always set. Now we do it on the coded values, not the visible values. In the
end the encoder should tell which alignment it wants on the input.
The coded size is deduced from the actual visible sizes that will be used.
The visible width/height is still forced to the even values. Even though
it should be up to the encoder to tell if it can't support odd dimensions.

The width/height configured by the user are applied even if there's only one of
them (fixes Chromecast rescaling), and only if there's no user scaling.

> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=fe7b7f153d10da4c82a932850c4746d963bbfed2
---

 modules/stream_out/transcode/encoder/video.c | 96 ++++++++++++++--------------
 1 file changed, 47 insertions(+), 49 deletions(-)

diff --git a/modules/stream_out/transcode/encoder/video.c b/modules/stream_out/transcode/encoder/video.c
index 4de9f3965a..d2513c68c4 100644
--- a/modules/stream_out/transcode/encoder/video.c
+++ b/modules/stream_out/transcode/encoder/video.c
@@ -64,61 +64,28 @@ static void transcode_video_scale_apply( vlc_object_t *p_obj,
 {
     /* Calculate scaling
      * width/height of source */
-    unsigned i_src_width = p_src->i_visible_width ? p_src->i_visible_width : p_src->i_width;
-    unsigned i_src_height = p_src->i_visible_height ? p_src->i_visible_height : p_src->i_height;
+    const unsigned i_src_width = p_src->i_visible_width;
+    const unsigned i_src_height = p_src->i_visible_height;
 
     /* with/height scaling */
     float f_scale_width = 1;
     float f_scale_height = 1;
 
     /* aspect ratio */
-    float f_aspect = (double)p_src->i_sar_num * p_src->i_width /
-                             p_src->i_sar_den / p_src->i_height;
+    float f_aspect = (double)p_src->i_sar_num * i_src_width /
+                            (p_src->i_sar_den * i_src_height);
 
     msg_Dbg( p_obj, "decoder aspect is %f:1", f_aspect );
 
     /* Change f_aspect from source frame to source pixel */
-    f_aspect = f_aspect * i_src_height / i_src_width;
+    f_aspect = (float)p_src->i_sar_num / p_src->i_sar_den;
     msg_Dbg( p_obj, "source pixel aspect is %f:1", f_aspect );
 
     /* Calculate scaling factor for specified parameters */
-    if( p_dst->i_visible_width == 0 && p_dst->i_visible_height == 0 && f_scale )
-    {
-        /* Global scaling. Make sure width will remain a factor of 16 */
-        float f_real_scale;
-        unsigned i_new_height;
-        unsigned i_new_width = i_src_width * f_scale;
-
-        if( i_new_width % 16 <= 7 && i_new_width >= 16 )
-            i_new_width -= i_new_width % 16;
-        else
-            i_new_width += 16 - i_new_width % 16;
+    unsigned i_new_height = __MAX( 16, i_src_height * f_scale );
 
-        f_real_scale = (float)( i_new_width ) / (float) i_src_width;
-
-        i_new_height = __MAX( 16, i_src_height * (float)f_real_scale );
-
-        f_scale_width = f_real_scale;
-        f_scale_height = (float) i_new_height / (float) i_src_height;
-    }
-    else if( p_dst->i_visible_width && p_dst->i_visible_height == 0 )
-    {
-        /* Only width specified */
-        f_scale_width = (float)p_dst->i_visible_width / i_src_width;
-        f_scale_height = f_scale_width;
-    }
-    else if( p_dst->i_visible_width == 0 && p_dst->i_visible_height )
-    {
-         /* Only height specified */
-         f_scale_height = (float)p_dst->i_visible_height / i_src_height;
-         f_scale_width = f_scale_height;
-     }
-     else if( p_dst->i_visible_width && p_dst->i_visible_height )
-     {
-         /* Width and height specified */
-         f_scale_width = (float)p_dst->i_visible_width / i_src_width;
-         f_scale_height = (float)p_dst->i_visible_height / i_src_height;
-     }
+    f_scale_width = f_scale;
+    f_scale_height = (float) i_new_height / (float) i_src_height;
 
      /* check maxwidth and maxheight */
      if( i_maxwidth && f_scale_width > (float)i_maxwidth / i_src_width )
@@ -143,13 +110,10 @@ static void transcode_video_scale_apply( vlc_object_t *p_obj,
      /* width/height of output stream */
      unsigned i_dst_visible_width =  lroundf(f_scale_width*i_src_width);
      unsigned i_dst_visible_height = lroundf(f_scale_height*i_src_height);
-     unsigned i_dst_width =  lroundf(f_scale_width*p_src->i_width);
-     unsigned i_dst_height = lroundf(f_scale_height*p_src->i_height);
-
-     if( i_dst_visible_width & 1 ) ++i_dst_visible_width;
-     if( i_dst_visible_height & 1 ) ++i_dst_visible_height;
-     if( i_dst_width & 1 ) ++i_dst_width;
-     if( i_dst_height & 1 ) ++i_dst_height;
+     if( i_dst_visible_width & 1 ) --i_dst_visible_width;
+     if( i_dst_visible_height & 1 ) --i_dst_visible_height;
+     unsigned i_dst_width =  (i_dst_visible_width  + 0x0F) & ~0x0F;
+     unsigned i_dst_height = (i_dst_visible_height + 0x01) & ~0x01;
 
      /* Store calculated values */
      p_dst->i_width = i_dst_width;
@@ -188,7 +152,7 @@ static void transcode_video_size_config_apply( vlc_object_t *p_obj,
                                                video_format_t *p_dst )
 {
     if( !p_cfg->video.f_scale &&
-        (p_cfg->video.i_width & ~1) && (p_cfg->video.i_width & ~1) )
+        (p_cfg->video.i_width & ~1) && (p_cfg->video.i_height & ~1) )
     {
         p_dst->i_width = p_dst->i_visible_width = p_cfg->video.i_width & ~1;
         p_dst->i_height = p_dst->i_visible_height = p_cfg->video.i_height & ~1;
@@ -202,6 +166,40 @@ static void transcode_video_size_config_apply( vlc_object_t *p_obj,
                                      p_cfg->video.i_maxheight,
                                      p_dst );
     }
+    else if( p_cfg->video.i_height || p_cfg->video.i_width )
+    {
+        if ( !p_cfg->video.i_height )
+        {
+            transcode_video_scale_apply( p_obj,
+                                        p_srcref,
+                                        (float)p_cfg->video.i_width / p_srcref->i_visible_width,
+                                        p_cfg->video.i_maxwidth,
+                                        p_cfg->video.i_maxheight,
+                                        p_dst );
+        }
+        else if ( !p_cfg->video.i_width )
+        {
+            transcode_video_scale_apply( p_obj,
+                                        p_srcref,
+                                        (float)p_cfg->video.i_height / p_srcref->i_visible_height,
+                                        p_cfg->video.i_maxwidth,
+                                        p_cfg->video.i_maxheight,
+                                        p_dst );
+        }
+        else
+        {
+            p_dst->i_visible_width = p_cfg->video.i_width;
+            p_dst->i_visible_height = p_cfg->video.i_height;
+
+            if( p_cfg->video.i_maxwidth && p_dst->i_visible_width > p_cfg->video.i_maxwidth )
+                p_dst->i_visible_width = p_cfg->video.i_maxwidth;
+            if( p_cfg->video.i_maxheight && p_dst->i_visible_height > p_cfg->video.i_maxheight )
+                p_dst->i_visible_height = p_cfg->video.i_maxheight;
+
+            p_dst->i_width  = (p_dst->i_visible_width  + 1) & ~1;
+            p_dst->i_height = (p_dst->i_visible_height + 1) & ~1;
+        }
+    }
     else
     {
         p_dst->i_width = p_srcref->i_width;



More information about the vlc-commits mailing list