[vlc-commits] swscale: scale within the crop area, not top-left (really fixes #12085)

Rémi Denis-Courmont git at videolan.org
Fri Dec 12 17:44:55 CET 2014


vlc | branch: master | Rémi Denis-Courmont <remi at remlab.net> | Fri Dec 12 18:41:18 2014 +0200| [05c433624791b01babcb1ccb72766fb2a5062fab] | committer: Rémi Denis-Courmont

swscale: scale within the crop area, not top-left (really fixes #12085)

Unfortunately, this can cause a slight offset of the colour planes if the
top/left crop offset is not a multiple of the subsampling ratio.

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

 modules/video_chroma/swscale.c |   50 +++++++++++++++++++++++++++++-----------
 1 file changed, 37 insertions(+), 13 deletions(-)

diff --git a/modules/video_chroma/swscale.c b/modules/video_chroma/swscale.c
index fc128da..c53cce5 100644
--- a/modules/video_chroma/swscale.c
+++ b/modules/video_chroma/swscale.c
@@ -90,6 +90,8 @@ struct filter_sys_t
 
     video_format_t fmt_in;
     video_format_t fmt_out;
+    const vlc_chroma_description_t *desc_in;
+    const vlc_chroma_description_t *desc_out;
 
     struct SwsContext *ctx;
     struct SwsContext *ctxA;
@@ -378,6 +380,11 @@ static int Init( filter_t *p_filter )
         return VLC_EGENERIC;
     }
 
+    p_sys->desc_in = vlc_fourcc_GetChromaDescription( p_fmti->i_chroma );
+    p_sys->desc_out = vlc_fourcc_GetChromaDescription( p_fmto->i_chroma );
+    if( p_sys->desc_in == NULL || p_sys->desc_out == NULL )
+        return VLC_EGENERIC;
+
     /* swscale does not like too small width */
     p_sys->i_extend_factor = 1;
     while( __MIN( p_fmti->i_visible_width, p_fmto->i_visible_width ) * p_sys->i_extend_factor < MINIMUM_WIDTH)
@@ -485,21 +492,35 @@ static void Clean( filter_t *p_filter )
 }
 
 static void GetPixels( uint8_t *pp_pixel[4], int pi_pitch[4],
-                       const picture_t *p_picture, int i_plane_count,
+                       const vlc_chroma_description_t *desc,
+                       const video_format_t *fmt,
+                       const picture_t *p_picture, unsigned planes,
                        bool b_swap_uv )
 {
-    assert( !b_swap_uv || i_plane_count >= 3 );
-    int n;
-    for( n = 0; n < __MIN(i_plane_count, p_picture->i_planes); n++ )
+    unsigned i = 0;
+
+    if( planes > (unsigned)p_picture->i_planes )
+        planes = p_picture->i_planes;
+    assert( !b_swap_uv || planes >= 3 );
+
+    for( ; i < planes; i++ )
     {
-        const int nd = ( b_swap_uv && n >= 1 && n <= 2 ) ? (3 - n) : n;
-        pp_pixel[nd] = p_picture->p[n].p_pixels;
-        pi_pitch[nd] = p_picture->p[n].i_pitch;
+        const plane_t *p = p_picture->p + i;
+        if( b_swap_uv && (i == 1 || i== 2) )
+            p = p_picture->p + 3 - i;
+
+        pp_pixel[i] = p->p_pixels
+            + (((fmt->i_x_offset * desc->p[i].w.num) / desc->p[i].w.den)
+                * p->i_pixel_pitch)
+            + (((fmt->i_y_offset * desc->p[i].h.num) / desc->p[i].h.den)
+                * p->i_pitch);
+        pi_pitch[i] = p->i_pitch;
     }
-    for( ; n < 4; n++ )
+
+    for( ; i < 4; i++ )
     {
-        pp_pixel[n] = NULL;
-        pi_pitch[n] = 0;
+        pp_pixel[i] = NULL;
+        pi_pitch[i] = 0;
     }
 }
 
@@ -556,16 +577,18 @@ static void SwapUV( picture_t *p_dst, const picture_t *p_src )
 
     picture_CopyPixels( p_dst, &tmp );
 }
+
 static void Convert( filter_t *p_filter, struct SwsContext *ctx,
                      picture_t *p_dst, picture_t *p_src, int i_height,
                      int i_plane_count, bool b_swap_uvi, bool b_swap_uvo )
 {
+    filter_sys_t *p_sys = p_filter->p_sys;
     uint8_t palette[AVPALETTE_SIZE];
-
     uint8_t *src[4]; int src_stride[4];
     uint8_t *dst[4]; int dst_stride[4];
 
-    GetPixels( src, src_stride, p_src, i_plane_count, b_swap_uvi );
+    GetPixels( src, src_stride, p_sys->desc_in, &p_filter->fmt_in.video,
+               p_src, i_plane_count, b_swap_uvi );
     if( p_filter->fmt_in.video.i_chroma == VLC_CODEC_RGBP )
     {
         video_palette_t *src_pal =
@@ -580,7 +603,8 @@ static void Convert( filter_t *p_filter, struct SwsContext *ctx,
         src_stride[1] = 4;
     }
 
-    GetPixels( dst, dst_stride, p_dst, i_plane_count, b_swap_uvo );
+    GetPixels( dst, dst_stride, p_sys->desc_out, &p_filter->fmt_out.video,
+               p_dst, i_plane_count, b_swap_uvo );
 
 #if LIBSWSCALE_VERSION_INT  >= ((0<<16)+(5<<8)+0)
     sws_scale( ctx, src, src_stride, 0, i_height,



More information about the vlc-commits mailing list