#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 );
+
+/*****************************************************************************
+ * 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;
+}
+
/*****************************************************************************
- * vout_InitYUV: allocate and initialize translations tables
+ * 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 );
+}
+
+/*****************************************************************************
+ * yuv_Init: allocate and initialize translations tables
*****************************************************************************
* This function will allocate memory to store translation tables, depending
* of the screen depth.
*****************************************************************************/
-int yuv_CInit( vout_thread_t *p_vout )
+static int yuv_Init( vout_thread_t *p_vout )
{
size_t tables_size; /* tables size, in bytes */
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 );
}
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 );
}
/*****************************************************************************
- * yuv_CEnd: destroy translations tables
+ * yuv_End: destroy translations tables
*****************************************************************************
* Free memory allocated by yuv_CCreate.
*****************************************************************************/
-void yuv_CEnd( vout_thread_t *p_vout )
+static void yuv_End( vout_thread_t *p_vout )
{
free( p_vout->yuv.p_base );
free( p_vout->yuv.p_buffer );
}
/*****************************************************************************
- * yuv_CReset: re-initialize translations tables
+ * yuv_Reset: re-initialize translations tables
*****************************************************************************
* This function will initialize the tables allocated by vout_CreateTables and
* set functions pointers.
*****************************************************************************/
-int yuv_CReset( vout_thread_t *p_vout )
+static int yuv_Reset( vout_thread_t *p_vout )
{
- yuv_CEnd( p_vout );
- return( yuv_CInit( p_vout ) );
+ 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 */
/*****************************************************************************
* 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 */
&& 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 );
* 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 */
/*
* 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 )
+ {
+ for( i_x = i_width; i_x--; )
+ {
+ while( (i_scale_count -= i_width) > 0 )
+ {
+ *p_offset++ = 0;
+ }
+ *p_offset++ = 1;
+ i_scale_count += i_pic_width;
+ }
+ }
+ else
{
- while( (i_scale_count -= i_width) > 0 )
+ int i_dummy = 0;
+ for( i_x = i_width; i_x--; )
{
- *p_offset++ = 0;
+ 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;
}
}