X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=modules%2Fvideo_filter%2Fpanoramix.c;h=73c92814fbbafb454b33f6cafdfe91fd6845aa51;hb=9a9570009287f6ea810c725afae86556c454e39a;hp=19e9ebd34d7b3a5e1d9230de1b9491bb85b7dbd9;hpb=dbddc5ae452252807b520abdb803cf5f231bbdf0;p=vlc diff --git a/modules/video_filter/panoramix.c b/modules/video_filter/panoramix.c index 19e9ebd34d..73c92814fb 100644 --- a/modules/video_filter/panoramix.c +++ b/modules/video_filter/panoramix.c @@ -30,8 +30,10 @@ # include "config.h" #endif -#include +#include +#include #include +#include #include "filter_common.h" @@ -39,8 +41,8 @@ #define OVERLAP 2350 #ifdef OVERLAP #include - // OS CODE DEPENDANT to get display dimensions - #ifdef SYS_MINGW32 + // OS CODE DEPENDENT to get display dimensions + #ifdef WIN32 #include #else #include @@ -71,8 +73,12 @@ static void RenderPackedRGB ( vout_thread_t *, picture_t * ); static void RemoveAllVout ( vout_thread_t *p_vout ); -static int SendEvents( vlc_object_t *, char const *, +static int MouseEvent( vlc_object_t *, char const *, vlc_value_t, vlc_value_t, void * ); +static int FullscreenEventUp( vlc_object_t *, char const *, + vlc_value_t, vlc_value_t, void * ); +static int FullscreenEventDown( vlc_object_t *, char const *, + vlc_value_t, vlc_value_t, void * ); /***************************************************************************** * Module descriptor @@ -91,62 +97,62 @@ static int SendEvents( vlc_object_t *, char const *, #define CFG_PREFIX "panoramix-" -vlc_module_begin(); - set_description( N_("Panoramix: wall with overlap video filter") ); - set_shortname( _("Panoramix" )); - set_capability( "video filter", 0 ); - set_category( CAT_VIDEO ); - set_subcategory( SUBCAT_VIDEO_VFILTER ); +vlc_module_begin () + set_description( N_("Panoramix: wall with overlap video filter") ) + set_shortname( N_("Panoramix" )) + set_capability( "video filter", 0 ) + set_category( CAT_VIDEO ) + set_subcategory( SUBCAT_VIDEO_VFILTER ) add_integer( CFG_PREFIX "cols", -1, NULL, - COLS_TEXT, COLS_LONGTEXT, VLC_TRUE ); + COLS_TEXT, COLS_LONGTEXT, true ) add_integer( CFG_PREFIX "rows", -1, NULL, - ROWS_TEXT, ROWS_LONGTEXT, VLC_TRUE ); + ROWS_TEXT, ROWS_LONGTEXT, true ) #ifdef OVERLAP #define OFFSET_X_TEXT N_("Offset X offset (automatic compensation)") #define OFFSET_X_LONGTEXT N_("Select if you want an automatic offset in horizontal (in case of misalignment due to autoratio control)") - add_bool( CFG_PREFIX "offset-x", 1, NULL, OFFSET_X_TEXT, OFFSET_X_LONGTEXT, VLC_TRUE ); + add_bool( CFG_PREFIX "offset-x", 1, NULL, OFFSET_X_TEXT, OFFSET_X_LONGTEXT, true ) #define LENGTH_TEXT N_("length of the overlapping area (in %)") #define LENGTH_LONGTEXT N_("Select in percent the length of the blended zone") - add_integer_with_range( CFG_PREFIX "bz-length", 100, 0, 100, NULL, LENGTH_TEXT, LENGTH_LONGTEXT, VLC_TRUE ); + add_integer_with_range( CFG_PREFIX "bz-length", 100, 0, 100, NULL, LENGTH_TEXT, LENGTH_LONGTEXT, true ) #define HEIGHT_TEXT N_("height of the overlapping area (in %)") #define HEIGHT_LONGTEXT N_("Select in percent the height of the blended zone (case of 2x2 wall)") - add_integer_with_range( CFG_PREFIX "bz-height", 100, 0, 100, NULL, HEIGHT_TEXT, HEIGHT_LONGTEXT, VLC_TRUE ); + add_integer_with_range( CFG_PREFIX "bz-height", 100, 0, 100, NULL, HEIGHT_TEXT, HEIGHT_LONGTEXT, true ) #define ATTENUATION_TEXT N_("Attenuation") #define ATTENUATION_LONGTEXT N_("Check this option if you want attenuate blended zone by this plug-in (if option is unchecked, attenuate is made by opengl)") - add_bool( CFG_PREFIX "attenuate", 1, NULL, ATTENUATION_TEXT, ATTENUATION_LONGTEXT, VLC_FALSE ); + add_bool( CFG_PREFIX "attenuate", 1, NULL, ATTENUATION_TEXT, ATTENUATION_LONGTEXT, false ) #define BEGIN_TEXT N_("Attenuation, begin (in %)") #define BEGIN_LONGTEXT N_("Select in percent the Lagrange coeff of the beginning blended zone") - add_integer_with_range( CFG_PREFIX "bz-begin", 0, 0, 100, NULL, BEGIN_TEXT, BEGIN_LONGTEXT, VLC_TRUE ); + add_integer_with_range( CFG_PREFIX "bz-begin", 0, 0, 100, NULL, BEGIN_TEXT, BEGIN_LONGTEXT, true ) #define MIDDLE_TEXT N_("Attenuation, middle (in %)") #define MIDDLE_LONGTEXT N_("Select in percent the Lagrange coeff of the middle of blended zone") - add_integer_with_range( CFG_PREFIX "bz-middle", 50, 0, 100, NULL, MIDDLE_TEXT, MIDDLE_LONGTEXT, VLC_FALSE ); + add_integer_with_range( CFG_PREFIX "bz-middle", 50, 0, 100, NULL, MIDDLE_TEXT, MIDDLE_LONGTEXT, false ) #define END_TEXT N_("Attenuation, end (in %)") #define END_LONGTEXT N_("Select in percent the Lagrange coeff of the end of blended zone") - add_integer_with_range( CFG_PREFIX "bz-end", 100, 0, 100, NULL, END_TEXT, END_LONGTEXT, VLC_TRUE ); + add_integer_with_range( CFG_PREFIX "bz-end", 100, 0, 100, NULL, END_TEXT, END_LONGTEXT, true ) #define MIDDLE_POS_TEXT N_("middle position (in %)") #define MIDDLE_POS_LONGTEXT N_("Select in percent (50 is center) the position of the middle point (Lagrange) of blended zone") - add_integer_with_range( CFG_PREFIX "bz-middle-pos", 50, 1, 99, NULL, MIDDLE_POS_TEXT, MIDDLE_POS_LONGTEXT, VLC_FALSE ); + add_integer_with_range( CFG_PREFIX "bz-middle-pos", 50, 1, 99, NULL, MIDDLE_POS_TEXT, MIDDLE_POS_LONGTEXT, false ) #ifdef GAMMA #define RGAMMA_TEXT N_("Gamma (Red) correction") #define RGAMMA_LONGTEXT N_("Select the gamma for the correction of blended zone (Red or Y component)") - add_float_with_range( CFG_PREFIX "bz-gamma-red", 1, 0, 5, NULL, RGAMMA_TEXT, RGAMMA_LONGTEXT, VLC_TRUE ); + add_float_with_range( CFG_PREFIX "bz-gamma-red", 1, 0, 5, NULL, RGAMMA_TEXT, RGAMMA_LONGTEXT, true ) #define GGAMMA_TEXT N_("Gamma (Green) correction") #define GGAMMA_LONGTEXT N_("Select the gamma for the correction of blended zone (Green or U component)") - add_float_with_range( CFG_PREFIX "bz-gamma-green", 1, 0, 5, NULL, GGAMMA_TEXT, GGAMMA_LONGTEXT, VLC_TRUE ); + add_float_with_range( CFG_PREFIX "bz-gamma-green", 1, 0, 5, NULL, GGAMMA_TEXT, GGAMMA_LONGTEXT, true ) #define BGAMMA_TEXT N_("Gamma (Blue) correction") #define BGAMMA_LONGTEXT N_("Select the gamma for the correction of blended zone (Blue or V component)") - add_float_with_range( CFG_PREFIX "bz-gamma-blue", 1, 0, 5, NULL, BGAMMA_TEXT, BGAMMA_LONGTEXT, VLC_TRUE ); + add_float_with_range( CFG_PREFIX "bz-gamma-blue", 1, 0, 5, NULL, BGAMMA_TEXT, BGAMMA_LONGTEXT, true ) #endif #define RGAMMA_BC_TEXT N_("Black Crush for Red") #define RGAMMA_BC_LONGTEXT N_("Select the Black Crush of blended zone (Red or Y component)") @@ -175,32 +181,32 @@ vlc_module_begin(); #define GGAMMA_WL_LONGTEXT N_("Select the White Level of blended zone (Green or U component)") #define BGAMMA_WL_TEXT N_("White Level for Blue") #define BGAMMA_WL_LONGTEXT N_("Select the White Level of blended zone (Blue or V component)") - add_integer_with_range( CFG_PREFIX "bz-blackcrush-red", 140, 0, 255, NULL, RGAMMA_BC_TEXT, RGAMMA_BC_LONGTEXT, VLC_TRUE ); - add_integer_with_range( CFG_PREFIX "bz-blackcrush-green", 140, 0, 255, NULL, GGAMMA_BC_TEXT, GGAMMA_BC_LONGTEXT, VLC_TRUE ); - add_integer_with_range( CFG_PREFIX "bz-blackcrush-blue", 140, 0, 255, NULL, BGAMMA_BC_TEXT, BGAMMA_BC_LONGTEXT, VLC_TRUE ); - add_integer_with_range( CFG_PREFIX "bz-whitecrush-red", 200, 0, 255, NULL, RGAMMA_WC_TEXT, RGAMMA_WC_LONGTEXT, VLC_TRUE ); - add_integer_with_range( CFG_PREFIX "bz-whitecrush-green", 200, 0, 255, NULL, GGAMMA_WC_TEXT, GGAMMA_WC_LONGTEXT, VLC_TRUE ); - add_integer_with_range( CFG_PREFIX "bz-whitecrush-blue", 200, 0, 255, NULL, BGAMMA_WC_TEXT, BGAMMA_WC_LONGTEXT, VLC_TRUE ); - add_integer_with_range( CFG_PREFIX "bz-blacklevel-red", 150, 0, 255, NULL, RGAMMA_BL_TEXT, RGAMMA_BL_LONGTEXT, VLC_TRUE ); - add_integer_with_range( CFG_PREFIX "bz-blacklevel-green", 150, 0, 255, NULL, GGAMMA_BL_TEXT, GGAMMA_BL_LONGTEXT, VLC_TRUE ); - add_integer_with_range( CFG_PREFIX "bz-blacklevel-blue", 150, 0, 255, NULL, BGAMMA_BL_TEXT, BGAMMA_BL_LONGTEXT, VLC_TRUE ); - add_integer_with_range( CFG_PREFIX "bz-whitelevel-red", 0, 0, 255, NULL, RGAMMA_WL_TEXT, RGAMMA_WL_LONGTEXT, VLC_TRUE ); - add_integer_with_range( CFG_PREFIX "bz-whitelevel-green", 0, 0, 255, NULL, GGAMMA_WL_TEXT, GGAMMA_WL_LONGTEXT, VLC_TRUE ); - add_integer_with_range( CFG_PREFIX "bz-whitelevel-blue", 0, 0, 255, NULL, BGAMMA_WL_TEXT, BGAMMA_WL_LONGTEXT, VLC_TRUE ); -#ifndef SYS_MINGW32 + add_integer_with_range( CFG_PREFIX "bz-blackcrush-red", 140, 0, 255, NULL, RGAMMA_BC_TEXT, RGAMMA_BC_LONGTEXT, true ) + add_integer_with_range( CFG_PREFIX "bz-blackcrush-green", 140, 0, 255, NULL, GGAMMA_BC_TEXT, GGAMMA_BC_LONGTEXT, true ) + add_integer_with_range( CFG_PREFIX "bz-blackcrush-blue", 140, 0, 255, NULL, BGAMMA_BC_TEXT, BGAMMA_BC_LONGTEXT, true ) + add_integer_with_range( CFG_PREFIX "bz-whitecrush-red", 200, 0, 255, NULL, RGAMMA_WC_TEXT, RGAMMA_WC_LONGTEXT, true ) + add_integer_with_range( CFG_PREFIX "bz-whitecrush-green", 200, 0, 255, NULL, GGAMMA_WC_TEXT, GGAMMA_WC_LONGTEXT, true ) + add_integer_with_range( CFG_PREFIX "bz-whitecrush-blue", 200, 0, 255, NULL, BGAMMA_WC_TEXT, BGAMMA_WC_LONGTEXT, true ) + add_integer_with_range( CFG_PREFIX "bz-blacklevel-red", 150, 0, 255, NULL, RGAMMA_BL_TEXT, RGAMMA_BL_LONGTEXT, true ) + add_integer_with_range( CFG_PREFIX "bz-blacklevel-green", 150, 0, 255, NULL, GGAMMA_BL_TEXT, GGAMMA_BL_LONGTEXT, true ) + add_integer_with_range( CFG_PREFIX "bz-blacklevel-blue", 150, 0, 255, NULL, BGAMMA_BL_TEXT, BGAMMA_BL_LONGTEXT, true ) + add_integer_with_range( CFG_PREFIX "bz-whitelevel-red", 0, 0, 255, NULL, RGAMMA_WL_TEXT, RGAMMA_WL_LONGTEXT, true ) + add_integer_with_range( CFG_PREFIX "bz-whitelevel-green", 0, 0, 255, NULL, GGAMMA_WL_TEXT, GGAMMA_WL_LONGTEXT, true ) + add_integer_with_range( CFG_PREFIX "bz-whitelevel-blue", 0, 0, 255, NULL, BGAMMA_WL_TEXT, BGAMMA_WL_LONGTEXT, true ) +#ifndef WIN32 #define XINERAMA_TEXT N_("Xinerama option") #define XINERAMA_LONGTEXT N_("Uncheck if you have not used xinerama") - add_bool( CFG_PREFIX "xinerama", 1, NULL, XINERAMA_TEXT, XINERAMA_LONGTEXT, VLC_TRUE ); + add_bool( CFG_PREFIX "xinerama", 1, NULL, XINERAMA_TEXT, XINERAMA_LONGTEXT, true ) #endif #endif - add_string( CFG_PREFIX "active", NULL, NULL, ACTIVE_TEXT, ACTIVE_LONGTEXT, VLC_TRUE ); + add_string( CFG_PREFIX "active", NULL, NULL, ACTIVE_TEXT, ACTIVE_LONGTEXT, true ) - add_shortcut( "panoramix" ); - set_callbacks( Create, Destroy ); -vlc_module_end(); + add_shortcut( "panoramix" ) + set_callbacks( Create, Destroy ) +vlc_module_end () -static const char *ppsz_filter_options[] = { +static const char *const ppsz_filter_options[] = { "cols", "rows", "offset-x", "bz-length", "bz-height", "attenuate", "bz-begin", "bz-middle", "bz-end", "bz-middle-pos", "bz-gamma-red", "bz-gamma-green", "bz-gamma-blue", "bz-blackcrush-red", @@ -220,13 +226,13 @@ static const char *ppsz_filter_options[] = { struct vout_sys_t { #ifdef OVERLAP - vlc_bool_t b_autocrop; - vlc_bool_t b_attenuate; + bool b_autocrop; + bool b_attenuate; unsigned int bz_length, bz_height, bz_begin, bz_middle, bz_end, bz_middle_pos; unsigned int i_ratio_max; unsigned int i_ratio; unsigned int a_0, a_1, a_2; - vlc_bool_t b_has_changed; + bool b_has_changed; int lambda[2][VOUT_MAX_PLANES][500]; int cstYUV[2][VOUT_MAX_PLANES][500]; int lambda2[2][VOUT_MAX_PLANES][500]; @@ -243,8 +249,8 @@ struct vout_sys_t uint8_t LUT2[VOUT_MAX_PLANES][256][500]; #endif #endif -#ifndef SYS_MINGW32 - vlc_bool_t b_xinerama; +#ifndef WIN32 + bool b_xinerama; #endif #endif int i_col; @@ -252,7 +258,7 @@ struct vout_sys_t int i_vout; struct vout_list_t { - vlc_bool_t b_active; + bool b_active; int i_width; int i_height; vout_thread_t *p_vout; @@ -294,10 +300,7 @@ static int Create( vlc_object_t *p_this ) /* Allocate structure */ p_vout->p_sys = malloc( sizeof( vout_sys_t ) ); if( p_vout->p_sys == NULL ) - { - msg_Err( p_vout, "out of memory" ); return VLC_ENOMEM; - } p_vout->pf_init = Init; p_vout->pf_end = End; @@ -359,8 +362,8 @@ case VLC_FOURCC('c','y','u','v'): // packed by 2 p_vout->p_sys->i_col = var_CreateGetInteger( p_vout, CFG_PREFIX "cols" ); p_vout->p_sys->i_row = var_CreateGetInteger( p_vout, CFG_PREFIX "rows" ); -// OS dependant code : Autodetect number of displays in wall -#ifdef SYS_MINGW32 +// OS dependent code : Autodetect number of displays in wall +#ifdef WIN32 if ((p_vout->p_sys->i_col < 0) || (p_vout->p_sys->i_row < 0) ) { int nbMonitors = GetSystemMetrics(SM_CMONITORS); @@ -386,11 +389,11 @@ case VLC_FOURCC('c','y','u','v'): // packed by 2 #endif #ifdef OVERLAP - p_vout->p_sys->i_offset_x = var_CreateGetInteger( p_vout, CFG_PREFIX "offset-x" ); + p_vout->p_sys->i_offset_x = var_CreateGetBool( p_vout, CFG_PREFIX "offset-x" ); if (p_vout->p_sys->i_col > 2) p_vout->p_sys->i_offset_x = 0; // offset-x is used in case of 2x1 wall & autocrop p_vout->p_sys->b_autocrop = !(var_CreateGetInteger( p_vout, "crop-ratio" ) == 0); if (!p_vout->p_sys->b_autocrop) p_vout->p_sys->b_autocrop = var_CreateGetInteger( p_vout, "autocrop" ); - p_vout->p_sys->b_attenuate = var_CreateGetInteger( p_vout, CFG_PREFIX "attenuate"); + p_vout->p_sys->b_attenuate = var_CreateGetBool( p_vout, CFG_PREFIX "attenuate"); p_vout->p_sys->bz_length = var_CreateGetInteger( p_vout, CFG_PREFIX "bz-length" ); if (p_vout->p_sys->i_row > 1) p_vout->p_sys->bz_height = var_CreateGetInteger( p_vout, CFG_PREFIX "bz-height" ); @@ -413,8 +416,8 @@ case VLC_FOURCC('c','y','u','v'): // packed by 2 p_vout->p_sys->f_gamma_green = var_CreateGetFloat( p_vout, CFG_PREFIX "bz-gamma-green" ); p_vout->p_sys->f_gamma_blue = var_CreateGetFloat( p_vout, CFG_PREFIX "bz-gamma-blue" ); #endif -#ifndef SYS_MINGW32 - p_vout->p_sys->b_xinerama= var_CreateGetInteger( p_vout, CFG_PREFIX "xinerama" ); +#ifndef WIN32 + p_vout->p_sys->b_xinerama = var_CreateGetBool( p_vout, CFG_PREFIX "xinerama" ); #endif #else p_vout->p_sys->i_col = __MAX( 1, __MIN( 15, p_vout->p_sys->i_col ) ); @@ -424,12 +427,11 @@ case VLC_FOURCC('c','y','u','v'): // packed by 2 msg_Dbg( p_vout, "opening a %i x %i wall", p_vout->p_sys->i_col, p_vout->p_sys->i_row ); - p_vout->p_sys->pp_vout = malloc( p_vout->p_sys->i_row * - p_vout->p_sys->i_col * + p_vout->p_sys->pp_vout = calloc( p_vout->p_sys->i_row * + p_vout->p_sys->i_col, sizeof(struct vout_list_t) ); if( p_vout->p_sys->pp_vout == NULL ) { - msg_Err( p_vout, "out of memory" ); free( p_vout->p_sys ); return VLC_ENOMEM; } @@ -508,14 +510,18 @@ static double Gamma_Correction(int i_plane, float f_component, float f_BlackCrus f_Input = (f_component * f_BlackLevel[i_plane]) / (f_BlackCrush[i_plane]) + (1.0 - f_BlackLevel[i_plane]); if (f_component <= f_BlackCrush[i_plane]) - return pow(f_Input, 1.0 / f_Gamma[i_plane]); + { + return pow(f_Input, 1.0 / f_Gamma[i_plane]); + } else if (f_component >= f_WhiteCrush[i_plane]) { f_Input = (f_component * (1.0 - (f_WhiteLevel[i_plane] + 1.0)) + (f_WhiteLevel[i_plane] + 1.0) * f_WhiteCrush[i_plane] - 1.0) / (f_WhiteCrush[i_plane] - 1.0); return pow(f_Input, 1.0 / f_Gamma[i_plane]); } - else - return 1.0; + else + { + return 1.0; + } } #ifdef PACKED_YUV @@ -525,15 +531,14 @@ static double Gamma_Correction(int i_plane, float f_component, float f_BlackCrus *****************************************************************************/ static uint8_t F(uint8_t i, float gamma) { - double input = (double) i / 255.0; - -// return clip(255 * pow(input, 1.0 / gamma)); + double input = (double) i / 255.0; - if (input < 0.5) - return clip_uint8((255 * pow(2 * input, gamma)) / 2); - else - return clip_uint8(255 * (1 - pow(2 * (1 - input), gamma) / 2)); + // return clip(255 * pow(input, 1.0 / gamma)); + if (input < 0.5) + return clip_uint8((255 * pow(2 * input, gamma)) / 2); + else + return clip_uint8(255 * (1 - pow(2 * (1 - input), gamma) / 2)); } #endif #endif @@ -543,7 +548,7 @@ static uint8_t F(uint8_t i, float gamma) *****************************************************************************/ static int AdjustHeight( vout_thread_t *p_vout ) { - vlc_bool_t b_fullscreen = var_CreateGetInteger( p_vout, "fullscreen" ); + bool b_fullscreen = p_vout->b_fullscreen; int i_window_width = p_vout->i_window_width; int i_window_height = p_vout->i_window_height; double d_halfLength = 0; @@ -551,59 +556,64 @@ static int AdjustHeight( vout_thread_t *p_vout ) double d_halfLength_calculated; int i_offset = 0; -// OS DEPENDANT CODE to get display dimensions - if (b_fullscreen) - { -#ifdef SYS_MINGW32 - i_window_width = GetSystemMetrics(SM_CXSCREEN); - i_window_height = GetSystemMetrics(SM_CYSCREEN); + // OS DEPENDENT CODE to get display dimensions + if (b_fullscreen ) + { +#ifdef WIN32 + i_window_width = GetSystemMetrics(SM_CXSCREEN); + i_window_height = GetSystemMetrics(SM_CYSCREEN); #else - Display *p_display = XOpenDisplay( "" ); - if (p_vout->p_sys->b_xinerama) - { - i_window_width = DisplayWidth(p_display, 0) / p_vout->p_sys->i_col; - i_window_height = DisplayHeight(p_display, 0) / p_vout->p_sys->i_row; - } - else - { - i_window_width = DisplayWidth(p_display, 0); - i_window_height = DisplayHeight(p_display, 0); - } - XCloseDisplay( p_display ); - free(p_display); + char *psz_display = var_CreateGetNonEmptyString( p_vout, + "x11-display" ); + Display *p_display = XOpenDisplay( psz_display ); + free( psz_display ); + if (p_vout->p_sys->b_xinerama) + { + i_window_width = DisplayWidth(p_display, 0) / p_vout->p_sys->i_col; + i_window_height = DisplayHeight(p_display, 0) / p_vout->p_sys->i_row; + } + else + { + i_window_width = DisplayWidth(p_display, 0); + i_window_height = DisplayHeight(p_display, 0); + } + XCloseDisplay( p_display ); #endif var_SetInteger( p_vout, "width", i_window_width); var_SetInteger( p_vout, "height", i_window_height); p_vout->i_window_width = i_window_width; - p_vout->i_window_height = i_window_height; - } + p_vout->i_window_height = i_window_height; + } - if (p_vout->p_sys->bz_length) + if( p_vout->p_sys->bz_length) if ((!p_vout->p_sys->b_autocrop) && (!p_vout->p_sys->i_ratio)) { if ((p_vout->p_sys->i_row > 1) || (p_vout->p_sys->i_col > 1)) { - while ((d_halfLength <= 0) || (d_halfLength > p_vout->render.i_width / (2 * p_vout->p_sys->i_col))) - { - if (p_vout->p_sys->bz_length >= 50) - d_halfLength = i_window_width * p_vout->render.i_height / (2 * i_window_height * p_vout->p_sys->i_row) - p_vout->render.i_width / (2 * p_vout->p_sys->i_col); - else - { - d_halfLength = (p_vout->render.i_width * p_vout->p_sys->bz_length) / (100.0 * p_vout->p_sys->i_col); - d_halfLength = __MAX(i_window_width * p_vout->render.i_height / (2 * i_window_height * p_vout->p_sys->i_row) - p_vout->render.i_width / (2 * p_vout->p_sys->i_col), d_halfLength); - } - if ((d_halfLength <= 0) || (d_halfLength > p_vout->render.i_width / (2 * p_vout->p_sys->i_col))) p_vout->p_sys->i_row--; - if (p_vout->p_sys->i_row < 1 ) + while ((d_halfLength <= 0) || (d_halfLength > p_vout->render.i_width / (2 * p_vout->p_sys->i_col))) { - p_vout->p_sys->i_row = 1; - break; + if (p_vout->p_sys->bz_length >= 50) + { + d_halfLength = i_window_width * p_vout->render.i_height / (2 * i_window_height * p_vout->p_sys->i_row) - p_vout->render.i_width / (2 * p_vout->p_sys->i_col); + } + else + { + d_halfLength = (p_vout->render.i_width * p_vout->p_sys->bz_length) / (100.0 * p_vout->p_sys->i_col); + d_halfLength = __MAX(i_window_width * p_vout->render.i_height / (2 * i_window_height * p_vout->p_sys->i_row) - p_vout->render.i_width / (2 * p_vout->p_sys->i_col), d_halfLength); + } + if ((d_halfLength <= 0) || (d_halfLength > p_vout->render.i_width / (2 * p_vout->p_sys->i_col))) + p_vout->p_sys->i_row--; + if (p_vout->p_sys->i_row < 1 ) + { + p_vout->p_sys->i_row = 1; + break; + } } - } - p_vout->p_sys->i_halfLength = (d_halfLength + 0.5); - p_vout->p_sys->bz_length = (p_vout->p_sys->i_halfLength * 100.0 * p_vout->p_sys->i_col) / p_vout->render.i_width; - var_SetInteger( p_vout, "bz-length", p_vout->p_sys->bz_length); - var_SetInteger( p_vout, "panoramix-rows", p_vout->p_sys->i_row); - } + p_vout->p_sys->i_halfLength = (d_halfLength + 0.5); + p_vout->p_sys->bz_length = (p_vout->p_sys->i_halfLength * 100.0 * p_vout->p_sys->i_col) / p_vout->render.i_width; + var_SetInteger( p_vout, "bz-length", p_vout->p_sys->bz_length); + var_SetInteger( p_vout, "panoramix-rows", p_vout->p_sys->i_row); + } } else { @@ -625,10 +635,10 @@ static int AdjustHeight( vout_thread_t *p_vout ) (p_vout->p_sys->i_halfLength * (double)i_window_height * (double)p_vout->render.i_aspect / VOUT_ASPECT_FACTOR / (double)p_vout->output.i_width); } - else - d_halfLength = 0; + else + p_vout->p_sys->i_halfLength = 0; - return i_offset; + return i_offset; } #endif @@ -636,10 +646,11 @@ static int AdjustHeight( vout_thread_t *p_vout ) /***************************************************************************** * Init: initialize Wall video thread output method *****************************************************************************/ +#define VLC_XCHG( type, a, b ) do { type __tmp = (b); (b) = (a); (a) = __tmp; } while(0) + static int Init( vout_thread_t *p_vout ) { - int i_index, i_row, i_col, i_width, i_height; - picture_t *p_pic; + int i_index, i_row, i_col; I_OUTPUTPICTURES = 0; @@ -676,6 +687,16 @@ static int Init( vout_thread_t *p_vout ) f_WhiteLevel[0] = var_CreateGetInteger( p_vout, CFG_PREFIX "bz-whitelevel-red" ) / 255.0; f_WhiteLevel[1] = var_CreateGetInteger( p_vout, CFG_PREFIX "bz-whitelevel-green" ) / 255.0; f_WhiteLevel[2] = var_CreateGetInteger( p_vout, CFG_PREFIX "bz-whitelevel-blue" ) / 255.0; + for( int i = 3; i < VOUT_MAX_PLANES; i++ ) + { + /* Initialize unsupported planes */ + f_BlackCrush[i] = 140.0/255.0; + f_WhiteCrush[i] = 200.0/255.0; + f_BlackLevel[i] = 150.0/255.0; + f_WhiteLevel[i] = 0.0/255.0; + p_vout->p_sys->f_gamma[i] = 1.0; + } + switch (p_vout->render.i_chroma) { // planar YVU @@ -686,16 +707,11 @@ static int Init( vout_thread_t *p_vout ) case VLC_FOURCC('U','Y','N','V'): // packed by 2 case VLC_FOURCC('Y','4','2','2'): // packed by 2 // case VLC_FOURCC('c','y','u','v'): // packed by 2 - p_vout->p_sys->f_gamma[2] = var_CreateGetFloat( p_vout, CFG_PREFIX "bz-gamma-green" ); - p_vout->p_sys->f_gamma[1] = var_CreateGetFloat( p_vout, CFG_PREFIX "bz-gamma-blue" ); - f_BlackCrush[2] = var_CreateGetInteger( p_vout, CFG_PREFIX "bz-blackcrush-green" ) / 255.0; - f_BlackCrush[1] = var_CreateGetInteger( p_vout, CFG_PREFIX "bz-blackcrush-blue" ) / 255.0; - f_WhiteCrush[2] = var_CreateGetInteger( p_vout, CFG_PREFIX "bz-whitecrush-green" ) / 255.0; - f_WhiteCrush[1] = var_CreateGetInteger( p_vout, CFG_PREFIX "bz-whitecrush-blue" ) / 255.0; - f_BlackLevel[2] = var_CreateGetInteger( p_vout, CFG_PREFIX "bz-blacklevel-green" ) / 255.0; - f_BlackLevel[1] = var_CreateGetInteger( p_vout, CFG_PREFIX "bz-blacklevel-blue" ) / 255.0; - f_WhiteLevel[2] = var_CreateGetInteger( p_vout, CFG_PREFIX "bz-whitelevel-green" ) / 255.0; - f_WhiteLevel[1] = var_CreateGetInteger( p_vout, CFG_PREFIX "bz-whitelevel-blue" ) / 255.0; + VLC_XCHG( float, p_vout->p_sys->f_gamma[1], p_vout->p_sys->f_gamma[2] ); + VLC_XCHG( float, f_BlackCrush[1], f_BlackCrush[2] ); + VLC_XCHG( float, f_WhiteCrush[1], f_WhiteCrush[2] ); + VLC_XCHG( float, f_BlackLevel[1], f_BlackLevel[2] ); + VLC_XCHG( float, f_WhiteLevel[1], f_WhiteLevel[2] ); // planar YUV case VLC_FOURCC('I','4','4','4'): case VLC_FOURCC('I','4','2','2'): @@ -746,70 +762,59 @@ static int Init( vout_thread_t *p_vout ) p_vout->p_sys->i_offset_x = AdjustHeight(p_vout); else AdjustHeight(p_vout); + if (p_vout->p_sys->i_row >= 2) + { + p_vout->p_sys->i_halfHeight = (p_vout->p_sys->i_halfLength * p_vout->p_sys->bz_height) / 100; + p_vout->p_sys->i_halfHeight -= (p_vout->p_sys->i_halfHeight % 2); + } #endif /* Try to open the real video output */ msg_Dbg( p_vout, "spawning the real video outputs" ); - p_vout->p_sys->i_vout = 0; - /* FIXME: use bresenham instead of those ugly divisions */ + p_vout->p_sys->i_vout = 0; for( i_row = 0; i_row < p_vout->p_sys->i_row; i_row++ ) { - for( i_col = 0; i_col < p_vout->p_sys->i_col; i_col++ ) + for( i_col = 0; i_col < p_vout->p_sys->i_col; i_col++, p_vout->p_sys->i_vout++ ) { + struct vout_list_t *p_entry = &p_vout->p_sys->pp_vout[ p_vout->p_sys->i_vout ]; video_format_t fmt; + int i_width, i_height; - memset( &fmt, 0, sizeof(video_format_t) ); - - if( i_col + 1 < p_vout->p_sys->i_col ) - { - i_width = ( p_vout->render.i_width - / p_vout->p_sys->i_col ) & ~0x1; - } - else - { - i_width = p_vout->render.i_width - - ( ( p_vout->render.i_width - / p_vout->p_sys->i_col ) & ~0x1 ) * i_col; + /* */ + i_width = ( p_vout->render.i_width / p_vout->p_sys->i_col ) & ~0x1; + if( i_col + 1 == p_vout->p_sys->i_col ) + i_width = p_vout->render.i_width - i_col * i_width; - } #ifdef OVERLAP i_width += p_vout->p_sys->i_halfLength; - if (p_vout->p_sys->i_col > 2 ) i_width += p_vout->p_sys->i_halfLength; - i_width -= i_width % 2; + if (p_vout->p_sys->i_col > 2 ) + i_width += p_vout->p_sys->i_halfLength; + i_width &= ~0x1; #endif - if( i_row + 1 < p_vout->p_sys->i_row ) - { - i_height = ( p_vout->render.i_height - / p_vout->p_sys->i_row ) & ~0x3; - } - else - { - i_height = p_vout->render.i_height - - ( ( p_vout->render.i_height - / p_vout->p_sys->i_row ) & ~0x3 ) * i_row; - } + /* */ + i_height = ( p_vout->render.i_height / p_vout->p_sys->i_row ) & ~0x3; + if( i_row + 1 == p_vout->p_sys->i_row ) + i_height = p_vout->render.i_height - i_row * i_height; #ifdef OVERLAP - if (p_vout->p_sys->i_row >= 2) + if(p_vout->p_sys->i_row >= 2 ) { - p_vout->p_sys->i_halfHeight = (p_vout->p_sys->i_halfLength * p_vout->p_sys->bz_height) / 100; - p_vout->p_sys->i_halfHeight -= (p_vout->p_sys->i_halfHeight % 2); i_height += p_vout->p_sys->i_halfHeight; - if (p_vout->p_sys->i_row > 2) i_height += p_vout->p_sys->i_halfHeight; + if( p_vout->p_sys->i_row > 2 ) + i_height += p_vout->p_sys->i_halfHeight; } - i_height -= i_height % 2; + i_height &= ~0x1; #endif - p_vout->p_sys->pp_vout[ p_vout->p_sys->i_vout ].i_width = i_width; - p_vout->p_sys->pp_vout[ p_vout->p_sys->i_vout ].i_height = i_height; + p_entry->i_width = i_width; + p_entry->i_height = i_height; - if( !p_vout->p_sys->pp_vout[ p_vout->p_sys->i_vout ].b_active ) - { - p_vout->p_sys->i_vout++; + if( !p_entry->b_active ) continue; - } + /* */ + memset( &fmt, 0, sizeof(video_format_t) ); fmt.i_width = fmt.i_visible_width = p_vout->render.i_width; fmt.i_height = fmt.i_visible_height = p_vout->render.i_height; fmt.i_x_offset = fmt.i_y_offset = 0; @@ -829,42 +834,46 @@ static int Init( vout_thread_t *p_vout ) p_vout->p_sys->i_offset_x = 0; } #endif - p_vout->p_sys->pp_vout[ p_vout->p_sys->i_vout ].p_vout = - vout_Create( p_vout, &fmt); + p_entry->p_vout = vout_Create( p_vout, &fmt); - if( p_vout->p_sys->pp_vout[ p_vout->p_sys->i_vout ].p_vout == NULL ) + if( p_entry->p_vout == NULL ) { msg_Err( p_vout, "failed to get %ix%i vout threads", p_vout->p_sys->i_col, p_vout->p_sys->i_row ); RemoveAllVout( p_vout ); return VLC_EGENERIC; } - ADD_CALLBACKS( - p_vout->p_sys->pp_vout[ p_vout->p_sys->i_vout ].p_vout, - SendEvents ); + vout_filter_SetupChild( p_vout, p_entry->p_vout, + MouseEvent, FullscreenEventUp, FullscreenEventDown, true ); + #ifdef OVERLAP - p_vout->p_sys->pp_vout[ p_vout->p_sys->i_vout ].p_vout->i_alignment = 0; - if (i_col == 0) p_vout->p_sys->pp_vout[ p_vout->p_sys->i_vout ].p_vout->i_alignment |= VOUT_ALIGN_RIGHT; - else if (i_col == p_vout->p_sys->i_col -1) p_vout->p_sys->pp_vout[ p_vout->p_sys->i_vout ].p_vout->i_alignment |= VOUT_ALIGN_LEFT; + p_entry->p_vout->i_alignment = 0; + if (i_col == 0) + p_entry->p_vout->i_alignment |= VOUT_ALIGN_RIGHT; + else if (i_col == p_vout->p_sys->i_col -1) + p_entry->p_vout->i_alignment |= VOUT_ALIGN_LEFT; if (p_vout->p_sys->i_row > 1) { - if (i_row == 0) p_vout->p_sys->pp_vout[ p_vout->p_sys->i_vout ].p_vout->i_alignment |= VOUT_ALIGN_BOTTOM; - else if (i_row == p_vout->p_sys->i_row -1) p_vout->p_sys->pp_vout[ p_vout->p_sys->i_vout ].p_vout->i_alignment |= VOUT_ALIGN_TOP; + if (i_row == 0) + p_entry->p_vout->i_alignment |= VOUT_ALIGN_BOTTOM; + else if (i_row == p_vout->p_sys->i_row -1) + p_entry->p_vout->i_alignment |= VOUT_ALIGN_TOP; } - // i_n : number of active pp_vout - int i_index, i_n = p_vout->p_sys->i_vout; - for (i_index = p_vout->p_sys->i_vout; i_index >= 0; i_index--) if (!p_vout->p_sys->pp_vout[i_index].b_active) i_n -= 1; - var_SetInteger( p_vout, "align", p_vout->p_sys->pp_vout[ p_vout->p_sys->i_vout ].p_vout->i_alignment ); - var_SetInteger( p_vout, "video-x",i_video_x + p_vout->p_sys->i_offset_x + ((i_n + 1) % p_vout->p_sys->i_col) * p_vout->i_window_width); - var_SetInteger( p_vout, "video-y",i_video_y + ((i_n + 1) / p_vout->p_sys->i_col) * p_vout->i_window_height); + // i_active : number of active pp_vout + int i_active = 0; + for( int i = 0; i <= p_vout->p_sys->i_vout; i++ ) + { + if( p_vout->p_sys->pp_vout[i].b_active ) + i_active++; + } + var_SetInteger( p_vout, "align", p_entry->p_vout->i_alignment ); + var_SetInteger( p_vout, "video-x", i_video_x + p_vout->p_sys->i_offset_x + (i_active % p_vout->p_sys->i_col) * p_vout->i_window_width); + var_SetInteger( p_vout, "video-y", i_video_y + (i_active / p_vout->p_sys->i_col) * p_vout->i_window_height); #endif - p_vout->p_sys->i_vout++; } } - ALLOCATE_DIRECTBUFFERS( VOUT_MAX_PICTURES ); - - ADD_PARENT_CALLBACKS( SendEventsToChild ); + vout_filter_AllocateDirectBuffers( p_vout, VOUT_MAX_PICTURES ); return VLC_SUCCESS; } @@ -874,17 +883,13 @@ static int Init( vout_thread_t *p_vout ) *****************************************************************************/ static void End( vout_thread_t *p_vout ) { - int i_index; + RemoveAllVout( p_vout ); + + vout_filter_ReleaseDirectBuffers( p_vout ); #ifdef OVERLAP var_SetInteger( p_vout, "bz-length", p_vout->p_sys->bz_length); #endif - /* Free the fake output buffers we allocated */ - for( i_index = I_OUTPUTPICTURES ; i_index ; ) - { - i_index--; - free( PP_OUTPUTPICTURE[ i_index ]->p_data_orig ); - } } /***************************************************************************** @@ -896,16 +901,6 @@ static void Destroy( vlc_object_t *p_this ) { vout_thread_t *p_vout = (vout_thread_t *)p_this; -#ifdef GLOBAL_OUTPUT - DEL_CALLBACKS( p_vout->p_sys->p_vout, SendEvents); - vlc_object_detach( p_vout->p_sys->p_vout ); - vout_Destroy( p_vout->p_sys->p_vout ); - DEL_PARENT_CALLBACKS( SendEventsToChild); -#endif - - RemoveAllVout( p_vout ); - DEL_PARENT_CALLBACKS( SendEventsToChild ); - free( p_vout->p_sys->pp_vout ); free( p_vout->p_sys ); @@ -924,7 +919,7 @@ static void RenderPlanarYUV( vout_thread_t *p_vout, picture_t *p_pic ) int i_col, i_row, i_vout, i_plane; int pi_left_skip[VOUT_MAX_PLANES], pi_top_skip[VOUT_MAX_PLANES]; #ifdef OVERLAP - int LeftOffset, TopOffset; + int TopOffset; int constantYUV[3] = {0,128,128}; int Denom; int a_2; @@ -933,54 +928,38 @@ static void RenderPlanarYUV( vout_thread_t *p_vout, picture_t *p_pic ) int i_index, i_index2; #endif - - i_vout = 0; - for( i_plane = 0 ; i_plane < p_pic->i_planes ; i_plane++ ) - { pi_top_skip[i_plane] = 0; - } - for( i_row = 0; i_row < p_vout->p_sys->i_row; i_row++ ) + for( i_vout = 0, i_row = 0; i_row < p_vout->p_sys->i_row; i_row++ ) { for( i_plane = 0 ; i_plane < p_pic->i_planes ; i_plane++ ) - { pi_left_skip[i_plane] = 0; - } - for( i_col = 0; i_col < p_vout->p_sys->i_col; i_col++ ) + for( i_col = 0; i_col < p_vout->p_sys->i_col; i_col++, i_vout++ ) { - if( !p_vout->p_sys->pp_vout[ i_vout ].b_active ) + struct vout_list_t *p_entry = &p_vout->p_sys->pp_vout[ i_vout ]; + if( !p_entry->b_active ) { for( i_plane = 0 ; i_plane < p_pic->i_planes ; i_plane++ ) { - pi_left_skip[i_plane] += - p_vout->p_sys->pp_vout[ i_vout ].i_width - * p_pic->p[i_plane].i_pitch / p_vout->output.i_width; + pi_left_skip[i_plane] += p_entry->i_width * p_pic->p[i_plane].i_pitch / p_vout->output.i_width; } - i_vout++; continue; } - while( ( p_outpic = - vout_CreatePicture( p_vout->p_sys->pp_vout[ i_vout ].p_vout, - 0, 0, 0 ) - ) == NULL ) + while( ( p_outpic = vout_CreatePicture( p_entry->p_vout, 0, 0, 0 )) == NULL ) { - if( p_vout->b_die || p_vout->b_error ) + if( !vlc_object_alive(p_vout) || p_vout->b_error ) { - vout_DestroyPicture( - p_vout->p_sys->pp_vout[ i_vout ].p_vout, p_outpic ); + vout_DestroyPicture( p_entry->p_vout, p_outpic ); return; } - msleep( VOUT_OUTMEM_SLEEP ); } - vout_DatePicture( p_vout->p_sys->pp_vout[ i_vout ].p_vout, - p_outpic, p_pic->date ); - vout_LinkPicture( p_vout->p_sys->pp_vout[ i_vout ].p_vout, - p_outpic ); + p_outpic->date = p_pic->date; + vout_LinkPicture( p_entry->p_vout, p_outpic ); for( i_plane = 0 ; i_plane < p_pic->i_planes ; i_plane++ ) { @@ -989,271 +968,236 @@ static void RenderPlanarYUV( vout_thread_t *p_vout, picture_t *p_pic ) int i_out_pitch = p_outpic->p[i_plane].i_pitch; int i_copy_pitch = p_outpic->p[i_plane].i_visible_pitch; int i_lines = p_outpic->p[i_plane].i_visible_lines; + const int i_div = p_entry->i_width / i_copy_pitch; + + const bool b_row_first = i_row == 0; + const bool b_row_last = i_row + 1 == p_vout->p_sys->i_row; + const bool b_col_first = i_col == 0; + const bool b_col_last = i_col + 1 == p_vout->p_sys->i_col; + #ifdef OVERLAP - if (i_col) pi_left_skip[i_plane] -= (2 * p_vout->p_sys->i_halfLength ) / (p_vout->p_sys->pp_vout[i_vout].i_width / i_copy_pitch); - if ((i_row) && (!i_col)) pi_top_skip[i_plane] -= (2 * p_vout->p_sys->i_halfHeight * p_pic->p[i_plane].i_pitch) / (p_vout->p_sys->pp_vout[i_vout].i_width / i_copy_pitch); - if ((p_vout->p_sys->i_row > 2) && (i_row == 1) && (!i_col)) pi_top_skip[i_plane] -= (2 * p_vout->p_sys->i_halfHeight * p_pic->p[i_plane].i_pitch) / (p_vout->p_sys->pp_vout[i_vout].i_width / i_copy_pitch); - if ((!p_vout->p_sys->pp_vout[p_vout->p_sys->i_col].b_active)) - pi_top_skip[i_plane] -= (2 * p_vout->p_sys->i_halfHeight * i_row * p_pic->p[i_plane].i_pitch) / (p_vout->p_sys->pp_vout[i_vout].i_width / i_copy_pitch); + if( !b_col_first ) + pi_left_skip[i_plane] -= (2 * p_vout->p_sys->i_halfLength ) / i_div; + + if( p_vout->p_sys->i_row >= 2 ) + { + if( !b_row_first && b_col_first ) + pi_top_skip[i_plane] -= (2 * p_vout->p_sys->i_halfHeight * p_pic->p[i_plane].i_pitch) / i_div; + if( p_vout->p_sys->i_row > 2 && i_row == 1 && b_col_first ) + pi_top_skip[i_plane] -= (2 * p_vout->p_sys->i_halfHeight * p_pic->p[i_plane].i_pitch) / i_div; + if( !p_vout->p_sys->pp_vout[p_vout->p_sys->i_col-1].b_active ) + pi_top_skip[i_plane] -= (2 * p_vout->p_sys->i_halfHeight * i_row * p_pic->p[i_plane].i_pitch) / i_div; + } // i_n : previous inactive pp_vout int i_n=0; - while ((!p_vout->p_sys->pp_vout[i_row * p_vout->p_sys->i_col + i_col - 1 - i_n].b_active) && (i_col - i_n > 1)) i_n++; - if ((i_col > 1) && i_n) - pi_left_skip[i_plane] -= i_n*(2 * p_vout->p_sys->i_halfLength ) / (p_vout->p_sys->pp_vout[i_vout].i_width / i_copy_pitch); + while( (i_col - i_n > 1) && (!p_vout->p_sys->pp_vout[i_row * p_vout->p_sys->i_col + i_col - 1 - i_n].b_active) ) i_n++; + if( i_col > 1 && i_n ) + pi_left_skip[i_plane] -= i_n * (2 * p_vout->p_sys->i_halfLength ) / i_div; - p_in = p_pic->p[i_plane].p_pixels - /* Wall proprities */ - + pi_top_skip[i_plane] + pi_left_skip[i_plane]; - if ((p_vout->p_sys->i_row > 2) && - ((!i_row) || (i_row + 1 == p_vout->p_sys->i_row))) - i_lines -= (2 * p_vout->p_sys->i_halfHeight) / (p_vout->p_sys->pp_vout[i_vout].i_width / i_copy_pitch); + if( p_vout->p_sys->i_row > 2 && ( b_row_first || b_row_last ) ) + i_lines -= (2 * p_vout->p_sys->i_halfHeight) / i_div; // 1088 lines bug in a mpeg2 stream of 1080 lines - if ((p_vout->p_sys->i_row - 1 == i_row) && - (p_pic->p[i_plane].i_lines == 1088)) - i_lines -= 8 / (p_vout->p_sys->pp_vout[i_vout].i_width / i_copy_pitch); - - p_in_end = p_in + i_lines * p_pic->p[i_plane].i_pitch; -#else - p_in = p_pic->p[i_plane].p_pixels - + pi_top_skip[i_plane] + pi_left_skip[i_plane]; - - p_in_end = p_in + i_lines * p_pic->p[i_plane].i_pitch; + if( b_row_last && p_pic->p[i_plane].i_lines == 1088 ) + i_lines -= 8 / i_div; #endif + /* */ + p_in = &p_pic->p[i_plane].p_pixels[ pi_top_skip[i_plane] + pi_left_skip[i_plane] ]; /* Wall proprities */ + p_in_end = &p_in[i_lines * p_pic->p[i_plane].i_pitch]; + p_out = p_outpic->p[i_plane].p_pixels; #ifdef OVERLAP - if ((p_vout->p_sys->i_row > 2) && (!i_row)) - p_out += (p_outpic->p[i_plane].i_pitch * (2 * p_vout->p_sys->i_halfHeight) / (p_vout->p_sys->pp_vout[i_vout].i_width / i_copy_pitch)); + if( p_vout->p_sys->i_row > 2 && b_row_first ) + p_out += p_outpic->p[i_plane].i_pitch * (2 * p_vout->p_sys->i_halfHeight) / i_div; - int length; - int i_col_mod; - length = 2 * p_vout->p_sys->i_halfLength / (p_vout->p_sys->pp_vout[i_vout].i_width / i_copy_pitch); + int i_col_mod; + int length = 2 * p_vout->p_sys->i_halfLength / i_div; - if (p_vout->p_sys->b_has_changed) - { - Denom = F2(length); - a_2 = p_vout->p_sys->a_2 * (ACCURACY / 100); - a_1 = p_vout->p_sys->a_1 * length * (ACCURACY / 100); - a_0 = p_vout->p_sys->a_0 * Denom * (ACCURACY / 100); - for(i_col_mod = 0; i_col_mod < 2; i_col_mod++) - for (i_index = 0; i_index < length; i_index++) - { - p_vout->p_sys->lambda[i_col_mod][i_plane][i_index] = CLIP_0A(!i_col_mod ? ACCURACY - (F4(a_2, a_1, i_index) + a_0) / Denom : ACCURACY - (F4(a_2, a_1,length - i_index) + a_0) / Denom); - p_vout->p_sys->cstYUV[i_col_mod][i_plane][i_index] = ((ACCURACY - p_vout->p_sys->lambda[i_col_mod][i_plane][i_index]) * constantYUV[i_plane]) / ACCURACY; - } - } -#endif - while( p_in < p_in_end ) - { -#ifndef OVERLAP - p_vout->p_libvlc->pf_memcpy( p_out , p_in, i_copy_pitch); -#else - if (p_vout->p_sys->i_col > 2) + if( p_vout->p_sys->b_has_changed ) { - length /= 2; - if (i_col == 0) - p_vout->p_libvlc->pf_memcpy( p_out + length , p_in, i_copy_pitch - length); - else if (i_col + 1 == p_vout->p_sys->i_col) - p_vout->p_libvlc->pf_memcpy( p_out, p_in - length, i_copy_pitch - length); - else - p_vout->p_libvlc->pf_memcpy( p_out, p_in - length, i_copy_pitch); - - if ((i_col == 0)) - // black bar + Denom = F2(length); + a_2 = p_vout->p_sys->a_2 * (ACCURACY / 100); + a_1 = p_vout->p_sys->a_1 * length * (ACCURACY / 100); + a_0 = p_vout->p_sys->a_0 * Denom * (ACCURACY / 100); + for( i_col_mod = 0; i_col_mod < 2; i_col_mod++ ) { - LeftOffset = 0; - p_out += LeftOffset; - memset(p_out, constantYUV[i_plane], length); - p_out -= LeftOffset; - } - else if ((i_col + 1 == p_vout->p_sys->i_col )) - // black bar + for( i_index = 0; i_index < length; i_index++ ) { - LeftOffset = i_copy_pitch - length; - p_out += LeftOffset; - memset(p_out, constantYUV[i_plane], length); - p_out -= LeftOffset; + p_vout->p_sys->lambda[i_col_mod][i_plane][i_index] = CLIP_0A(!i_col_mod ? ACCURACY - (F4(a_2, a_1, i_index) + a_0) / Denom : ACCURACY - (F4(a_2, a_1,length - i_index) + a_0) / Denom); + p_vout->p_sys->cstYUV[i_col_mod][i_plane][i_index] = ((ACCURACY - p_vout->p_sys->lambda[i_col_mod][i_plane][i_index]) * constantYUV[i_plane]) / ACCURACY; } - length *= 2; + } } - else - p_vout->p_libvlc->pf_memcpy( p_out , p_in, i_copy_pitch); - - if (p_vout->p_sys->b_attenuate) - { -// vertical blend -// first blended zone - if (i_col) +#endif + while( p_in < p_in_end ) { - LeftOffset = 0; - p_out += LeftOffset; - for (i_index = 0; i_index < length; i_index++) +#ifndef OVERLAP + vlc_memcpy( p_out, p_in, i_copy_pitch); +#else + if( p_vout->p_sys->i_col > 2 ) + { + const int halfl = length / 2; + if( b_col_first) + vlc_memcpy( &p_out[halfl], &p_in[0], i_copy_pitch - halfl ); + else if( b_col_last ) + vlc_memcpy( &p_out[ 0], &p_in[-halfl], i_copy_pitch - halfl ); + else + vlc_memcpy( &p_out[ 0], &p_in[-halfl], i_copy_pitch); + + // black bar + if( b_col_first ) + memset( &p_out[0], constantYUV[i_plane], halfl); + else if( b_col_last ) + memset( &p_out[i_copy_pitch - halfl], constantYUV[i_plane], halfl ); + } + else + { + vlc_memcpy( p_out , p_in, i_copy_pitch ); + } + + if( p_vout->p_sys->b_attenuate ) { + // vertical blend + // first blended zone + if( !b_col_first ) + { + uint8_t *p_dst = &p_out[0]; + for (i_index = 0; i_index < length; i_index++) + { #ifndef GAMMA - *(p_out + i_index) = (p_vout->p_sys->lambda[1][i_plane][i_index] * - (*(p_out + i_index))) / ACCURACY + - p_vout->p_sys->cstYUV[1][i_plane][i_index]; + p_dst[i_index] = (p_vout->p_sys->lambda[1][i_plane][i_index] * p_dst[i_index]) / ACCURACY + + p_vout->p_sys->cstYUV[1][i_plane][i_index]; #else - *(p_out + i_index) = p_vout->p_sys->LUT[i_plane][p_vout->p_sys->lambda[1][i_plane][i_index]][*(p_out + i_index)]; + p_dst[i_index] = p_vout->p_sys->LUT[i_plane][p_vout->p_sys->lambda[1][i_plane][i_index]][p_dst[i_index]]; #endif - } - p_out -= LeftOffset; - } -// second blended zone - if (i_col + 1 < p_vout->p_sys->i_col) - { - LeftOffset = i_copy_pitch - length; - p_out += LeftOffset; - for (i_index = 0; i_index < length; i_index++) - { + } + } + // second blended zone + if( !b_col_last ) + { + uint8_t *p_dst = &p_out[i_copy_pitch - length]; + for (i_index = 0; i_index < length; i_index++) + { #ifndef GAMMA - *(p_out + i_index) = (p_vout->p_sys->lambda[0][i_plane][i_index] * - (*(p_out + i_index))) / ACCURACY + - p_vout->p_sys->cstYUV[0][i_plane][i_index]; + p_dst[i_index] = (p_vout->p_sys->lambda[0][i_plane][i_index] * p_dst[i_index]) / ACCURACY + + p_vout->p_sys->cstYUV[0][i_plane][i_index]; #else - - *(p_out + i_index) = p_vout->p_sys->LUT[i_plane][p_vout->p_sys->lambda[0][i_plane][i_index]][*(p_out + i_index)]; + p_dst[i_index] = p_vout->p_sys->LUT[i_plane][p_vout->p_sys->lambda[0][i_plane][i_index]][p_dst[i_index]]; #endif + } + } + // end blended zone } - p_out -= LeftOffset; - } -// end blended zone - } #endif - p_in += i_in_pitch; - p_out += i_out_pitch; - } + p_in += i_in_pitch; + p_out += i_out_pitch; + } #ifdef OVERLAP -// horizontal blend - if (!p_vout->p_sys->b_attenuate) + // horizontal blend + if ( p_vout->p_sys->i_row >= 2 ) { - if ((i_row == 0) && (p_vout->p_sys->i_row > 2)) - // black bar - { - int height = 2 * p_vout->p_sys->i_halfHeight / (p_vout->p_sys->pp_vout[i_vout].i_width / i_copy_pitch); - TopOffset = i_lines + (2 * p_vout->p_sys->i_halfHeight) / (p_vout->p_sys->pp_vout[i_vout].i_width / i_copy_pitch); - p_out -= TopOffset * p_outpic->p[i_plane].i_pitch; - for (i_index = 0; i_index < height; i_index++) - for (i_index2 = 0; i_index2 < i_copy_pitch; i_index2++) - *(p_out + (i_index * p_outpic->p[i_plane].i_pitch) + i_index2) = constantYUV[i_plane]; - p_out += TopOffset * p_outpic->p[i_plane].i_pitch; - } - else if ((i_row + 1 == p_vout->p_sys->i_row) && (p_vout->p_sys->i_row > 2)) - // black bar + // black bar + if (( p_vout->p_sys->i_row > 2 ) && (( b_row_first ) || ( b_row_last ))) + { + + int height = 2 * p_vout->p_sys->i_halfHeight / i_div; + if ( b_row_first ) + { + TopOffset = i_lines + (2 * p_vout->p_sys->i_halfHeight) / i_div; + } + else { - int height = 2 * p_vout->p_sys->i_halfHeight / (p_vout->p_sys->pp_vout[i_vout].i_width / i_copy_pitch); - TopOffset = height - (2 * p_vout->p_sys->i_halfHeight) / (p_vout->p_sys->pp_vout[i_vout].i_width / i_copy_pitch); - p_out -= TopOffset * p_outpic->p[i_plane].i_pitch; - for (i_index = 0; i_index < height; i_index++) - for (i_index2 = 0; i_index2 < i_copy_pitch; i_index2++) - *(p_out + (i_index * p_outpic->p[i_plane].i_pitch) + i_index2) = constantYUV[i_plane]; - p_out += TopOffset * p_outpic->p[i_plane].i_pitch; + TopOffset = height - (2 * p_vout->p_sys->i_halfHeight) / i_div; } - } - else - { - if (p_vout->p_sys->i_row >= 2) - { - length = 2 * p_vout->p_sys->i_halfHeight / (p_vout->p_sys->pp_vout[i_vout].i_width / i_copy_pitch); - if (p_vout->p_sys->b_has_changed) - { - Denom = F2(length); - a_2 = p_vout->p_sys->a_2 * (ACCURACY / 100); - a_1 = p_vout->p_sys->a_1 * length * (ACCURACY / 100); - a_0 = p_vout->p_sys->a_0 * Denom * (ACCURACY / 100); + uint8_t *p_dst = p_out - TopOffset * i_out_pitch; + for (i_index = 0; i_index < height; i_index++) + for (i_index2 = 0; i_index2 < i_copy_pitch; i_index2++) + p_dst[i_index * i_out_pitch + i_index2] = constantYUV[i_plane]; + } + if( p_vout->p_sys->b_attenuate ) + { + length = 2 * p_vout->p_sys->i_halfHeight / (p_vout->p_sys->pp_vout[i_vout].i_width / i_copy_pitch); + if (p_vout->p_sys->b_has_changed) + { + Denom = F2(length); + a_2 = p_vout->p_sys->a_2 * (ACCURACY / 100); + a_1 = p_vout->p_sys->a_1 * length * (ACCURACY / 100); + a_0 = p_vout->p_sys->a_0 * Denom * (ACCURACY / 100); for(i_col_mod = 0; i_col_mod < 2; i_col_mod++) - for (i_index = 0; i_index < length; i_index++) - { - p_vout->p_sys->lambda2[i_col_mod][i_plane][i_index] = CLIP_0A(!i_col_mod ? ACCURACY - (F4(a_2, a_1, i_index) + a_0) / Denom : ACCURACY - (F4(a_2, a_1,length - i_index) + a_0) / Denom); - p_vout->p_sys->cstYUV2[i_col_mod][i_plane][i_index] = ((ACCURACY - p_vout->p_sys->lambda2[i_col_mod][i_plane][i_index]) * constantYUV[i_plane]) / ACCURACY; - } - } -// first blended zone + for (i_index = 0; i_index < length; i_index++) + { + p_vout->p_sys->lambda2[i_col_mod][i_plane][i_index] = CLIP_0A(!i_col_mod ? ACCURACY - (F4(a_2, a_1, i_index) + a_0) / Denom : ACCURACY - (F4(a_2, a_1,length - i_index) + a_0) / Denom); + p_vout->p_sys->cstYUV2[i_col_mod][i_plane][i_index] = ((ACCURACY - p_vout->p_sys->lambda2[i_col_mod][i_plane][i_index]) * constantYUV[i_plane]) / ACCURACY; + } + } + // first blended zone + if ( !b_row_first ) + { + TopOffset = i_lines; + uint8_t *p_dst = p_out - TopOffset * i_out_pitch; - if (i_row) - { - TopOffset = i_lines; - p_out -= TopOffset * p_outpic->p[i_plane].i_pitch; - for (i_index = 0; i_index < length; i_index++) - for (i_index2 = 0; i_index2 < i_copy_pitch; i_index2++) + for (i_index = 0; i_index < length; i_index++) + { + for (i_index2 = 0; i_index2 < i_copy_pitch; i_index2++) + { #ifndef GAMMA - *(p_out + (i_index * p_outpic->p[i_plane].i_pitch) + i_index2) = (p_vout->p_sys->lambda2[1][i_plane][i_index] * - (*(p_out + (i_index * p_outpic->p[i_plane].i_pitch) + i_index2))) / ACCURACY + - p_vout->p_sys->cstYUV2[1][i_plane][i_index]; + p_dst[i_index * i_out_pitch + i_index2] = ( p_vout->p_sys->lambda2[1][i_plane][i_index] * + p_dst[i_index * i_out_pitch + i_index2] ) / ACCURACY + + p_vout->p_sys->cstYUV2[1][i_plane][i_index]; #else - - *(p_out + (i_index * p_outpic->p[i_plane].i_pitch) + i_index2) = p_vout->p_sys->LUT[i_plane][p_vout->p_sys->lambda2[1][i_plane][i_index]][*(p_out + (i_index * p_outpic->p[i_plane].i_pitch) + i_index2)]; + p_dst[i_index * i_out_pitch + i_index2] = p_vout->p_sys->LUT[i_plane][p_vout->p_sys->lambda2[1][i_plane][i_index]][p_dst[i_index * i_out_pitch + i_index2]]; #endif - p_out += TopOffset * p_outpic->p[i_plane].i_pitch; - } - else if (p_vout->p_sys->i_row > 2) - // black bar - { - TopOffset = i_lines + (2 * p_vout->p_sys->i_halfHeight) / (p_vout->p_sys->pp_vout[i_vout].i_width / i_copy_pitch); - p_out -= TopOffset * p_outpic->p[i_plane].i_pitch; - for (i_index = 0; i_index < length; i_index++) - for (i_index2 = 0; i_index2 < i_copy_pitch; i_index2++) - *(p_out + (i_index * p_outpic->p[i_plane].i_pitch) + i_index2) = constantYUV[i_plane]; - p_out += TopOffset * p_outpic->p[i_plane].i_pitch; - } - -// second blended zone + } + } + } + // second blended zone + if ( !b_row_last ) + { + TopOffset = length; + uint8_t *p_dst = p_out - TopOffset * p_outpic->p[i_plane].i_pitch; - if (i_row + 1 < p_vout->p_sys->i_row) - { - TopOffset = length; - p_out -= TopOffset * p_outpic->p[i_plane].i_pitch; - for (i_index = 0; i_index < length; i_index++) - for (i_index2 = 0; i_index2 < i_copy_pitch; i_index2++) + for (i_index = 0; i_index < length; i_index++) + { + for (i_index2 = 0; i_index2 < i_copy_pitch; i_index2++) + { #ifndef GAMMA - *(p_out + (i_index * p_outpic->p[i_plane].i_pitch) + i_index2) = (p_vout->p_sys->lambda2[0][i_plane][i_index] * - (*(p_out + (i_index * p_outpic->p[i_plane].i_pitch) + i_index2))) / ACCURACY + - p_vout->p_sys->cstYUV2[0][i_plane][i_index]; + p_dst[i_index * i_out_pitch + i_index2] = (p_vout->p_sys->lambda2[0][i_plane][i_index] * + p_dst[i_index * i_out_pitch + i_index2]) / ACCURACY + + p_vout->p_sys->cstYUV2[0][i_plane][i_index]; #else - *(p_out + (i_index * p_outpic->p[i_plane].i_pitch) + i_index2) = p_vout->p_sys->LUT[i_plane][p_vout->p_sys->lambda2[0][i_plane][i_index]][*(p_out + (i_index * p_outpic->p[i_plane].i_pitch) + i_index2)]; - + p_dst[i_index * i_out_pitch + i_index2] = p_vout->p_sys->LUT[i_plane][p_vout->p_sys->lambda2[0][i_plane][i_index]][p_dst[i_index * i_out_pitch + i_index2]]; #endif - p_out += TopOffset * p_outpic->p[i_plane].i_pitch; - } - else if (p_vout->p_sys->i_row > 2) - // black bar - { - TopOffset = length - (2 * p_vout->p_sys->i_halfHeight) / (p_vout->p_sys->pp_vout[i_vout].i_width / i_copy_pitch); - p_out -= TopOffset * p_outpic->p[i_plane].i_pitch; - for (i_index = 0; i_index < length; i_index++) - for (i_index2 = 0; i_index2 < i_copy_pitch; i_index2++) - *(p_out + (i_index * p_outpic->p[i_plane].i_pitch) + i_index2) = constantYUV[i_plane]; - p_out += TopOffset * p_outpic->p[i_plane].i_pitch; - } -// end blended zone - } + } + } + } + } } + // end blended zone #endif -// bug for wall filter : fix by CC -// pi_left_skip[i_plane] += i_out_pitch; - pi_left_skip[i_plane] += i_copy_pitch; + // bug for wall filter : fix by CC + // pi_left_skip[i_plane] += i_out_pitch; + pi_left_skip[i_plane] += i_copy_pitch; } vout_UnlinkPicture( p_vout->p_sys->pp_vout[ i_vout ].p_vout, p_outpic ); vout_DisplayPicture( p_vout->p_sys->pp_vout[ i_vout ].p_vout, p_outpic ); - i_vout++; } for( i_plane = 0 ; i_plane < p_pic->i_planes ; i_plane++ ) - { - pi_top_skip[i_plane] += p_vout->p_sys->pp_vout[ i_vout ].i_height + { + pi_top_skip[i_plane] += p_vout->p_sys->pp_vout[ i_vout-1 ].i_height * p_pic->p[i_plane].i_lines / p_vout->output.i_height * p_pic->p[i_plane].i_pitch; - } - + } } #ifdef OVERLAP - if (p_vout->p_sys->b_has_changed) p_vout->p_sys->b_has_changed = VLC_FALSE; + if (p_vout->p_sys->b_has_changed) + p_vout->p_sys->b_has_changed = false; #endif } @@ -1279,21 +1223,15 @@ static void RenderPackedRGB( vout_thread_t *p_vout, picture_t *p_pic ) int i_index, i_index2; #endif - i_vout = 0; - for( i_plane = 0 ; i_plane < p_pic->i_planes ; i_plane++ ) - { pi_top_skip[i_plane] = 0; - } - for( i_row = 0; i_row < p_vout->p_sys->i_row; i_row++ ) + for( i_vout = 0, i_row = 0; i_row < p_vout->p_sys->i_row; i_row++ ) { for( i_plane = 0 ; i_plane < p_pic->i_planes ; i_plane++ ) - { pi_left_skip[i_plane] = 0; - } - for( i_col = 0; i_col < p_vout->p_sys->i_col; i_col++ ) + for( i_col = 0; i_col < p_vout->p_sys->i_col; i_col++, i_vout++ ) { if( !p_vout->p_sys->pp_vout[ i_vout ].b_active ) { @@ -1302,7 +1240,6 @@ static void RenderPackedRGB( vout_thread_t *p_vout, picture_t *p_pic ) pi_left_skip[i_plane] += p_vout->p_sys->pp_vout[ i_vout ].i_width * p_pic->p->i_pixel_pitch; } - i_vout++; continue; } @@ -1311,7 +1248,7 @@ static void RenderPackedRGB( vout_thread_t *p_vout, picture_t *p_pic ) 0, 0, 0 ) ) == NULL ) { - if( p_vout->b_die || p_vout->b_error ) + if( !vlc_object_alive (p_vout) || p_vout->b_error ) { vout_DestroyPicture( p_vout->p_sys->pp_vout[ i_vout ].p_vout, p_outpic ); @@ -1321,8 +1258,7 @@ static void RenderPackedRGB( vout_thread_t *p_vout, picture_t *p_pic ) msleep( VOUT_OUTMEM_SLEEP ); } - vout_DatePicture( p_vout->p_sys->pp_vout[ i_vout ].p_vout, - p_outpic, p_pic->date ); + p_outpic->date = p_pic->date; vout_LinkPicture( p_vout->p_sys->pp_vout[ i_vout ].p_vout, p_outpic ); @@ -1334,10 +1270,17 @@ static void RenderPackedRGB( vout_thread_t *p_vout, picture_t *p_pic ) int i_copy_pitch = p_outpic->p[i_plane].i_visible_pitch; #ifdef OVERLAP - if (i_col) pi_left_skip[i_plane] -= (2 * p_vout->p_sys->i_halfLength) * p_pic->p->i_pixel_pitch; - if ((i_row) && (!i_col)) pi_top_skip[i_plane] -= (2 * p_vout->p_sys->i_halfHeight * p_pic->p[i_plane].i_pitch); - if ((!p_vout->p_sys->pp_vout[p_vout->p_sys->i_col].b_active)) - pi_top_skip[i_plane] -= (2 * p_vout->p_sys->i_halfHeight * i_row * p_pic->p[i_plane].i_pitch); + if (i_col) + pi_left_skip[i_plane] -= (2 * p_vout->p_sys->i_halfLength) * p_pic->p->i_pixel_pitch; + if( p_vout->p_sys->i_row >= 2 ) + { + if( (i_row) && (!i_col)) + pi_top_skip[i_plane] -= (2 * p_vout->p_sys->i_halfHeight * p_pic->p[i_plane].i_pitch); + if( (p_vout->p_sys->i_row > 2) && (i_row == 1) && (!i_col) ) + pi_top_skip[i_plane] -= (2 * p_vout->p_sys->i_halfHeight * p_pic->p[i_plane].i_pitch); + if( !p_vout->p_sys->pp_vout[p_vout->p_sys->i_col-1].b_active ) + pi_top_skip[i_plane] -= (2 * p_vout->p_sys->i_halfHeight * i_row * p_pic->p[i_plane].i_pitch); + } // i_n : previous inactive pp_vout int i_n=0; while ((!p_vout->p_sys->pp_vout[i_row * p_vout->p_sys->i_col + i_col - 1 - i_n].b_active) && (i_col - i_n > 1)) i_n++; @@ -1390,18 +1333,18 @@ static void RenderPackedRGB( vout_thread_t *p_vout, picture_t *p_pic ) while( p_in < p_in_end ) { #ifndef OVERLAP - p_vout->p_libvlc->pf_memcpy( p_out, p_in, i_copy_pitch); + vlc_memcpy( p_out, p_in, i_copy_pitch ); #else if (p_vout->p_sys->i_col > 2) { // vertical blend length /= 2; if (i_col == 0) - p_vout->p_libvlc->pf_memcpy( p_out + length, p_in, i_copy_pitch - length); + vlc_memcpy( p_out + length, p_in, i_copy_pitch - length); else if (i_col + 1 == p_vout->p_sys->i_col) - p_vout->p_libvlc->pf_memcpy( p_out, p_in - length, i_copy_pitch - length); - else - p_vout->p_libvlc->pf_memcpy( p_out, p_in - length, i_copy_pitch); + vlc_memcpy( p_out, p_in - length, i_copy_pitch - length); + else + vlc_memcpy( p_out, p_in - length, i_copy_pitch); if ((i_col == 0)) // black bar @@ -1428,7 +1371,7 @@ static void RenderPackedRGB( vout_thread_t *p_vout, picture_t *p_pic ) length *= 2; } else - p_vout->p_libvlc->pf_memcpy( p_out, p_in, i_copy_pitch); + vlc_memcpy( p_out, p_in, i_copy_pitch); // vertical blend // first blended zone @@ -1574,19 +1517,18 @@ static void RenderPackedRGB( vout_thread_t *p_vout, picture_t *p_pic ) p_outpic ); vout_DisplayPicture( p_vout->p_sys->pp_vout[ i_vout ].p_vout, p_outpic ); - i_vout++; } for( i_plane = 0 ; i_plane < p_pic->i_planes ; i_plane++ ) { - pi_top_skip[i_plane] += p_vout->p_sys->pp_vout[ i_vout ].i_height + pi_top_skip[i_plane] += p_vout->p_sys->pp_vout[ i_vout-1 ].i_height * p_pic->p[i_plane].i_lines / p_vout->output.i_height * p_pic->p[i_plane].i_pitch; } } #ifdef OVERLAP - if (p_vout->p_sys->b_has_changed) p_vout->p_sys->b_has_changed = VLC_FALSE; + if (p_vout->p_sys->b_has_changed) p_vout->p_sys->b_has_changed = false; #endif } @@ -1615,22 +1557,15 @@ static void RenderPackedYUV( vout_thread_t *p_vout, picture_t *p_pic ) int i_index, i_index2; #endif - - i_vout = 0; - for( i_plane = 0 ; i_plane < p_pic->i_planes ; i_plane++ ) - { pi_top_skip[i_plane] = 0; - } - for( i_row = 0; i_row < p_vout->p_sys->i_row; i_row++ ) + for( i_vout = 0;, i_row = 0; i_row < p_vout->p_sys->i_row; i_row++ ) { for( i_plane = 0 ; i_plane < p_pic->i_planes ; i_plane++ ) - { pi_left_skip[i_plane] = 0; - } - for( i_col = 0; i_col < p_vout->p_sys->i_col; i_col++ ) + for( i_col = 0; i_col < p_vout->p_sys->i_col; i_col++, i_vout++ ) { if( !p_vout->p_sys->pp_vout[ i_vout ].b_active ) { @@ -1640,7 +1575,6 @@ static void RenderPackedYUV( vout_thread_t *p_vout, picture_t *p_pic ) p_vout->p_sys->pp_vout[ i_vout ].i_width * p_pic->p[i_plane].i_pitch / p_vout->output.i_width; } - i_vout++; continue; } @@ -1649,7 +1583,7 @@ static void RenderPackedYUV( vout_thread_t *p_vout, picture_t *p_pic ) 0, 0, 0 ) ) == NULL ) { - if( p_vout->b_die || p_vout->b_error ) + if( !vlc_object_alive (p_vout) || p_vout->b_error ) { vout_DestroyPicture( p_vout->p_sys->pp_vout[ i_vout ].p_vout, p_outpic ); @@ -1659,8 +1593,7 @@ static void RenderPackedYUV( vout_thread_t *p_vout, picture_t *p_pic ) msleep( VOUT_OUTMEM_SLEEP ); } - vout_DatePicture( p_vout->p_sys->pp_vout[ i_vout ].p_vout, - p_outpic, p_pic->date ); + p_outpic->date = p_pic->date; vout_LinkPicture( p_vout->p_sys->pp_vout[ i_vout ].p_vout, p_outpic ); @@ -1670,18 +1603,19 @@ static void RenderPackedYUV( vout_thread_t *p_vout, picture_t *p_pic ) int i_in_pitch = p_pic->p[i_plane].i_pitch; int i_out_pitch = p_outpic->p[i_plane].i_pitch; int i_copy_pitch = p_outpic->p[i_plane].i_visible_pitch; + const int i_div = p_vout->p_sys->pp_vout[i_vout].i_width / i_copy_pitch; #ifdef OVERLAP - if (i_col) pi_left_skip[i_plane] -= (2 * p_vout->p_sys->i_halfLength ) / (p_vout->p_sys->pp_vout[i_vout].i_width / i_copy_pitch); - if ((i_row) && (!i_col)) pi_top_skip[i_plane] -= (2 * p_vout->p_sys->i_halfHeight * p_pic->p[i_plane].i_pitch) / (p_vout->p_sys->pp_vout[i_vout].i_width / i_copy_pitch); - if ((p_vout->p_sys->i_row > 2) && (i_row == 1) && (!i_col)) pi_top_skip[i_plane] -= (2 * p_vout->p_sys->i_halfHeight * p_pic->p[i_plane].i_pitch) / (p_vout->p_sys->pp_vout[i_vout].i_width / i_copy_pitch); - if ((!p_vout->p_sys->pp_vout[p_vout->p_sys->i_col].b_active)) - pi_top_skip[i_plane] -= (2 * p_vout->p_sys->i_halfHeight * i_row * p_pic->p[i_plane].i_pitch) / (p_vout->p_sys->pp_vout[i_vout].i_width / i_copy_pitch); + if (i_col) pi_left_skip[i_plane] -= (2 * p_vout->p_sys->i_halfLength ) / i_div; + if ((p_vout->p_sys->i_row >= 2) && (i_row) && (!i_col)) pi_top_skip[i_plane] -= (2 * p_vout->p_sys->i_halfHeight * p_pic->p[i_plane].i_pitch) / i_div; + if ((p_vout->p_sys->i_row > 2) && (i_row == 1) && (!i_col)) pi_top_skip[i_plane] -= (2 * p_vout->p_sys->i_halfHeight * p_pic->p[i_plane].i_pitch) / i_div; + if( !p_vout->p_sys->pp_vout[p_vout->p_sys->i_col-1].b_active ) + pi_top_skip[i_plane] -= (2 * p_vout->p_sys->i_halfHeight * i_row * p_pic->p[i_plane].i_pitch) / i_div; // i_n : previous inactive pp_vout int i_n=0; while ((!p_vout->p_sys->pp_vout[i_row * p_vout->p_sys->i_col + i_col - 1 - i_n].b_active) && (i_col - i_n > 1)) i_n++; if ((i_col > 1) && i_n) - pi_left_skip[i_plane] -= i_n*(2 * p_vout->p_sys->i_halfLength ) / (p_vout->p_sys->pp_vout[i_vout].i_width / i_copy_pitch); + pi_left_skip[i_plane] -= i_n*(2 * p_vout->p_sys->i_halfLength ) / i_div; p_in = p_pic->p[i_plane].p_pixels /* Wall proprities */ @@ -1768,9 +1702,9 @@ static void RenderPackedYUV( vout_thread_t *p_vout, picture_t *p_pic ) while( p_in < p_in_end ) { #ifndef OVERLAP - p_vout->p_libvlc->pf_memcpy( p_out, p_in, i_copy_pitch); + vlc_memcpy( p_out, p_in, i_copy_pitch); #else - p_vout->p_libvlc->pf_memcpy( p_out + i_col * length, p_in + i_col * length, i_copy_pitch - length); + vlc_memcpy( p_out + i_col * length, p_in + i_col * length, i_copy_pitch - length); p_out += LeftOffset; p_in += LeftOffset; #ifndef GAMMA @@ -1880,19 +1814,18 @@ static void RenderPackedYUV( vout_thread_t *p_vout, picture_t *p_pic ) p_outpic ); vout_DisplayPicture( p_vout->p_sys->pp_vout[ i_vout ].p_vout, p_outpic ); - i_vout++; } for( i_plane = 0 ; i_plane < p_pic->i_planes ; i_plane++ ) { - pi_top_skip[i_plane] += p_vout->p_sys->pp_vout[ i_vout ].i_height + pi_top_skip[i_plane] += p_vout->p_sys->pp_vout[ i_vout-1 ].i_height * p_pic->p[i_plane].i_lines / p_vout->output.i_height * p_pic->p[i_plane].i_pitch; } } #ifdef OVERLAP - if (p_vout->p_sys->b_has_changed) p_vout->p_sys->b_has_changed = VLC_FALSE; + if (p_vout->p_sys->b_has_changed) p_vout->p_sys->b_has_changed = false; #endif } #endif @@ -1903,97 +1836,119 @@ static void RenderPackedYUV( vout_thread_t *p_vout, picture_t *p_pic ) *****************************************************************************/ static void RemoveAllVout( vout_thread_t *p_vout ) { - while( p_vout->p_sys->i_vout ) + vout_sys_t *p_sys = p_vout->p_sys; + + for( int i = 0; i < p_vout->p_sys->i_vout; i++ ) { - --p_vout->p_sys->i_vout; - if( p_vout->p_sys->pp_vout[ p_vout->p_sys->i_vout ].b_active ) - { - DEL_CALLBACKS( - p_vout->p_sys->pp_vout[ p_vout->p_sys->i_vout ].p_vout, - SendEvents ); - vlc_object_detach( - p_vout->p_sys->pp_vout[ p_vout->p_sys->i_vout ].p_vout ); - vout_Destroy( - p_vout->p_sys->pp_vout[ p_vout->p_sys->i_vout ].p_vout ); - } + if( p_sys->pp_vout[i].b_active ) + { + vout_filter_SetupChild( p_vout, p_sys->pp_vout[i].p_vout, + MouseEvent, FullscreenEventUp, FullscreenEventDown, true ); + vout_CloseAndRelease( p_sys->pp_vout[i].p_vout ); + p_sys->pp_vout[i].p_vout = NULL; + } } } /***************************************************************************** * SendEvents: forward mouse and keyboard events to the parent p_vout *****************************************************************************/ -static int SendEvents( vlc_object_t *p_this, char const *psz_var, - vlc_value_t oldval, vlc_value_t newval, void *_p_vout ) +static int MouseEvent( vlc_object_t *p_this, char const *psz_var, + vlc_value_t oldval, vlc_value_t newval, void *p_data ) { + vout_thread_t *p_vout = p_data; + vout_sys_t *p_sys = p_vout->p_sys; VLC_UNUSED(oldval); - vout_thread_t *p_vout = (vout_thread_t *)_p_vout; int i_vout; - vlc_value_t sentval = newval; /* Find the video output index */ - for( i_vout = 0; i_vout < p_vout->p_sys->i_vout; i_vout++ ) + for( i_vout = 0; i_vout < p_sys->i_vout; i_vout++ ) { - if( p_this == (vlc_object_t *)p_vout->p_sys->pp_vout[ i_vout ].p_vout ) - { + if( p_sys->pp_vout[i_vout].b_active && + p_this == VLC_OBJECT(p_sys->pp_vout[i_vout].p_vout) ) break; - } - } - - if( i_vout == p_vout->p_sys->i_vout ) - { - return VLC_EGENERIC; } + assert( i_vout < p_vout->p_sys->i_vout ); /* Translate the mouse coordinates */ if( !strcmp( psz_var, "mouse-x" ) ) { #ifdef OVERLAP - int i_overlap = ((p_vout->p_sys->i_col > 2) ? 0 : 2 * p_vout->p_sys->i_halfLength); - sentval.i_int += (p_vout->output.i_width - i_overlap) + int i_overlap = ((p_sys->i_col > 2) ? 0 : 2 * p_sys->i_halfLength); + newval.i_int += (p_vout->output.i_width - i_overlap) #else - sentval.i_int += p_vout->output.i_width + newval.i_int += p_vout->output.i_width #endif - * (i_vout % p_vout->p_sys->i_col) - / p_vout->p_sys->i_col; + * (i_vout % p_sys->i_col) + / p_sys->i_col; } else if( !strcmp( psz_var, "mouse-y" ) ) { #ifdef OVERLAP - int i_overlap = ((p_vout->p_sys->i_row > 2) ? 0 : 2 * p_vout->p_sys->i_halfHeight); - sentval.i_int += (p_vout->output.i_height - i_overlap) + int i_overlap = ((p_sys->i_row > 2) ? 0 : 2 * p_sys->i_halfHeight); + newval.i_int += (p_vout->output.i_height - i_overlap) #else - sentval.i_int += p_vout->output.i_height + newval.i_int += p_vout->output.i_height #endif //bug fix in Wall plug-in // * (i_vout / p_vout->p_sys->i_row) - * (i_vout / p_vout->p_sys->i_col) - / p_vout->p_sys->i_row; + * (i_vout / p_sys->i_col) + / p_sys->i_row; } - var_Set( p_vout, psz_var, sentval ); + return var_Set( p_vout, psz_var, newval ); +} - return VLC_SUCCESS; +/** + * Forward fullscreen event to/from the childrens. + * FIXME pretty much duplicated from wall.c + */ +static bool IsFullscreenActive( vout_thread_t *p_vout ) +{ + vout_sys_t *p_sys = p_vout->p_sys; + for( int i = 0; i < p_sys->i_vout; i++ ) + { + if( p_sys->pp_vout[i].b_active && + var_GetBool( p_sys->pp_vout[i].p_vout, "fullscreen" ) ) + return true; + } + return false; } +static int FullscreenEventUp( vlc_object_t *p_this, char const *psz_var, + vlc_value_t oldval, vlc_value_t newval, void *p_data ) +{ + vout_thread_t *p_vout = p_data; + VLC_UNUSED(oldval); VLC_UNUSED(p_this); VLC_UNUSED(psz_var); VLC_UNUSED(newval); -/***************************************************************************** - * SendEventsToChild: forward events to the child/children vout - *****************************************************************************/ -static int SendEventsToChild( vlc_object_t *p_this, char const *psz_var, - vlc_value_t oldval, vlc_value_t newval, void *p_data ) + const bool b_fullscreen = IsFullscreenActive( p_vout ); + if( !var_GetBool( p_vout, "fullscreen" ) != !b_fullscreen ) + return var_SetBool( p_vout, "fullscreen", b_fullscreen ); + return VLC_SUCCESS; +} +static int FullscreenEventDown( vlc_object_t *p_this, char const *psz_var, + vlc_value_t oldval, vlc_value_t newval, void *p_data ) { - VLC_UNUSED(oldval); VLC_UNUSED(p_data); - vout_thread_t *p_vout = (vout_thread_t *)p_this; - int i_row, i_col, i_vout = 0; + vout_thread_t *p_vout = (vout_thread_t*)p_this; + vout_sys_t *p_sys = p_vout->p_sys; + VLC_UNUSED(oldval); VLC_UNUSED(p_data); VLC_UNUSED(psz_var); - for( i_row = 0; i_row < p_vout->p_sys->i_row; i_row++ ) + const bool b_fullscreen = IsFullscreenActive( p_vout ); + if( !b_fullscreen != !newval.b_bool ) { - for( i_col = 0; i_col < p_vout->p_sys->i_col; i_col++ ) + for( int i = 0; i < p_sys->i_vout; i++ ) { - var_Set( p_vout->p_sys->pp_vout[ i_vout ].p_vout, psz_var, newval); - if( !strcmp( psz_var, "fullscreen" ) ) break; - i_vout++; + if( !p_sys->pp_vout[i].b_active ) + continue; + + vout_thread_t *p_child = p_sys->pp_vout[i].p_vout; + if( !var_GetBool( p_child, "fullscreen" ) != !newval.b_bool ) + { + var_SetBool( p_child, "fullscreen", newval.b_bool ); + if( newval.b_bool ) + return VLC_SUCCESS; + } } } - return VLC_SUCCESS; } +