]> git.sesse.net Git - vlc/blobdiff - plugins/yuv/video_yuv.c
The motion compensation routines are now modules as well ; choose your
[vlc] / plugins / yuv / video_yuv.c
index 20a43e2b64900a82eaf4df306427fde317e79a9b..37e7d12072f0b30b5d96075da675ccb0a738c118 100644 (file)
 #include "common.h"
 #include "threads.h"
 #include "mtime.h"
-#include "plugins.h"
+#include "tests.h"
+#include "modules.h"
+
 #include "video.h"
 #include "video_output.h"
-#include "video_yuv.h"
+
+#include "video_common.h"
 
 #include "intf_msg.h"
 
+static int     yuv_Probe      ( probedata_t *p_data );
+static int     yuv_Init       ( vout_thread_t *p_vout );
+static int     yuv_Reset      ( vout_thread_t *p_vout );
+static void    yuv_End        ( vout_thread_t *p_vout );
+
+static void    SetGammaTable  ( int *pi_table, double f_gamma );
+static void    SetYUV         ( vout_thread_t *p_vout );
+
 /*****************************************************************************
- * Constants
+ * Functions exported as capabilities. They are declared as static so that
+ * we don't pollute the namespace too much.
  *****************************************************************************/
+void yuv_getfunctions( function_list_t * p_function_list )
+{
+    p_function_list->pf_probe = yuv_Probe;
+    p_function_list->functions.yuv.pf_init = yuv_Init;
+    p_function_list->functions.yuv.pf_reset = yuv_Reset;
+    p_function_list->functions.yuv.pf_end = yuv_End;
+}
 
-int     yuv_SysInit     ( vout_thread_t *p_vout );
-int     yuv_SysReset    ( vout_thread_t *p_vout );
-void    yuv_SysEnd      ( vout_thread_t *p_vout );
+/*****************************************************************************
+ * yuv_Probe: tests probe the audio device and return a score
+ *****************************************************************************
+ * This function tries to open the DSP and returns a score to the plugin
+ * manager so that it can choose the most appropriate one.
+ *****************************************************************************/
+static int yuv_Probe( probedata_t *p_data )
+{
+    if( TestMethod( YUV_METHOD_VAR, "yuv" ) )
+    {
+        return( 999 );
+    }
+
+    /* This module always works */
+    return( 50 );
+}
 
 /*****************************************************************************
- * vout_InitYUV: allocate and initialize translations tables
+ * yuv_Init: allocate and initialize translations tables
  *****************************************************************************
  * This function will allocate memory to store translation tables, depending
  * of the screen depth.
  *****************************************************************************/
-int yuv_SysInit( vout_thread_t *p_vout )
+static int yuv_Init( vout_thread_t *p_vout )
 {
     size_t      tables_size;                        /* tables size, in bytes */
 
@@ -86,7 +118,7 @@ int yuv_SysInit( vout_thread_t *p_vout )
     p_vout->yuv.p_base = malloc( tables_size );
     if( p_vout->yuv.p_base == NULL )
     {
-        intf_ErrMsg("error: %s\n", strerror(ENOMEM));
+        intf_ErrMsg("error: %s", strerror(ENOMEM));
         return( 1 );
     }
 
@@ -94,14 +126,18 @@ int yuv_SysInit( vout_thread_t *p_vout )
     p_vout->yuv.p_buffer = malloc( VOUT_MAX_WIDTH * p_vout->i_bytes_per_pixel );
     if( p_vout->yuv.p_buffer == NULL )
     {
-        intf_ErrMsg("error: %s\n", strerror(ENOMEM));
+        intf_ErrMsg("error: %s", strerror(ENOMEM));
         free( p_vout->yuv.p_base );
         return( 1 );
     }
-    p_vout->yuv.p_offset = malloc( p_vout->i_width * sizeof( int ) );
+
+    /* In 8bpp we have a twice as big offset table because we also
+     * need the offsets for U and V (not only Y) */
+    p_vout->yuv.p_offset = malloc( p_vout->i_width * sizeof( int ) *
+                             ( ( p_vout->i_bytes_per_pixel == 1 ) ? 2 : 1 ) );
     if( p_vout->yuv.p_offset == NULL )
     {
-        intf_ErrMsg("error: %s\n", strerror(ENOMEM));
+        intf_ErrMsg("error: %s", strerror(ENOMEM));
         free( p_vout->yuv.p_base );
         free( p_vout->yuv.p_buffer );
         return( 1 );
@@ -113,37 +149,35 @@ int yuv_SysInit( vout_thread_t *p_vout )
 }
 
 /*****************************************************************************
- * yuv_SysReset: re-initialize translations tables
+ * yuv_End: destroy translations tables
  *****************************************************************************
- * This function will initialize the tables allocated by vout_CreateTables and
- * set functions pointers.
+ * Free memory allocated by yuv_CCreate.
  *****************************************************************************/
-int yuv_SysReset( vout_thread_t *p_vout )
+static void yuv_End( vout_thread_t *p_vout )
 {
-    yuv_SysEnd( p_vout );
-    return( yuv_SysInit( p_vout ) );
+    free( p_vout->yuv.p_base );
+    free( p_vout->yuv.p_buffer );
+    free( p_vout->yuv.p_offset );
 }
 
 /*****************************************************************************
- * yuv_SysEnd: destroy translations tables
+ * yuv_Reset: re-initialize translations tables
  *****************************************************************************
- * Free memory allocated by yuv_SysCreate.
+ * This function will initialize the tables allocated by vout_CreateTables and
+ * set functions pointers.
  *****************************************************************************/
-void yuv_SysEnd( vout_thread_t *p_vout )
+static int yuv_Reset( vout_thread_t *p_vout )
 {
-    free( p_vout->yuv.p_base );
-    free( p_vout->yuv.p_buffer );
-    free( p_vout->yuv.p_offset );
+    yuv_End( p_vout );
+    return( yuv_Init( p_vout ) );
 }
 
-/* following functions are local */
-
 /*****************************************************************************
  * SetGammaTable: return intensity table transformed by gamma curve.
  *****************************************************************************
  * pi_table is a table of 256 entries from 0 to 255.
  *****************************************************************************/
-void SetGammaTable( int *pi_table, double f_gamma )
+static void SetGammaTable( int *pi_table, double f_gamma )
 {
     int         i_y;                                       /* base intensity */
 
@@ -159,8 +193,8 @@ void SetGammaTable( int *pi_table, double f_gamma )
 
 /*****************************************************************************
  * SetYUV: compute tables and set function pointers
-+ *****************************************************************************/
-void SetYUV( vout_thread_t *p_vout )
+ *****************************************************************************/
+static void SetYUV( vout_thread_t *p_vout )
 {
     int         pi_gamma[256];                                /* gamma table */
     int         i_index;                                  /* index in tables */
@@ -266,7 +300,7 @@ void SetYUV( vout_thread_t *p_vout )
                                 && r <= RGB_MAX && g <= RGB_MAX && b <= RGB_MAX )
                         {
                             /* this one should never happen unless someone fscked up my code */
-                            if(j == 256) { intf_ErrMsg( "vout error: no colors left to build palette\n" ); break; }
+                            if(j == 256) { intf_ErrMsg( "vout error: no colors left to build palette" ); break; }
 
                             /* clip the colors */
                             red[j] = CLIP( r );
@@ -459,10 +493,12 @@ void SetYUV( vout_thread_t *p_vout )
  * SetOffset: build offset array for conversion functions
  *****************************************************************************
  * This function will build an offset array used in later conversion functions.
- * It will also set horizontal and vertical scaling indicators.
+ * It will also set horizontal and vertical scaling indicators. If b_double
+ * is set, the p_offset structure has interleaved Y and U/V offsets.
  *****************************************************************************/
 void SetOffset( int i_width, int i_height, int i_pic_width, int i_pic_height,
-                boolean_t *pb_h_scaling, int *pi_v_scaling, int *p_offset )
+                boolean_t *pb_h_scaling, int *pi_v_scaling,
+                int *p_offset, boolean_t b_double )
 {
     int i_x;                                    /* x position in destination */
     int i_scale_count;                                     /* modulo counter */
@@ -470,57 +506,96 @@ void SetOffset( int i_width, int i_height, int i_pic_width, int i_pic_height,
     /*
      * Prepare horizontal offset array
      */
-    if( i_pic_width - i_width > 0 )
+    if( i_pic_width - i_width == 0 )
+    {
+        /* No horizontal scaling: YUV conversion is done directly to picture */
+        *pb_h_scaling = 0;
+    }
+    else if( i_pic_width - i_width > 0 )
     {
         /* Prepare scaling array for horizontal extension */
-        *pb_h_scaling =  1;
-        i_scale_count =         i_pic_width;
-        for( i_x = i_width; i_x--; )
+        *pb_h_scaling = 1;
+        i_scale_count = i_pic_width;
+        if( !b_double )
         {
-            while( (i_scale_count -= i_width) > 0 )
+            for( i_x = i_width; i_x--; )
             {
-                *p_offset++ = 0;
+                while( (i_scale_count -= i_width) > 0 )
+                {
+                    *p_offset++ = 0;
+                }
+                *p_offset++ = 1;
+                i_scale_count += i_pic_width;
+            }
+        }
+        else
+        {
+            int i_dummy = 0;
+            for( i_x = i_width; i_x--; )
+            {
+                while( (i_scale_count -= i_width) > 0 )
+                {
+                    *p_offset++ = 0;
+                    *p_offset++ = 0;
+                }
+                *p_offset++ = 1;
+                *p_offset++ = i_dummy;
+                i_dummy = 1 - i_dummy;
+                i_scale_count += i_pic_width;
             }
-            *p_offset++ = 1;
-            i_scale_count += i_pic_width;
         }
     }
-    else if( i_pic_width - i_width < 0 )
+    else /* if( i_pic_width - i_width < 0 ) */
     {
         /* Prepare scaling array for horizontal reduction */
-        *pb_h_scaling =  1;
-        i_scale_count =         i_pic_width;
-        for( i_x = i_pic_width; i_x--; )
+        *pb_h_scaling = 1;
+        i_scale_count = i_width;
+        if( !b_double )
         {
-            *p_offset = 1;
-            while( (i_scale_count -= i_pic_width) >= 0 )
+           for( i_x = i_pic_width; i_x--; )
             {
-                *p_offset += 1;
+                *p_offset = 1;
+                while( (i_scale_count -= i_pic_width) > 0 )
+                {
+                    *p_offset += 1;
+                }
+                p_offset++;
+                i_scale_count += i_width;
             }
-            p_offset++;
-            i_scale_count += i_width;
         }
-    }
-    else
-    {
-        /* No horizontal scaling: YUV conversion is done directly to picture */
-        *pb_h_scaling = 0;
-    }
+        else
+        {
+            int i_remainder = 0;
+            int i_jump;
+            for( i_x = i_pic_width; i_x--; )
+            {
+                i_jump = 1;
+                while( (i_scale_count -= i_pic_width) > 0 )
+                {
+                    i_jump += 1;
+                }
+                *p_offset++ = i_jump;
+                *p_offset++ = ( i_jump += i_remainder ) >> 1;
+                i_remainder = i_jump & 1;
+                i_scale_count += i_width;
+            }
+        }
+     }
 
     /*
      * Set vertical scaling indicator
      */
-    if( i_pic_height - i_height > 0 )
+    if( i_pic_height - i_height == 0 )
     {
-        *pi_v_scaling = 1;
+        *pi_v_scaling = 0;
     }
-    else if( i_pic_height - i_height < 0 )
+    else if( i_pic_height - i_height > 0 )
     {
-        *pi_v_scaling = -1;
+        *pi_v_scaling = 1;
     }
-    else
+    else /* if( i_pic_height - i_height < 0 ) */
     {
-        *pi_v_scaling = 0;
+        *pi_v_scaling = -1;
     }
 }