diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/dxr3/video_out_dxr3.c | 17 | ||||
-rw-r--r-- | src/dxr3/video_out_dxr3.h | 4 | ||||
-rw-r--r-- | src/video_out/alphablend.c | 820 | ||||
-rw-r--r-- | src/video_out/alphablend.h | 26 | ||||
-rw-r--r-- | src/video_out/video_out_directfb.c | 19 | ||||
-rwxr-xr-x | src/video_out/video_out_directx.c | 12 | ||||
-rw-r--r-- | src/video_out/video_out_fb.c | 19 | ||||
-rw-r--r-- | src/video_out/video_out_opengl.c | 23 | ||||
-rw-r--r-- | src/video_out/video_out_pgx32.c | 9 | ||||
-rw-r--r-- | src/video_out/video_out_pgx64.c | 17 | ||||
-rw-r--r-- | src/video_out/video_out_sdl.c | 14 | ||||
-rw-r--r-- | src/video_out/video_out_stk.c | 14 | ||||
-rw-r--r-- | src/video_out/video_out_syncfb.c | 11 | ||||
-rw-r--r-- | src/video_out/video_out_vidix.c | 12 | ||||
-rw-r--r-- | src/video_out/video_out_xshm.c | 19 | ||||
-rw-r--r-- | src/video_out/video_out_xv.c | 14 | ||||
-rw-r--r-- | src/video_out/video_out_xvmc.c | 15 | ||||
-rw-r--r-- | src/video_out/video_out_xxmc.c | 15 | ||||
-rw-r--r-- | src/video_out/xxmc.h | 4 |
19 files changed, 767 insertions, 317 deletions
diff --git a/src/dxr3/video_out_dxr3.c b/src/dxr3/video_out_dxr3.c index cec83ceab..d12afb27a 100644 --- a/src/dxr3/video_out_dxr3.c +++ b/src/dxr3/video_out_dxr3.c @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: video_out_dxr3.c,v 1.104 2004/09/22 20:29:13 miguelfreitas Exp $ + * $Id: video_out_dxr3.c,v 1.105 2004/11/24 16:11:02 mroi Exp $ */ /* mpeg1 encoding video out plugin for the dxr3. @@ -234,7 +234,7 @@ static vo_driver_t *dxr3_vo_open_plugin(video_driver_class_t *class_gen, const v this = (dxr3_driver_t *)xine_xmalloc(sizeof(dxr3_driver_t)); if (!this) return NULL; - + this->vo_driver.get_capabilities = dxr3_get_capabilities; this->vo_driver.alloc_frame = dxr3_alloc_frame; this->vo_driver.update_frame_format = dxr3_update_frame_format; @@ -253,6 +253,7 @@ static vo_driver_t *dxr3_vo_open_plugin(video_driver_class_t *class_gen, const v pthread_mutex_init(&this->spu_device_lock, NULL); _x_vo_scale_init(&this->scale, 0, 0, config); + _x_alphablend_init(&this->alphablend_extra_data, class->xine); this->class = class; this->swap_fields = config->register_bool(config, @@ -808,19 +809,22 @@ static void dxr3_overlay_begin(vo_driver_t *this_gen, vo_frame_t *frame_gen, int static void dxr3_overlay_blend(vo_driver_t *this_gen, vo_frame_t *frame_gen, vo_overlay_t *overlay) { + dxr3_driver_t *this = (dxr3_driver_t *)this_gen; + if (frame_gen->format != XINE_IMGFMT_DXR3) { dxr3_frame_t *frame = (dxr3_frame_t *)frame_gen; if (overlay->rle) { if (frame_gen->format == XINE_IMGFMT_YV12) blend_yuv(frame->vo_frame.base, overlay, - frame->vo_frame.width, frame->vo_frame.height, frame->vo_frame.pitches); + frame->vo_frame.width, frame->vo_frame.height, + frame->vo_frame.pitches, &this->alphablend_extra_data); else blend_yuy2(frame->vo_frame.base[0], overlay, - frame->vo_frame.width, frame->vo_frame.height, frame->vo_frame.pitches[0]); + frame->vo_frame.width, frame->vo_frame.height, + frame->vo_frame.pitches[0], &this->alphablend_extra_data); } } else { /* XINE_IMGFMT_DXR3 */ - dxr3_driver_t *this = (dxr3_driver_t *)this_gen; if (!this->spu_enc->need_reencode) return; /* FIXME: we only handle the last overlay because previous ones are simply overwritten */ this->spu_enc->overlay = overlay; @@ -1248,6 +1252,9 @@ static void dxr3_dispose(vo_driver_t *this_gen) pthread_mutex_unlock(&this->spu_device_lock); pthread_mutex_destroy(&this->video_device_lock); pthread_mutex_destroy(&this->spu_device_lock); + + _x_alphablend_free(&this->alphablend_extra_data); + free(this); } diff --git a/src/dxr3/video_out_dxr3.h b/src/dxr3/video_out_dxr3.h index 8454eb2bc..2157e8f3a 100644 --- a/src/dxr3/video_out_dxr3.h +++ b/src/dxr3/video_out_dxr3.h @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: video_out_dxr3.h,v 1.22 2004/04/10 15:29:58 mroi Exp $ + * $Id: video_out_dxr3.h,v 1.23 2004/11/24 16:11:03 mroi Exp $ */ #ifdef HAVE_CONFIG_H @@ -32,6 +32,7 @@ #include "vo_scale.h" #include "dxr3_scr.h" #include "dxr3.h" +#include "alphablend.h" /* the number of supported encoders */ #define SUPPORTED_ENCODER_COUNT 3 @@ -116,6 +117,7 @@ typedef struct dxr3_driver_s { int top_bar; /* the height of the upper black bar */ vo_scale_t scale; + alphablend_t alphablend_extra_data; dxr3_overlay_t overlay; #ifdef HAVE_X11 diff --git a/src/video_out/alphablend.c b/src/video_out/alphablend.c index a9f216a9e..1d8980103 100644 --- a/src/video_out/alphablend.c +++ b/src/video_out/alphablend.c @@ -38,6 +38,7 @@ #include "xine_internal.h" #include "video_out.h" #include "alphablend.h" +#include "bswap.h" #define BLEND_COLOR(dst, src, mask, o) ((((src&mask)*o + ((dst&mask)*(0x0f-o)))/0xf) & mask) @@ -56,7 +57,7 @@ static void mem_blend16(uint16_t *mem, uint16_t clr, uint8_t o, int len) { } static void mem_blend24(uint8_t *mem, uint8_t r, uint8_t g, uint8_t b, - uint8_t o, int len) { + uint8_t o, int len) { uint8_t *limit = mem + len*3; while (mem < limit) { *mem = BLEND_BYTE(*mem, r, o); @@ -112,7 +113,8 @@ rle_img_advance_line(rle_elem_t *rle, rle_elem_t *rle_limit, int w) void blend_rgb16 (uint8_t * img, vo_overlay_t * img_overl, int img_width, int img_height, - int dst_width, int dst_height) + int dst_width, int dst_height, + alphablend_t *extra_data) { uint8_t *trans; clut_t *clut; @@ -184,11 +186,11 @@ void blend_rgb16 (uint8_t * img, vo_overlay_t * img_overl, if( (img_overl->x + img_overl->clip_right) < dst_width ) clip_right = img_overl->clip_right; else - clip_right = dst_width - 1 - img_overl->x; + clip_right = dst_width - img_overl->x; /* avoid buffer overflow */ if( (src_height + img_overl->y) >= dst_height ) - src_height = dst_height - 1 - img_overl->y; + src_height = dst_height - img_overl->y; rlelen = rle_remainder = rle_this_bite = 0; rle_remainder = rlelen = rle->len; @@ -224,13 +226,13 @@ void blend_rgb16 (uint8_t * img, vo_overlay_t * img_overl, if (y < img_overl->clip_top) { zone_state = 1; break; - } else if (y > img_overl->clip_bottom) { + } else if (y >= img_overl->clip_bottom) { zone_state = 5; break; } else if (x < img_overl->clip_left) { zone_state = 2; break; - } else if (x > img_overl->clip_right) { + } else if (x >= img_overl->clip_right) { zone_state = 4; break; } else { @@ -294,7 +296,7 @@ void blend_rgb16 (uint8_t * img, vo_overlay_t * img_overl, clut = (clut_t*) img_overl->color; trans = img_overl->trans; o = trans[clr]; - if (x + rle_remainder < img_overl->clip_left) { + if (x + rle_remainder <= img_overl->clip_left) { rle_this_bite = rle_remainder; rle_remainder = rlelen = rle->len; clr_next = rle->color; @@ -326,7 +328,7 @@ void blend_rgb16 (uint8_t * img, vo_overlay_t * img_overl, } else { rle = rle_start; /* y-scaling, reuse the last rle encoded line */ } - if (y > img_overl->clip_bottom) { + if (y >= img_overl->clip_bottom) { zone_state = 5; break; } @@ -339,7 +341,7 @@ void blend_rgb16 (uint8_t * img, vo_overlay_t * img_overl, clut = (clut_t*) img_overl->clip_color; trans = img_overl->clip_trans; o = trans[clr]; - if (x + rle_remainder < img_overl->clip_right) { + if (x + rle_remainder <= img_overl->clip_right) { rle_this_bite = rle_remainder; rle_remainder = rlelen = rle->len; clr_next = rle->color; @@ -371,7 +373,7 @@ void blend_rgb16 (uint8_t * img, vo_overlay_t * img_overl, } else { rle = rle_start; /* y-scaling, reuse the last rle encoded line */ } - if (y > img_overl->clip_bottom) { + if (y >= img_overl->clip_bottom) { zone_state = 5; break; } @@ -384,7 +386,7 @@ void blend_rgb16 (uint8_t * img, vo_overlay_t * img_overl, clut = (clut_t*) img_overl->color; trans = img_overl->trans; o = trans[clr]; - if (x + rle_remainder < src_width) { + if (x + rle_remainder <= src_width) { rle_this_bite = rle_remainder; rle_remainder = rlelen = rle->len; clr_next = rle->color; @@ -416,7 +418,7 @@ void blend_rgb16 (uint8_t * img, vo_overlay_t * img_overl, } else { rle = rle_start; /* y-scaling, reuse the last rle encoded line */ } - if (y > img_overl->clip_bottom) { + if (y >= img_overl->clip_bottom) { zone_state = 5; break; } @@ -514,10 +516,9 @@ void blend_rgb16 (uint8_t * img, vo_overlay_t * img_overl, void blend_rgb24 (uint8_t * img, vo_overlay_t * img_overl, int img_width, int img_height, - int dst_width, int dst_height) + int dst_width, int dst_height, + alphablend_t *extra_data) { - clut_t* clut = (clut_t*) img_overl->clip_color; - uint8_t *trans; int src_width = img_overl->width; int src_height = img_overl->height; rle_elem_t *rle = img_overl->rle; @@ -533,65 +534,106 @@ void blend_rgb24 (uint8_t * img, vo_overlay_t * img_overl, img_pix = img + 3 * ( (img_overl->y * img_height / dst_height) * img_width + (img_overl->x * img_width / dst_width)); - trans = img_overl->clip_trans; - /* avoid wraping overlay if drawing to small image */ - if( (img_overl->x + img_overl->clip_right) < dst_width ) + if( (img_overl->x + img_overl->clip_right) <= dst_width ) clip_right = img_overl->clip_right; else - clip_right = dst_width - 1 - img_overl->x; + clip_right = dst_width - img_overl->x; /* avoid buffer overflow */ - if( (src_height + img_overl->y) >= dst_height ) - src_height = dst_height - 1 - img_overl->y; + if( (src_height + img_overl->y) > dst_height ) + src_height = dst_height - img_overl->y; for (dy = y = 0; y < src_height && rle < rle_limit; ) { - int mask = !(img_overl->clip_top > y || img_overl->clip_bottom < y); + int mask = !(y < img_overl->clip_top || y >= img_overl->clip_bottom); rle_elem_t *rle_start = rle; + int rlelen = 0; + uint8_t clr = 0; + for (x = x1_scaled = 0; x < src_width;) { - uint8_t clr; + int rle_bite; + clut_t *colors; + uint8_t *trans; uint16_t o; - int rlelen; - clr = rle->color; - o = trans[clr]; - rlelen = rle->len; - - if (o && mask) { - /* threat cases where clipping border is inside rle->len pixels */ - if ( img_overl->clip_left > x ) { - if( img_overl->clip_left < x + rlelen ) { - x1_scaled = SCALED_TO_INT( img_overl->clip_left * x_scale ); - rlelen -= img_overl->clip_left - x; - x += img_overl->clip_left - x; + /* take next element from rle list everytime an element is finished */ + if (rlelen <= 0) { + if (rle >= rle_limit) + break; + + rlelen = rle->len; + clr = rle->color; + rle++; + } + + if (!mask) { + /* above or below clipping area */ + + rle_bite = rlelen; + /* choose palette for surrounding area */ + colors = (clut_t*)img_overl->color; + trans = img_overl->trans; + } else { + /* treat cases where clipping border is inside rle->len pixels */ + if ( x < img_overl->clip_left ) { + /* starts left */ + if( x + rlelen > img_overl->clip_left ) { + /* ends not left */ + + /* choose the largest "bite" up to palette change */ + rle_bite = img_overl->clip_left - x; + /* choose palette for surrounding area */ + colors = (clut_t*)img_overl->color; + trans = img_overl->trans; } else { - o = 0; + /* ends left */ + + rle_bite = rlelen; + /* choose palette for surrounding area */ + colors = (clut_t*)img_overl->color; + trans = img_overl->trans; } - } else if( clip_right < x + rlelen ) { - if( clip_right > x ) { - x2_scaled = SCALED_TO_INT( clip_right * x_scale); - mem_blend24(img_pix + x1_scaled*3, clut[clr].cb, - clut[clr].cr, clut[clr].y, - o, x2_scaled-x1_scaled); - o = 0; + } else if( x + rlelen > clip_right ) { + /* ends right */ + if( x < clip_right ) { + /* starts not right */ + + /* choose the largest "bite" up to palette change */ + rle_bite = clip_right - x; + /* we're in the center area so choose clip palette */ + colors = (clut_t*)img_overl->clip_color; + trans = img_overl->clip_trans; } else { - o = 0; + /* starts right */ + + rle_bite = rlelen; + /* choose palette for surrounding area */ + colors = (clut_t*)img_overl->color; + trans = img_overl->trans; } - } + } else { + /* starts not left and ends not right */ + + rle_bite = rlelen; + /* we're in the center area so choose clip palette */ + colors = (clut_t*)img_overl->clip_color; + trans = img_overl->clip_trans; + } } - x2_scaled = SCALED_TO_INT((x + rlelen) * x_scale); - if (o && mask) { - mem_blend24(img_pix + x1_scaled*3, clut[clr].cb, - clut[clr].cr, clut[clr].y, + x2_scaled = SCALED_TO_INT((x + rle_bite) * x_scale); + + o = trans[clr]; + if (o) { + mem_blend24(img_pix + x1_scaled*3, + colors[clr].cb, colors[clr].cr, colors[clr].y, o, x2_scaled-x1_scaled); } x1_scaled = x2_scaled; - x += rlelen; - rle++; - if (rle >= rle_limit) break; + x += rle_bite; + rlelen -= rle_bite; } img_pix += img_width * 3; @@ -612,10 +654,9 @@ void blend_rgb24 (uint8_t * img, vo_overlay_t * img_overl, void blend_rgb32 (uint8_t * img, vo_overlay_t * img_overl, int img_width, int img_height, - int dst_width, int dst_height) + int dst_width, int dst_height, + alphablend_t *extra_data) { - clut_t* clut = (clut_t*) img_overl->clip_color; - uint8_t *trans; int src_width = img_overl->width; int src_height = img_overl->height; rle_elem_t *rle = img_overl->rle; @@ -631,61 +672,104 @@ void blend_rgb32 (uint8_t * img, vo_overlay_t * img_overl, img_pix = img + 4 * ( (img_overl->y * img_height / dst_height) * img_width + (img_overl->x * img_width / dst_width)); - trans = img_overl->clip_trans; - /* avoid wraping overlay if drawing to small image */ - if( (img_overl->x + img_overl->clip_right) < dst_width ) + if( (img_overl->x + img_overl->clip_right) <= dst_width ) clip_right = img_overl->clip_right; else - clip_right = dst_width - 1 - img_overl->x; + clip_right = dst_width - img_overl->x; /* avoid buffer overflow */ - if( (src_height + img_overl->y) >= dst_height ) - src_height = dst_height - 1 - img_overl->y; + if( (src_height + img_overl->y) > dst_height ) + src_height = dst_height - img_overl->y; for (y = dy = 0; y < src_height && rle < rle_limit; ) { - int mask = !(img_overl->clip_top > y || img_overl->clip_bottom < y); + int mask = !(y < img_overl->clip_top || y >= img_overl->clip_bottom); rle_elem_t *rle_start = rle; + int rlelen = 0; + uint8_t clr = 0; + for (x = x1_scaled = 0; x < src_width;) { - uint8_t clr; + int rle_bite; + clut_t *colors; + uint8_t *trans; uint16_t o; - int rlelen; + + /* take next element from rle list everytime an element is finished */ + if (rlelen <= 0) { + if (rle >= rle_limit) + break; + + rlelen = rle->len; + clr = rle->color; + rle++; + } - clr = rle->color; - o = trans[clr]; - rlelen = rle->len; - - if (o && mask) { - /* threat cases where clipping border is inside rle->len pixels */ - if ( img_overl->clip_left > x ) { - if( img_overl->clip_left < x + rlelen ) { - x1_scaled = SCALED_TO_INT( img_overl->clip_left * x_scale ); - rlelen -= img_overl->clip_left - x; - x += img_overl->clip_left - x; + if (!mask) { + /* above or below clipping area */ + + rle_bite = rlelen; + /* choose palette for surrounding area */ + colors = (clut_t*)img_overl->color; + trans = img_overl->trans; + } else { + /* treat cases where clipping border is inside rle->len pixels */ + if ( x < img_overl->clip_left ) { + /* starts left */ + if( x + rlelen > img_overl->clip_left ) { + /* ends not left */ + + /* choose the largest "bite" up to palette change */ + rle_bite = img_overl->clip_left - x; + /* choose palette for surrounding area */ + colors = (clut_t*)img_overl->color; + trans = img_overl->trans; } else { - o = 0; + /* ends left */ + + rle_bite = rlelen; + /* choose palette for surrounding area */ + colors = (clut_t*)img_overl->color; + trans = img_overl->trans; } - } else if( clip_right < x + rlelen ) { - if( clip_right > x ) { - x2_scaled = SCALED_TO_INT( clip_right * x_scale); - mem_blend32(img_pix + x1_scaled*4, (uint8_t *)&clut[clr], o, x2_scaled-x1_scaled); - o = 0; + } else if( x + rlelen > clip_right ) { + /* ends right */ + if( x < clip_right ) { + /* starts not right */ + + /* choose the largest "bite" up to palette change */ + rle_bite = clip_right - x; + /* we're in the center area so choose clip palette */ + colors = (clut_t*)img_overl->clip_color; + trans = img_overl->clip_trans; } else { - o = 0; + /* starts right */ + + rle_bite = rlelen; + /* choose palette for surrounding area */ + colors = (clut_t*)img_overl->color; + trans = img_overl->trans; } - } + } else { + /* starts not left and ends not right */ + + rle_bite = rlelen; + /* we're in the center area so choose clip palette */ + colors = (clut_t*)img_overl->clip_color; + trans = img_overl->clip_trans; + } } + + x2_scaled = SCALED_TO_INT((x + rle_bite) * x_scale); - x2_scaled = SCALED_TO_INT((x + rlelen) * x_scale); - if (o && mask) { - mem_blend32(img_pix + x1_scaled*4, (uint8_t *)&clut[clr], o, x2_scaled-x1_scaled); + o = trans[clr]; + if (o) { + mem_blend32(img_pix + x1_scaled*4, (uint8_t *)&colors[clr], o, x2_scaled-x1_scaled); } x1_scaled = x2_scaled; - x += rlelen; - rle++; - if (rle >= rle_limit) break; + x += rle_bite; + rlelen -= rle_bite; } img_pix += img_width * 4; @@ -713,52 +797,38 @@ static void mem_blend8(uint8_t *mem, uint8_t val, uint8_t o, size_t sz) } } - -#define EXACT_BLENDING 1 - - -#ifdef EXACT_BLENDING - -#define BLEND_MAXWIDTH 2048 -uint8_t blend_yuv_data[ 3 ][ 2 ][ BLEND_MAXWIDTH ]; -uint8_t blend_yuv_data[ 3 ][ 2 ][ BLEND_MAXWIDTH ]; -uint8_t blend_yuv_data[ 3 ][ 2 ][ BLEND_MAXWIDTH ]; - -void blend_yuv_exact(uint8_t *dst_cr, uint8_t *dst_cb, int src_width, int x_odd); -void blend_yuv_exact(uint8_t *dst_cr, uint8_t *dst_cb, int src_width, int x_odd) +static void blend_yuv_exact(uint8_t *dst_cr, uint8_t *dst_cb, + int src_width, int x_odd, + uint8_t *(*blend_yuv_data)[ 3 ][ 2 ]) { int x; for (x = 0; x < src_width; x += 2) { /* get opacity of the 4 pixels that share chroma */ - int o00 = blend_yuv_data[ 0 ][ 0 ][ x + 0 ]; - int o01 = blend_yuv_data[ 0 ][ 0 ][ x + 1 ]; - int o10 = blend_yuv_data[ 0 ][ 1 ][ x + 0 ]; - int o11 = blend_yuv_data[ 0 ][ 1 ][ x + 1 ]; + int o00 = (*blend_yuv_data)[ 0 ][ 0 ][ x + 0 ]; + int o01 = (*blend_yuv_data)[ 0 ][ 0 ][ x + 1 ]; + int o10 = (*blend_yuv_data)[ 0 ][ 1 ][ x + 0 ]; + int o11 = (*blend_yuv_data)[ 0 ][ 1 ][ x + 1 ]; /* are there any pixels a little bit opaque? */ - if (o00 || o01 || o10 || o11) - { - /* get the chroma componets of the 4 pixels */ - int cr00 = -128 + blend_yuv_data[ 1 ][ 0 ][ x + 0 ]; - int cr01 = -128 + blend_yuv_data[ 1 ][ 0 ][ x + 1 ]; - int cr10 = -128 + blend_yuv_data[ 1 ][ 1 ][ x + 0 ]; - int cr11 = -128 + blend_yuv_data[ 1 ][ 1 ][ x + 1 ]; + if (o00 || o01 || o10 || o11) { + /* get the chroma components of the 4 pixels */ + int cr00 = -128 + (*blend_yuv_data)[ 1 ][ 0 ][ x + 0 ]; + int cr01 = -128 + (*blend_yuv_data)[ 1 ][ 0 ][ x + 1 ]; + int cr10 = -128 + (*blend_yuv_data)[ 1 ][ 1 ][ x + 0 ]; + int cr11 = -128 + (*blend_yuv_data)[ 1 ][ 1 ][ x + 1 ]; - int cb00 = -128 + blend_yuv_data[ 2 ][ 0 ][ x + 0 ]; - int cb01 = -128 + blend_yuv_data[ 2 ][ 0 ][ x + 1 ]; - int cb10 = -128 + blend_yuv_data[ 2 ][ 1 ][ x + 0 ]; - int cb11 = -128 + blend_yuv_data[ 2 ][ 1 ][ x + 1 ]; + int cb00 = -128 + (*blend_yuv_data)[ 2 ][ 0 ][ x + 0 ]; + int cb01 = -128 + (*blend_yuv_data)[ 2 ][ 0 ][ x + 1 ]; + int cb10 = -128 + (*blend_yuv_data)[ 2 ][ 1 ][ x + 0 ]; + int cb11 = -128 + (*blend_yuv_data)[ 2 ][ 1 ][ x + 1 ]; /* are all pixels completely opaque? */ - if (o00 >= 0xf && o01 >= 0xf && o10 >= 0xf && o11 >= 0xf) - { + if (o00 >= 0xf && o01 >= 0xf && o10 >= 0xf && o11 >= 0xf) { /* set the output chroma to the average of the four pixels */ *dst_cr = 128 + (cr00 + cr01 + cr10 + cr11) / 4; *dst_cb = 128 + (cb00 + cb01 + cb10 + cb11) / 4; - } - else - { + } else { int t4, cr, cb; /* blending required, so clamp opacity values to allowed range */ @@ -786,11 +856,50 @@ void blend_yuv_exact(uint8_t *dst_cr, uint8_t *dst_cb, int src_width, int x_odd) } } -#endif +static uint8_t *(*blend_yuv_grow_extra_data(alphablend_t *extra_data, int osd_width))[ 3 ][ 2 ] +{ + struct __attribute__((packed)) header_s { + int id; + int max_width; + uint8_t *data[ 3 ][ 2 ]; + } **header = (struct header_s **)&extra_data->buffer; + + int needed_buffer_size = sizeof (**header) + sizeof (uint8_t[ 3 ][ 2 ][ osd_width ]); + + if (extra_data->buffer_size < needed_buffer_size) { + + free(extra_data->buffer); + extra_data->buffer = xine_xmalloc(needed_buffer_size); + + if (!extra_data->buffer) { + extra_data->buffer_size = 0; + return 0; + } + + extra_data->buffer_size = needed_buffer_size; + (*header)->max_width = 0; + } + if ((*header)->id != ME_FOURCC('y', 'u', 'v', 0) || (*header)->max_width < osd_width) { + (*header)->id = ME_FOURCC('y', 'u', 'v', 0); + (*header)->max_width = osd_width; + + (*header)->data[ 0 ][ 0 ] = ((uint8_t *)extra_data->buffer) + sizeof (**header); + (*header)->data[ 0 ][ 1 ] = (*header)->data[ 0 ][ 0 ] + osd_width; + (*header)->data[ 1 ][ 0 ] = (*header)->data[ 0 ][ 1 ] + osd_width; + (*header)->data[ 1 ][ 1 ] = (*header)->data[ 1 ][ 0 ] + osd_width; + (*header)->data[ 2 ][ 0 ] = (*header)->data[ 1 ][ 1 ] + osd_width; + (*header)->data[ 2 ][ 1 ] = (*header)->data[ 2 ][ 0 ] + osd_width; + } + + return &(*header)->data; +} + void blend_yuv (uint8_t *dst_base[3], vo_overlay_t * img_overl, - int dst_width, int dst_height, int dst_pitches[3]) + int dst_width, int dst_height, int dst_pitches[3], + alphablend_t *extra_data) { + int enable_exact_blending = !extra_data->disable_exact_blending; clut_t *my_clut; uint8_t *my_trans; @@ -809,10 +918,11 @@ void blend_yuv (uint8_t *dst_base[3], vo_overlay_t * img_overl, int x, y; int clip_right; uint8_t clr=0; -#ifdef EXACT_BLENDING - int anyLineBufferd = 0; - int exactBlendWidth = ((src_width <= (dst_width - x_off)) ? src_width : (dst_width - x_off)); -#endif + + int any_line_buffered = 0; + int exact_blend_width = ((src_width <= (dst_width - x_off)) ? src_width : (dst_width - x_off)); + int exact_blend_width_m2 = (x_odd + exact_blend_width + 1) & ~1; /* make it a (larger) multiple of 2 */ + uint8_t *(*blend_yuv_data)[ 3 ][ 2 ] = 0; uint8_t *dst_y = dst_base[0] + dst_pitches[0] * y_off + x_off; uint8_t *dst_cr = dst_base[2] + (y_off / 2) * dst_pitches[1] + (x_off / 2); @@ -833,10 +943,21 @@ void blend_yuv (uint8_t *dst_base[3], vo_overlay_t * img_overl, if( (src_height + y_off) > dst_height ) src_height = dst_height - y_off; -#ifdef EXACT_BLENDING - /* make linebuffer transparent */ - memset(&blend_yuv_data[ 0 ][ 0 ][ 0 ], 0, 2 * BLEND_MAXWIDTH); -#endif + if (src_height <= 0) + return; + + if (enable_exact_blending) { + if (exact_blend_width <= 0) + return; + + blend_yuv_data = blend_yuv_grow_extra_data(extra_data, exact_blend_width_m2); + if (!blend_yuv_data) + return; + + /* make linebuffer transparent */ + memset(&(*blend_yuv_data)[ 0 ][ 0 ][ 0 ], 0, exact_blend_width_m2); + memset(&(*blend_yuv_data)[ 0 ][ 1 ][ 0 ], 0, exact_blend_width_m2); + } rlelen=rle_remainder=0; for (y = 0; y < src_height; y++) { @@ -940,7 +1061,7 @@ void blend_yuv (uint8_t *dst_base[3], vo_overlay_t * img_overl, xmask++; } } else if (x >= clip_right) { - /* Starts outside clip area, ends outsite clip area */ + /* Starts outside clip area, ends outside clip area */ if ((x + rle_remainder ) > src_width ) { #ifdef LOG_BLEND_YUV printf("Outside clip right %d, ending eol\n", clip_right); @@ -981,49 +1102,47 @@ void blend_yuv (uint8_t *dst_base[3], vo_overlay_t * img_overl, printf("Trans=%d clr=%d xmask=%d my_clut[clr]=%d\n",o, clr, xmask, my_clut[clr].y); #endif - if (x < (dst_width - x_off)) - { + if (x < (dst_width - x_off)) { /* clip against right edge of destination area */ - if ((x + rle_this_bite) > (dst_width - x_off)) - { + if ((x + rle_this_bite) > (dst_width - x_off)) { int toClip = (x + rle_this_bite) - (dst_width - x_off); rle_this_bite -= toClip; rle_remainder += toClip; rlelen += toClip; } - -#ifdef EXACT_BLENDING - /* remember opacity of current line */ - memset(&blend_yuv_data[ 0 ][ (y + y_odd) & 1 ][ x + x_odd ], o, rle_this_bite); - anyLineBufferd |= ((y + y_odd) & 1) ? 2 : 1; -#endif + + if (enable_exact_blending) { + /* remember opacity of current line */ + memset(&(*blend_yuv_data)[ 0 ][ (y + y_odd) & 1 ][ x + x_odd ], o, rle_this_bite); + any_line_buffered |= ((y + y_odd) & 1) ? 2 : 1; + } if (o) { if(o >= 15) { memset(dst_y + x, my_clut[clr].y, rle_this_bite); -#ifndef EXACT_BLENDING - if ((y + y_odd) & 1) { - memset(dst_cr + ((x + x_odd) >> 1), my_clut[clr].cr, (rle_this_bite+1) >> 1); - memset(dst_cb + ((x + x_odd) >> 1), my_clut[clr].cb, (rle_this_bite+1) >> 1); + if (!enable_exact_blending) { + if ((y + y_odd) & 1) { + memset(dst_cr + ((x + x_odd) >> 1), my_clut[clr].cr, (rle_this_bite+1) >> 1); + memset(dst_cb + ((x + x_odd) >> 1), my_clut[clr].cb, (rle_this_bite+1) >> 1); + } } -#endif } else { mem_blend8(dst_y + x, my_clut[clr].y, o, rle_this_bite); -#ifndef EXACT_BLENDING - if ((y + y_odd) & 1) { - /* Blending cr and cb should use a different function, with pre -128 to each sample */ - mem_blend8(dst_cr + ((x + x_odd) >> 1), my_clut[clr].cr, o, (rle_this_bite+1) >> 1); - mem_blend8(dst_cb + ((x + x_odd) >> 1), my_clut[clr].cb, o, (rle_this_bite+1) >> 1); + if (!enable_exact_blending) { + if ((y + y_odd) & 1) { + /* Blending cr and cb should use a different function, with pre -128 to each sample */ + mem_blend8(dst_cr + ((x + x_odd) >> 1), my_clut[clr].cr, o, (rle_this_bite+1) >> 1); + mem_blend8(dst_cb + ((x + x_odd) >> 1), my_clut[clr].cb, o, (rle_this_bite+1) >> 1); + } } -#endif } - -#ifdef EXACT_BLENDING - /* remember chroma of current line */ - memset(&blend_yuv_data[ 1 ][ (y + y_odd) & 1 ][ x + x_odd ], my_clut[ clr ].cr, rle_this_bite); - memset(&blend_yuv_data[ 2 ][ (y + y_odd) & 1 ][ x + x_odd ], my_clut[ clr ].cb, rle_this_bite); -#endif + + if (enable_exact_blending) { + /* remember chroma of current line */ + memset(&(*blend_yuv_data)[ 1 ][ (y + y_odd) & 1 ][ x + x_odd ], my_clut[ clr ].cr, rle_this_bite); + memset(&(*blend_yuv_data)[ 2 ][ (y + y_odd) & 1 ][ x + x_odd ], my_clut[ clr ].cb, rle_this_bite); + } } } #ifdef LOG_BLEND_YUV @@ -1032,53 +1151,137 @@ void blend_yuv (uint8_t *dst_base[3], vo_overlay_t * img_overl, x += rle_this_bite; } - dst_y += dst_pitches[0]; - if ((y + y_odd) & 1) { - -#ifdef EXACT_BLENDING - /* blend bufferd chroma */ - if (anyLineBufferd) - { - if (!(anyLineBufferd & 2)) - { - /* make second line transparent */ - memset(&blend_yuv_data[ 0 ][ 1 ][ 0 ], 0, BLEND_MAXWIDTH); + if (enable_exact_blending) { + /* blend buffered lines */ + if (any_line_buffered) { + if (!(any_line_buffered & 2)) { + /* make second line transparent */ + memset(&(*blend_yuv_data)[ 0 ][ 1 ][ 0 ], 0, exact_blend_width_m2); + } + + blend_yuv_exact(dst_cr, dst_cb, exact_blend_width, x_odd, blend_yuv_data); + + any_line_buffered = 0; } - - blend_yuv_exact(dst_cr, dst_cb, exactBlendWidth, x_odd); - - anyLineBufferd = 0; } -#endif dst_cr += dst_pitches[2]; dst_cb += dst_pitches[1]; } + + dst_y += dst_pitches[0]; } - -#ifdef EXACT_BLENDING - /* blend bufferd chroma */ - if (anyLineBufferd) - { - if (!(anyLineBufferd & 2)) - { - /* make second line transparent */ - memset(&blend_yuv_data[ 0 ][ 1 ][ 0 ], 0, BLEND_MAXWIDTH); + + if (enable_exact_blending) { + /* blend buffered lines */ + if (any_line_buffered) { + if (!(any_line_buffered & 2)) { + /* make second line transparent */ + memset(&(*blend_yuv_data)[ 0 ][ 1 ][ 0 ], 0, exact_blend_width_m2); + } + + blend_yuv_exact(dst_cr, dst_cb, exact_blend_width, x_odd, blend_yuv_data); } - - blend_yuv_exact(dst_cr, dst_cb, exactBlendWidth, x_odd); } -#endif #ifdef LOG_BLEND_YUV printf("overlay_blend ended\n"); #endif } +static void blend_yuy2_exact(uint8_t *dst_cr, uint8_t *dst_cb, + int src_width, int x_odd, + uint8_t *(*blend_yuy2_data)[ 3 ]) +{ + int x; + + for (x = 0; x < src_width; x += 2) { + /* get opacity of the 2 pixels that share chroma */ + int o0 = (*blend_yuy2_data)[ 0 ][ x + 0 ]; + int o1 = (*blend_yuy2_data)[ 0 ][ x + 1 ]; + + /* are there any pixels a little bit opaque? */ + if (o0 || o1) { + /* get the chroma components of the 2 pixels */ + int cr0 = -128 + (*blend_yuy2_data)[ 1 ][ x + 0 ]; + int cr1 = -128 + (*blend_yuy2_data)[ 1 ][ x + 1 ]; + + int cb0 = -128 + (*blend_yuy2_data)[ 2 ][ x + 0 ]; + int cb1 = -128 + (*blend_yuy2_data)[ 2 ][ x + 1 ]; + + /* are all pixels completely opaque? */ + if (o0 >= 0xf && o1 >= 0xf) { + /* set the output chroma to the average of the two pixels */ + *dst_cr = 128 + (cr0 + cr1) / 2; + *dst_cb = 128 + (cb0 + cb1) / 2; + } else { + int t2, cr, cb; + + /* blending required, so clamp opacity values to allowed range */ + if (o0 > 0xf) o0 = 0xf; + if (o1 > 0xf) o1 = 0xf; + + /* calculate transparency of background over the two pixels */ + t2 = (0xf - o0) + (0xf - o1); + + /* get background chroma */ + cr = -128 + *dst_cr; + cb = -128 + *dst_cb; + + /* blend the output chroma to the average of the two pixels */ + *dst_cr = 128 + (cr * t2 + cr0 * o0 + cr1 * o1) / (2 * 0xf); + *dst_cb = 128 + (cb * t2 + cb0 * o0 + cb1 * o1) / (2 * 0xf); + } + } + + /* next chroma sample */ + dst_cr += 4; + dst_cb += 4; + } +} + +static uint8_t *(*blend_yuy2_grow_extra_data(alphablend_t *extra_data, int osd_width))[ 3 ] +{ + struct __attribute__((packed)) header_s { + int id; + int max_width; + uint8_t *data[ 3 ]; + } **header = (struct header_s **)&extra_data->buffer; + + int needed_buffer_size = sizeof (**header) + sizeof (uint8_t[ 3 ][ osd_width ]); + + if (extra_data->buffer_size < needed_buffer_size) { + + free(extra_data->buffer); + extra_data->buffer = xine_xmalloc(needed_buffer_size); + + if (!extra_data->buffer) { + extra_data->buffer_size = 0; + return 0; + } + + extra_data->buffer_size = needed_buffer_size; + (*header)->max_width = 0; + } + + if ((*header)->id != ME_FOURCC('y', 'u', 'y', '2') || (*header)->max_width < osd_width) { + (*header)->id = ME_FOURCC('y', 'u', 'y', '2'); + (*header)->max_width = osd_width; + + (*header)->data[ 0 ] = ((uint8_t *)extra_data->buffer) + sizeof (**header); + (*header)->data[ 1 ] = (*header)->data[ 0 ] + osd_width; + (*header)->data[ 2 ] = (*header)->data[ 1 ] + osd_width; + } + + return &(*header)->data; +} + void blend_yuy2 (uint8_t * dst_img, vo_overlay_t * img_overl, - int dst_width, int dst_height, int dst_pitch) + int dst_width, int dst_height, int dst_pitch, + alphablend_t *extra_data) { + int enable_exact_blending = !extra_data->disable_exact_blending; clut_t *my_clut; uint8_t *my_trans; @@ -1088,20 +1291,27 @@ void blend_yuy2 (uint8_t * dst_img, vo_overlay_t * img_overl, rle_elem_t *rle_limit = rle + img_overl->num_rle; int x_off = img_overl->x; int y_off = img_overl->y; + int x_odd = x_off & 1; int ymask; int rle_this_bite; int rle_remainder; int rlelen; int x, y; - int l; + int l = 0; int clip_right; + union { - uint32_t value; - uint8_t b[4]; - uint16_t h[2]; + uint32_t value; + uint8_t b[4]; + uint16_t h[2]; } yuy2; uint8_t clr = 0; + + int any_line_buffered = 0; + int exact_blend_width = ((src_width <= (dst_width - x_off)) ? src_width : (dst_width - x_off)); + int exact_blend_width_m2 = (x_odd + exact_blend_width + 1) & ~1; /* make it a (larger) multiple of 2 */ + uint8_t *(*blend_yuy2_data)[ 3 ] = 0; uint8_t *dst_y = dst_img + dst_pitch * y_off + 2 * x_off; uint8_t *dst; @@ -1110,23 +1320,44 @@ void blend_yuy2 (uint8_t * dst_img, vo_overlay_t * img_overl, my_trans = img_overl->clip_trans; /* avoid wraping overlay if drawing to small image */ - if( (x_off + img_overl->clip_right) < dst_width ) + if( (x_off + img_overl->clip_right) <= dst_width ) clip_right = img_overl->clip_right; else - clip_right = dst_width - 1 - x_off; + clip_right = dst_width - x_off; /* avoid buffer overflow */ - if( (src_height + y_off) >= dst_height ) - src_height = dst_height - 1 - y_off; + if( (src_height + y_off) > dst_height ) + src_height = dst_height - y_off; + + if (src_height <= 0) + return; + + if (enable_exact_blending) { + if (exact_blend_width <= 0) + return; + + blend_yuy2_data = blend_yuy2_grow_extra_data(extra_data, exact_blend_width_m2); + if (!blend_yuy2_data) + return; + + /* make linebuffer transparent */ + memset(&(*blend_yuy2_data)[ 0 ][ 0 ], 0, exact_blend_width_m2); + } rlelen=rle_remainder=0; for (y = 0; y < src_height; y++) { - ymask = ((img_overl->clip_top > y) || (img_overl->clip_bottom < y)); + if (rle >= rle_limit) + break; + + ymask = ((y < img_overl->clip_top) || (y >= img_overl->clip_bottom)); dst = dst_y; for (x = 0; x < src_width;) { uint16_t o; + if (rle >= rle_limit) + break; + if ((rlelen < 0) || (rle_remainder < 0)) { #ifdef LOG_BLEND_YUV printf("alphablend: major bug in blend_yuv < 0\n"); @@ -1149,14 +1380,14 @@ void blend_yuy2 (uint8_t * dst_img, vo_overlay_t * img_overl, #endif if (ymask == 0) { - if (x <= img_overl->clip_left) { + if (x < img_overl->clip_left) { /* Starts outside clip area */ - if ((x + rle_remainder - 1) > img_overl->clip_left ) { + if ((x + rle_remainder) > img_overl->clip_left ) { #ifdef LOG_BLEND_YUV printf("Outside clip left %d, ending inside\n", img_overl->clip_left); #endif /* Cutting needed, starts outside, ends inside */ - rle_this_bite = (img_overl->clip_left - x + 1); + rle_this_bite = (img_overl->clip_left - x); rle_remainder -= rle_this_bite; rlelen -= rle_this_bite; my_clut = (clut_t*) img_overl->color; @@ -1231,48 +1462,99 @@ void blend_yuy2 (uint8_t * dst_img, vo_overlay_t * img_overl, } o = my_trans[clr]; - if (o) { - l = rle_this_bite>>1; - if( !((x_off+x) & 1) ) { - yuy2.b[0] = my_clut[clr].y; - yuy2.b[1] = my_clut[clr].cb; - yuy2.b[2] = my_clut[clr].y; - yuy2.b[3] = my_clut[clr].cr; + if (x < (dst_width - x_off)) { + /* clip against right edge of destination area */ + if ((x + rle_this_bite) > (dst_width - x_off)) { + int toClip = (x + rle_this_bite) - (dst_width - x_off); + + rle_this_bite -= toClip; + rle_remainder += toClip; + rlelen += toClip; + } + + if (enable_exact_blending) { + /* remember opacity of current line */ + memset(&(*blend_yuy2_data)[ 0 ][ x + x_odd ], o, rle_this_bite); + any_line_buffered = 1; + } + + if (o) { + if (!enable_exact_blending) { + l = rle_this_bite>>1; + if( !((x_odd+x) & 1) ) { + yuy2.b[0] = my_clut[clr].y; + yuy2.b[1] = my_clut[clr].cb; + yuy2.b[2] = my_clut[clr].y; + yuy2.b[3] = my_clut[clr].cr; + } else { + yuy2.b[0] = my_clut[clr].y; + yuy2.b[1] = my_clut[clr].cr; + yuy2.b[2] = my_clut[clr].y; + yuy2.b[3] = my_clut[clr].cb; + } + } + if (o >= 15) { + if (!enable_exact_blending) { + while(l--) { + *(uint16_t *)dst = yuy2.h[0]; + dst += 2; + *(uint16_t *)dst = yuy2.h[1]; + dst += 2; + } + if(rle_this_bite & 1) { + *(uint16_t *)dst = yuy2.h[0]; + dst += 2; + } + } else { + l = rle_this_bite; + while (l--) { + *dst = my_clut[clr].y; + dst += 2; + } + } + } else { + if (!enable_exact_blending) { + if( l ) { + mem_blend32(dst, &yuy2.b[0], o, l); + dst += 4*l; + } + + if(rle_this_bite & 1) { + *dst = BLEND_BYTE(*dst, yuy2.b[0], o); + dst++; + *dst = BLEND_BYTE(*dst, yuy2.b[1], o); + dst++; + } + } else { + l = rle_this_bite; + while (l--) { + *dst = BLEND_BYTE(*dst, my_clut[clr].y, o); + dst += 2; + } + } + } + + if (enable_exact_blending) { + /* remember chroma of current line */ + memset(&(*blend_yuy2_data)[ 1 ][ x + x_odd ], my_clut[ clr ].cr, rle_this_bite); + memset(&(*blend_yuy2_data)[ 2 ][ x + x_odd ], my_clut[ clr ].cb, rle_this_bite); + } } else { - yuy2.b[0] = my_clut[clr].y; - yuy2.b[1] = my_clut[clr].cr; - yuy2.b[2] = my_clut[clr].y; - yuy2.b[3] = my_clut[clr].cb; + dst += rle_this_bite*2; } - - if (o >= 15) { - while(l--) { - *((uint16_t *)dst)++ = yuy2.h[0]; - *((uint16_t *)dst)++ = yuy2.h[1]; - } - if(rle_this_bite & 1) - *((uint16_t *)dst)++ = yuy2.h[0]; - } else { - if( l ) { - mem_blend32(dst, &yuy2.b[0], o, l); - dst += 4*l; - } - - if(rle_this_bite & 1) { - *dst = BLEND_BYTE(*dst, yuy2.b[0], o); - dst++; - *dst = BLEND_BYTE(*dst, yuy2.b[1], o); - dst++; - } - } - } else { - dst += rle_this_bite*2; } - + x += rle_this_bite; - if (rle >= rle_limit) break; } - if (rle >= rle_limit) break; + + if (enable_exact_blending) { + /* blend buffered line */ + if (any_line_buffered) { + blend_yuy2_exact(dst_y - x_odd * 2 + 3, dst_y - x_odd * 2 + 1, exact_blend_width, x_odd, blend_yuy2_data); + + any_line_buffered = 0; + } + } dst_y += dst_pitch; } @@ -1368,6 +1650,7 @@ static void memblend_xx44(uint8_t *mem,uint8_t val, register size_t size, uint8_ void blend_xx44 (uint8_t *dst_img, vo_overlay_t *img_overl, int dst_width, int dst_height, int dst_pitch, + alphablend_t *extra_data, xx44_palette_t *palette,int ia44) { int src_width = img_overl->width; @@ -1389,7 +1672,7 @@ void blend_xx44 (uint8_t *dst_img, vo_overlay_t *img_overl, dst_y = dst_img + dst_pitch*y_off + x_off; - if( (x_off + img_overl->width) < dst_width ) + if( (x_off + img_overl->width) <= dst_width ) clip_right = img_overl->width; else clip_right = dst_width - x_off; @@ -1399,11 +1682,11 @@ void blend_xx44 (uint8_t *dst_img, vo_overlay_t *img_overl, for (y = 0; y < src_height; y++) { - mask = !(img_overl->clip_top > y || img_overl->clip_bottom < y); + mask = !(y < img_overl->clip_top || y >= img_overl->clip_bottom); dst = dst_y; for (x = 0; x < src_width;) { - int len = (x + rle->len > clip_right) ? clip_right -x + 1 : rle->len; + int len = (x + rle->len > clip_right) ? clip_right - x : rle->len; if (len > 0) { norm_pixel = (uint8_t)((xx44_paletteIndex(palette,rle->color, @@ -1418,33 +1701,33 @@ void blend_xx44 (uint8_t *dst_img, vo_overlay_t *img_overl, } if (mask) { if (x < img_overl->clip_left) { - if (x + len - 1 < img_overl->clip_left) { + if (x + len <= img_overl->clip_left) { memblend_xx44(dst,norm_pixel,len, alphamask); dst += len; } else { memblend_xx44(dst,norm_pixel,img_overl->clip_left -x, alphamask); dst += img_overl->clip_left - x; len -= img_overl->clip_left - x; - if (len < img_overl->clip_right - img_overl->clip_left + 1) { + if (len <= img_overl->clip_right - img_overl->clip_left) { memblend_xx44(dst,clip_pixel,len, alphamask); dst += len; } else { - memblend_xx44(dst,clip_pixel,img_overl->clip_right - img_overl->clip_left +1, + memblend_xx44(dst,clip_pixel,img_overl->clip_right - img_overl->clip_left, alphamask); - dst += img_overl->clip_right - img_overl->clip_left +1; - len -= img_overl->clip_right - img_overl->clip_left +1; + dst += img_overl->clip_right - img_overl->clip_left; + len -= img_overl->clip_right - img_overl->clip_left; memblend_xx44(dst,norm_pixel,len, alphamask); dst += len; } } - } else if (x <= img_overl->clip_right) { - if (len < img_overl->clip_right - x + 1) { + } else if (x < img_overl->clip_right) { + if (len <= img_overl->clip_right - x) { memblend_xx44(dst,clip_pixel,len, alphamask); dst += len; } else { - memblend_xx44(dst,clip_pixel,img_overl->clip_right - x +1,alphamask); - dst += img_overl->clip_right - x +1; - len -= img_overl->clip_right - x +1; + memblend_xx44(dst,clip_pixel,img_overl->clip_right - x,alphamask); + dst += img_overl->clip_right - x; + len -= img_overl->clip_right - x; memblend_xx44(dst,norm_pixel,len, alphamask); dst += len; } @@ -1465,3 +1748,38 @@ void blend_xx44 (uint8_t *dst_img, vo_overlay_t *img_overl, dst_y += dst_pitch; } } + +static void alphablend_disable_exact_osd_alpha_blending_changed(void *user_data, xine_cfg_entry_t *entry) +{ + alphablend_t *extra_data = (alphablend_t *)user_data; + + extra_data->disable_exact_blending = entry->num_value; +} + +void _x_alphablend_init(alphablend_t *extra_data, xine_t *xine) +{ + config_values_t *config = xine->config; + + extra_data->buffer = 0; + extra_data->buffer_size = 0; + + extra_data->disable_exact_blending = + config->register_bool(config, "video.disable_exact_osd_alpha_blending", 0, + _("disable exact alpha blending of overlays"), + _("If you experience a performance impact when an On Screen Display or other " + "overlays like DVD subtitles are active, then you might want to enable this option.\n" + "The result is that alpha blending of overlays is less accurate than before, " + "but the CPU usage will be decreased as well."), + 10, alphablend_disable_exact_osd_alpha_blending_changed, extra_data); +} + +void _x_alphablend_free(alphablend_t *extra_data) +{ + if (extra_data->buffer) { + free(extra_data->buffer); + extra_data->buffer = NULL; + } + + extra_data->buffer_size = 0; +} + diff --git a/src/video_out/alphablend.h b/src/video_out/alphablend.h index dd7f799ea..b49a902c3 100644 --- a/src/video_out/alphablend.h +++ b/src/video_out/alphablend.h @@ -27,6 +27,16 @@ #include "video_out.h" +typedef struct { + void *buffer; + int buffer_size; + + int disable_exact_blending; +} alphablend_t; + +void _x_alphablend_init(alphablend_t *extra_data, xine_t *xine); +void _x_alphablend_free(alphablend_t *extra_data); + /* _MSC_VER port changes */ #undef ATTRIBUTE_PACKED #undef PRAGMA_PACK_BEGIN @@ -71,21 +81,26 @@ typedef struct { void blend_rgb16 (uint8_t * img, vo_overlay_t * img_overl, int img_width, int img_height, - int dst_width, int dst_height); + int dst_width, int dst_height, + alphablend_t *extra_data); void blend_rgb24 (uint8_t * img, vo_overlay_t * img_overl, int img_width, int img_height, - int dst_width, int dst_height); + int dst_width, int dst_height, + alphablend_t *extra_data); void blend_rgb32 (uint8_t * img, vo_overlay_t * img_overl, int img_width, int img_height, - int dst_width, int dst_height); + int dst_width, int dst_height, + alphablend_t *extra_data); void blend_yuv (uint8_t *dst_base[3], vo_overlay_t * img_overl, - int dst_width, int dst_height, int dst_pitches[3]); + int dst_width, int dst_height, int dst_pitches[3], + alphablend_t *extra_data); void blend_yuy2 (uint8_t * dst_img, vo_overlay_t * img_overl, - int dst_width, int dst_height, int dst_pitch); + int dst_width, int dst_height, int dst_pitch, + alphablend_t *extra_data); /* * This function isn't too smart about blending. We want to avoid creating new @@ -96,6 +111,7 @@ void blend_yuy2 (uint8_t * dst_img, vo_overlay_t * img_overl, void blend_xx44 (uint8_t *dst_img, vo_overlay_t *img_overl, int dst_width, int dst_height, int dst_pitch, + alphablend_t *extra_data, xx44_palette_t *palette,int ia44); /* diff --git a/src/video_out/video_out_directfb.c b/src/video_out/video_out_directfb.c index 2560d4dfb..84af34eb1 100644 --- a/src/video_out/video_out_directfb.c +++ b/src/video_out/video_out_directfb.c @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: video_out_directfb.c,v 1.27 2004/09/22 20:29:15 miguelfreitas Exp $ + * $Id: video_out_directfb.c,v 1.28 2004/11/24 16:11:03 mroi Exp $ * * DirectFB based output plugin. * Rich Wareham <richwareham@users.sourceforge.net> @@ -117,6 +117,7 @@ typedef struct directfb_driver_s { int video_width, int video_height, int *dest_width, int *dest_height); + alphablend_t alphablend_extra_data; } directfb_driver_t; typedef struct { @@ -358,11 +359,13 @@ static void directfb_overlay_blend (vo_driver_t *this_gen, vo_frame_t *frame_gen # if BYTES_PER_PIXEL == 3 blend_rgb24 ((uint8_t *)frame->texture, overlay, frame->width, frame->height, - this->delivered_width, this->delivered_height); + this->delivered_width, this->delivered_height, + &this->alphablend_extra_data); # elif BYTES_PER_PIXEL == 4 blend_rgb32 ((uint8_t *)frame->texture, overlay, frame->width, frame->height, - this->delivered_width, this->delivered_height); + this->delivered_width, this->delivered_height, + &this->alphablend_extra_data); # else # error "bad BYTES_PER_PIXEL" # endif @@ -505,12 +508,16 @@ static int directfb_gui_data_exchange (vo_driver_t *this_gen, static int directfb_redraw_needed (vo_driver_t *this_gen) { /* directfb_driver_t *this = (directfb_driver_t *) this_gen; */ - return 0; + return 0; } static void directfb_dispose (vo_driver_t *this_gen) { - /* directfb_driver_t *this = (directfb_driver_t *) this_gen; */ + directfb_driver_t *this = (directfb_driver_t *) this_gen; + + _x_alphablend_free(&this->alphablend_extra_data); + + free(this); } typedef struct { @@ -533,6 +540,8 @@ static vo_driver_t *open_plugin (video_driver_class_t *class_gen, const void *vi if (!this) return NULL; + _x_alphablend_init(&this->alphablend_extra_data, class->xine); + this->xine = class->xine; this->frame_width = 0; this->frame_height = 0; diff --git a/src/video_out/video_out_directx.c b/src/video_out/video_out_directx.c index 8e113f7a8..e9e3d9dd1 100755 --- a/src/video_out/video_out_directx.c +++ b/src/video_out/video_out_directx.c @@ -20,7 +20,7 @@ * video_out_directx.c, direct draw video output plugin for xine * by Matthew Grooms <elon@altavista.com> * - * $Id: video_out_directx.c,v 1.19 2004/09/22 20:29:15 miguelfreitas Exp $ + * $Id: video_out_directx.c,v 1.20 2004/11/24 16:11:04 mroi Exp $ */ typedef unsigned char boolean; @@ -117,6 +117,8 @@ typedef struct { yuv2rgb_t *yuv2rgb; /* used for format conversion */ int mode; /* rgb mode */ int bytespp; /* rgb bits per pixel */ + + alphablend_t alphablend_extra_data; } win32_driver_t; typedef struct { @@ -399,6 +401,8 @@ void Destroy( win32_driver_t * win32_driver ) if( win32_driver->ddobj ) IDirectDraw_Release( win32_driver->ddobj ); + _x_alphablend_free(&this->alphablend_extra_data); + free( win32_driver ); } @@ -1099,9 +1103,9 @@ static void win32_overlay_blend( vo_driver_t * vo_driver, vo_frame_t * vo_frame, if( vo_overlay->rle ) { if( vo_frame->format == XINE_IMGFMT_YV12 ) - blend_yuv( win32_frame->vo_frame.base, vo_overlay, win32_frame->width, win32_frame->height, win32_frame->vo_frame.pitches ); + blend_yuv( win32_frame->vo_frame.base, vo_overlay, win32_frame->width, win32_frame->height, win32_frame->vo_frame.pitches, &this->alphablend_extra_data ); else - blend_yuy2( win32_frame->vo_frame.base[0], vo_overlay, win32_frame->width, win32_frame->height, win32_frame->vo_frame.pitches[0] ); + blend_yuy2( win32_frame->vo_frame.base[0], vo_overlay, win32_frame->width, win32_frame->height, win32_frame->vo_frame.pitches[0], &this->alphablend_extra_data ); } } @@ -1171,6 +1175,8 @@ static vo_driver_t *open_plugin (video_driver_class_t *class_gen, const void *wi directx_class_t *class = (directx_class_t *)class_gen; win32_driver_t *win32_driver = ( win32_driver_t * ) xine_xmalloc ( sizeof( win32_driver_t ) ); + _x_alphablend_init(&this->alphablend_extra_data, class->xine); + win32_driver->xine = class->xine; /* Make sure that the DirectX drivers are available and present! */ diff --git a/src/video_out/video_out_fb.c b/src/video_out/video_out_fb.c index 2c99bf58c..22a715ec1 100644 --- a/src/video_out/video_out_fb.c +++ b/src/video_out/video_out_fb.c @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: video_out_fb.c,v 1.38 2004/10/09 06:45:48 mroi Exp $ + * $Id: video_out_fb.c,v 1.39 2004/11/24 16:11:04 mroi Exp $ * * video_out_fb.c, frame buffer xine driver by Miguel Freitas * @@ -144,6 +144,8 @@ typedef struct fb_driver_s int use_zero_copy; xine_t *xine; + + alphablend_t alphablend_extra_data; } fb_driver_t; typedef struct @@ -529,7 +531,8 @@ static void fb_overlay_blend (vo_driver_t *this_gen, vo_frame_t *frame_gen, frame->sc.output_width, frame->sc.output_height, frame->sc.delivered_width, - frame->sc.delivered_height); + frame->sc.delivered_height, + &this->alphablend_extra_data); break; case 24: @@ -538,7 +541,8 @@ static void fb_overlay_blend (vo_driver_t *this_gen, vo_frame_t *frame_gen, frame->sc.output_width, frame->sc.output_height, frame->sc.delivered_width, - frame->sc.delivered_height); + frame->sc.delivered_height, + &this->alphablend_extra_data); break; case 32: @@ -547,7 +551,8 @@ static void fb_overlay_blend (vo_driver_t *this_gen, vo_frame_t *frame_gen, frame->sc.output_width, frame->sc.output_height, frame->sc.delivered_width, - frame->sc.delivered_height); + frame->sc.delivered_height, + &this->alphablend_extra_data); break; } } @@ -700,6 +705,10 @@ static void fb_dispose(vo_driver_t *this_gen) munmap(0, this->mem_size); close(this->fd); + + _x_alphablend_free(&this->alphablend_extra_data); + + free(this); } static int get_fb_var_screeninfo(int fd, struct fb_var_screeninfo *var, xine_t *xine) @@ -968,6 +977,8 @@ static vo_driver_t *fb_open_plugin(video_driver_class_t *class_gen, this = (fb_driver_t *) xine_xmalloc(sizeof(fb_driver_t)); if(!this) return NULL; + + _x_alphablend_init(&this->alphablend_extra_data, class->xine); register_callbacks(this); diff --git a/src/video_out/video_out_opengl.c b/src/video_out/video_out_opengl.c index c440002e3..8b3f11e18 100644 --- a/src/video_out/video_out_opengl.c +++ b/src/video_out/video_out_opengl.c @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: video_out_opengl.c,v 1.42 2004/11/23 15:01:23 mshopf Exp $ + * $Id: video_out_opengl.c,v 1.43 2004/11/24 16:11:04 mroi Exp $ * * video_out_opengl.c, OpenGL based interface for xine * @@ -114,6 +114,7 @@ typedef struct { vo_driver_t vo_driver; vo_scale_t sc; + alphablend_t alphablend_extra_data; /* X11 related stuff */ Display *display; @@ -950,13 +951,15 @@ static void opengl_overlay_blend (vo_driver_t *this_gen, opengl_overlay_clut_yuv2rgb (this, overlay, frame); # if BYTES_PER_PIXEL == 3 - blend_rgb24 ((uint8_t *)frame->rgb, overlay, - frame->width, frame->height, - frame->width, frame->height); + blend_rgb24 ((uint8_t *)frame->texture, overlay, + frame->width, frame->height, + frame->width, frame->height, + &this->alphablend_extra_data); # elif BYTES_PER_PIXEL == 4 - blend_rgb32 ((uint8_t *)frame->rgb, overlay, - frame->width, frame->height, - frame->width, frame->height); + blend_rgb32 ((uint8_t *)frame->texture, overlay, + frame->width, frame->height, + frame->width, frame->height, + &this->alphablend_extra_data); # else # error "bad BYTES_PER_PIXEL" # endif @@ -1256,6 +1259,8 @@ static void opengl_dispose (vo_driver_t *this_gen) { XUnlockDisplay (this->display); } + _x_alphablend_free(&this->alphablend_extra_data); + free (this); } @@ -1295,6 +1300,8 @@ static vo_driver_t *opengl_open_plugin (video_driver_class_t *class_gen, const v this->sc.user_data = visual->user_data; this->sc.user_ratio = XINE_VO_ASPECT_AUTO; + _x_alphablend_init (&this->alphablend_extra_data, class->xine); + this->drawable = visual->d; this->gui_width = this->gui_height = -1; this->last_width = this->last_height = -1; @@ -1368,7 +1375,7 @@ static vo_driver_t *opengl_open_plugin (video_driver_class_t *class_gen, const v _("enable double buffering"), _("For OpenGL double buffering does not only remove tearing artifacts,\n" "it also reduces flickering a lot.\n" - " It should not have any performance impact."), + "It should not have any performance impact."), 20, NULL, NULL); pthread_mutex_init (&this->render_action_mutex, NULL); diff --git a/src/video_out/video_out_pgx32.c b/src/video_out/video_out_pgx32.c index 1c370f221..b0a7fb894 100644 --- a/src/video_out/video_out_pgx32.c +++ b/src/video_out/video_out_pgx32.c @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: video_out_pgx32.c,v 1.11 2004/09/22 20:29:15 miguelfreitas Exp $ + * $Id: video_out_pgx32.c,v 1.12 2004/11/24 16:11:05 mroi Exp $ * * video_out_pgx32.c, Sun PGX32 output plugin for xine * @@ -173,6 +173,8 @@ typedef struct { pgx32_frame_t *current; int delivered_format, deinterlace_en; + + alphablend_t alphablend_extra_data; } pgx32_driver_t; /* @@ -775,6 +777,9 @@ static void pgx32_dispose(vo_driver_t *this_gen) munmap(this->vbase, GFXP_VRAM_MMAPLEN); munmap((void *)this->vregs, GFXP_REGS_MMAPLEN); + + _x_alphablend_free(&this->alphablend_extra_data); + free(this); } @@ -804,6 +809,8 @@ static vo_driver_t *pgx32_init_driver(video_driver_class_t *class_gen, const voi return NULL; } + _x_alphablend_init(&this->alphablend_extra_data, class->xine); + this->vo_driver.get_capabilities = pgx32_get_capabilities; this->vo_driver.alloc_frame = pgx32_alloc_frame; this->vo_driver.update_frame_format = pgx32_update_frame_format; diff --git a/src/video_out/video_out_pgx64.c b/src/video_out/video_out_pgx64.c index ce637ebdc..d6409110d 100644 --- a/src/video_out/video_out_pgx64.c +++ b/src/video_out/video_out_pgx64.c @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: video_out_pgx64.c,v 1.70 2004/09/22 20:29:16 miguelfreitas Exp $ + * $Id: video_out_pgx64.c,v 1.71 2004/11/24 16:11:05 mroi Exp $ * * video_out_pgx64.c, Sun XVR100/PGX64/PGX24 output plugin for xine * @@ -251,6 +251,8 @@ typedef struct { buf_mode_t buf_mode; int multibuf_en, dblbuf_select, delivered_format; int colour_key, colour_key_rgb, brightness, saturation, deinterlace_en; + + alphablend_t alphablend_extra_data; } pgx64_driver_t; /* @@ -1080,12 +1082,12 @@ static void pgx64_overlay_blend(vo_driver_t *this_gen, vo_frame_t *frame_gen, vo /* FIXME: Implement out of place alphablending functions for better performance */ switch (frame->format) { case XINE_IMGFMT_YV12: { - blend_yuv(frame->buffer_ptrs, overlay, frame->width, frame->height, frame->vo_frame.pitches); + blend_yuv(frame->buffer_ptrs, overlay, frame->width, frame->height, frame->vo_frame.pitches, &this->alphablend_extra_data); } break; case XINE_IMGFMT_YUY2: { - blend_yuy2(frame->buffer_ptrs[0], overlay, frame->width, frame->height, frame->vo_frame.pitches[0]); + blend_yuy2(frame->buffer_ptrs[0], overlay, frame->width, frame->height, frame->vo_frame.pitches[0], &this->alphablend_extra_data); } break; } @@ -1093,12 +1095,12 @@ static void pgx64_overlay_blend(vo_driver_t *this_gen, vo_frame_t *frame_gen, vo else { switch (frame->format) { case XINE_IMGFMT_YV12: { - blend_yuv(frame->vo_frame.base, overlay, frame->width, frame->height, frame->vo_frame.pitches); + blend_yuv(frame->vo_frame.base, overlay, frame->width, frame->height, frame->vo_frame.pitches, &this->alphablend_extra_data); } break; case XINE_IMGFMT_YUY2: { - blend_yuy2(frame->vo_frame.base[0], overlay, frame->width, frame->height, frame->vo_frame.pitches[0]); + blend_yuy2(frame->vo_frame.base[0], overlay, frame->width, frame->height, frame->vo_frame.pitches[0], &this->alphablend_extra_data); } break; } @@ -1305,6 +1307,9 @@ static void pgx64_dispose(vo_driver_t *this_gen) } close(this->devfd); + + _x_alphablend_free(&this->alphablend_extra_data); + free(this); } @@ -1359,6 +1364,8 @@ static vo_driver_t *pgx64_init_driver(video_driver_class_t *class_gen, const voi return NULL; } + _x_alphablend_init(&this->alphablend_extra_data, class->xine); + this->vo_driver.get_capabilities = pgx64_get_capabilities; this->vo_driver.alloc_frame = pgx64_alloc_frame; this->vo_driver.update_frame_format = pgx64_update_frame_format; diff --git a/src/video_out/video_out_sdl.c b/src/video_out/video_out_sdl.c index 04aa7cd49..1b6e7f791 100644 --- a/src/video_out/video_out_sdl.c +++ b/src/video_out/video_out_sdl.c @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: video_out_sdl.c,v 1.40 2004/09/22 20:29:16 miguelfreitas Exp $ + * $Id: video_out_sdl.c,v 1.41 2004/11/24 16:11:06 mroi Exp $ * * video_out_sdl.c, Simple DirectMedia Layer * @@ -105,6 +105,8 @@ struct sdl_driver_s { vo_scale_t sc; xine_t *xine; + + alphablend_t alphablend_extra_data; }; typedef struct { @@ -237,14 +239,14 @@ static void sdl_update_frame_format (vo_driver_t *this_gen, * */ static void sdl_overlay_blend (vo_driver_t *this_gen, vo_frame_t *frame_gen, vo_overlay_t *overlay) { - + sdl_driver_t *this = (sdl_driver_t *) this_gen; sdl_frame_t *frame = (sdl_frame_t *) frame_gen; if (overlay->rle) { if( frame->format == XINE_IMGFMT_YV12 ) - blend_yuv( frame->vo_frame.base, overlay, frame->width, frame->height, frame->vo_frame.pitches); + blend_yuv( frame->vo_frame.base, overlay, frame->width, frame->height, frame->vo_frame.pitches, &this->alphablend_extra_data); else - blend_yuy2( frame->vo_frame.base[0], overlay, frame->width, frame->height, frame->vo_frame.pitches[0]); + blend_yuy2( frame->vo_frame.base[0], overlay, frame->width, frame->height, frame->vo_frame.pitches[0], &this->alphablend_extra_data); } } @@ -446,6 +448,8 @@ static void sdl_dispose (vo_driver_t * this_gen) { SDL_FreeSurface (this->surface); SDL_QuitSubSystem (SDL_INIT_VIDEO); + _x_alphablend_free(&this->alphablend_extra_data); + free(this); } @@ -466,6 +470,8 @@ static vo_driver_t *open_plugin (video_driver_class_t *class_gen, const void *vi if (!this) return NULL; + _x_alphablend_init(&this->alphablend_extra_data, class->xine); + this->sdlflags = SDL_HWSURFACE | SDL_RESIZABLE; this->hw_accel = class->config->register_bool(class->config, diff --git a/src/video_out/video_out_stk.c b/src/video_out/video_out_stk.c index 528b18bea..5f3025071 100644 --- a/src/video_out/video_out_stk.c +++ b/src/video_out/video_out_stk.c @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: video_out_stk.c,v 1.13 2004/09/22 20:29:16 miguelfreitas Exp $ + * $Id: video_out_stk.c,v 1.14 2004/11/24 16:11:06 mroi Exp $ * * video_out_stk.c, Libstk Surface Video Driver * more info on Libstk at http://www.libstk.org @@ -93,6 +93,8 @@ typedef struct stk_driver_s { uint32_t capabilities; vo_scale_t sc; xine_t *xine; + + alphablend_t alphablend_extra_data; } stk_driver_t; @@ -222,14 +224,15 @@ static void stk_update_frame_format (vo_driver_t *this_gen, vo_frame_t *frame_ge static void stk_overlay_blend (vo_driver_t *this_gen, vo_frame_t *frame_gen, vo_overlay_t *overlay) { + stk_driver_t* this = (stk_driver_t*)this_gen; stk_frame_t* frame = (stk_frame_t*)frame_gen; //printf("video_out_stk: overlay_blend()\n"); if (overlay->rle) { if (frame->format == XINE_IMGFMT_YV12) - blend_yuv( frame->vo_frame.base, overlay, frame->width, frame->height, frame->vo_frame.pitches); + blend_yuv( frame->vo_frame.base, overlay, frame->width, frame->height, frame->vo_frame.pitches, &this->alphablend_extra_data); else - blend_yuy2( frame->vo_frame.base[0], overlay, frame->width, frame->height, frame->vo_frame.pitches[0]); + blend_yuy2( frame->vo_frame.base[0], overlay, frame->width, frame->height, frame->vo_frame.pitches[0], &this->alphablend_extra_data); } } @@ -373,6 +376,9 @@ static void stk_dispose (vo_driver_t * this_gen) { /* FIXME: any libstk deleting must be done in the app or library * since we didn't create the surface */ + + _x_alphablend_free(&this->alphablend_extra_data); + free(this); } @@ -387,6 +393,8 @@ static vo_driver_t *open_plugin(video_driver_class_t *class_gen, const void *vis if (!this) return NULL; + _x_alphablend_init(&this->alphablend_extra_data, class->xine); + /* populate the video output driver members */ this->config = class->config; this->xine = class->xine; diff --git a/src/video_out/video_out_syncfb.c b/src/video_out/video_out_syncfb.c index 3e9637637..c689958f2 100644 --- a/src/video_out/video_out_syncfb.c +++ b/src/video_out/video_out_syncfb.c @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: video_out_syncfb.c,v 1.98 2004/09/22 20:29:16 miguelfreitas Exp $ + * $Id: video_out_syncfb.c,v 1.99 2004/11/24 16:11:06 mroi Exp $ * * video_out_syncfb.c, SyncFB (for Matrox G200/G400 cards) interface for xine * @@ -117,6 +117,7 @@ struct syncfb_driver_s { int video_win_visibility; xine_t *xine; + alphablend_t alphablend_extra_data; }; typedef struct { @@ -570,9 +571,9 @@ static void syncfb_overlay_blend(vo_driver_t* this_gen, vo_frame_t* frame_gen, v /* alpha blend here */ if (overlay->rle) { if (frame->format == XINE_IMGFMT_YV12) - blend_yuv(frame->vo_frame.base, overlay, frame->width, frame->height, frame->vo_frame.pitches); + blend_yuv(frame->vo_frame.base, overlay, frame->width, frame->height, frame->vo_frame.pitches, &this->alphablend_extra_data); else - blend_yuy2(frame->vo_frame.base[0], overlay, frame->width, frame->height, frame->vo_frame.pitches[0]); + blend_yuy2(frame->vo_frame.base[0], overlay, frame->width, frame->height, frame->vo_frame.pitches[0], &this->alphablend_extra_data); } } @@ -849,6 +850,8 @@ static void syncfb_dispose(vo_driver_t *this_gen) XFreeGC(this->display, this->gc); XUnlockDisplay (this->display); + _x_alphablend_free(&this->alphablend_extra_data); + free(this); } @@ -868,6 +871,8 @@ static vo_driver_t *open_plugin (video_driver_class_t *class_gen, const void *vi if(!(this = xine_xmalloc(sizeof (syncfb_driver_t)))) return NULL; + _x_alphablend_init(&this->alphablend_extra_data, class->xine); + /* check for syncfb device */ if((this->fd = open(class->device_name, O_RDWR)) < 0) { xprintf(class->xine, XINE_VERBOSITY_DEBUG, diff --git a/src/video_out/video_out_vidix.c b/src/video_out/video_out_vidix.c index 740bd2eb7..1df9b459b 100644 --- a/src/video_out/video_out_vidix.c +++ b/src/video_out/video_out_vidix.c @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: video_out_vidix.c,v 1.65 2004/09/22 20:29:16 miguelfreitas Exp $ + * $Id: video_out_vidix.c,v 1.66 2004/11/24 16:11:07 mroi Exp $ * * video_out_vidix.c * @@ -144,6 +144,8 @@ struct vidix_driver_s { int delivered_format; xine_t *xine; + + alphablend_t alphablend_extra_data; }; typedef struct vidix_class_s { @@ -587,9 +589,9 @@ static void vidix_overlay_blend (vo_driver_t *this_gen, vo_frame_t *frame_gen, v #endif } else { if( frame->format == XINE_IMGFMT_YV12 ) - blend_yuv( frame->vo_frame.base, overlay, frame->width, frame->height, frame->vo_frame.pitches); + blend_yuv( frame->vo_frame.base, overlay, frame->width, frame->height, frame->vo_frame.pitches, &this->alphablend_extra_data); else - blend_yuy2( frame->vo_frame.base[0], overlay, frame->width, frame->height, frame->vo_frame.pitches[0]); + blend_yuy2( frame->vo_frame.base[0], overlay, frame->width, frame->height, frame->vo_frame.pitches[0], &this->alphablend_extra_data); } } } @@ -896,6 +898,8 @@ static void vidix_exit (vo_driver_t *this_gen) { XUnlockDisplay (this->display); #endif + _x_alphablend_free(&this->alphablend_extra_data); + free (this); } @@ -908,6 +912,8 @@ static vidix_driver_t *open_plugin (video_driver_class_t *class_gen) { this = (vidix_driver_t *) xine_xmalloc (sizeof (vidix_driver_t)); if (!this) return NULL; + + _x_alphablend_init(&this->alphablend_extra_data, class->xine); pthread_mutex_init (&this->mutex, NULL); diff --git a/src/video_out/video_out_xshm.c b/src/video_out/video_out_xshm.c index fa7c59be9..43ec06d14 100644 --- a/src/video_out/video_out_xshm.c +++ b/src/video_out/video_out_xshm.c @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: video_out_xshm.c,v 1.136 2004/10/08 20:54:36 mroi Exp $ + * $Id: video_out_xshm.c,v 1.137 2004/11/24 16:11:08 mroi Exp $ * * video_out_xshm.c, X11 shared memory extension interface for xine * @@ -119,6 +119,8 @@ typedef struct { int (*x11_old_error_handler) (Display *, XErrorEvent *); xine_t *xine; + + alphablend_t alphablend_extra_data; } xshm_driver_t; typedef struct { @@ -662,17 +664,20 @@ static void xshm_overlay_blend (vo_driver_t *this_gen, case 16: blend_rgb16 ((uint8_t *)frame->image->data, overlay, frame->sc.output_width, frame->sc.output_height, - frame->sc.delivered_width, frame->sc.delivered_height); + frame->sc.delivered_width, frame->sc.delivered_height, + &this->alphablend_extra_data); break; case 24: blend_rgb24 ((uint8_t *)frame->image->data, overlay, frame->sc.output_width, frame->sc.output_height, - frame->sc.delivered_width, frame->sc.delivered_height); + frame->sc.delivered_width, frame->sc.delivered_height, + &this->alphablend_extra_data); break; case 32: blend_rgb32 ((uint8_t *)frame->image->data, overlay, frame->sc.output_width, frame->sc.output_height, - frame->sc.delivered_width, frame->sc.delivered_height); + frame->sc.delivered_width, frame->sc.delivered_height, + &this->alphablend_extra_data); break; default: xprintf(this->xine, XINE_VERBOSITY_DEBUG, @@ -991,6 +996,8 @@ static void xshm_dispose (vo_driver_t *this_gen) { XUnlockDisplay (this->display); } + _x_alphablend_free(&this->alphablend_extra_data); + free (this); } @@ -1067,6 +1074,8 @@ static vo_driver_t *xshm_open_plugin (video_driver_class_t *class_gen, const voi if (!this) return NULL; + _x_alphablend_init(&this->alphablend_extra_data, class->xine); + this->display = visual->display; this->screen = visual->screen; @@ -1101,7 +1110,7 @@ static vo_driver_t *xshm_open_plugin (video_driver_class_t *class_gen, const voi this->vo_driver.gui_data_exchange = xshm_gui_data_exchange; this->vo_driver.dispose = xshm_dispose; this->vo_driver.redraw_needed = xshm_redraw_needed; - + XLockDisplay(this->display); XAllocNamedColor (this->display, DefaultColormap (this->display, this->screen), diff --git a/src/video_out/video_out_xv.c b/src/video_out/video_out_xv.c index c3787c983..3107b2978 100644 --- a/src/video_out/video_out_xv.c +++ b/src/video_out/video_out_xv.c @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: video_out_xv.c,v 1.205 2004/09/22 20:29:16 miguelfreitas Exp $ + * $Id: video_out_xv.c,v 1.206 2004/11/24 16:11:08 mroi Exp $ * * video_out_xv.c, X11 video extension interface for xine * @@ -154,6 +154,8 @@ struct xv_driver_s { int (*x11_old_error_handler) (Display *, XErrorEvent *); xine_t *xine; + + alphablend_t alphablend_extra_data; }; typedef struct { @@ -667,10 +669,12 @@ static void xv_overlay_blend (vo_driver_t *this_gen, } else { if (frame->format == XINE_IMGFMT_YV12) blend_yuv(frame->vo_frame.base, overlay, - frame->width, frame->height, frame->vo_frame.pitches); + frame->width, frame->height, frame->vo_frame.pitches, + &this->alphablend_extra_data); else blend_yuy2(frame->vo_frame.base[0], overlay, - frame->width, frame->height, frame->vo_frame.pitches[0]); + frame->width, frame->height, frame->vo_frame.pitches[0], + &this->alphablend_extra_data); } } } @@ -1083,6 +1087,8 @@ static void xv_dispose (vo_driver_t *this_gen) { XUnlockDisplay (this->display); } + _x_alphablend_free(&this->alphablend_extra_data); + free (this); } @@ -1244,6 +1250,8 @@ static vo_driver_t *open_plugin (video_driver_class_t *class_gen, const void *vi if (!this) return NULL; + _x_alphablend_init(&this->alphablend_extra_data, class->xine); + this->display = visual->display; this->screen = visual->screen; this->config = config; diff --git a/src/video_out/video_out_xvmc.c b/src/video_out/video_out_xvmc.c index 8c2dee108..10c6b0a20 100644 --- a/src/video_out/video_out_xvmc.c +++ b/src/video_out/video_out_xvmc.c @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: video_out_xvmc.c,v 1.18 2004/09/28 18:49:40 miguelfreitas Exp $ + * $Id: video_out_xvmc.c,v 1.19 2004/11/24 16:11:09 mroi Exp $ * * video_out_xvmc.c, X11 video motion compensation extension interface for xine * @@ -219,6 +219,8 @@ struct xvmc_driver_s { void *user_data; xine_t *xine; + + alphablend_t alphablend_extra_data; }; @@ -868,6 +870,7 @@ static void xvmc_compute_output_size (xvmc_driver_t *this) { static void xvmc_overlay_blend (vo_driver_t *this_gen, vo_frame_t *frame_gen, vo_overlay_t *overlay) { + xvmc_driver_t *this = (xvmc_driver_t *) this_gen; xvmc_frame_t *frame = (xvmc_frame_t *) frame_gen; lprintf ("xvmc_overlay_blend\n"); @@ -879,10 +882,12 @@ static void xvmc_overlay_blend (vo_driver_t *this_gen, if (overlay->rle) { if (frame->format == XINE_IMGFMT_YV12) blend_yuv(frame->vo_frame.base, overlay, - frame->width, frame->height, frame->vo_frame.pitches); + frame->width, frame->height, frame->vo_frame.pitches, + &this->alphablend_extra_data); else blend_yuy2(frame->vo_frame.base[0], overlay, - frame->width, frame->height, frame->vo_frame.pitches[0]); + frame->width, frame->height, frame->vo_frame.pitches[0], + &this->alphablend_extra_data); } } @@ -1281,6 +1286,8 @@ static void xvmc_dispose (vo_driver_t *this_gen) { this->recent_frames[i] = NULL; } + _x_alphablend_free(&this->alphablend_extra_data); + free (this); } @@ -1387,6 +1394,8 @@ static vo_driver_t *open_plugin (video_driver_class_t *class_gen, const void *vi if (!this) return NULL; + _x_alphablend_init(&this->alphablend_extra_data, class->xine); + this->display = visual->display; this->overlay = NULL; this->screen = visual->screen; diff --git a/src/video_out/video_out_xxmc.c b/src/video_out/video_out_xxmc.c index 95e80cec4..d0dfaa3b7 100644 --- a/src/video_out/video_out_xxmc.c +++ b/src/video_out/video_out_xxmc.c @@ -18,7 +18,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: video_out_xxmc.c,v 1.9 2004/11/19 08:56:30 totte67 Exp $ + * $Id: video_out_xxmc.c,v 1.10 2004/11/24 16:11:10 mroi Exp $ * * video_out_xxmc.c, X11 decoding accelerated video extension interface for xine * @@ -1397,7 +1397,8 @@ static void xxmc_overlay_blend (vo_driver_t *this_gen, vo_frame_t *frame_gen, this->first_overlay = 0; } blend_xx44(this->subImage->data, overlay, this->subImage->width, - this->subImage->height, this->subImage->width, + this->subImage->height, this->subImage->width, + &this->alphablend_extra_data, &this->palette, (this->subImage->id == FOURCC_IA44)); XVMCLOCKDISPLAY( this->display ); XvMCCompositeSubpicture( this->display, this->new_subpic, @@ -1412,10 +1413,12 @@ static void xxmc_overlay_blend (vo_driver_t *this_gen, vo_frame_t *frame_gen, } else { if (frame->format == XINE_IMGFMT_YV12) { blend_yuv(frame->vo_frame.base, overlay, - frame->width, frame->height, frame->vo_frame.pitches); + frame->width, frame->height, frame->vo_frame.pitches, + &this->alphablend_extra_data); } else { blend_yuy2(frame->vo_frame.base[0], overlay, - frame->width, frame->height, frame->vo_frame.pitches[0]); + frame->width, frame->height, frame->vo_frame.pitches[0], + &this->alphablend_extra_data); } } } @@ -1820,6 +1823,8 @@ static void xxmc_dispose (vo_driver_t *this_gen) { } free_context_lock(&this->xvmc_lock); + _x_alphablend_free(&this->alphablend_extra_data); + free (this); } @@ -2138,6 +2143,8 @@ static vo_driver_t *open_plugin (video_driver_class_t *class_gen, const void *vi if (!this) return NULL; + _x_alphablend_init(&this->alphablend_extra_data, class->xine); + this->display = visual->display; this->screen = visual->screen; this->config = config; diff --git a/src/video_out/xxmc.h b/src/video_out/xxmc.h index bf1bddebf..645fd9269 100644 --- a/src/video_out/xxmc.h +++ b/src/video_out/xxmc.h @@ -18,7 +18,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: xxmc.h,v 1.5 2004/11/19 08:56:30 totte67 Exp $ + * $Id: xxmc.h,v 1.6 2004/11/24 16:11:10 mroi Exp $ * * video_out_xxmc.c, X11 decoding accelerated video extension interface for xine * @@ -265,6 +265,8 @@ struct xxmc_driver_s { * to protect the XvMC Calls. */ context_lock_t xvmc_lock; + + alphablend_t alphablend_extra_data; }; typedef struct { |