]> git.sesse.net Git - vlc/commitdiff
Scaling horizontal >=1
authorVincent Seguin <seguin@videolan.org>
Tue, 1 Feb 2000 23:13:54 +0000 (23:13 +0000)
committerVincent Seguin <seguin@videolan.org>
Tue, 1 Feb 2000 23:13:54 +0000 (23:13 +0000)
include/config.h
include/video_output.h
src/video_output/video_output.c
src/video_output/video_yuv.c

index a6f1004db71c92d24318b53933c6ab5381f6dca1..7c90e2da77cc56d718b43cc0ff3338c52c556ce7 100644 (file)
 
 #define VPAR_IDLE_SLEEP                 100000
 
-/* Time to sleep when waiting for a buffer (from vout or the video fifo). */
-#define VPAR_OUTMEM_SLEEP               100000
+/* Time to sleep when waiting for a buffer (from vout or the video fifo). 
+ * It should be approximately the time needed to perform a complete picture
+ * loop. Since it only happens when the video heap is full, it does not need
+ * to be too low, even if it blocks the decoder. */
+#define VPAR_OUTMEM_SLEEP               50000
 
 /* Optimization level, from 0 to 2 - 1 is generally a good compromise. Remember
  * that raising this level dramatically lengthens the compilation time. */
index 84436c999cd6414abdc0e0f7feb5d4ab82415ee3..5a710910c4874a8ffe36875244d821cefd3e8dc9 100644 (file)
@@ -20,6 +20,7 @@
  *      i_pic_width, i_pic_height       picture extension
  *      i_pic_line_width                picture total line width
  *      i_matrix_coefficients           matrix coefficients
+ * Picture width and source dimensions must be multiples of 16.
  *******************************************************************************/
 typedef void (vout_yuv_convert_t)( p_vout_thread_t p_vout, void *p_pic,
                                    yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
index ac5d87a2de826a64015a2e25f08bc90ae4b0761d..bf706405d5f4ad01d2e8e095abff7b7106ae15c7 100644 (file)
@@ -396,13 +396,13 @@ void vout_DestroySubPicture( vout_thread_t *p_vout, subpicture_t *p_subpic )
 #endif
 }
 
-/******************************************************************************
+/*******************************************************************************
  * vout_DisplayPicture: display a picture
- ******************************************************************************
+ *******************************************************************************
  * Remove the reservation flag of a picture, which will cause it to be ready for
  * display. The picture won't be displayed until vout_DatePicture has been 
  * called.
- ******************************************************************************/
+ *******************************************************************************/
 void  vout_DisplayPicture( vout_thread_t *p_vout, picture_t *p_pic )
 {
     vlc_mutex_lock( &p_vout->picture_lock );
@@ -422,21 +422,24 @@ void  vout_DisplayPicture( vout_thread_t *p_vout, picture_t *p_pic )
     }
 
 #ifdef DEBUG_VIDEO
-    intf_DbgMsg("picture %p\n", p_pic );
+    intf_DbgMsg("picture %p\n", p_pic);
 #endif
-
     vlc_mutex_unlock( &p_vout->picture_lock );
 }
 
-/******************************************************************************
+/*******************************************************************************
  * vout_DatePicture: date a picture
- ******************************************************************************
+ *******************************************************************************
  * Remove the reservation flag of a picture, which will cause it to be ready for
  * display. The picture won't be displayed until vout_DisplayPicture has been 
  * called.
- ******************************************************************************/
+ *******************************************************************************/
 void  vout_DatePicture( vout_thread_t *p_vout, picture_t *p_pic, mtime_t date )
 {
+#ifdef DEBUG_VIDEO
+    char        psz_date[MSTRTIME_MAX_SIZE];                           /* date */
+#endif
+
     vlc_mutex_lock( &p_vout->picture_lock );
     p_pic->date = date;    
     switch( p_pic->i_status )
@@ -455,9 +458,8 @@ void  vout_DatePicture( vout_thread_t *p_vout, picture_t *p_pic, mtime_t date )
     }
 
 #ifdef DEBUG_VIDEO
-    intf_DbgMsg("picture %p\n", p_pic);
+    intf_DbgMsg("picture %p, display date: %s\n", p_pic, mstrtime( psz_date, p_pic->date) );
 #endif
-
     vlc_mutex_unlock( &p_vout->picture_lock );
 }
 
@@ -1265,10 +1267,9 @@ static void SetBufferPicture( vout_thread_t *p_vout, picture_t *p_pic )
      */
     if( p_pic != NULL )
     {
-        /* Try horizontal scaling first */
-        i_pic_width = ( p_vout->b_scale || (p_pic->i_width > i_vout_width)) ? 
-            i_vout_width : p_pic->i_width;
-        i_pic_width = i_pic_width;
+        /* Try horizontal scaling first - width must be a mutiple of 16 */
+        i_pic_width = (( p_vout->b_scale || (p_pic->i_width > i_vout_width)) ? 
+                       i_vout_width : p_pic->i_width) & ~0xf;
         switch( p_pic->i_aspect_ratio )
         {
         case AR_3_4_PICTURE:
@@ -1287,7 +1288,8 @@ static void SetBufferPicture( vout_thread_t *p_vout, picture_t *p_pic )
         }
 
         /* If picture dimensions using horizontal scaling are too large, use 
-         * vertical scaling */
+         * vertical scaling. Since width must be a multiple of 16, height is
+         * adjusted again after. */
         if( i_pic_height > i_vout_height )
         {
             i_pic_height = ( p_vout->b_scale || (p_pic->i_height > i_vout_height)) ? 
@@ -1295,20 +1297,23 @@ static void SetBufferPicture( vout_thread_t *p_vout, picture_t *p_pic )
             switch( p_pic->i_aspect_ratio )
             {
             case AR_3_4_PICTURE:
-                i_pic_width = i_pic_height * 4 / 3;
+                i_pic_width = (i_pic_height * 4 / 3) & ~0xf;
+                i_pic_height = i_pic_width * 3 / 4;
                 break;                
             case AR_16_9_PICTURE:
-                i_pic_width = i_pic_height * 16 / 9;
+                i_pic_width = (i_pic_height * 16 / 9) & ~0xf;
+                i_pic_height = i_pic_width * 9 / 16;
                 break;
             case AR_221_1_PICTURE:        
-                i_pic_width = i_pic_height * 221 / 100;
+                i_pic_width = (i_pic_height * 221 / 100) & ~0xf;
+                i_pic_height = i_pic_width * 100 / 221;
                 break;               
             case AR_SQUARE_PICTURE:
             default:
-                i_pic_width = p_pic->i_width * i_pic_height / p_pic->i_height;
+                i_pic_width = (p_pic->i_width * i_pic_height / p_pic->i_height) & ~0xf;
+                i_pic_height = p_pic->i_height * i_pic_width / p_pic->i_width;
                 break;
             }        
-            i_pic_width = i_pic_width;
         }        
 
         /* Set picture position */
@@ -1386,7 +1391,7 @@ static void SetBufferPicture( vout_thread_t *p_vout, picture_t *p_pic )
 
 #ifdef DEBUG_VIDEO
     /*
-     * In DEBUG_VIDEO_MODE, draw white pixels at the beginning and the end of
+     * 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 !
      */
@@ -1423,6 +1428,10 @@ static void SetBufferPicture( vout_thread_t *p_vout, picture_t *p_pic )
  ******************************************************************************/
 static void RenderPicture( vout_thread_t *p_vout, picture_t *p_pic )
 {
+#ifdef DEBUG_VIDEO
+    char                psz_date[MSTRTIME_MAX_SIZE];          /* picture date */    
+    mtime_t             render_time;                /* picture rendering time */
+#endif
     vout_buffer_t *     p_buffer;                         /* rendering buffer */    
     byte_t *            p_pic_data;                 /* convertion destination */
     
@@ -1431,6 +1440,9 @@ static void RenderPicture( vout_thread_t *p_vout, picture_t *p_pic )
     p_pic_data =        p_buffer->p_data + 
         p_buffer->i_pic_x * p_vout->i_bytes_per_pixel +
         p_buffer->i_pic_y * p_vout->i_bytes_per_line;
+#ifdef DEBUG_VIDEO
+    render_time = mdate();    
+#endif
 
     /*
      * Choose appropriate rendering function and render picture 
@@ -1467,6 +1479,12 @@ static void RenderPicture( vout_thread_t *p_vout, picture_t *p_pic )
         break;        
 #endif
     }
+
+#ifdef DEBUG_VIDEO
+    /* Print picture date and rendering time */
+    intf_DbgMsg("picture %p rendered (%ld us), display date: %s\n", p_pic,
+                (long) (mdate() - render_time), mstrtime( psz_date, p_pic->date ));
+#endif
 }
 
 /******************************************************************************
index 4b66708121212e46ab80e1e7f7bb1a548256c7b9..f8a6162c47df98f04e587d7d69a5dff061952413 100644 (file)
@@ -194,13 +194,12 @@ for (i_y = 0; i_y < i_height ; i_y++)                                   \
  * 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.
+ * Convertion are made from p_y, p_u, p_v, which are modified, to i_dst. ??
  *******************************************************************************/
 #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_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];                     \
 
@@ -213,6 +212,14 @@ for (i_y = 0; i_y < i_height ; i_y++)                                   \
     i_blue =    (U_BLUE_COEF * i_uval) >> SHIFT;                                \
     CONVERT_Y_PIXEL                                                             \
 
+#define COPY_PIXEL                                                              \
+    /* Pixel may be copied, but only once */                                    \
+    while( (i_width_count -= i_width) > 0 )                                     \
+    {                                                                           \
+        *p_pic++ = *(p_pic - 1);                                                \
+    }                                                                           \
+    i_width_count += i_pic_width;                                               \
+
 /*******************************************************************************
  * vout_InitYUV: allocate and initialize translations tables
  *******************************************************************************
@@ -386,7 +393,7 @@ static void SetYUV( vout_thread_t *p_vout )
     switch( p_vout->i_screen_depth )
     {
     case 15:
-        MaskToShift( &i_red_right,   &i_red_left,   0x7c00 );
+        MaskToShift( &i_red_right,   &i_red_left,   0xf800 );
         MaskToShift( &i_green_right, &i_green_left, 0x03e0 );
         MaskToShift( &i_blue_right,  &i_blue_left,  0x001f );        
         break;        
@@ -625,52 +632,142 @@ 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_horizontal_scaling;               /* horizontal scaling type */
+    int         i_vertical_scaling;                   /* vertical scaling type */
     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 */
     int         i_chroma_width;                                /* chroma width */
+    int         i_width_count;                         /* width modulo counter */    
     int         i_height_count;                       /* height modulo counter */
     u16 *       p_yuv;                                /* base convertion table */
     u16 *       p_ybase;                       /* Y dependant convertion table */   
-    u16 *       p_pic_start;                  /* beginning of the current line */    
+    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;
 
+    /* Set scalings */
+    if( i_pic_width - i_width > 0 )
+    {
+        i_horizontal_scaling = 1;        
+    }
+    else if( i_pic_width - i_width < 0 )
+    {
+        i_horizontal_scaling = -1;        
+    }
+    else
+    {
+        i_horizontal_scaling = 0;        
+    }
+    if( i_pic_height - i_height > 0 )
+    {
+        i_vertical_scaling = 1;        
+    }
+    else if( i_pic_height - i_height < 0 )
+    {
+        i_vertical_scaling = -1;        
+    }
+    else
+    {
+        i_vertical_scaling = 0;        
+    }
+
     /*
      * Perform convertion
      */
+    i_height_count = i_pic_height;
     for( i_y = 0; i_y < i_height; i_y++ )
     {
         /* Mark beginnning of line */
         p_pic_start = p_pic;        
 
-        /* Convert line using 16 pixels blocks, since picture come from 16 pixels width
-         * macroblocks */
-        for( i_x = i_width / 16; i_x--; )
+        /* Convert line using 16 pixels blocks, since picture come from 16 pixels 
+         * width macroblocks - several loops will be used, depending of the 
+         * scaling type */
+        switch( i_horizontal_scaling )
         {
-            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;
+        case 1:                                   /* horizontal scaling is > 1 */
+            i_width_count = i_pic_width;
+            for( i_x = i_width / 16; i_x--; )
+            {
+                CONVERT_YUV_PIXEL;            
+                COPY_PIXEL;
+                CONVERT_Y_PIXEL;
+                COPY_PIXEL;
+                CONVERT_YUV_PIXEL;            
+                COPY_PIXEL;
+                CONVERT_Y_PIXEL;
+                COPY_PIXEL;
+                CONVERT_YUV_PIXEL;            
+                COPY_PIXEL;
+                CONVERT_Y_PIXEL;
+                COPY_PIXEL;
+                CONVERT_YUV_PIXEL;            
+                COPY_PIXEL;
+                CONVERT_Y_PIXEL;
+                COPY_PIXEL;
+                CONVERT_YUV_PIXEL;            
+                COPY_PIXEL;
+                CONVERT_Y_PIXEL;
+                COPY_PIXEL;
+                CONVERT_YUV_PIXEL;            
+                COPY_PIXEL;
+                CONVERT_Y_PIXEL;
+                COPY_PIXEL;
+                CONVERT_YUV_PIXEL;            
+                COPY_PIXEL;
+                CONVERT_Y_PIXEL;
+                COPY_PIXEL;
+                CONVERT_YUV_PIXEL;            
+                COPY_PIXEL;
+                CONVERT_Y_PIXEL;
+                COPY_PIXEL;
+            }            
+            break;            
+        case 0:
+            for( i_x = i_width / 16; i_x--;  )
+            {
+                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;
+            }
+            break;            
+        case -1:
+            i_width_count = i_width;            
+/*            {
+                while( (i_width_count -= i_pic_width) > 0)
+                {
+                    p_y++;
+                    p_u++;                    
+                }
+                i_width_count += i_width;            
+            }            
             CONVERT_Y_PIXEL;
-        }        
+            while( (i_width_count -= i_width) > 0)
+            {
+                *p_pic++ = *(p_pic - 1);                
+            }
+            i_width_count += i_pic_width;
+            break;            
+  */
+            break;
+        }
 
         /* If line is odd, rewind U and V samples */
         if( i_y & 0x1 )
@@ -686,8 +783,22 @@ static void ConvertYUV420RGB16( p_vout_thread_t p_vout, u16 *p_pic, yuv_data_t *
          * Handle vertical scaling. The current line is copied or next one
          * is ignored.
          */
-        if( b_inc_height )
+        switch( i_vertical_scaling )
         {
+        case -1:                         /* vertical scaling factor is < 1 */
+            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;
+            break;            
+        case 1:                          /* vertical scaling factor is > 1 */
             while( (i_height_count -= i_height) > 0 )
             {                
                 /* Height increment: copy previous picture line */
@@ -702,21 +813,8 @@ static void ConvertYUV420RGB16( p_vout_thread_t p_vout, u16 *p_pic, yuv_data_t *
                 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;            
-        }        
+            break;
+        }
     }    
 #endif
 }
@@ -826,60 +924,6 @@ static void ConvertYUV444RGB32( p_vout_thread_t p_vout, u32 *p_pic, yuv_data_t *
  * calculated to minimize the cache interactions of the 3 tables.
  */
 
-int rgbTable16 (short table [1935],
-                      int redMask, int greenMask, int blueMask,
-                      unsigned char gamma[256])
-{
-    int redRight;
-    int redLeft;
-    int greenRight;
-    int greenLeft;
-    int blueRight;
-    int blueLeft;
-    short * redTable;
-    short * greenTable;
-    short * blueTable;
-    int i;
-    int y;
-
-    MaskToShift (&redRight, &redLeft, redMask);    
-    MaskToShift (&greenRight, &greenLeft, greenMask);    
-    MaskToShift (&blueRight, &blueLeft, blueMask);
-
-    /*
-     * green blue red +- 2 just to be sure
-     * green = 0-525 [151-370]
-     * blue = 594-1297 [834-1053] <834-29>
-     * red = 1323-1934 [1517-1736] <493-712>
-     */
-
-    redTable = table + 1501;
-    greenTable = table + 135;
-    blueTable = table + 818;
-
-    for (i = 0; i < 178; i++) {
-       redTable[i-178] = 0;
-       redTable[i+256] = redMask;
-    }
-    for (i = 0; i < 135; i++) {
-       greenTable[i-135] = 0;
-       greenTable[i+256] = greenMask;
-    }
-    for (i = 0; i < 224; i++) {
-       blueTable[i-224] = 0;
-       blueTable[i+256] = blueMask;
-    }
-
-    for (i = 0; i < 256; i++) {
-       y = gamma[i];
-       redTable[i] = ((y >> redRight) << redLeft);
-       greenTable[i] = ((y >> greenRight) << greenLeft);
-       blueTable[i] = ((y >> blueRight) << blueLeft);
-    }
-
-    return 0;
-}
-
 static int rgbTable32 (int table [1935],
                       int redMask, int greenMask, int blueMask,
                       unsigned char gamma[256])