Commit 55645776 authored by Rocky Bernstein's avatar Rocky Bernstein

Transparancy for more chromas more complete.

parent 7cef32c0
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* render.c : Philips OGT and CVD (VCD Subtitle) blending routines * render.c : Philips OGT and CVD (VCD Subtitle) blending routines
***************************************************************************** *****************************************************************************
* Copyright (C) 2003, 2004 VideoLAN * Copyright (C) 2003, 2004 VideoLAN
* $Id: render.c,v 1.24 2004/01/27 03:45:17 rocky Exp $ * $Id: render.c,v 1.25 2004/01/29 04:04:21 rocky Exp $
* *
* Author: Rocky Bernstein <rocky@panix.com> * Author: Rocky Bernstein <rocky@panix.com>
* based on code from: * based on code from:
...@@ -105,7 +105,14 @@ void VCDSubBlend( vout_thread_t *p_vout, picture_t *p_pic, ...@@ -105,7 +105,14 @@ void VCDSubBlend( vout_thread_t *p_vout, picture_t *p_pic,
case VLC_FOURCC('R','V','1','6'): case VLC_FOURCC('R','V','1','6'):
BlendRV16( p_vout, p_pic, p_spu, p_spu->p_sys->b_crop, BlendRV16( p_vout, p_pic, p_spu, p_spu->p_sys->b_crop,
/* Not sure under what conditions RV16 is really
RV16 and not RV15.
*/
#if 0
VLC_FALSE ); VLC_FALSE );
#else
VLC_TRUE );
#endif
break; break;
/* RV24 target, scaling */ /* RV24 target, scaling */
...@@ -226,6 +233,10 @@ static void BlendI420( vout_thread_t *p_vout, picture_t *p_pic, ...@@ -226,6 +233,10 @@ static void BlendI420( vout_thread_t *p_vout, picture_t *p_pic,
} }
} }
#ifdef TESTING_BLENDING
if (p_source->s.t == MAX_ALPHA) p_source->s.t >>= 1;
#endif
switch( p_source->s.t ) switch( p_source->s.t )
{ {
case 0: case 0:
...@@ -243,8 +254,10 @@ static void BlendI420( vout_thread_t *p_vout, picture_t *p_pic, ...@@ -243,8 +254,10 @@ static void BlendI420( vout_thread_t *p_vout, picture_t *p_pic,
*p_pixel_Y = p_source->plane[Y_PLANE]; *p_pixel_Y = p_source->plane[Y_PLANE];
if ( even_scanline && i_x % 2 == 0 ) { if ( even_scanline && i_x % 2 == 0 ) {
uint8_t *p_pixel_U = p_pixel_base_U_y + i_x/2; uint8_t *p_pixel_U = p_pixel_base_U_y + i_x/2
uint8_t *p_pixel_V = p_pixel_base_V_y + i_x/2; - p_pic->p[U_PLANE].i_pitch / 2;
uint8_t *p_pixel_V = p_pixel_base_V_y + i_x/2
- p_pic->p[V_PLANE].i_pitch / 2;
*p_pixel_U = p_source->plane[U_PLANE]; *p_pixel_U = p_source->plane[U_PLANE];
*p_pixel_V = p_source->plane[V_PLANE]; *p_pixel_V = p_source->plane[V_PLANE];
} }
...@@ -289,8 +302,10 @@ static void BlendI420( vout_thread_t *p_vout, picture_t *p_pic, ...@@ -289,8 +302,10 @@ static void BlendI420( vout_thread_t *p_vout, picture_t *p_pic,
*p_pixel_Y = ( i_sub_color_Y + i_pixel_color_Y ) >> ALPHA_BITS; *p_pixel_Y = ( i_sub_color_Y + i_pixel_color_Y ) >> ALPHA_BITS;
if ( even_scanline && i_x % 2 == 0 ) { if ( even_scanline && i_x % 2 == 0 ) {
uint8_t *p_pixel_U = p_pixel_base_U_y + i_x/2; uint8_t *p_pixel_U = p_pixel_base_U_y + i_x/2
uint8_t *p_pixel_V = p_pixel_base_V_y + i_x/2; - p_pic->p[U_PLANE].i_pitch / 2;
uint8_t *p_pixel_V = p_pixel_base_V_y + i_x/2
- p_pic->p[V_PLANE].i_pitch / 2;
uint16_t i_sub_color_U = uint16_t i_sub_color_U =
(uint16_t) ( p_source->plane[U_PLANE] * (uint16_t) ( p_source->plane[U_PLANE] *
(uint16_t) (p_source->s.t) ); (uint16_t) (p_source->s.t) );
...@@ -339,10 +354,8 @@ static void BlendYUY2( vout_thread_t *p_vout, picture_t *p_pic, ...@@ -339,10 +354,8 @@ static void BlendYUY2( vout_thread_t *p_vout, picture_t *p_pic,
/* This is the where the subtitle pixels come from */ /* This is the where the subtitle pixels come from */
ogt_yuvt_t *p_source = (ogt_yuvt_t *) p_spu->p_sys->p_data;; ogt_yuvt_t *p_source = (ogt_yuvt_t *) p_spu->p_sys->p_data;;
#if 1
ogt_yuvt_t *p_source_end = (ogt_yuvt_t *)p_spu->p_sys->p_data + ogt_yuvt_t *p_source_end = (ogt_yuvt_t *)p_spu->p_sys->p_data +
(p_spu->i_width * p_spu->i_height); (p_spu->i_width * p_spu->i_height);
#endif
uint16_t i_x, i_y; uint16_t i_x, i_y;
...@@ -394,13 +407,11 @@ static void BlendYUY2( vout_thread_t *p_vout, picture_t *p_pic, ...@@ -394,13 +407,11 @@ static void BlendYUY2( vout_thread_t *p_vout, picture_t *p_pic,
{ {
uint16_t i_avg_tr; /* transparancy sort of averaged over 2 pixels*/ uint16_t i_avg_tr; /* transparancy sort of averaged over 2 pixels*/
#if 1
if (p_source > p_source_end-1) { if (p_source > p_source_end-1) {
msg_Err( p_vout, "Trying to access beyond subtitle x: %d y: %d", msg_Err( p_vout, "Trying to access beyond subtitle x: %d y: %d",
i_x, i_y); i_x, i_y);
return; return;
} }
#endif
if( b_crop ) { if( b_crop ) {
...@@ -423,6 +434,9 @@ static void BlendYUY2( vout_thread_t *p_vout, picture_t *p_pic, ...@@ -423,6 +434,9 @@ static void BlendYUY2( vout_thread_t *p_vout, picture_t *p_pic,
else else
i_avg_tr = ( p_source->s.t + (p_source+1)->s.t ) / 2; i_avg_tr = ( p_source->s.t + (p_source+1)->s.t ) / 2;
#ifdef TESTING_BLENDING /**/
if (i_avg_tr == MAX_ALPHA) i_avg_tr >>= 1;
#endif
switch( i_avg_tr ) switch( i_avg_tr )
{ {
...@@ -611,6 +625,68 @@ yuv2rgb565(ogt_yuvt_t *p_yuv, uint8_t *p_rgb1, uint8_t *p_rgb2 ) ...@@ -611,6 +625,68 @@ yuv2rgb565(ogt_yuvt_t *p_yuv, uint8_t *p_rgb1, uint8_t *p_rgb2 )
} }
static inline void
rv16_pack_blend(uint8_t *p_pixel, ogt_yuvt_t *p_source, uint8_t *p_rgb1,
uint8_t *p_rgb2, vlc_bool_t b_15bpp, uint8_t i_alpha,
int a_scale_down )
{
uint8_t rgb_source[3];
uint8_t rgb[3];
int i;
yuv2rgb(p_source, rgb_source);
/* Scale RGB from 8 bits down to 6 or 5. */
rgb_source[RED_PIXEL] >>= b_15bpp ? (8-5) : (8-6);
rgb_source[GREEN_PIXEL] >>= (8-5);
rgb_source[BLUE_PIXEL] >>= (8-5);
rgb[GREEN_PIXEL] = *(p_pixel+1) & 0x1f;
if (b_15bpp) {
rgb[BLUE_PIXEL] = ((*p_pixel)>>2) & 0x1f;
rgb[RED_PIXEL] = ((*p_pixel & 0x03) << 3) | ((*(p_pixel+1)&0xe0)>>5);
} else {
rgb[BLUE_PIXEL] = ((*p_pixel)>>3) & 0x1f;
rgb[RED_PIXEL] = ((*p_pixel & 0x07) << 3) | ((*(p_pixel+1)&0xe0)>>5);
}
#if 0
printf("r,g,b=(%d,%d,%d), source r,g,b=(%d,%d,%d), alpha %d, dest_alpha %d\n",
rgb[RED_PIXEL], rgb[GREEN_PIXEL], rgb[BLUE_PIXEL],
rgb_source[RED_PIXEL], rgb_source[GREEN_PIXEL],
rgb_source[BLUE_PIXEL], i_alpha, i_dest_alpha);
#endif
for (i=0; i<3; i++) {
/* Average the two pixels. */
#ifdef FIXED_RV16_TRANSPARENCY
uint8_t i_dest_alpha = MAX_ALPHA - i_alpha;
rgb[i] = ( (uint16_t) rgb_source[i]*i_alpha + rgb[i]*i_dest_alpha) >>
ALPHA_BITS;
#else
/* For now the Best we can do is fade the color. Picking up
video underneath doesn't work. */
/* rgb[i] = ( (uint16_t) rgb[i]*i_dest_alpha ) >> ALPHA_BITS; */
rgb[i] = ( (uint16_t) rgb_source[i]*i_alpha ) >> ALPHA_BITS;
#endif
}
#if 0
printf("avg r,g,b=(%d,%d,%d)\n",
rgb[RED_PIXEL], rgb[GREEN_PIXEL], rgb[BLUE_PIXEL] );
#endif
if (b_15bpp) {
*p_rgb1 = ( (rgb[BLUE_PIXEL] << 2)&0x7c )|( (rgb[RED_PIXEL]>>3)&0x03 );
} else {
*p_rgb1 = ( (rgb[BLUE_PIXEL] << 3)&0xF8 )|( (rgb[RED_PIXEL]>>3)&0x07 );
}
*p_rgb2 = ( (rgb[RED_PIXEL] << 5)&0xe0 ) | ( rgb[GREEN_PIXEL]&0x1f );
}
#undef BYTES_PER_PIXEL #undef BYTES_PER_PIXEL
#define BYTES_PER_PIXEL 2 #define BYTES_PER_PIXEL 2
...@@ -720,13 +796,16 @@ BlendRV16( vout_thread_t *p_vout, picture_t *p_pic, ...@@ -720,13 +796,16 @@ BlendRV16( vout_thread_t *p_vout, picture_t *p_pic,
return; return;
} }
#ifdef TESTING_BLENDING
if (p_source->s.t == MAX_ALPHA) p_source->s.t >>= 1;
#endif
switch( p_source->s.t ) switch( p_source->s.t )
{ {
case 0: case 0:
/* Completely transparent. Don't change pixel. */ /* Completely transparent. Don't change pixel. */
break; break;
default:
case MAX_ALPHA: case MAX_ALPHA:
{ {
/* Completely opaque. Completely overwrite underlying /* Completely opaque. Completely overwrite underlying
...@@ -756,7 +835,6 @@ BlendRV16( vout_thread_t *p_vout, picture_t *p_pic, ...@@ -756,7 +835,6 @@ BlendRV16( vout_thread_t *p_vout, picture_t *p_pic,
break; break;
} }
#ifdef TRANSPARENCY_FINISHED
default: default:
{ {
/* Blend in underlying pixel subtitle pixel. */ /* Blend in underlying pixel subtitle pixel. */
...@@ -765,28 +843,21 @@ BlendRV16( vout_thread_t *p_vout, picture_t *p_pic, ...@@ -765,28 +843,21 @@ BlendRV16( vout_thread_t *p_vout, picture_t *p_pic,
* BYTES_PER_PIXEL ); * BYTES_PER_PIXEL );
uint32_t i_xlast = ( (((i_x+1)*i_xscale) >> ASCALE) uint32_t i_xlast = ( (((i_x+1)*i_xscale) >> ASCALE)
* BYTES_PER_PIXEL ); * BYTES_PER_PIXEL );
uint8_t i_rgb1;
uint8_t i_rgb2;
uint32_t len = i_xlast - i_xdest; uint32_t len = i_xlast - i_xdest;
/* This is the location that's going to get changed. */ /* This is the location that's going to get changed. */
uint8_t *p_dest = p_pixel_base_y + i_x * BYTES_PER_PIXEL; uint8_t *p_dest = p_pixel_base_y + i_x * BYTES_PER_PIXEL;
/* To be able to scale correctly for full opaqueness, we for ( len = i_xlast - i_xdest; len ; len--) {
add 1 to the alpha. This means alpha value 0 won't rv16_pack_blend(p_dest, p_source, &i_rgb1, &i_rgb2,
be completely transparent and is not correct, but b_15bpp, p_source->s.t, ALPHA_SCALEDOWN);
that's handled in a special case above anyway. */ *p_dest++ = i_rgb1;
*p_dest++ = i_rgb2;
uint8_t i_destalpha = MAX_ALPHA - p_source->s.t; }
uint8_t i_rgb1;
uint8_t i_rgb2;
if (b_15bpp)
yuv2rgb555(p_source, &i_rgb1, &i_rgb2);
else
yuv2rgb565(p_source, &i_rgb1, &i_rgb2);
rv16_pack_blend(p_dest, rgb, dest_alpha, ALPHA_SCALEDOWN);
break; break;
} }
#endif /*TRANSPARENCY_FINISHED*/
} }
} }
} }
...@@ -824,7 +895,6 @@ BlendRV16( vout_thread_t *p_vout, picture_t *p_pic, ...@@ -824,7 +895,6 @@ BlendRV16( vout_thread_t *p_vout, picture_t *p_pic,
/* Completely transparent. Don't change pixel. */ /* Completely transparent. Don't change pixel. */
break; break;
default:
case MAX_ALPHA: case MAX_ALPHA:
{ {
/* Completely opaque. Completely overwrite underlying /* Completely opaque. Completely overwrite underlying
...@@ -842,8 +912,7 @@ BlendRV16( vout_thread_t *p_vout, picture_t *p_pic, ...@@ -842,8 +912,7 @@ BlendRV16( vout_thread_t *p_vout, picture_t *p_pic,
{ {
/* This is the location that's going to get changed. */ /* This is the location that's going to get changed. */
uint8_t *p_dest = p_pixel_base_x + i_ytmp; uint8_t *p_dest = p_pixel_base_x + i_ytmp;
uint8_t i_rgb1; uint8_t i_rgb1, i_rgb2;
uint8_t i_rgb2;
if (b_15bpp) if (b_15bpp)
yuv2rgb555(p_source, &i_rgb1, &i_rgb2); yuv2rgb555(p_source, &i_rgb1, &i_rgb2);
else else
...@@ -856,30 +925,27 @@ BlendRV16( vout_thread_t *p_vout, picture_t *p_pic, ...@@ -856,30 +925,27 @@ BlendRV16( vout_thread_t *p_vout, picture_t *p_pic,
} }
break; break;
} }
#ifdef TRANSPARENCY_FINISHED
default: default:
for( ; i_ytmp < i_ynext ; y_ytmp += p_pic->p->i_pitch ) {
uint32_t i_xdest = ( ((i_x*i_xscale) >> ASCALE)
* BYTES_PER_PIXEL );
uint32_t i_xlast = ( (((i_x+1)*i_xscale) >> ASCALE)
* BYTES_PER_PIXEL );
uint32_t len = i_xlast - i_xdest;
uint8_t i_rgb1, i_rgb2;
for( ; i_ytmp < i_ynext ; i_ytmp += p_pic->p->i_pitch )
{ {
/* Blend in underlying pixel subtitle pixel. */ /* Blend in underlying pixel subtitle pixel. */
/* To be able to scale correctly for full opaqueness, we
add 1 to the alpha. This means alpha value 0 won't
be completely transparent and is not correct, but
that's handled in a special case above anyway. */
uint8_t *p_dest = p_pixel_base + i_ytmp; uint8_t *p_dest = p_pixel_base + i_ytmp;
uint8_t i_destalpha = MAX_ALPHA - p_source->s.t; for ( len = i_xlast - i_xdest; len ; len--) {
uint8_t i_rgb1; rv16_pack_blend(p_dest, p_source, &i_rgb1, &i_rgb2,
uint8_t i_rgb2; b_15bpp, p_source->s.t, ALPHA_SCALEDOWN);
*p_dest++ = i_rgb1;
if (b_15bpp) *p_dest++ = i_rgb2;
yuv2rgb555(p_source, &i_rgb1, &i_rgb2); }
else
yuv2rgb565(p_source, &i_rgb1, &i_rgb2);
rv16_pack_blend(p_dest, rgb, dest_alpha,ALPHA_SCALEDOWN);
} }
break; break;
#endif /*TRANSPARENCY_FINISHED*/ }
} }
} }
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment