diff options
author | Matthias Dahl <matt2000@users.sourceforge.net> | 2001-11-03 13:57:34 +0000 |
---|---|---|
committer | Matthias Dahl <matt2000@users.sourceforge.net> | 2001-11-03 13:57:34 +0000 |
commit | a1e1a6edcb9b7a82bfc2c4aa6a34cf2f761698a5 (patch) | |
tree | 8f4c77230419c02a448607715e63b744ac546704 | |
parent | fb9dd420fe74f1c6a9664ac9e3467d9a10192a98 (diff) | |
download | xine-lib-a1e1a6edcb9b7a82bfc2c4aa6a34cf2f761698a5.tar.gz xine-lib-a1e1a6edcb9b7a82bfc2c4aa6a34cf2f761698a5.tar.bz2 |
Fixed a bad bug in the new SyncFB plugin that caused it to crash easily. And
finally added overlay blending support. Also cleaned up the alphablend
header file and added new blend_yuv function that uses the vo_frame_t struct
for its blending.
CVS patchset: 934
CVS date: 2001/11/03 13:57:34
-rw-r--r-- | src/video_out/alphablend.c | 68 | ||||
-rw-r--r-- | src/video_out/alphablend.h | 23 | ||||
-rw-r--r-- | src/video_out/video_out_syncfb.c | 25 |
3 files changed, 92 insertions, 24 deletions
diff --git a/src/video_out/alphablend.c b/src/video_out/alphablend.c index a10c64a6d..635fd8c8a 100644 --- a/src/video_out/alphablend.c +++ b/src/video_out/alphablend.c @@ -383,3 +383,71 @@ void blend_yuv (uint8_t * dst_img, vo_overlay_t * img_overl, } } } + +void blend_yuv_vo_frame(vo_frame_t* dst_img, vo_overlay_t* img_overl) +{ + clut_t *my_clut; + uint8_t *my_trans; + + int src_width = img_overl->width; + int src_height = img_overl->height; + rle_elem_t *rle = img_overl->rle; + rle_elem_t *rle_limit = rle + img_overl->num_rle; + int x_off = img_overl->x; + int y_off = img_overl->y; + int mask; + int x, y; + + uint8_t *dst_y = dst_img->base[0] + dst_img->width * y_off + x_off; + uint8_t *dst_cr = dst_img->base[1] + (y_off / 2) * (dst_img->width / 2) + (x_off / 2) + 1; + uint8_t *dst_cb = dst_img->base[2] + (y_off / 2) * (dst_img->width / 2) + (x_off / 2) + 1; + + my_clut = (clut_t*) img_overl->color; + my_trans = img_overl->trans; + + for (y = 0; y < src_height; y++) { + mask = !(img_overl->clip_top > y || img_overl->clip_bottom < y); + + for (x = 0; x < src_width;) { + uint8_t clr; + uint16_t o; + + clr = rle->color; + o = my_trans[clr]; + + /* These three lines assume that menu buttons are "clean" separated + * and do not overlap with the button clip borders */ + if (o) if (img_overl->clip_left > x || + img_overl->clip_right < x) + o = 0; + + if (o && mask) { + if (o >= 15) { + memset(dst_y + x, my_clut[clr].y, rle->len); + if (y & 1) { + memset(dst_cr + (x >> 1), my_clut[clr].cr, rle->len >> 1); + memset(dst_cb + (x >> 1), my_clut[clr].cb, rle->len >> 1); + } + } else { + mem_blend8(dst_y + x, my_clut[clr].y, o, rle->len); + if (y & 1) { + mem_blend8(dst_cr + (x >> 1), my_clut[clr].cr, o, rle->len >> 1); + mem_blend8(dst_cb + (x >> 1), my_clut[clr].cb, o, rle->len >> 1); + } + } + } + + x += rle->len; + rle++; + if (rle >= rle_limit) break; + } + if (rle >= rle_limit) break; + + dst_y += dst_img->width; + + if (y & 1) { + dst_cr += (dst_img->width + 1) / 2; + dst_cb += (dst_img->width + 1) / 2; + } + } +} diff --git a/src/video_out/alphablend.h b/src/video_out/alphablend.h index c973c59ed..bb3f4ae59 100644 --- a/src/video_out/alphablend.h +++ b/src/video_out/alphablend.h @@ -1,4 +1,3 @@ - /* * * Copyright (C) 2000 Thomas Mirlacher @@ -35,17 +34,23 @@ typedef struct { /* CLUT == Color LookUp Table */ uint8_t foo : 8; } __attribute__ ((packed)) clut_t; -void blend_rgb16 (uint8_t * img, vo_overlay_t * overlay, +void blend_rgb16 (uint8_t * img, vo_overlay_t * img_overl, int img_width, int img_height, - int delivered_width, int delivered_height); -void blend_rgb24 (uint8_t * img, vo_overlay_t * overlay, + int dst_width, int dst_height); + +void blend_rgb24 (uint8_t * img, vo_overlay_t * img_overl, int img_width, int img_height, - int delivered_iwdth, int delivered_height); -void blend_rgb32 (uint8_t * img, vo_overlay_t * overlay, + int dst_width, int dst_height); + +void blend_rgb32 (uint8_t * img, vo_overlay_t * img_overl, int img_width, int img_height, - int delivered_iwdth, int delivered_height); -void blend_yuv (uint8_t * img, vo_overlay_t * overlay, - int width, int height); + int dst_width, int dst_height); + +void blend_yuv (uint8_t * dst_img, vo_overlay_t * img_overl, + int dst_width, int dst_height); + +void blend_yuv_vo_frame(vo_frame_t* dst_img, vo_overlay_t* img_overl); + void crop_overlay (vo_overlay_t * overlay); #endif diff --git a/src/video_out/video_out_syncfb.c b/src/video_out/video_out_syncfb.c index 3d3ba9ce6..46fb0763c 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.17 2001/11/03 00:13:11 matt2000 Exp $ + * $Id: video_out_syncfb.c,v 1.18 2001/11/03 13:57:34 matt2000 Exp $ * * video_out_syncfb.c, SyncFB (for Matrox G200/G400 cards) interface for xine * @@ -282,19 +282,19 @@ static void syncfb_adapt_to_output_area(syncfb_driver_t* this, this->output_xoffset = dest_x + (dest_width - this->output_width) / 2; this->output_yoffset = dest_y; } - - /* - * set up the syncfb module - */ + + // + // configuring SyncFB module from this point on. + // if(ioctl(this->fd, SYNCFB_OFF)) printf("video_out_syncfb: error. (off ioctl failed)\n"); else this->overlay_state = 0; - // in case we have the window somewhere *off* the desktop, this *could* - // cause some screen corruption... so better leave things deactivated. - if(posx >= 0 && posy >= 0) { + // sanity checking - certain situations *may* crash the SyncFB module, so + // take care that we always have valid numbers. + if(posx >= 0 && posy >= 0 && this->frame_width > 0 && this->frame_height > 0 && this->output_width > 0 && this->output_height > 0) { if(ioctl(this->fd, SYNCFB_GET_CONFIG, &this->syncfb_config)) printf("video_out_syncfb: error. (get_config ioctl failed)\n"); @@ -322,7 +322,6 @@ static void syncfb_adapt_to_output_area(syncfb_driver_t* this, if(ioctl(this->fd,SYNCFB_SET_CONFIG,&this->syncfb_config)) printf("video_out_syncfb: error. (set_config ioctl failed)\n"); - if(ioctl(this->fd, SYNCFB_ON)) printf("video_out_syncfb: error. (on ioctl failed)\n"); else @@ -610,17 +609,14 @@ static void syncfb_update_frame_format(vo_driver_t* this_gen, frame->ratio_code = ratio_code; } -// FIXME: not yet implemented, being worked on! -/* static void syncfb_overlay_blend(vo_driver_t* this_gen, vo_frame_t* frame_gen, vo_overlay_t* overlay) { syncfb_frame_t* frame = (syncfb_frame_t *) frame_gen; if(overlay->rle) { - blend_yuv(frame->XXX, overlay, frame->width, frame->height); + blend_yuv_vo_frame(&frame->vo_frame, overlay); } } -*/ static void syncfb_display_frame(vo_driver_t* this_gen, vo_frame_t* frame_gen) { @@ -859,8 +855,7 @@ vo_driver_t *init_video_out_plugin (config_values_t *config, void *visual_gen) this->vo_driver.get_capabilities = syncfb_get_capabilities; this->vo_driver.alloc_frame = syncfb_alloc_frame; this->vo_driver.update_frame_format = syncfb_update_frame_format; -// this->vo_driver.overlay_blend = syncfb_overlay_blend; - this->vo_driver.overlay_blend = NULL; // FIXME: support coming soon + this->vo_driver.overlay_blend = syncfb_overlay_blend; this->vo_driver.display_frame = syncfb_display_frame; this->vo_driver.get_property = syncfb_get_property; this->vo_driver.set_property = syncfb_set_property; |