X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=plugins%2Fyuv%2Fvideo_yuv.c;h=37e7d12072f0b30b5d96075da675ccb0a738c118;hb=647cca0ebb2e897a570018ba80483bb81a7d90c6;hp=20a43e2b64900a82eaf4df306427fde317e79a9b;hpb=57e189eb5d1d387f2036c31720e1e9aa8cb3ea78;p=vlc diff --git a/plugins/yuv/video_yuv.c b/plugins/yuv/video_yuv.c index 20a43e2b64..37e7d12072 100644 --- a/plugins/yuv/video_yuv.c +++ b/plugins/yuv/video_yuv.c @@ -38,28 +38,60 @@ #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; } }