summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/dxr3/video_out_dxr3.c17
-rw-r--r--src/dxr3/video_out_dxr3.h4
-rw-r--r--src/video_out/alphablend.c820
-rw-r--r--src/video_out/alphablend.h26
-rw-r--r--src/video_out/video_out_directfb.c19
-rwxr-xr-xsrc/video_out/video_out_directx.c12
-rw-r--r--src/video_out/video_out_fb.c19
-rw-r--r--src/video_out/video_out_opengl.c23
-rw-r--r--src/video_out/video_out_pgx32.c9
-rw-r--r--src/video_out/video_out_pgx64.c17
-rw-r--r--src/video_out/video_out_sdl.c14
-rw-r--r--src/video_out/video_out_stk.c14
-rw-r--r--src/video_out/video_out_syncfb.c11
-rw-r--r--src/video_out/video_out_vidix.c12
-rw-r--r--src/video_out/video_out_xshm.c19
-rw-r--r--src/video_out/video_out_xv.c14
-rw-r--r--src/video_out/video_out_xvmc.c15
-rw-r--r--src/video_out/video_out_xxmc.c15
-rw-r--r--src/video_out/xxmc.h4
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 {