Commit e29200cb authored by Steve Lhomme's avatar Steve Lhomme Committed by Jean-Baptiste Kempf

i420_rgb: only handle visible pixels

fixes a crash similar to #16686 when an RGB output is used instead of YUYV
Signed-off-by: Jean-Baptiste Kempf's avatarJean-Baptiste Kempf <jb@videolan.org>
parent ffcc0623
......@@ -173,7 +173,7 @@ void I420_A8B8G8R8 ( filter_t *, picture_t *, picture_t * );
* Rewind buffer and offset, then copy and scale line */ \
p_buffer = p_buffer_start; \
p_offset = p_offset_start; \
for( i_x = p_filter->fmt_out.video.i_width / 16; i_x--; ) \
for( i_x = (p_filter->fmt_out.video.i_x_offset + p_filter->fmt_out.video.i_visible_width) / 16; i_x--; ) \
{ \
*p_pic++ = *p_buffer; p_buffer += *p_offset++; \
*p_pic++ = *p_buffer; p_buffer += *p_offset++; \
......@@ -192,7 +192,7 @@ void I420_A8B8G8R8 ( filter_t *, picture_t *, picture_t * );
*p_pic++ = *p_buffer; p_buffer += *p_offset++; \
*p_pic++ = *p_buffer; p_buffer += *p_offset++; \
} \
for( i_x = p_filter->fmt_out.video.i_width & 15; i_x--; ) \
for( i_x = (p_filter->fmt_out.video.i_x_offset + p_filter->fmt_out.video.i_visible_width) & 15; i_x--; ) \
{ \
*p_pic++ = *p_buffer; p_buffer += *p_offset++; \
} \
......@@ -215,7 +215,7 @@ void I420_A8B8G8R8 ( filter_t *, picture_t *, picture_t * );
{ \
/* Horizontal scaling - we can't use a buffer due to dithering */ \
p_offset = p_offset_start; \
for( i_x = p_filter->fmt_out.video.i_width / 16; i_x--; ) \
for( i_x = (p_filter->fmt_out.video.i_x_offset + p_filter->fmt_out.video.i_visible_width) / 16; i_x--; ) \
{ \
CONVERT_4YUV_PIXEL_SCALE( CHROMA ) \
CONVERT_4YUV_PIXEL_SCALE( CHROMA ) \
......@@ -225,7 +225,7 @@ void I420_A8B8G8R8 ( filter_t *, picture_t *, picture_t * );
} \
else \
{ \
for( i_x = p_filter->fmt_in.video.i_width / 16; i_x--; ) \
for( i_x = (p_filter->fmt_in.video.i_x_offset + p_filter->fmt_in.video.i_visible_width) / 16; i_x--; ) \
{ \
CONVERT_4YUV_PIXEL( CHROMA ) \
CONVERT_4YUV_PIXEL( CHROMA ) \
......@@ -261,10 +261,10 @@ void I420_A8B8G8R8 ( filter_t *, picture_t *, picture_t * );
switch( i_vscale ) \
{ \
case -1: /* vertical scaling factor is < 1 */ \
while( (i_scale_count -= p_filter->fmt_out.video.i_height) > 0 ) \
while( (i_scale_count -= (p_filter->fmt_out.video.i_y_offset + p_filter->fmt_out.video.i_visible_height)) > 0 ) \
{ \
/* Height reduction: skip next source line */ \
p_y += p_filter->fmt_in.video.i_width; \
p_y += (p_filter->fmt_in.video.i_x_offset + p_filter->fmt_in.video.i_visible_width); \
i_y++; \
if( (CHROMA == 420) || (CHROMA == 422) ) \
{ \
......@@ -276,20 +276,20 @@ void I420_A8B8G8R8 ( filter_t *, picture_t *, picture_t * );
} \
else if( CHROMA == 444 ) \
{ \
p_u += p_filter->fmt_in.video.i_width; \
p_v += p_filter->fmt_in.video.i_width; \
p_u += (p_filter->fmt_in.video.i_x_offset + p_filter->fmt_in.video.i_visible_width); \
p_v += (p_filter->fmt_in.video.i_x_offset + p_filter->fmt_in.video.i_visible_width); \
} \
} \
i_scale_count += p_filter->fmt_in.video.i_height; \
i_scale_count += (p_filter->fmt_in.video.i_y_offset + p_filter->fmt_in.video.i_visible_height); \
break; \
case 1: /* vertical scaling factor is > 1 */ \
while( (i_scale_count -= p_filter->fmt_in.video.i_height) > 0 ) \
while( (i_scale_count -= (p_filter->fmt_in.video.i_y_offset + p_filter->fmt_in.video.i_visible_height)) > 0 ) \
{ \
/* Height increment: copy previous picture line */ \
memcpy( p_pic, p_pic_start, p_filter->fmt_out.video.i_width * BPP ); \
memcpy( p_pic, p_pic_start, (p_filter->fmt_out.video.i_x_offset + p_filter->fmt_out.video.i_visible_width) * BPP ); \
p_pic = (void*)((uint8_t*)p_pic + p_dest->p->i_pitch ); \
} \
i_scale_count += p_filter->fmt_out.video.i_height; \
i_scale_count += (p_filter->fmt_out.video.i_y_offset + p_filter->fmt_out.video.i_visible_height); \
break; \
} \
......@@ -316,10 +316,10 @@ void I420_A8B8G8R8 ( filter_t *, picture_t *, picture_t * );
switch( i_vscale ) \
{ \
case -1: /* vertical scaling factor is < 1 */ \
while( (i_scale_count -= p_filter->fmt_out.video.i_height) > 0 ) \
while( (i_scale_count -= (p_filter->fmt_out.video.i_y_offset + p_filter->fmt_out.video.i_visible_height)) > 0 ) \
{ \
/* Height reduction: skip next source line */ \
p_y += p_filter->fmt_in.video.i_width; \
p_y += (p_filter->fmt_in.video.i_x_offset + p_filter->fmt_in.video.i_visible_width); \
i_y++; \
if( (CHROMA == 420) || (CHROMA == 422) ) \
{ \
......@@ -331,21 +331,21 @@ void I420_A8B8G8R8 ( filter_t *, picture_t *, picture_t * );
} \
else if( CHROMA == 444 ) \
{ \
p_u += p_filter->fmt_in.video.i_width; \
p_v += p_filter->fmt_in.video.i_width; \
p_u += (p_filter->fmt_in.video.i_x_offset + p_filter->fmt_in.video.i_visible_width); \
p_v += (p_filter->fmt_in.video.i_x_offset + p_filter->fmt_in.video.i_visible_width); \
} \
} \
i_scale_count += p_filter->fmt_in.video.i_height; \
i_scale_count += (p_filter->fmt_in.video.i_y_offset + p_filter->fmt_in.video.i_visible_height); \
break; \
case 1: /* vertical scaling factor is > 1 */ \
while( (i_scale_count -= p_filter->fmt_in.video.i_height) > 0 ) \
while( (i_scale_count -= (p_filter->fmt_in.video.i_y_offset + p_filter->fmt_in.video.i_visible_height)) > 0 ) \
{ \
p_y -= p_filter->fmt_in.video.i_width; \
p_y -= (p_filter->fmt_in.video.i_x_offset + p_filter->fmt_in.video.i_visible_width); \
p_u -= i_chroma_width; \
p_v -= i_chroma_width; \
SCALE_WIDTH_DITHER( CHROMA ); \
} \
i_scale_count += p_filter->fmt_out.video.i_height; \
i_scale_count += (p_filter->fmt_out.video.i_y_offset + p_filter->fmt_out.video.i_visible_height); \
break; \
} \
......@@ -119,7 +119,7 @@ void I420_RGB16( filter_t *p_filter, picture_t *p_src, picture_t *p_dest )
int i_right_margin;
int i_rewind;
int i_scale_count; /* scale modulo counter */
int i_chroma_width = p_filter->fmt_in.video.i_width / 2; /* chroma width */
int i_chroma_width = (p_filter->fmt_in.video.i_x_offset + p_filter->fmt_in.video.i_visible_width) / 2; /* chroma width */
uint16_t * p_pic_start; /* beginning of the current line for copy */
int i_uval, i_vval; /* U and V samples */
int i_red, i_green, i_blue; /* U and V modified samples */
......@@ -135,34 +135,36 @@ void I420_RGB16( filter_t *p_filter, picture_t *p_src, picture_t *p_dest )
int * p_offset;
const int i_source_margin = p_src->p[0].i_pitch
- p_src->p[0].i_visible_pitch;
- p_src->p[0].i_visible_pitch
- p_filter->fmt_in.video.i_x_offset;
const int i_source_margin_c = p_src->p[1].i_pitch
- p_src->p[1].i_visible_pitch;
- p_src->p[1].i_visible_pitch
- ( p_filter->fmt_in.video.i_x_offset / 2 );
i_right_margin = p_dest->p->i_pitch - p_dest->p->i_visible_pitch;
i_rewind = (-p_filter->fmt_in.video.i_width) & 7;
i_rewind = (-(p_filter->fmt_in.video.i_x_offset + p_filter->fmt_in.video.i_visible_width)) & 7;
/* Rule: when a picture of size (x1,y1) with aspect ratio r1 is rendered
* on a picture of size (x2,y2) with aspect ratio r2, if x1 grows to x1'
* then y1 grows to y1' = x1' * y2/x2 * r2/r1 */
SetOffset( p_filter->fmt_in.video.i_width,
p_filter->fmt_in.video.i_height,
p_filter->fmt_out.video.i_width,
p_filter->fmt_out.video.i_height,
SetOffset( (p_filter->fmt_in.video.i_x_offset + p_filter->fmt_in.video.i_visible_width),
(p_filter->fmt_in.video.i_y_offset + p_filter->fmt_in.video.i_visible_height),
(p_filter->fmt_out.video.i_x_offset + p_filter->fmt_out.video.i_visible_width),
(p_filter->fmt_out.video.i_y_offset + p_filter->fmt_out.video.i_visible_height),
&b_hscale, &i_vscale, p_offset_start );
/*
* Perform conversion
*/
i_scale_count = ( i_vscale == 1 ) ?
p_filter->fmt_out.video.i_height :
p_filter->fmt_in.video.i_height;
for( i_y = 0; i_y < p_filter->fmt_in.video.i_height; i_y++ )
(p_filter->fmt_out.video.i_y_offset + p_filter->fmt_out.video.i_visible_height) :
(p_filter->fmt_in.video.i_y_offset + p_filter->fmt_in.video.i_visible_height);
for( i_y = 0; i_y < (p_filter->fmt_in.video.i_y_offset + p_filter->fmt_in.video.i_visible_height); i_y++ )
{
p_pic_start = p_pic;
p_buffer = b_hscale ? p_buffer_start : p_pic;
for ( i_x = p_filter->fmt_in.video.i_width / 8; i_x--; )
for ( i_x = (p_filter->fmt_in.video.i_x_offset + p_filter->fmt_in.video.i_visible_width) / 8; i_x--; )
{
CONVERT_YUV_PIXEL(2); CONVERT_Y_PIXEL(2);
CONVERT_YUV_PIXEL(2); CONVERT_Y_PIXEL(2);
......@@ -222,7 +224,7 @@ void I420_RGB32( filter_t *p_filter, picture_t *p_src, picture_t *p_dest )
int i_right_margin;
int i_rewind;
int i_scale_count; /* scale modulo counter */
int i_chroma_width = p_filter->fmt_in.video.i_width / 2; /* chroma width */
int i_chroma_width = (p_filter->fmt_in.video.i_x_offset + p_filter->fmt_in.video.i_visible_width) / 2; /* chroma width */
uint32_t * p_pic_start; /* beginning of the current line for copy */
int i_uval, i_vval; /* U and V samples */
int i_red, i_green, i_blue; /* U and V modified samples */
......@@ -238,34 +240,36 @@ void I420_RGB32( filter_t *p_filter, picture_t *p_src, picture_t *p_dest )
int * p_offset;
const int i_source_margin = p_src->p[0].i_pitch
- p_src->p[0].i_visible_pitch;
- p_src->p[0].i_visible_pitch
- p_filter->fmt_in.video.i_x_offset;
const int i_source_margin_c = p_src->p[1].i_pitch
- p_src->p[1].i_visible_pitch;
- p_src->p[1].i_visible_pitch
- ( p_filter->fmt_in.video.i_x_offset / 2 );
i_right_margin = p_dest->p->i_pitch - p_dest->p->i_visible_pitch;
i_rewind = (-p_filter->fmt_in.video.i_width) & 7;
i_rewind = (-(p_filter->fmt_in.video.i_x_offset + p_filter->fmt_in.video.i_visible_width)) & 7;
/* Rule: when a picture of size (x1,y1) with aspect ratio r1 is rendered
* on a picture of size (x2,y2) with aspect ratio r2, if x1 grows to x1'
* then y1 grows to y1' = x1' * y2/x2 * r2/r1 */
SetOffset( p_filter->fmt_in.video.i_width,
p_filter->fmt_in.video.i_height,
p_filter->fmt_out.video.i_width,
p_filter->fmt_out.video.i_height,
SetOffset( (p_filter->fmt_in.video.i_x_offset + p_filter->fmt_in.video.i_visible_width),
(p_filter->fmt_in.video.i_y_offset + p_filter->fmt_in.video.i_visible_height),
(p_filter->fmt_out.video.i_x_offset + p_filter->fmt_out.video.i_visible_width),
(p_filter->fmt_out.video.i_y_offset + p_filter->fmt_out.video.i_visible_height),
&b_hscale, &i_vscale, p_offset_start );
/*
* Perform conversion
*/
i_scale_count = ( i_vscale == 1 ) ?
p_filter->fmt_out.video.i_height :
p_filter->fmt_in.video.i_height;
for( i_y = 0; i_y < p_filter->fmt_in.video.i_height; i_y++ )
(p_filter->fmt_out.video.i_y_offset + p_filter->fmt_out.video.i_visible_height) :
(p_filter->fmt_in.video.i_y_offset + p_filter->fmt_in.video.i_visible_height);
for( i_y = 0; i_y < (p_filter->fmt_in.video.i_y_offset + p_filter->fmt_in.video.i_visible_height); i_y++ )
{
p_pic_start = p_pic;
p_buffer = b_hscale ? p_buffer_start : p_pic;
for ( i_x = p_filter->fmt_in.video.i_width / 8; i_x--; )
for ( i_x = (p_filter->fmt_in.video.i_x_offset + p_filter->fmt_in.video.i_visible_width) / 8; i_x--; )
{
CONVERT_YUV_PIXEL(4); CONVERT_Y_PIXEL(4);
CONVERT_YUV_PIXEL(4); CONVERT_Y_PIXEL(4);
......
......@@ -115,7 +115,7 @@ void I420_R5G5B5( filter_t *p_filter, picture_t *p_src, picture_t *p_dest )
int i_right_margin;
int i_rewind;
int i_scale_count; /* scale modulo counter */
int i_chroma_width = p_filter->fmt_in.video.i_width / 2; /* chroma width */
int i_chroma_width = (p_filter->fmt_in.video.i_x_offset + p_filter->fmt_in.video.i_visible_width) / 2; /* chroma width */
uint16_t * p_pic_start; /* beginning of the current line for copy */
/* Conversion buffer pointer */
......@@ -127,19 +127,21 @@ void I420_R5G5B5( filter_t *p_filter, picture_t *p_src, picture_t *p_dest )
int * p_offset;
const int i_source_margin = p_src->p[0].i_pitch
- p_src->p[0].i_visible_pitch;
- p_src->p[0].i_visible_pitch
- p_filter->fmt_in.video.i_x_offset;
const int i_source_margin_c = p_src->p[1].i_pitch
- p_src->p[1].i_visible_pitch;
- p_src->p[1].i_visible_pitch
- ( p_filter->fmt_in.video.i_x_offset / 2 );
i_right_margin = p_dest->p->i_pitch - p_dest->p->i_visible_pitch;
/* Rule: when a picture of size (x1,y1) with aspect ratio r1 is rendered
* on a picture of size (x2,y2) with aspect ratio r2, if x1 grows to x1'
* then y1 grows to y1' = x1' * y2/x2 * r2/r1 */
SetOffset( p_filter->fmt_in.video.i_width,
p_filter->fmt_in.video.i_height,
p_filter->fmt_out.video.i_width,
p_filter->fmt_out.video.i_height,
SetOffset( (p_filter->fmt_in.video.i_x_offset + p_filter->fmt_in.video.i_visible_width),
(p_filter->fmt_in.video.i_y_offset + p_filter->fmt_in.video.i_visible_height),
(p_filter->fmt_out.video.i_x_offset + p_filter->fmt_out.video.i_visible_width),
(p_filter->fmt_out.video.i_y_offset + p_filter->fmt_out.video.i_visible_height),
&b_hscale, &i_vscale, p_offset_start );
......@@ -147,12 +149,12 @@ void I420_R5G5B5( filter_t *p_filter, picture_t *p_src, picture_t *p_dest )
* Perform conversion
*/
i_scale_count = ( i_vscale == 1 ) ?
p_filter->fmt_out.video.i_height :
p_filter->fmt_in.video.i_height;
(p_filter->fmt_out.video.i_y_offset + p_filter->fmt_out.video.i_visible_height) :
(p_filter->fmt_in.video.i_y_offset + p_filter->fmt_in.video.i_visible_height);
#ifdef SSE2
i_rewind = (-p_filter->fmt_in.video.i_width) & 15;
i_rewind = (-(p_filter->fmt_in.video.i_x_offset + p_filter->fmt_in.video.i_visible_width)) & 15;
/*
** SSE2 128 bits fetch/store instructions are faster
......@@ -166,11 +168,11 @@ void I420_R5G5B5( filter_t *p_filter, picture_t *p_src, picture_t *p_dest )
((intptr_t)p_buffer))) )
{
/* use faster SSE2 aligned fetch and store */
for( i_y = 0; i_y < p_filter->fmt_in.video.i_height; i_y++ )
for( i_y = 0; i_y < (p_filter->fmt_in.video.i_y_offset + p_filter->fmt_in.video.i_visible_height); i_y++ )
{
p_pic_start = p_pic;
for ( i_x = p_filter->fmt_in.video.i_width/16; i_x--; )
for ( i_x = (p_filter->fmt_in.video.i_x_offset + p_filter->fmt_in.video.i_visible_width)/16; i_x--; )
{
SSE2_CALL (
SSE2_INIT_16_ALIGNED
......@@ -217,12 +219,12 @@ void I420_R5G5B5( filter_t *p_filter, picture_t *p_src, picture_t *p_dest )
else
{
/* use slower SSE2 unaligned fetch and store */
for( i_y = 0; i_y < p_filter->fmt_in.video.i_height; i_y++ )
for( i_y = 0; i_y < (p_filter->fmt_in.video.i_y_offset + p_filter->fmt_in.video.i_visible_height); i_y++ )
{
p_pic_start = p_pic;
p_buffer = b_hscale ? p_buffer_start : p_pic;
for ( i_x = p_filter->fmt_in.video.i_width/16; i_x--; )
for ( i_x = (p_filter->fmt_in.video.i_x_offset + p_filter->fmt_in.video.i_visible_width)/16; i_x--; )
{
SSE2_CALL (
SSE2_INIT_16_UNALIGNED
......@@ -272,14 +274,14 @@ void I420_R5G5B5( filter_t *p_filter, picture_t *p_src, picture_t *p_dest )
#else /* SSE2 */
i_rewind = (-p_filter->fmt_in.video.i_width) & 7;
i_rewind = (-(p_filter->fmt_in.video.i_x_offset + p_filter->fmt_in.video.i_visible_width)) & 7;
for( i_y = 0; i_y < p_filter->fmt_in.video.i_height; i_y++ )
for( i_y = 0; i_y < (p_filter->fmt_in.video.i_y_offset + p_filter->fmt_in.video.i_visible_height); i_y++ )
{
p_pic_start = p_pic;
p_buffer = b_hscale ? p_buffer_start : p_pic;
for ( i_x = p_filter->fmt_in.video.i_width / 8; i_x--; )
for ( i_x = (p_filter->fmt_in.video.i_x_offset + p_filter->fmt_in.video.i_visible_width) / 8; i_x--; )
{
MMX_CALL (
MMX_INIT_16
......@@ -345,7 +347,7 @@ void I420_R5G6B5( filter_t *p_filter, picture_t *p_src, picture_t *p_dest )
int i_right_margin;
int i_rewind;
int i_scale_count; /* scale modulo counter */
int i_chroma_width = p_filter->fmt_in.video.i_width / 2; /* chroma width */
int i_chroma_width = (p_filter->fmt_in.video.i_x_offset + p_filter->fmt_in.video.i_visible_width) / 2; /* chroma width */
uint16_t * p_pic_start; /* beginning of the current line for copy */
/* Conversion buffer pointer */
......@@ -357,19 +359,21 @@ void I420_R5G6B5( filter_t *p_filter, picture_t *p_src, picture_t *p_dest )
int * p_offset;
const int i_source_margin = p_src->p[0].i_pitch
- p_src->p[0].i_visible_pitch;
- p_src->p[0].i_visible_pitch
- p_filter->fmt_in.video.i_x_offset;
const int i_source_margin_c = p_src->p[1].i_pitch
- p_src->p[1].i_visible_pitch;
- p_src->p[1].i_visible_pitch
- ( p_filter->fmt_in.video.i_x_offset / 2 );
i_right_margin = p_dest->p->i_pitch - p_dest->p->i_visible_pitch;
/* Rule: when a picture of size (x1,y1) with aspect ratio r1 is rendered
* on a picture of size (x2,y2) with aspect ratio r2, if x1 grows to x1'
* then y1 grows to y1' = x1' * y2/x2 * r2/r1 */
SetOffset( p_filter->fmt_in.video.i_width,
p_filter->fmt_in.video.i_height,
p_filter->fmt_out.video.i_width,
p_filter->fmt_out.video.i_height,
SetOffset( (p_filter->fmt_in.video.i_x_offset + p_filter->fmt_in.video.i_visible_width),
(p_filter->fmt_in.video.i_y_offset + p_filter->fmt_in.video.i_visible_height),
(p_filter->fmt_out.video.i_x_offset + p_filter->fmt_out.video.i_visible_width),
(p_filter->fmt_out.video.i_y_offset + p_filter->fmt_out.video.i_visible_height),
&b_hscale, &i_vscale, p_offset_start );
......@@ -377,12 +381,12 @@ void I420_R5G6B5( filter_t *p_filter, picture_t *p_src, picture_t *p_dest )
* Perform conversion
*/
i_scale_count = ( i_vscale == 1 ) ?
p_filter->fmt_out.video.i_height :
p_filter->fmt_in.video.i_height;
(p_filter->fmt_out.video.i_y_offset + p_filter->fmt_out.video.i_visible_height) :
(p_filter->fmt_in.video.i_y_offset + p_filter->fmt_in.video.i_visible_height);
#ifdef SSE2
i_rewind = (-p_filter->fmt_in.video.i_width) & 15;
i_rewind = (-(p_filter->fmt_in.video.i_x_offset + p_filter->fmt_in.video.i_visible_width)) & 15;
/*
** SSE2 128 bits fetch/store instructions are faster
......@@ -396,11 +400,11 @@ void I420_R5G6B5( filter_t *p_filter, picture_t *p_src, picture_t *p_dest )
((intptr_t)p_buffer))) )
{
/* use faster SSE2 aligned fetch and store */
for( i_y = 0; i_y < p_filter->fmt_in.video.i_height; i_y++ )
for( i_y = 0; i_y < (p_filter->fmt_in.video.i_y_offset + p_filter->fmt_in.video.i_visible_height); i_y++ )
{
p_pic_start = p_pic;
for ( i_x = p_filter->fmt_in.video.i_width/16; i_x--; )
for ( i_x = (p_filter->fmt_in.video.i_x_offset + p_filter->fmt_in.video.i_visible_width)/16; i_x--; )
{
SSE2_CALL (
SSE2_INIT_16_ALIGNED
......@@ -447,12 +451,12 @@ void I420_R5G6B5( filter_t *p_filter, picture_t *p_src, picture_t *p_dest )
else
{
/* use slower SSE2 unaligned fetch and store */
for( i_y = 0; i_y < p_filter->fmt_in.video.i_height; i_y++ )
for( i_y = 0; i_y < (p_filter->fmt_in.video.i_y_offset + p_filter->fmt_in.video.i_visible_height); i_y++ )
{
p_pic_start = p_pic;
p_buffer = b_hscale ? p_buffer_start : p_pic;
for ( i_x = p_filter->fmt_in.video.i_width/16; i_x--; )
for ( i_x = (p_filter->fmt_in.video.i_x_offset + p_filter->fmt_in.video.i_visible_width)/16; i_x--; )
{
SSE2_CALL(
SSE2_INIT_16_UNALIGNED
......@@ -502,14 +506,14 @@ void I420_R5G6B5( filter_t *p_filter, picture_t *p_src, picture_t *p_dest )
#else /* SSE2 */
i_rewind = (-p_filter->fmt_in.video.i_width) & 7;
i_rewind = (-(p_filter->fmt_in.video.i_x_offset + p_filter->fmt_in.video.i_visible_width)) & 7;
for( i_y = 0; i_y < p_filter->fmt_in.video.i_height; i_y++ )
for( i_y = 0; i_y < (p_filter->fmt_in.video.i_y_offset + p_filter->fmt_in.video.i_visible_height); i_y++ )
{
p_pic_start = p_pic;
p_buffer = b_hscale ? p_buffer_start : p_pic;
for ( i_x = p_filter->fmt_in.video.i_width / 8; i_x--; )
for ( i_x = (p_filter->fmt_in.video.i_x_offset + p_filter->fmt_in.video.i_visible_width) / 8; i_x--; )
{
MMX_CALL (
MMX_INIT_16
......@@ -576,7 +580,7 @@ void I420_A8R8G8B8( filter_t *p_filter, picture_t *p_src,
int i_right_margin;
int i_rewind;
int i_scale_count; /* scale modulo counter */
int i_chroma_width = p_filter->fmt_in.video.i_width / 2; /* chroma width */
int i_chroma_width = (p_filter->fmt_in.video.i_x_offset + p_filter->fmt_in.video.i_visible_width) / 2; /* chroma width */
uint32_t * p_pic_start; /* beginning of the current line for copy */
/* Conversion buffer pointer */
uint32_t * p_buffer_start = (uint32_t*)p_filter->p_sys->p_buffer;
......@@ -587,31 +591,33 @@ void I420_A8R8G8B8( filter_t *p_filter, picture_t *p_src,
int * p_offset;
const int i_source_margin = p_src->p[0].i_pitch
- p_src->p[0].i_visible_pitch;
- p_src->p[0].i_visible_pitch
- p_filter->fmt_in.video.i_x_offset;
const int i_source_margin_c = p_src->p[1].i_pitch
- p_src->p[1].i_visible_pitch;
- p_src->p[1].i_visible_pitch
- ( p_filter->fmt_in.video.i_x_offset / 2 );
i_right_margin = p_dest->p->i_pitch - p_dest->p->i_visible_pitch;
/* Rule: when a picture of size (x1,y1) with aspect ratio r1 is rendered
* on a picture of size (x2,y2) with aspect ratio r2, if x1 grows to x1'
* then y1 grows to y1' = x1' * y2/x2 * r2/r1 */
SetOffset( p_filter->fmt_in.video.i_width,
p_filter->fmt_in.video.i_height,
p_filter->fmt_out.video.i_width,
p_filter->fmt_out.video.i_height,
SetOffset( p_filter->fmt_in.video.i_x_offset + p_filter->fmt_in.video.i_visible_width,
p_filter->fmt_in.video.i_y_offset + p_filter->fmt_in.video.i_visible_height,
(p_filter->fmt_out.video.i_x_offset + p_filter->fmt_out.video.i_visible_width),
(p_filter->fmt_out.video.i_y_offset + p_filter->fmt_out.video.i_visible_height),
&b_hscale, &i_vscale, p_offset_start );
/*
* Perform conversion
*/
i_scale_count = ( i_vscale == 1 ) ?
p_filter->fmt_out.video.i_height :
p_filter->fmt_in.video.i_height;
(p_filter->fmt_out.video.i_y_offset + p_filter->fmt_out.video.i_visible_height) :
(p_filter->fmt_in.video.i_y_offset + p_filter->fmt_in.video.i_visible_height);
#ifdef SSE2
i_rewind = (-p_filter->fmt_in.video.i_width) & 15;
i_rewind = (-(p_filter->fmt_in.video.i_x_offset + p_filter->fmt_in.video.i_visible_width)) & 15;
/*
** SSE2 128 bits fetch/store instructions are faster
......@@ -625,11 +631,11 @@ void I420_A8R8G8B8( filter_t *p_filter, picture_t *p_src,
((intptr_t)p_buffer))) )
{
/* use faster SSE2 aligned fetch and store */
for( i_y = 0; i_y < p_filter->fmt_in.video.i_height; i_y++ )
for( i_y = 0; i_y < (p_filter->fmt_in.video.i_y_offset + p_filter->fmt_in.video.i_visible_height); i_y++ )
{
p_pic_start = p_pic;
for ( i_x = p_filter->fmt_in.video.i_width / 16; i_x--; )
for ( i_x = (p_filter->fmt_in.video.i_x_offset + p_filter->fmt_in.video.i_visible_width) / 16; i_x--; )
{
SSE2_CALL (
SSE2_INIT_32_ALIGNED
......@@ -676,12 +682,12 @@ void I420_A8R8G8B8( filter_t *p_filter, picture_t *p_src,
else
{
/* use slower SSE2 unaligned fetch and store */
for( i_y = 0; i_y < p_filter->fmt_in.video.i_height; i_y++ )
for( i_y = 0; i_y < (p_filter->fmt_in.video.i_y_offset + p_filter->fmt_in.video.i_visible_height); i_y++ )
{
p_pic_start = p_pic;
p_buffer = b_hscale ? p_buffer_start : p_pic;
for ( i_x = p_filter->fmt_in.video.i_width / 16; i_x--; )
for ( i_x = (p_filter->fmt_in.video.i_x_offset + p_filter->fmt_in.video.i_visible_width) / 16; i_x--; )
{
SSE2_CALL (
SSE2_INIT_32_UNALIGNED
......@@ -731,14 +737,14 @@ void I420_A8R8G8B8( filter_t *p_filter, picture_t *p_src,
#else
i_rewind = (-p_filter->fmt_in.video.i_width) & 7;
i_rewind = (-(p_filter->fmt_in.video.i_x_offset + p_filter->fmt_in.video.i_visible_width)) & 7;
for( i_y = 0; i_y < p_filter->fmt_in.video.i_height; i_y++ )
for( i_y = 0; i_y < (p_filter->fmt_in.video.i_y_offset + p_filter->fmt_in.video.i_visible_height); i_y++ )
{
p_pic_start = p_pic;
p_buffer = b_hscale ? p_buffer_start : p_pic;
for ( i_x = p_filter->fmt_in.video.i_width / 8; i_x--; )
for ( i_x = (p_filter->fmt_in.video.i_x_offset + p_filter->fmt_in.video.i_visible_width) / 8; i_x--; )
{
MMX_CALL (
MMX_INIT_32
......@@ -804,7 +810,7 @@ void I420_R8G8B8A8( filter_t *p_filter, picture_t *p_src, picture_t *p_dest )
int i_right_margin;
int i_rewind;
int i_scale_count; /* scale modulo counter */
int i_chroma_width = p_filter->fmt_in.video.i_width / 2; /* chroma width */
int i_chroma_width = (p_filter->fmt_in.video.i_x_offset + p_filter->fmt_in.video.i_visible_width) / 2; /* chroma width */
uint32_t * p_pic_start; /* beginning of the current line for copy */
/* Conversion buffer pointer */
uint32_t * p_buffer_start = (uint32_t*)p_filter->p_sys->p_buffer;
......@@ -815,31 +821,33 @@ void I420_R8G8B8A8( filter_t *p_filter, picture_t *p_src, picture_t *p_dest )
int * p_offset;
const int i_source_margin = p_src->p[0].i_pitch
- p_src->p[0].i_visible_pitch;
- p_src->p[0].i_visible_pitch
- p_filter->fmt_in.video.i_x_offset;
const int i_source_margin_c = p_src->p[1].i_pitch
- p_src->p[1].i_visible_pitch;
- p_src->p[1].i_visible_pitch
- ( p_filter->fmt_in.video.i_x_offset / 2 );
i_right_margin = p_dest->p->i_pitch - p_dest->p->i_visible_pitch;
/* Rule: when a picture of size (x1,y1) with aspect ratio r1 is rendered
* on a picture of size (x2,y2) with aspect ratio r2, if x1 grows to x1'
* then y1 grows to y1' = x1' * y2/x2 * r2/r1 */
SetOffset( p_filter->fmt_in.video.i_width,
p_filter->fmt_in.video.i_height,
p_filter->fmt_out.video.i_width,
p_filter->fmt_out.video.i_height,
SetOffset( (p_filter->fmt_in.video.i_x_offset + p_filter->fmt_in.video.i_visible_width),
(p_filter->fmt_in.video.i_y_offset + p_filter->fmt_in.video.i_visible_height),
(p_filter->fmt_out.video.i_x_offset + p_filter->fmt_out.video.i_visible_width),
(p_filter->fmt_out.video.i_y_offset + p_filter->fmt_out.video.i_visible_height),
&b_hscale, &i_vscale, p_offset_start );
/*
* Perform conversion
*/
i_scale_count = ( i_vscale == 1 ) ?
p_filter->fmt_out.video.i_height :
p_filter->fmt_in.video.i_height;
(p_filter->fmt_out.video.i_y_offset + p_filter->fmt_out.video.i_visible_height) :
(p_filter->fmt_in.video.i_y_offset + p_filter->fmt_in.video.i_visible_height);
#ifdef SSE2
i_rewind = (-p_filter->fmt_in.video.i_width) & 15;
i_rewind = (-(p_filter->fmt_in.video.i_x_offset + p_filter->fmt_in.video.i_visible_width)) & 15;
/*
** SSE2 128 bits fetch/store instructions are faster
......@@ -853,11 +861,11 @@ void I420_R8G8B8A8( filter_t *p_filter, picture_t *p_src, picture_t *p_dest )
((intptr_t)p_buffer))) )
{
/* use faster SSE2 aligned fetch and store */
for( i_y = 0; i_y < p_filter->fmt_in.video.i_height; i_y++ )
for( i_y = 0; i_y < (p_filter->fmt_in.video.i_y_offset + p_filter->fmt_in.video.i_visible_height); i_y++ )
{
p_pic_start = p_pic;
for ( i_x = p_filter->fmt_in.video.i_width / 16; i_x--; )
for ( i_x = (p_filter->fmt_in.video.i_x_offset + p_filter->fmt_in.video.i_visible_width) / 16; i_x--; )
{
SSE2_CALL (
SSE2_INIT_32_ALIGNED
......@@ -904,12 +912,12 @@ void I420_R8G8B8A8( filter_t *p_filter, picture_t *p_src, picture_t *p_dest )
else
{
/* use slower SSE2 unaligned fetch and store */
for( i_y = 0; i_y < p_filter->fmt_in.video.i_height; i_y++ )
for( i_y = 0; i_y < (p_filter->fmt_in.video.i_y_offset + p_filter->fmt_in.video.i_visible_height); i_y++ )
{
p_pic_start = p_pic;
p_buffer = b_hscale ? p_buffer_start : p_pic;
for ( i_x = p_filter->fmt_in.video.i_width / 16; i_x--; )
for ( i_x = (p_filter->fmt_in.video.i_x_offset + p_filter->fmt_in.video.i_visible_width) / 16; i_x--; )
{
SSE2_CALL (
SSE2_INIT_32_UNALIGNED
......@@ -959,14 +967,14 @@ void I420_R8G8B8A8( filter_t *p_filter, picture_t *p_src, picture_t *p_dest )
#else
i_rewind = (-p_filter->fmt_in.video.i_width) & 7;
i_rewind = (-(p_filter->fmt_in.video.i_x_offset + p_filter->fmt_in.video.i_visible_width)) & 7;
for( i_y = 0; i_y < p_filter->fmt_in.video.i_height; i_y++ )
for( i_y = 0; i_y < (p_filter->fmt_in.video.i_y_offset + p_filter->fmt_in.video.i_visible_height); i_y++ )
{
p_pic_start = p_pic;
p_buffer = b_hscale ? p_buffer_start : p_pic;
for ( i_x = p_filter->fmt_in.video.i_width / 8; i_x--; )
for ( i_x = (p_filter->fmt_in.video.i_x_offset + p_filter->fmt_in.video.i_visible_width) / 8; i_x--; )
{
MMX_CALL (
MMX_INIT_32
......@@ -1032,7 +1040,7 @@ void I420_B8G8R8A8( filter_t *p_filter, picture_t *p_src, picture_t *p_dest )
int i_right_margin;
int i_rewind;
int i_scale_count; /* scale modulo counter */
int i_chroma_width = p_filter->fmt_in.video.i_width / 2; /* chroma width */
int i_chroma_width = (p_filter->fmt_in.video.i_x_offset + p_filter->fmt_in.video.i_visible_width) / 2; /* chroma width */
uint32_t * p_pic_start; /* beginning of the current line for copy */
/* Conversion buffer pointer */
uint32_t * p_buffer_start = (uint32_t*)p_filter->p_sys->p_buffer;
......@@ -1043,31 +1051,33 @@ void I420_B8G8R8A8( filter_t *p_filter, picture_t *p_src, picture_t *p_dest )
int * p_offset;
const int i_source_margin = p_src->p[0].i_pitch
- p_src->p[0].i_visible_pitch;
- p_src->p[0].i_visible_pitch
- p_filter->fmt_in.video.i_x_offset;
const int i_source_margin_c = p_src->p[1].i_pitch
- p_src->p[1].i_visible_pitch;
- p_src->p[1].i_visible_pitch
- ( p_filter->fmt_in.video.i_x_offset / 2 );
i_right_margin = p_dest->p->i_pitch - p_dest->p->i_visible_pitch;
/* Rule: when a picture of size (x1,y1) with aspect ratio r1 is rendered
* on a picture of size (x2,y2) with aspect ratio r2, if x1 grows to x1'
* then y1 grows to y1' = x1' * y2/x2 * r2/r1 */
SetOffset( p_filter->fmt_in.video.i_width,
p_filter->fmt_in.video.i_height,
p_filter->fmt_out.video.i_width,
p_filter->fmt_out.video.i_height,
SetOffset( (p_filter->fmt_in.video.i_x_offset + p_filter->fmt_in.video.i_visible_width),
(p_filter->fmt_in.video.i_y_offset + p_filter->fmt_in.video.i_visible_height),
(p_filter->fmt_out.video.i_x_offset + p_filter->fmt_out.video.i_visible_width),
(p_filter->fmt_out.video.i_y_offset + p_filter->fmt_out.video.i_visible_height),
&b_hscale, &i_vscale, p_offset_start );
/*
* Perform conversion
*/
i_scale_count = ( i_vscale == 1 ) ?