summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/libspudec/spu.c14
-rw-r--r--src/video_out/alphablend.c410
-rw-r--r--src/video_out/video_out_xshm.c8
-rw-r--r--src/video_out/yuv2rgb.c11
-rw-r--r--src/xine-engine/osd.c2
5 files changed, 374 insertions, 71 deletions
diff --git a/src/libspudec/spu.c b/src/libspudec/spu.c
index 005f74627..1e2ffda49 100644
--- a/src/libspudec/spu.c
+++ b/src/libspudec/spu.c
@@ -35,7 +35,7 @@
* along with this program; see the file COPYING. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*
- * $Id: spu.c,v 1.47 2002/09/18 15:42:56 mroi Exp $
+ * $Id: spu.c,v 1.48 2002/09/30 05:16:45 jcdutton Exp $
*
*/
@@ -519,14 +519,16 @@ static void spudec_do_commands(spudec_state_t *state, spudec_seq_t* seq, vo_over
ovl->trans[2] = trans->entry1;
ovl->trans[1] = trans->entry2;
ovl->trans[0] = trans->entry3;
-/**************************88
+/* FIXME: Force invisible SPUs to be visible. */
+/*
if ( (trans->entry0 | trans->entry1 | trans->entry2 | trans->entry3) == 0) {
ovl->trans[3] = 15;
ovl->trans[2] = 15;
ovl->trans[1] = 15;
- ovl->trans[0] = 0;
+ ovl->trans[0] = 8;
}
-*************************/
+*/
+
#ifdef LOG_DEBUG
printf ("spu: \ttrans [%d %d %d %d]\n",
ovl->trans[0], ovl->trans[1], ovl->trans[2], ovl->trans[3]);
@@ -547,7 +549,7 @@ static void spudec_do_commands(spudec_state_t *state, spudec_seq_t* seq, vo_over
ovl->y = (buf[4] << 4) | (buf[5] >> 4);
ovl->width = (((buf[2] & 0x0f) << 8) | buf[3]) - ovl->x + 1;
ovl->height = (((buf[5] & 0x0f) << 8) | buf[6]) - ovl->y + 1;
- ovl->clip_top = 0;
+ ovl->clip_top = -1;
ovl->clip_bottom = ovl->height - 1;
ovl->clip_left = 0;
ovl->clip_right = ovl->width - 1;
@@ -859,7 +861,7 @@ void spudec_copy_nav_to_overlay(pci_t* nav_pci, uint32_t* clut, int32_t button,
* overlay clipping areas are in overlay coordinates;
* therefore we must subtract the display coordinates of the underlying overlay */
overlay->clip_left = (button_ptr->x_start > base->x) ? (button_ptr->x_start - base->x) : 0;
- overlay->clip_top = (button_ptr->y_start > base->y) ? (button_ptr->y_start - base->y) : 0;
+ overlay->clip_top = (button_ptr->y_start > base->y) ? (button_ptr->y_start - base->y) : -1;
overlay->clip_right = (button_ptr->x_end > base->x) ? (button_ptr->x_end - base->x) : 0;
overlay->clip_bottom = (button_ptr->y_end > base->y) ? (button_ptr->y_end - base->y) : 0;
if(button_ptr->btn_coln != 0) {
diff --git a/src/video_out/alphablend.c b/src/video_out/alphablend.c
index 1e9d19a6a..3ade25735 100644
--- a/src/video_out/alphablend.c
+++ b/src/video_out/alphablend.c
@@ -30,6 +30,7 @@
/*
#define LOG_BLEND_YUV
+#define LOG_BLEND_RGB16
*/
#include <string.h>
@@ -126,31 +127,70 @@ rle_img_advance_line(rle_elem_t *rle, rle_elem_t *rle_limit, int w)
return rle;
}
-
void blend_rgb16 (uint8_t * img, vo_overlay_t * img_overl,
- int img_width, int img_height,
- int dst_width, int dst_height)
+ int img_width, int img_height,
+ int dst_width, int dst_height)
{
uint8_t *trans;
- clut_t* clut = (clut_t*) img_overl->clip_color;
+ clut_t *clut;
int src_width = img_overl->width;
int src_height = img_overl->height;
rle_elem_t *rle = img_overl->rle;
+ rle_elem_t *rle_start = img_overl->rle;
rle_elem_t *rle_limit = rle + img_overl->num_rle;
int x, y, x1_scaled, x2_scaled;
- int dy, dy_step, x_scale; /* scaled 2**SCALE_SHIFT */
+ int dy, dy_step, x_scale; /* scaled 2**SCALE_SHIFT */
+ int dst_y;
int clip_right;
uint16_t *img_pix;
+ int rlelen;
+ int rle_this_bite;
+ int rle_remainder;
+ int zone_state=0;
+ uint8_t clr_next,clr;
+ uint16_t o;
+ double img_offset;
+ int stripe_height;
+/*
+ * Let zone_state keep state.
+ * 0 = Starting.
+ * 1 = Above button.
+ * 2 = Left of button.
+ * 3 = Inside of button.
+ * 4 = Right of button.
+ * 5 = Below button.
+ * 6 = Finished.
+ *
+ * Each time round the loop, update the state.
+ * We can do this easily and cheaply(fewer IF statements per cycle) as we are testing rle end position anyway.
+ * Possible optimization is to ensure that rle never overlaps from outside to inside a button.
+ * Possible optimization is to pre-scale the RLE overlay, so that no scaling is needed here.
+ */
- dy_step = INT_TO_SCALED(dst_height) / img_height;
+#ifdef LOG_BLEND_RGB16
+ printf("blend_rgb16: img_height=%i, dst_height=%i\n", img_height, dst_height);
+ printf("blend_rgb16: img_width=%i, dst_width=%i\n", img_width, dst_width);
+#endif
+/* stripe_height is used in yuv2rgb scaling, so use the same scale factor here for overlays. */
+ stripe_height = 16 * img_height / dst_height;
+/* dy_step = INT_TO_SCALED(dst_height) / img_height; */
+ dy_step = INT_TO_SCALED(16) / stripe_height;
x_scale = INT_TO_SCALED(img_width) / dst_width;
+#ifdef LOG_BLEND_RGB16
+ printf("blend_rgb16: dy_step=%i, x_scale=%i\n", dy_step, x_scale);
+#endif
- img_pix = (uint16_t *) img
+ img_offset = ( ( (img_overl->y * img_height) / dst_height) * img_width)
+ + ( (img_overl->x * img_width) / dst_width);
+#ifdef LOG_BLEND_RGB16
+ printf("blend_rgb16: x=%i, y=%i, img_offset=%lf\n", img_overl->x, img_overl->y, img_offset);
+#endif
+ img_pix = (uint16_t *) img + (int)img_offset;
+/*
+ (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 )
@@ -162,66 +202,320 @@ void blend_rgb16 (uint8_t * img, vo_overlay_t * img_overl,
if( (src_height + img_overl->y) >= dst_height )
src_height = dst_height - 1 - 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);
- rle_elem_t *rle_start = rle;
+ rlelen = rle_remainder = rle_this_bite = 0;
+ rle_remainder = rlelen = rle->len;
+ clr_next = rle->color;
+ rle++;
+ y = dy = 0;
+ dst_y = 0;
+ x = x1_scaled = x2_scaled = 0;
- for (x = x1_scaled = 0; x < src_width;) {
- uint8_t clr;
- uint16_t o;
- int rlelen;
+#ifdef LOG_BLEND_RGB16
+ printf("blend_rgb16 started\n");
+#endif
- clr = rle->color;
- o = trans[clr];
- rlelen = rle->len;
+ while (zone_state != 6) {
+ clr = clr_next;
+ switch (zone_state) {
+ case 0: /* Starting */
+ /* FIXME: Get libspudec to set clip_top to -1 if no button */
+ if (img_overl->clip_top < 0) {
+#ifdef LOG_BLEND_RGB16
+ printf("blend_rgb16: No button clip area\n");
+#endif
- 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;
- } else {
- o = 0;
+ zone_state = 7;
+ break;
+ }
+#ifdef LOG_BLEND_RGB16
+ printf("blend_rgb16: Button clip area found\n");
+#endif
+ if (y < img_overl->clip_top) {
+ zone_state = 1;
+ break;
+ } 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) {
+ zone_state = 4;
+ break;
+ } else {
+ zone_state = 3;
+ break;
+ }
+ break;
+ case 1: /* Above clip area */
+ clut = (clut_t*) img_overl->color;
+ trans = img_overl->trans;
+ o = trans[clr];
+ rle_this_bite = rle_remainder;
+ rle_remainder = 0;
+ rlelen -= rle_this_bite;
+ /*printf("(x,y) = (%03i,%03i), clr=%03x, len=%03i, zone=%i\n", x, y, clr, rle_this_bite, zone_state); */
+ if (o) {
+ x1_scaled = SCALED_TO_INT( x * x_scale );
+ x2_scaled = SCALED_TO_INT( (x + rle_this_bite) * x_scale);
+ mem_blend16(img_pix+x1_scaled, *((uint16_t *)&clut[clr]), o, x2_scaled-x1_scaled);
+ }
+ x += rle_this_bite;
+ if (x >= src_width ) {
+ x -= src_width;
+ img_pix += img_width;
+
+ dy += dy_step;
+ if (dy >= INT_TO_SCALED(1)) {
+ dy -= INT_TO_SCALED(1);
+ ++y;
+ while (dy >= INT_TO_SCALED(1)) {
+ rle = rle_img_advance_line(rle, rle_limit, src_width);
+ dy -= INT_TO_SCALED(1);
+ ++y;
}
- } else if( clip_right < x + rlelen ) {
- if( clip_right > x ) {
- x2_scaled = SCALED_TO_INT( clip_right * x_scale);
- mem_blend16(img_pix+x1_scaled, *((uint16_t *)&clut[clr]), o,
- x2_scaled-x1_scaled);
- o = 0;
- } else {
- o = 0;
+ rle_start = rle;
+ } else {
+ rle = rle_start; /* y-scaling, reuse the last rle encoded line */
+ }
+ }
+ rle_remainder = rlelen = rle->len;
+ clr_next = rle->color;
+ rle++;
+ if (rle >= rle_limit) {
+ zone_state = 6;
+ }
+ if (y >= img_overl->clip_top) {
+ zone_state = 2;
+ if (x >= img_overl->clip_left) {
+ zone_state = 3;
+ if (x >= img_overl->clip_right) {
+ zone_state = 4;
}
- }
+ }
}
-
- x2_scaled = SCALED_TO_INT((x + rlelen) * x_scale);
- if (o && mask) {
- mem_blend16(img_pix+x1_scaled, *((uint16_t *)&clut[clr]), o, x2_scaled-x1_scaled);
+ break;
+ case 2: /* Left of button */
+ clut = (clut_t*) img_overl->color;
+ trans = img_overl->trans;
+ o = trans[clr];
+ if (x + rle_remainder < img_overl->clip_left) {
+ rle_this_bite = rle_remainder;
+ rle_remainder = rlelen = rle->len;
+ clr_next = rle->color;
+ rle++;
+ } else {
+ rle_this_bite = img_overl->clip_left - x;
+ rle_remainder -= rle_this_bite;
+ zone_state = 3;
}
-
- x1_scaled = x2_scaled;
- x += rlelen;
+ if (o) {
+ x1_scaled = SCALED_TO_INT( x * x_scale );
+ x2_scaled = SCALED_TO_INT( (x + rle_this_bite) * x_scale);
+ mem_blend16(img_pix+x1_scaled, *((uint16_t *)&clut[clr]), o, x2_scaled-x1_scaled);
+ }
+ x += rle_this_bite;
+ if (x >= src_width ) {
+ x -= src_width;
+ img_pix += img_width;
+ dy += dy_step;
+ if (dy >= INT_TO_SCALED(1)) {
+ dy -= INT_TO_SCALED(1);
+ ++y;
+ while (dy >= INT_TO_SCALED(1)) {
+ rle = rle_img_advance_line(rle, rle_limit, src_width);
+ dy -= INT_TO_SCALED(1);
+ ++y;
+ }
+ rle_start = rle;
+ } else {
+ rle = rle_start; /* y-scaling, reuse the last rle encoded line */
+ }
+ if (y > img_overl->clip_bottom) {
+ zone_state = 5;
+ break;
+ }
+ }
+ if (rle >= rle_limit) {
+ zone_state = 6;
+ }
+ break;
+ case 3: /* In button */
+ clut = (clut_t*) img_overl->clip_color;
+ trans = img_overl->clip_trans;
+ o = trans[clr];
+ if (x + rle_remainder < img_overl->clip_right) {
+ rle_this_bite = rle_remainder;
+ rle_remainder = rlelen = rle->len;
+ clr_next = rle->color;
+ rle++;
+ } else {
+ rle_this_bite = img_overl->clip_right - x;
+ rle_remainder -= rle_this_bite;
+ zone_state = 4;
+ }
+ if (o) {
+ x1_scaled = SCALED_TO_INT( x * x_scale );
+ x2_scaled = SCALED_TO_INT( (x + rle_this_bite) * x_scale);
+ mem_blend16(img_pix+x1_scaled, *((uint16_t *)&clut[clr]), o, x2_scaled-x1_scaled);
+ }
+ x += rle_this_bite;
+ if (x >= src_width ) {
+ x -= src_width;
+ img_pix += img_width;
+ dy += dy_step;
+ if (dy >= INT_TO_SCALED(1)) {
+ dy -= INT_TO_SCALED(1);
+ ++y;
+ while (dy >= INT_TO_SCALED(1)) {
+ rle = rle_img_advance_line(rle, rle_limit, src_width);
+ dy -= INT_TO_SCALED(1);
+ ++y;
+ }
+ rle_start = rle;
+ } else {
+ rle = rle_start; /* y-scaling, reuse the last rle encoded line */
+ }
+ if (y > img_overl->clip_bottom) {
+ zone_state = 5;
+ break;
+ }
+ }
+ if (rle >= rle_limit) {
+ zone_state = 6;
+ }
+ break;
+ case 4: /* Right of button */
+ clut = (clut_t*) img_overl->color;
+ trans = img_overl->trans;
+ o = trans[clr];
+ if (x + rle_remainder < src_width) {
+ rle_this_bite = rle_remainder;
+ rle_remainder = rlelen = rle->len;
+ clr_next = rle->color;
+ rle++;
+ } else {
+ rle_this_bite = src_width - x;
+ rle_remainder -= rle_this_bite;
+ zone_state = 2;
+ }
+ if (o) {
+ x1_scaled = SCALED_TO_INT( x * x_scale );
+ x2_scaled = SCALED_TO_INT( (x + rle_this_bite) * x_scale);
+ mem_blend16(img_pix+x1_scaled, *((uint16_t *)&clut[clr]), o, x2_scaled-x1_scaled);
+ }
+ x += rle_this_bite;
+ if (x >= src_width ) {
+ x -= src_width;
+ img_pix += img_width;
+ dy += dy_step;
+ if (dy >= INT_TO_SCALED(1)) {
+ dy -= INT_TO_SCALED(1);
+ ++y;
+ while (dy >= INT_TO_SCALED(1)) {
+ rle = rle_img_advance_line(rle, rle_limit, src_width);
+ dy -= INT_TO_SCALED(1);
+ ++y;
+ }
+ rle_start = rle;
+ } else {
+ rle = rle_start; /* y-scaling, reuse the last rle encoded line */
+ }
+ if (y > img_overl->clip_bottom) {
+ zone_state = 5;
+ break;
+ }
+ }
+ if (rle >= rle_limit) {
+ zone_state = 6;
+ }
+ break;
+ case 5: /* Below button */
+ clut = (clut_t*) img_overl->color;
+ trans = img_overl->trans;
+ o = trans[clr];
+ rle_this_bite = rle_remainder;
+ rle_remainder = 0;
+ rlelen -= rle_this_bite;
+ if (o) {
+ x1_scaled = SCALED_TO_INT( x * x_scale );
+ x2_scaled = SCALED_TO_INT( (x + rle_this_bite) * x_scale);
+ mem_blend16(img_pix+x1_scaled, *((uint16_t *)&clut[clr]), o, x2_scaled-x1_scaled);
+ }
+ x += rle_this_bite;
+ if (x >= src_width ) {
+ x -= src_width;
+ img_pix += img_width;
+ dy += dy_step;
+ if (dy >= INT_TO_SCALED(1)) {
+ dy -= INT_TO_SCALED(1);
+ ++y;
+ while (dy >= INT_TO_SCALED(1)) {
+ rle = rle_img_advance_line(rle, rle_limit, src_width);
+ dy -= INT_TO_SCALED(1);
+ ++y;
+ }
+ rle_start = rle;
+ } else {
+ rle = rle_start; /* y-scaling, reuse the last rle encoded line */
+ }
+ }
+ rle_remainder = rlelen = rle->len;
+ clr_next = rle->color;
rle++;
- if (rle >= rle_limit) break;
- }
-
- img_pix += img_width;
- dy += dy_step;
- if (dy >= INT_TO_SCALED(1)) {
- dy -= INT_TO_SCALED(1);
- ++y;
- while (dy >= INT_TO_SCALED(1)) {
- rle = rle_img_advance_line(rle, rle_limit, src_width);
- dy -= INT_TO_SCALED(1);
- ++y;
+ if (rle >= rle_limit) {
+ zone_state = 6;
}
- } else {
- rle = rle_start; /* y-scaling, reuse the last rle encoded line */
+ break;
+ case 6: /* Finished */
+ printf("Don't ever get here\n");
+ assert(0);
+ case 7: /* No button */
+ clut = (clut_t*) img_overl->color;
+ trans = img_overl->trans;
+ o = trans[clr];
+ rle_this_bite = rle_remainder;
+ rle_remainder = 0;
+ rlelen -= rle_this_bite;
+ if (o) {
+ x1_scaled = SCALED_TO_INT( x * x_scale );
+ x2_scaled = SCALED_TO_INT( (x + rle_this_bite) * x_scale);
+ mem_blend16(img_pix+x1_scaled, *((uint16_t *)&clut[clr]), o, x2_scaled-x1_scaled);
+ }
+ x += rle_this_bite;
+ if (x >= src_width ) {
+ x -= src_width;
+ img_pix += img_width;
+ dst_y++;
+ dy += dy_step;
+ if (dy >= INT_TO_SCALED(1)) {
+ dy -= INT_TO_SCALED(1);
+ ++y;
+ while (dy >= INT_TO_SCALED(1)) {
+ rle = rle_img_advance_line(rle, rle_limit, src_width);
+ dy -= INT_TO_SCALED(1);
+ ++y;
+ }
+ rle_start = rle;
+ } else {
+ rle = rle_start; /* y-scaling, reuse the last rle encoded line */
+ }
+ }
+ rle_remainder = rlelen = rle->len;
+ clr_next = rle->color;
+ rle++;
+ if (rle >= rle_limit) {
+ zone_state = 6;
+ }
+ break;
+ default:
+ ;
}
}
+#ifdef LOG_BLEND_RGB16
+ printf("blend_rgb16 ended\n");
+#endif
+
}
void blend_rgb24 (uint8_t * img, vo_overlay_t * img_overl,
diff --git a/src/video_out/video_out_xshm.c b/src/video_out/video_out_xshm.c
index 66cb205fc..a37b8777c 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.90 2002/09/16 11:35:25 jcdutton Exp $
+ * $Id: video_out_xshm.c,v 1.91 2002/09/30 05:16:45 jcdutton Exp $
*
* video_out_xshm.c, X11 shared memory extension interface for xine
*
@@ -540,7 +540,11 @@ static void xshm_update_frame_format (xine_vo_driver_t *this_gen,
frame->stripe_height = 16 * frame->sc.output_height / frame->sc.delivered_height;
- /* printf ("video_out_xshm: stripe height is %d\n", frame->stripe_height); */
+#ifdef LOG
+ printf ("video_out_xshm: stripe out_ht=%i, deliv_ht=%i\n",
+ frame->sc.output_height, frame->sc.delivered_height);
+ printf ("video_out_xshm: stripe height is %d\n", frame->stripe_height);
+#endif
/*
* set up colorspace converter
diff --git a/src/video_out/yuv2rgb.c b/src/video_out/yuv2rgb.c
index a6e7d195d..8342ddd5a 100644
--- a/src/video_out/yuv2rgb.c
+++ b/src/video_out/yuv2rgb.c
@@ -22,7 +22,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: yuv2rgb.c,v 1.32 2002/08/14 12:23:33 esnel Exp $
+ * $Id: yuv2rgb.c,v 1.33 2002/09/30 05:16:45 jcdutton Exp $
*/
#include "config.h"
@@ -73,10 +73,10 @@ static int yuv2rgb_configure (yuv2rgb_t *this,
int y_stride, int uv_stride,
int dest_width, int dest_height,
int rgb_stride) {
- /*
+/*
printf ("yuv2rgb setup (%d x %d => %d x %d)\n", source_width, source_height,
dest_width, dest_height);
- */
+*/
if (prof_scale_line == -1)
prof_scale_line = xine_profiler_allocate_slot("xshm scale line");
@@ -104,7 +104,10 @@ static int yuv2rgb_configure (yuv2rgb_t *this,
this->step_dx = source_width * 32768 / dest_width;
this->step_dy = source_height * 32768 / dest_height;
-
+/*
+ printf("yuv2rgb config: src_ht=%i, dst_ht=%i\n",source_height, dest_height);
+ printf("yuv2rgb config: step_dy=%i %f\n",this->step_dy, (float)this->step_dy / 32768.0);
+*/
this->scale_line = find_scale_line_func(this->step_dx);
if ((source_width == dest_width) && (source_height == dest_height)) {
diff --git a/src/xine-engine/osd.c b/src/xine-engine/osd.c
index 3e3eb521d..302e0ac8d 100644
--- a/src/xine-engine/osd.c
+++ b/src/xine-engine/osd.c
@@ -169,7 +169,7 @@ static int osd_show (osd_object_t *osd, int64_t vpts ) {
this->event.object.overlay->width = osd->x2 - osd->x1 + 1;
this->event.object.overlay->height = osd->y2 - osd->y1 + 1;
- this->event.object.overlay->clip_top = 0;
+ this->event.object.overlay->clip_top = -1;
this->event.object.overlay->clip_bottom = this->event.object.overlay->height +
osd->display_x;
this->event.object.overlay->clip_left = 0;