[vlc-devel] [PATCH 4/4] [RFC] chroma:i420_nv12: copy only the visible src area to the visible dest area

Steve Lhomme robux4 at videolabs.io
Wed May 11 16:01:24 CEST 2016


--
By default the offset isn't carried over the filter output.
Is it the reponsibility of the filter to fill this value ?
Is the filter responsible for doing the cropping ? This patch does this.
---
 modules/video_chroma/i420_nv12.c | 104 +++++++++++++++++++++++++--------------
 1 file changed, 66 insertions(+), 38 deletions(-)

diff --git a/modules/video_chroma/i420_nv12.c b/modules/video_chroma/i420_nv12.c
index de791e3..736ed5e 100644
--- a/modules/video_chroma/i420_nv12.c
+++ b/modules/video_chroma/i420_nv12.c
@@ -106,34 +106,48 @@ static void I420_NV12( filter_t *p_filter, picture_t *p_src,
                                            picture_t *p_dst )
 {
     VLC_UNUSED(p_filter);
-    p_dst->format.i_x_offset = p_src->format.i_x_offset;
-    p_dst->format.i_y_offset = p_src->format.i_y_offset;
-
     // copy Y plane
-    unsigned int copy_lines = __MAX( (unsigned int) p_dst->p[Y_PLANE].i_visible_lines,
-                            p_src->format.i_y_offset + p_src->format.i_visible_height );
-    memcpy( p_dst->p[Y_PLANE].p_pixels,
-            p_src->p[Y_PLANE].p_pixels,
-            copy_lines * p_dst->p[Y_PLANE].i_pitch );
+    if ( p_dst->format.i_x_offset == 0 && p_src->format.i_x_offset == 0 )
+    {
+        const int copy_lines = p_dst->p[Y_PLANE].i_visible_lines;
+        memcpy( p_dst->p[Y_PLANE].p_pixels + p_dst->format.i_y_offset * p_dst->p[Y_PLANE].i_pitch,
+                p_src->p[Y_PLANE].p_pixels + p_src->format.i_y_offset * p_src->p[Y_PLANE].i_pitch,
+                copy_lines * p_dst->p[Y_PLANE].i_pitch );
+    }
+    else
+    {
+        const int copy_lines = p_dst->p[Y_PLANE].i_visible_lines;
+        const int copy_pitch = p_dst->p[Y_PLANE].i_visible_pitch;
+
+        const int src_pitch = p_src->p[Y_PLANE].i_pitch;
+        const int dst_pitch = p_dst->p[Y_PLANE].i_pitch;
+
+        uint8_t *dstY = p_dst->p[Y_PLANE].p_pixels + p_dst->format.i_x_offset + p_dst->format.i_y_offset * p_dst->p[Y_PLANE].i_pitch;
+        uint8_t *srcY = p_src->p[Y_PLANE].p_pixels + p_src->format.i_x_offset + p_src->format.i_y_offset * p_src->p[Y_PLANE].i_pitch;
+
+
+        for ( int line = 0; line < copy_lines; line++ )
+        {
+            memcpy( dstY, srcY, copy_pitch );
+            srcY += src_pitch;
+            dstY += dst_pitch;
+        }
+    }
 
     // copy the U and V planes into UV
-    copy_lines = __MIN( __MAX( (unsigned int) p_dst->p[UVPLANE].i_visible_lines,
-                               ( p_src->format.i_y_offset + p_src->format.i_visible_height) / 2 ),
-                        (unsigned int) p_src->p[U_PLANE].i_lines );
-    const unsigned int copy_pitch = __MIN( __MAX( (unsigned int) p_dst->p[UVPLANE].i_visible_pitch,
-                                                  p_src->format.i_x_offset + p_src->format.i_visible_width ) / 2,
-                                           (unsigned int) p_src->p[U_PLANE].i_pitch );
+    const int copy_lines = p_dst->p[UVPLANE].i_visible_lines;
+    const int copy_pitch = p_dst->p[UVPLANE].i_visible_pitch;
 
     const int i_extra_pitch_uv = p_dst->p[UVPLANE].i_pitch - 2 * copy_pitch;
     const int i_extra_pitch_u  = p_src->p[U_PLANE].i_pitch - copy_pitch;
     const int i_extra_pitch_v  = p_src->p[V_PLANE].i_pitch - copy_pitch;
 
-    uint8_t *dstUV = p_dst->p[UVPLANE].p_pixels;
-    uint8_t *srcU  = p_src->p[U_PLANE].p_pixels;
-    uint8_t *srcV  = p_src->p[V_PLANE].p_pixels;
-    for ( unsigned int line = 0; line < copy_lines; line++ )
+    uint8_t *dstUV = p_dst->p[UVPLANE].p_pixels + p_dst->format.i_x_offset     + p_dst->format.i_y_offset * p_dst->p[UVPLANE].i_pitch;
+    uint8_t *srcU  = p_src->p[U_PLANE].p_pixels + ( p_src->format.i_x_offset + p_src->format.i_y_offset * p_src->p[U_PLANE].i_pitch ) / 2;
+    uint8_t *srcV  = p_src->p[V_PLANE].p_pixels + ( p_src->format.i_x_offset + p_src->format.i_y_offset * p_src->p[V_PLANE].i_pitch ) / 2;
+    for ( int line = 0; line < copy_lines; line++ )
     {
-        for ( unsigned int col = 0; col < copy_pitch; col++ )
+        for ( int col = 0; col < copy_pitch; col++ )
         {
             *dstUV++ = *srcU++;
             *dstUV++ = *srcV++;
@@ -151,34 +165,48 @@ static void YV12_NV12( filter_t *p_filter, picture_t *p_src,
                                            picture_t *p_dst )
 {
     VLC_UNUSED(p_filter);
-    p_dst->format.i_x_offset = p_src->format.i_x_offset;
-    p_dst->format.i_y_offset = p_src->format.i_y_offset;
-
     // copy Y plane
-    unsigned int copy_lines = __MAX( (unsigned int) p_dst->p[Y_PLANE].i_visible_lines,
-                            p_src->format.i_y_offset + p_src->format.i_visible_height );
-    memcpy( p_dst->p[Y_PLANE].p_pixels,
-            p_src->p[Y_PLANE].p_pixels,
-            copy_lines * p_dst->p[Y_PLANE].i_pitch );
+    if ( p_dst->format.i_x_offset == 0 && p_src->format.i_x_offset == 0 )
+    {
+        const unsigned int copy_lines = p_dst->p[Y_PLANE].i_visible_lines;
+        memcpy( p_dst->p[Y_PLANE].p_pixels + p_dst->format.i_y_offset * p_dst->p[Y_PLANE].i_pitch,
+                p_src->p[Y_PLANE].p_pixels + p_src->format.i_y_offset * p_src->p[Y_PLANE].i_pitch,
+                copy_lines * p_dst->p[Y_PLANE].i_pitch );
+    }
+    else
+    {
+        const int copy_lines = p_dst->p[Y_PLANE].i_visible_lines;
+        const int copy_pitch = p_dst->p[Y_PLANE].i_visible_pitch;
+
+        const int src_pitch = p_src->p[Y_PLANE].i_pitch;
+        const int dst_pitch = p_dst->p[Y_PLANE].i_pitch;
+
+        uint8_t *dstY = p_dst->p[Y_PLANE].p_pixels + p_dst->format.i_x_offset + p_dst->format.i_y_offset * p_dst->p[Y_PLANE].i_pitch;
+        uint8_t *srcY = p_src->p[Y_PLANE].p_pixels + p_src->format.i_x_offset + p_src->format.i_y_offset * p_src->p[Y_PLANE].i_pitch;
+
+
+        for ( int line = 0; line < copy_lines; line++ )
+        {
+            memcpy( dstY, srcY, copy_pitch );
+            srcY += src_pitch;
+            dstY += dst_pitch;
+        }
+    }
 
     // copy the U and V planes into UV
-    copy_lines = __MIN( __MAX( (unsigned int) p_dst->p[UVPLANE].i_visible_lines,
-                               ( p_src->format.i_y_offset + p_src->format.i_visible_height) / 2 ),
-                        (unsigned int) p_src->p[U_PLANE].i_lines );
-    const unsigned int copy_pitch = __MIN( __MAX( (unsigned int) p_dst->p[UVPLANE].i_visible_pitch,
-                                                  p_src->format.i_x_offset + p_src->format.i_visible_width ) / 2,
-                                           (unsigned int) p_src->p[U_PLANE].i_pitch );
+    const int copy_lines = p_dst->p[UVPLANE].i_visible_lines;
+    const int copy_pitch = p_dst->p[UVPLANE].i_visible_pitch;
 
     const int i_extra_pitch_uv = p_dst->p[UVPLANE].i_pitch - 2 * copy_pitch;
     const int i_extra_pitch_u  = p_src->p[U_PLANE].i_pitch - copy_pitch;
     const int i_extra_pitch_v  = p_src->p[V_PLANE].i_pitch - copy_pitch;
 
-    uint8_t *dstUV = p_dst->p[UVPLANE].p_pixels;
-    uint8_t *srcU  = p_src->p[U_PLANE].p_pixels;
-    uint8_t *srcV  = p_src->p[V_PLANE].p_pixels;
-    for ( unsigned int line = 0; line < copy_lines; line++ )
+    uint8_t *dstUV = p_dst->p[UVPLANE].p_pixels + p_dst->format.i_x_offset     + p_dst->format.i_y_offset * p_dst->p[UVPLANE].i_pitch;
+    uint8_t *srcU  = p_src->p[U_PLANE].p_pixels + ( p_src->format.i_x_offset + p_src->format.i_y_offset * p_src->p[U_PLANE].i_pitch ) / 2;
+    uint8_t *srcV  = p_src->p[V_PLANE].p_pixels + ( p_src->format.i_x_offset + p_src->format.i_y_offset * p_src->p[V_PLANE].i_pitch ) / 2;
+    for ( int line = 0; line < copy_lines; line++ )
     {
-        for ( unsigned int col = 0; col < copy_pitch; col++ )
+        for ( int col = 0; col < copy_pitch; col++ )
         {
             *dstUV++ = *srcV++;
             *dstUV++ = *srcU++;
-- 
2.8.1



More information about the vlc-devel mailing list