]> git.sesse.net Git - vlc/commitdiff
Scaling vertical dans les 2 sens en YUV walken.
authorVincent Seguin <seguin@videolan.org>
Tue, 1 Feb 2000 09:30:10 +0000 (09:30 +0000)
committerVincent Seguin <seguin@videolan.org>
Tue, 1 Feb 2000 09:30:10 +0000 (09:30 +0000)
src/video_output/video_output.c
src/video_output/video_yuv.c

index 83196afef88ecbeb8fa34430b63d90d938725607..ac5d87a2de826a64015a2e25f08bc90ae4b0761d 100644 (file)
@@ -1383,6 +1383,34 @@ static void SetBufferPicture( vout_thread_t *p_vout, picture_t *p_pic )
      * Clear areas array
      */
     p_buffer->i_areas = 0;
+
+#ifdef DEBUG_VIDEO
+    /*
+     * In DEBUG_VIDEO_MODE, draw white pixels at the beginning and the end of
+     * the picture area. These pixels should not be erased by rendering functions,
+     * otherwise segmentation fault is menacing !
+     */
+    if( i_pic_x > 0 )
+    {
+        *(u16*)(p_buffer->p_data + p_vout->i_bytes_per_line * i_pic_y + 
+                p_vout->i_bytes_per_pixel * (i_pic_x - 1)) = 0xffff;
+    }
+    if( i_pic_y > 0 )
+    {
+        *(u16*)(p_buffer->p_data + p_vout->i_bytes_per_line * (i_pic_y - 1) + 
+                p_vout->i_bytes_per_pixel * i_pic_x ) = 0xffff;
+    }
+    if( i_pic_x + i_pic_width < p_vout->i_width )
+    {
+        *(u16*)(p_buffer->p_data + p_vout->i_bytes_per_line * (i_pic_y + i_pic_height - 1) + 
+                p_vout->i_bytes_per_pixel * (i_pic_x + i_pic_width) ) = 0xffff;
+    }    
+    if( i_pic_y + i_pic_height < p_vout->i_height )
+    {
+        *(u16*)(p_buffer->p_data + p_vout->i_bytes_per_line * (i_pic_y + i_pic_height) + 
+                p_vout->i_bytes_per_pixel * (i_pic_x + i_pic_width - 1) ) = 0xffff;
+    }    
+#endif
 }
 
 /******************************************************************************
index 55fa144f3da894732bc5880c084edc873571743c..4b66708121212e46ab80e1e7f7bb1a548256c7b9 100644 (file)
@@ -190,6 +190,29 @@ for (i_y = 0; i_y < i_height ; i_y++)                                   \
     p_pic += i_pic_line_width;                                          \
 }
 
+/*******************************************************************************
+ * CONVERT_YUV_PIXEL, CONVERT_Y_PIXEL: pixel convertion blocks
+ *******************************************************************************
+ * These convertion routines are used by YUV convertion functions.
+ * Convertion are made from p_y, p_u, p_v, which are modified, to p_pic, which
+ * is also modified.
+ *******************************************************************************/
+#define CONVERT_Y_PIXEL                                                         \
+    /* Only Y sample is present */                                              \
+    p_ybase = p_yuv + *(p_y++);                                                 \
+    *(p_pic++) = p_ybase[1501 - ((V_RED_COEF*128)>>SHIFT) + i_red] |            \
+        p_ybase[135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) + i_green ] |  \
+        p_ybase[818 - ((U_BLUE_COEF*128)>>SHIFT) + i_blue];                     \
+
+#define CONVERT_YUV_PIXEL                                                       \
+    /* Y, U and V samples are present */                                        \
+    i_uval =    *p_u++;                                                         \
+    i_vval =    *p_v++;                                                         \
+    i_red =     (V_RED_COEF * i_vval) >> SHIFT;                                 \
+    i_green =   (U_GREEN_COEF * i_uval + V_GREEN_COEF * i_vval) >> SHIFT;       \
+    i_blue =    (U_BLUE_COEF * i_uval) >> SHIFT;                                \
+    CONVERT_Y_PIXEL                                                             \
+
 /*******************************************************************************
  * vout_InitYUV: allocate and initialize translations tables
  *******************************************************************************
@@ -602,6 +625,7 @@ static void ConvertYUV420RGB16( p_vout_thread_t p_vout, u16 *p_pic, yuv_data_t *
     
     CONVERT_YUV_RGB( 420, i_crv, i_cgv, i_cbu, i_cgu );        
 #else
+    boolean_t   b_inc_width, b_inc_height;       /* width/heidth are increased */
     int         i_x, i_y;                   /* horizontal and vertical indexes */
     int         i_uval, i_vval;                             /* U and V samples */
     int         i_red, i_green, i_blue;            /* U and V modified samples */
@@ -609,16 +633,15 @@ static void ConvertYUV420RGB16( p_vout_thread_t p_vout, u16 *p_pic, yuv_data_t *
     int         i_height_count;                       /* height modulo counter */
     u16 *       p_yuv;                                /* base convertion table */
     u16 *       p_ybase;                       /* Y dependant convertion table */   
-    u16 *       p_pic_start;    
+    u16 *       p_pic_start;                  /* beginning of the current line */    
     
     /* Initialize values */
+    b_inc_width =       i_width < i_pic_width;    
+    b_inc_height =      i_height < i_pic_height;
     i_height_count =    i_pic_height;
     i_chroma_width =    i_width / 2;
     p_yuv =             p_vout->yuv.yuv2.p_rgb16;
 
-    /*?? temporary kludge to protect from segfault at startup */
-    i_height = MIN( i_height, i_pic_height );    
-
     /*
      * Perform convertion
      */
@@ -631,125 +654,22 @@ static void ConvertYUV420RGB16( p_vout_thread_t p_vout, u16 *p_pic, yuv_data_t *
          * macroblocks */
         for( i_x = i_width / 16; i_x--; )
         {
-            i_uval =    *p_u++;
-            i_vval =    *p_v++;
-            i_red =     (V_RED_COEF * i_vval) >> SHIFT;
-            i_green =   (U_GREEN_COEF * i_uval + V_GREEN_COEF * i_vval) >> SHIFT;
-            i_blue =    (U_BLUE_COEF * i_uval) >> SHIFT;
-
-            p_ybase = p_yuv + *(p_y++);
-            *(p_pic++) = p_ybase[1501 - ((V_RED_COEF*128)>>SHIFT) + i_red] |
-                p_ybase[135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) + i_green ] |
-                p_ybase[818 - ((U_BLUE_COEF*128)>>SHIFT) + i_blue];
-            p_ybase = p_yuv + *(p_y++);
-            *(p_pic++) = p_ybase[1501 - ((V_RED_COEF*128)>>SHIFT) + i_red] |
-                p_ybase[135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) + i_green ] |
-                p_ybase[818 - ((U_BLUE_COEF*128)>>SHIFT) + i_blue];
-
-            i_uval =    *p_u++;
-            i_vval =    *p_v++;
-            i_red =     (V_RED_COEF * i_vval) >> SHIFT;
-            i_green =   (U_GREEN_COEF * i_uval + V_GREEN_COEF * i_vval) >> SHIFT;
-            i_blue =    (U_BLUE_COEF * i_uval) >> SHIFT;
-
-            p_ybase = p_yuv + *(p_y++);
-            *(p_pic++) = p_ybase[1501 - ((V_RED_COEF*128)>>SHIFT) + i_red] |
-                p_ybase[135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) + i_green ] |
-                p_ybase[818 - ((U_BLUE_COEF*128)>>SHIFT) + i_blue];
-            p_ybase = p_yuv + *(p_y++);
-            *(p_pic++) = p_ybase[1501 - ((V_RED_COEF*128)>>SHIFT) + i_red] |
-                p_ybase[135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) + i_green ] |
-                p_ybase[818 - ((U_BLUE_COEF*128)>>SHIFT) + i_blue];
-
-            i_uval =    *p_u++;
-            i_vval =    *p_v++;
-            i_red =     (V_RED_COEF * i_vval) >> SHIFT;
-            i_green =   (U_GREEN_COEF * i_uval + V_GREEN_COEF * i_vval) >> SHIFT;
-            i_blue =    (U_BLUE_COEF * i_uval) >> SHIFT;
-
-            p_ybase = p_yuv + *(p_y++);
-            *(p_pic++) = p_ybase[1501 - ((V_RED_COEF*128)>>SHIFT) + i_red] |
-                p_ybase[135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) + i_green ] |
-                p_ybase[818 - ((U_BLUE_COEF*128)>>SHIFT) + i_blue];
-            p_ybase = p_yuv + *(p_y++);
-            *(p_pic++) = p_ybase[1501 - ((V_RED_COEF*128)>>SHIFT) + i_red] |
-                p_ybase[135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) + i_green ] |
-                p_ybase[818 - ((U_BLUE_COEF*128)>>SHIFT) + i_blue];
-
-            i_uval =    *p_u++;
-            i_vval =    *p_v++;
-            i_red =     (V_RED_COEF * i_vval) >> SHIFT;
-            i_green =   (U_GREEN_COEF * i_uval + V_GREEN_COEF * i_vval) >> SHIFT;
-            i_blue =    (U_BLUE_COEF * i_uval) >> SHIFT;
-
-            p_ybase = p_yuv + *(p_y++);
-            *(p_pic++) = p_ybase[1501 - ((V_RED_COEF*128)>>SHIFT) + i_red] |
-                p_ybase[135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) + i_green ] |
-                p_ybase[818 - ((U_BLUE_COEF*128)>>SHIFT) + i_blue];
-            p_ybase = p_yuv + *(p_y++);
-            *(p_pic++) = p_ybase[1501 - ((V_RED_COEF*128)>>SHIFT) + i_red] |
-                p_ybase[135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) + i_green ] |
-                p_ybase[818 - ((U_BLUE_COEF*128)>>SHIFT) + i_blue];
-
-            i_uval =    *p_u++;
-            i_vval =    *p_v++;
-            i_red =     (V_RED_COEF * i_vval) >> SHIFT;
-            i_green =   (U_GREEN_COEF * i_uval + V_GREEN_COEF * i_vval) >> SHIFT;
-            i_blue =    (U_BLUE_COEF * i_uval) >> SHIFT;
-
-            p_ybase = p_yuv + *(p_y++);
-            *(p_pic++) = p_ybase[1501 - ((V_RED_COEF*128)>>SHIFT) + i_red] |
-                p_ybase[135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) + i_green ] |
-                p_ybase[818 - ((U_BLUE_COEF*128)>>SHIFT) + i_blue];
-            p_ybase = p_yuv + *(p_y++);
-            *(p_pic++) = p_ybase[1501 - ((V_RED_COEF*128)>>SHIFT) + i_red] |
-                p_ybase[135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) + i_green ] |
-                p_ybase[818 - ((U_BLUE_COEF*128)>>SHIFT) + i_blue];
-
-            i_uval =    *p_u++;
-            i_vval =    *p_v++;
-            i_red =     (V_RED_COEF * i_vval) >> SHIFT;
-            i_green =   (U_GREEN_COEF * i_uval + V_GREEN_COEF * i_vval) >> SHIFT;
-            i_blue =    (U_BLUE_COEF * i_uval) >> SHIFT;
-
-            p_ybase = p_yuv + *(p_y++);
-            *(p_pic++) = p_ybase[1501 - ((V_RED_COEF*128)>>SHIFT) + i_red] |
-                p_ybase[135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) + i_green ] |
-                p_ybase[818 - ((U_BLUE_COEF*128)>>SHIFT) + i_blue];
-            p_ybase = p_yuv + *(p_y++);
-            *(p_pic++) = p_ybase[1501 - ((V_RED_COEF*128)>>SHIFT) + i_red] |
-                p_ybase[135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) + i_green ] |
-                p_ybase[818 - ((U_BLUE_COEF*128)>>SHIFT) + i_blue];
-
-            i_uval =    *p_u++;
-            i_vval =    *p_v++;
-            i_red =     (V_RED_COEF * i_vval) >> SHIFT;
-            i_green =   (U_GREEN_COEF * i_uval + V_GREEN_COEF * i_vval) >> SHIFT;
-            i_blue =    (U_BLUE_COEF * i_uval) >> SHIFT;
-
-            p_ybase = p_yuv + *(p_y++);
-            *(p_pic++) = p_ybase[1501 - ((V_RED_COEF*128)>>SHIFT) + i_red] |
-                p_ybase[135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) + i_green ] |
-                p_ybase[818 - ((U_BLUE_COEF*128)>>SHIFT) + i_blue];
-            p_ybase = p_yuv + *(p_y++);
-            *(p_pic++) = p_ybase[1501 - ((V_RED_COEF*128)>>SHIFT) + i_red] |
-                p_ybase[135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) + i_green ] |
-                p_ybase[818 - ((U_BLUE_COEF*128)>>SHIFT) + i_blue];
-
-            i_uval =    *p_u++;
-            i_vval =    *p_v++;
-            i_red =     (V_RED_COEF * i_vval) >> SHIFT;
-            i_green =   (U_GREEN_COEF * i_uval + V_GREEN_COEF * i_vval) >> SHIFT;
-            i_blue =    (U_BLUE_COEF * i_uval) >> SHIFT;
-
-            p_ybase = p_yuv + *(p_y++);
-            *(p_pic++) = p_ybase[1501 - ((V_RED_COEF*128)>>SHIFT) + i_red] |
-                p_ybase[135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) + i_green ] |
-                p_ybase[818 - ((U_BLUE_COEF*128)>>SHIFT) + i_blue];
-            p_ybase = p_yuv + *(p_y++);
-            *(p_pic++) = p_ybase[1501 - ((V_RED_COEF*128)>>SHIFT) + i_red] |
-                p_ybase[135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) + i_green ] |
-                p_ybase[818 - ((U_BLUE_COEF*128)>>SHIFT) + i_blue];            
+            CONVERT_YUV_PIXEL;
+            CONVERT_Y_PIXEL;
+            CONVERT_YUV_PIXEL;
+            CONVERT_Y_PIXEL;
+            CONVERT_YUV_PIXEL;
+            CONVERT_Y_PIXEL;
+            CONVERT_YUV_PIXEL;
+            CONVERT_Y_PIXEL;
+            CONVERT_YUV_PIXEL;
+            CONVERT_Y_PIXEL;
+            CONVERT_YUV_PIXEL;
+            CONVERT_Y_PIXEL;
+            CONVERT_YUV_PIXEL;
+            CONVERT_Y_PIXEL;
+            CONVERT_YUV_PIXEL;
+            CONVERT_Y_PIXEL;
         }        
 
         /* If line is odd, rewind U and V samples */
@@ -762,20 +682,41 @@ static void ConvertYUV420RGB16( p_vout_thread_t p_vout, u16 *p_pic, yuv_data_t *
         /* End of line: skip picture to reach beginning of next line */
         p_pic += i_pic_line_width - i_pic_width;
  
-        /* Copy line if needed */
-        while( (i_height_count -= i_height) >= 0 )
-        {   
-            for( i_x = i_pic_width / 16; i_x--; )
-            {
-                *(((u64 *) p_pic)++) = *(((u64 *) p_pic_start)++ );
-                *(((u64 *) p_pic)++) = *(((u64 *) p_pic_start)++ );
-                *(((u64 *) p_pic)++) = *(((u64 *) p_pic_start)++ );
-                *(((u64 *) p_pic)++) = *(((u64 *) p_pic_start)++ );
+        /* 
+         * Handle vertical scaling. The current line is copied or next one
+         * is ignored.
+         */
+        if( b_inc_height )
+        {
+            while( (i_height_count -= i_height) > 0 )
+            {                
+                /* Height increment: copy previous picture line */
+                for( i_x = i_pic_width / 16; i_x--; )
+                {
+                    *(((u64 *) p_pic)++) = *(((u64 *) p_pic_start)++ );
+                    *(((u64 *) p_pic)++) = *(((u64 *) p_pic_start)++ );
+                    *(((u64 *) p_pic)++) = *(((u64 *) p_pic_start)++ );
+                    *(((u64 *) p_pic)++) = *(((u64 *) p_pic_start)++ );
+                }
+                p_pic +=        i_pic_line_width - i_pic_width;
+                p_pic_start +=  i_pic_line_width - i_pic_width;
             }
-            p_pic +=            i_pic_line_width - i_pic_width;            
-            p_pic_start +=      i_pic_line_width - i_pic_width;            
+            i_height_count += i_pic_height; 
+        }        
+        else
+        {
+            while( (i_height_count -= i_pic_height) >= 0 )
+            {                
+                /* Height reduction: skip next source line */
+                p_y += i_width;
+                if( ! (++i_y & 0x1) )
+                {
+                    p_u += i_chroma_width;
+                    p_v += i_chroma_width;
+                }                
+            }            
+            i_height_count += i_height;            
         }        
-        i_height_count += i_pic_height;        
     }    
 #endif
 }