[MPlayer-dev-eng] [PATCH] color SPU - Part 5/3
- Date: Wed, 28 May 2008 20:57:37 +0200
- From: Ötvös Attila <dc@xxxxxxxxx>
- Subject: [MPlayer-dev-eng] [PATCH] color SPU - Part 5/3
Hi All!
modify spudec.c to UV and RGB planes (scale more plane)
04-colorspu-spudec.patch:
- add need variables to spudec_handle_t
- move split function scaler code from spudec_draw_scaled() to
spudec_scaled_approx(), spudec_scaled_none(), ...
05-colorspu-spudec.patch:
- add scaler more planes to spudec_scaled_none()
06-colorspu-spudec.patch:
- add scaler more planes to spudec_scaled_approx()
07-colorspu-spudec.patch:
- add scaler more planes to spudec_scaled_bilinear()
08-colorspu-spudec.patch:
- add scaler more planes to spudec_scaled_sws()
09-colorspu-spudec.patch:
- add scaler more planes to spudec_scaled_full()
10-colorspu-spudec.patch:
- draw code to U,V or R,G.B planes
11-colorspu-spudec.patch:
- add create code to UV and RGB planes
12-colorspu-spudec.patch:
- add spudec_set_spu_format() function
Best regards!
Attila
--- spudec.c 2008-05-27 20:19:32.000000000 +0200
+++ spudec.c 2008-05-27 20:22:24.000000000 +0200
@@ -794,20 +794,30 @@
sws_freeContext(ctx);
}
-void spu_scaled_none(spudec_handle_t *spu, unsigned int dxs, unsigned int dys,
- unsigned int scalex, unsigned int scaley)
+void spu_scaled_none(unsigned int dxs, unsigned int dys,
+ int src_stride,
+ int dst_width, int dst_height, int dst_stride,
+ unsigned int scalex, unsigned int scaley,
+ unsigned char *src_y, unsigned char *src_a,
+ unsigned char *src_u, unsigned char *src_v,
+ unsigned char *dst_y, unsigned char *dst_a,
+ unsigned char *dst_u, unsigned char *dst_v)
{
unsigned int x, y;
/* no antialiasing */
- for (y = 0; y < spu->scaled_height; ++y) {
+ for (y = 0; y < dst_height; ++y) {
int unscaled_y = y * 0x100 / scaley;
- int strides = spu->stride * unscaled_y;
- int scaled_strides = spu->scaled_stride * y;
- for (x = 0; x < spu->scaled_width; ++x) {
+ int strides = src_stride * unscaled_y;
+ int scaled_strides = dst_stride * y;
+ for (x = 0; x < dst_width; ++x) {
int unscaled_x = x * 0x100 / scalex;
- spu->scaled_image[scaled_strides + x] = spu->image[strides + unscaled_x];
- spu->scaled_aimage[scaled_strides + x] = spu->aimage[strides + unscaled_x];
+ dst_y[scaled_strides + x] = src_y[strides + unscaled_x];
+ dst_a[scaled_strides + x] = src_a[strides + unscaled_x];
+ if(src_u)
+ dst_u[scaled_strides + x] = src_u[strides + unscaled_x];
+ if(src_v)
+ dst_v[scaled_strides + x] = src_v[strides + unscaled_x];
}
}
}
@@ -1055,6 +1065,40 @@
spu->stride);
}
+void aa_scaler(int aamode, int width, int height, int dxs, int dys,
+ int src_width, int src_height, int src_stride,
+ int dst_width, int dst_height, int dst_stride,
+ unsigned int scalex, unsigned int scaley,
+ unsigned char *src_y, unsigned char *src_a,
+ unsigned char *src_u, unsigned char *src_v,
+ unsigned char *dst_y, unsigned char *dst_a,
+ unsigned char *dst_u, unsigned char *dst_v,
+ spudec_handle_t *spu)
+{
+switch(aamode&15) {
+ case 4:
+ spu_scaled_sws(spu,dxs,dys,scalex,scaley);
+ break;
+ case 3:
+ spu_scaled_bilinear(spu,dxs,dys,scalex,scaley);
+ break;
+ case 0:
+ spu_scaled_none(dxs, dys,
+ src_stride,
+ dst_width, dst_height, dst_stride,
+ scalex,scaley,
+ src_y, src_a, src_u, src_v,
+ dst_y, dst_a, dst_u, dst_v);
+ break;
+ case 1:
+ spu_scaled_approx(spu,dxs,dys,scalex,scaley);
+ break;
+ case 2:
+ spu_scaled_full(spu,dxs,dys,scalex,scaley);
+ break;
+ }
+}
+
void spudec_draw_scaled(void *me, unsigned int dxs, unsigned int dys, void (*draw_alpha)(int x0,int y0, int w,int h, int dp, unsigned char* src, unsigned char *srca, int stride))
{
spudec_handle_t *spu = (spudec_handle_t *)me;
@@ -1102,23 +1146,13 @@
if (spu->scaled_image) {
unsigned int y;
if (spu->scaled_width > 1 && spu->scaled_height > 1)
- switch(spu_aamode&15) {
- case 4:
- spu_scaled_sws(spu,dxs,dys,scalex,scaley);
- break;
- case 3:
- spu_scaled_bilinear(spu,dxs,dys,scalex,scaley);
- break;
- case 0:
- spu_scaled_none(spu,dxs,dys,scalex,scaley);
- break;
- case 1:
- spu_scaled_approx(spu,dxs,dys,scalex,scaley);
- break;
- case 2:
- spu_scaled_full(spu,dxs,dys,scalex,scaley);
- break;
- }
+ aa_scaler(spu_aamode&15, spu->width, spu->height, dxs, dys,
+ spu->orig_frame_width, spu->orig_frame_height,spu->stride,
+ spu->scaled_width, spu->scaled_height, spu->scaled_stride,
+ scalex, scaley,
+ spu->image, spu->aimage, NULL, NULL,
+ spu->scaled_image, spu->scaled_aimage, NULL, NULL,
+ spu);
/* Kludge: draw_alpha needs width multiple of 8. */
if (spu->scaled_width < spu->scaled_stride)
for (y = 0; y < spu->scaled_height; ++y) {
--- spudec.c 2008-05-27 20:12:13.000000000 +0200
+++ spudec.c 2008-05-27 20:19:32.000000000 +0200
@@ -39,6 +39,15 @@
float spu_gaussvar = 1.0;
extern int sub_pos;
+/* color mode flags */
+typedef enum {
+ COLORSPU_Y = 0, /* Grayscale */
+ COLORSPU_YUV = 1,
+ COLORSPU_YUY = 2,
+ COLORSPU_RGB = 3,
+ COLORSPU_BGR = 4,
+} colorspu_t;
+
typedef struct packet_t packet_t;
struct packet_t {
unsigned char *packet;
@@ -74,22 +83,40 @@
unsigned int start_pts, end_pts;
unsigned int start_col, end_col;
unsigned int start_row, end_row;
+ unsigned int start_coluv, end_coluv;
+ unsigned int start_rowuv, end_rowuv;
unsigned int width, height, stride;
+ unsigned int widthuv, heightuv, strideuv, strideyuy;
size_t image_size; /* Size of the image buffer */
- unsigned char *image; /* Grayscale value */
+ size_t image_sizeuv; /* Size of the imageuv buffer */
+ size_t image_sizeyuy; /* Size of the imageyuy buffer */
+ unsigned char *image; /* Grayscale value or Y value or RB value */
+ unsigned char *imageu; /* U value or G value */
+ unsigned char *imagev; /* V value or BR value */
+ unsigned char *imageyuy; /* image yuy */
unsigned char *aimage; /* Alpha value */
+ unsigned char *aimageuv; /* Alpha value to uv planes */
+ unsigned char *aimageyuy; /* Alpha valur to yuy planes */
unsigned int scaled_frame_width, scaled_frame_height;
unsigned int scaled_start_col, scaled_start_row;
unsigned int scaled_width, scaled_height, scaled_stride;
+ unsigned int scaled_frame_widthuv, scaled_frame_heightuv;
+ unsigned int scaled_start_coluv, scaled_start_rowuv;
+ unsigned int scaled_widthuv, scaled_heightuv, scaled_strideuv;
size_t scaled_image_size;
+ size_t scaled_image_sizeuv;
unsigned char *scaled_image;
unsigned char *scaled_aimage;
+ unsigned char *scaled_imageu;
+ unsigned char *scaled_imagev;
+ unsigned char *scaled_aimageuv;
int auto_palette; /* 1 if we lack a palette and must use an heuristic. */
int font_start_level; /* Darkest value used for the computed font */
const vo_functions_t *hw_spu;
int spu_changed;
unsigned int forced_subs_only; /* flag: 0=display all subtitle, !0 display only forced subtitles */
unsigned int is_forced_sub; /* true if current subtitle is a forced subtitle */
+ colorspu_t colorspu; /* spu color mode */
} spudec_handle_t;
static void spudec_queue_packet(spudec_handle_t *this, packet_t *packet)
@@ -767,78 +794,11 @@
sws_freeContext(ctx);
}
-void spudec_draw_scaled(void *me, unsigned int dxs, unsigned int dys, void (*draw_alpha)(int x0,int y0, int w,int h, int dp, unsigned char* src, unsigned char *srca, int stride))
+void spu_scaled_none(spudec_handle_t *spu, unsigned int dxs, unsigned int dys,
+ unsigned int scalex, unsigned int scaley)
{
- spudec_handle_t *spu = (spudec_handle_t *)me;
- scale_pixel *table_x;
- scale_pixel *table_y;
-
- if (spu->start_pts <= spu->now_pts && spu->now_pts < spu->end_pts) {
-
- // check if only forced subtitles are requested
- if( (spu->forced_subs_only) && !(spu->is_forced_sub) ){
- return;
- }
-
- if (!(spu_aamode&16) && (spu->orig_frame_width == 0 || spu->orig_frame_height == 0
- || (spu->orig_frame_width == dxs && spu->orig_frame_height == dys))) {
- if (spu->image)
- {
- draw_alpha(spu->start_col, spu->start_row, spu->width, spu->height,
- DEST_PLANES_Y, spu->image, spu->aimage, spu->stride);
- spu->spu_changed = 0;
- }
- }
- else {
- if (spu->scaled_frame_width != dxs || spu->scaled_frame_height != dys) { /* Resizing is needed */
- /* scaled_x = scalex * x / 0x100
- scaled_y = scaley * y / 0x100
- order of operations is important because of rounding. */
- unsigned int scalex = 0x100 * dxs / spu->orig_frame_width;
- unsigned int scaley = 0x100 * dys / spu->orig_frame_height;
- spu->scaled_start_col = spu->start_col * scalex / 0x100;
- spu->scaled_start_row = spu->start_row * scaley / 0x100;
- spu->scaled_width = spu->width * scalex / 0x100;
- spu->scaled_height = spu->height * scaley / 0x100;
- /* Kludge: draw_alpha needs width multiple of 8 */
- spu->scaled_stride = (spu->scaled_width + 7) & ~7;
- if (spu->scaled_image_size < spu->scaled_stride * spu->scaled_height) {
- if (spu->scaled_image) {
- free(spu->scaled_image);
- spu->scaled_image_size = 0;
- }
- spu->scaled_image = malloc(2 * spu->scaled_stride * spu->scaled_height);
- if (spu->scaled_image) {
- spu->scaled_image_size = spu->scaled_stride * spu->scaled_height;
- spu->scaled_aimage = spu->scaled_image + spu->scaled_image_size;
- }
- }
- if (spu->scaled_image) {
unsigned int x, y;
- if (spu->scaled_width <= 1 || spu->scaled_height <= 1) {
- goto nothing_to_do;
- }
- switch(spu_aamode&15) {
- case 4:
- sws_spu_image(spu->scaled_image, spu->scaled_aimage,
- spu->scaled_width, spu->scaled_height, spu->scaled_stride,
- spu->image, spu->aimage, spu->width, spu->height, spu->stride);
- break;
- case 3:
- table_x = calloc(spu->scaled_width, sizeof(scale_pixel));
- table_y = calloc(spu->scaled_height, sizeof(scale_pixel));
- if (!table_x || !table_y) {
- mp_msg(MSGT_SPUDEC, MSGL_FATAL, "Fatal: spudec_draw_scaled: calloc failed\n");
- }
- scale_table(0, 0, spu->width - 1, spu->scaled_width - 1, table_x);
- scale_table(0, 0, spu->height - 1, spu->scaled_height - 1, table_y);
- for (y = 0; y < spu->scaled_height; y++)
- for (x = 0; x < spu->scaled_width; x++)
- scale_image(x, y, table_x, table_y, spu);
- free(table_x);
- free(table_y);
- break;
- case 0:
+
/* no antialiasing */
for (y = 0; y < spu->scaled_height; ++y) {
int unscaled_y = y * 0x100 / scaley;
@@ -850,9 +810,13 @@
spu->scaled_aimage[scaled_strides + x] = spu->aimage[strides + unscaled_x];
}
}
- break;
- case 1:
+}
+
+void spu_scaled_approx(spudec_handle_t *spu, unsigned int dxs, unsigned int dys,
+ unsigned int scalex, unsigned int scaley)
{
+ unsigned int x, y;
+
/* Intermediate antialiasing. */
for (y = 0; y < spu->scaled_height; ++y) {
const unsigned int unscaled_top = y * spu->orig_frame_height / dys;
@@ -889,9 +853,12 @@
}
}
}
- break;
- case 2:
+
+void spu_scaled_full(spudec_handle_t *spu, unsigned int dxs, unsigned int dys,
+ unsigned int scalex, unsigned int scaley)
{
+ unsigned int x, y;
+
/* Best antialiasing. Very slow. */
/* Any pixel (x, y) represents pixels from the original
rectangular region comprised between the columns
@@ -1057,8 +1024,101 @@
}
}
}
+
+void spu_scaled_bilinear(spudec_handle_t *spu, unsigned int dxs, unsigned int dys,
+ unsigned int scalex, unsigned int scaley)
+{
+ unsigned int x, y;
+ scale_pixel *table_x;
+ scale_pixel *table_y;
+
+ table_x = calloc(spu->scaled_width, sizeof(scale_pixel));
+ table_y = calloc(spu->scaled_height, sizeof(scale_pixel));
+ if (!table_x || !table_y) {
+ mp_msg(MSGT_SPUDEC, MSGL_FATAL, "Fatal: spudec_draw_scaled: calloc failed\n");
+ }
+ scale_table(0, 0, spu->width - 1, spu->scaled_width - 1, table_x);
+ scale_table(0, 0, spu->height - 1, spu->scaled_height - 1, table_y);
+ for (y = 0; y < spu->scaled_height; y++)
+ for (x = 0; x < spu->scaled_width; x++)
+ scale_image(x, y, table_x, table_y, spu);
+ free(table_x);
+ free(table_y);
+}
+
+void spu_scaled_sws(spudec_handle_t *spu, unsigned int dxs, unsigned int dys,
+ unsigned int scalex, unsigned int scaley)
+{
+ sws_spu_image(spu->scaled_image, spu->scaled_aimage,
+ spu->scaled_width, spu->scaled_height, spu->scaled_stride,
+ spu->image, spu->aimage, spu->width, spu->height,
+ spu->stride);
+}
+
+void spudec_draw_scaled(void *me, unsigned int dxs, unsigned int dys, void (*draw_alpha)(int x0,int y0, int w,int h, int dp, unsigned char* src, unsigned char *srca, int stride))
+{
+ spudec_handle_t *spu = (spudec_handle_t *)me;
+
+ if (spu->start_pts <= spu->now_pts && spu->now_pts < spu->end_pts) {
+
+ // check if only forced subtitles are requested
+ if( (spu->forced_subs_only) && !(spu->is_forced_sub) ){
+ return;
+ }
+
+ if (!(spu_aamode&16) && (spu->orig_frame_width == 0 || spu->orig_frame_height == 0
+ || (spu->orig_frame_width == dxs && spu->orig_frame_height == dys))) {
+ if (spu->image)
+ {
+ draw_alpha(spu->start_col, spu->start_row, spu->width, spu->height,
+ DEST_PLANES_Y, spu->image, spu->aimage, spu->stride);
+ spu->spu_changed = 0;
+ }
+ }
+ else {
+ if (spu->scaled_frame_width != dxs || spu->scaled_frame_height != dys) { /* Resizing is needed */
+ /* scaled_x = scalex * x / 0x100
+ scaled_y = scaley * y / 0x100
+ order of operations is important because of rounding. */
+ unsigned int scalex = 0x100 * dxs / spu->orig_frame_width;
+ unsigned int scaley = 0x100 * dys / spu->orig_frame_height;
+ spu->scaled_start_col = spu->start_col * scalex / 0x100;
+ spu->scaled_start_row = spu->start_row * scaley / 0x100;
+ spu->scaled_width = spu->width * scalex / 0x100;
+ spu->scaled_height = spu->height * scaley / 0x100;
+ /* Kludge: draw_alpha needs width multiple of 8 */
+ spu->scaled_stride = (spu->scaled_width + 7) & ~7;
+ if (spu->scaled_image_size < spu->scaled_stride * spu->scaled_height) {
+ if (spu->scaled_image) {
+ free(spu->scaled_image);
+ spu->scaled_image_size = 0;
+ }
+ spu->scaled_image = malloc(2 * spu->scaled_stride * spu->scaled_height);
+ if (spu->scaled_image) {
+ spu->scaled_image_size = spu->scaled_stride * spu->scaled_height;
+ spu->scaled_aimage = spu->scaled_image + spu->scaled_image_size;
+ }
+ }
+ if (spu->scaled_image) {
+ unsigned int y;
+ if (spu->scaled_width > 1 && spu->scaled_height > 1)
+ switch(spu_aamode&15) {
+ case 4:
+ spu_scaled_sws(spu,dxs,dys,scalex,scaley);
+ break;
+ case 3:
+ spu_scaled_bilinear(spu,dxs,dys,scalex,scaley);
+ break;
+ case 0:
+ spu_scaled_none(spu,dxs,dys,scalex,scaley);
+ break;
+ case 1:
+ spu_scaled_approx(spu,dxs,dys,scalex,scaley);
+ break;
+ case 2:
+ spu_scaled_full(spu,dxs,dys,scalex,scaley);
+ break;
}
-nothing_to_do:
/* Kludge: draw_alpha needs width multiple of 8. */
if (spu->scaled_width < spu->scaled_stride)
for (y = 0; y < spu->scaled_height; ++y) {
@@ -1170,6 +1230,13 @@
free(spu->scaled_image);
if (spu->image)
free(spu->image);
+ if (spu->imageu) // Free dvdnav SPU uv or GB image
+ free(spu->imageu);
+ if (spu->imageyuy) // Free dvdnav SPU YUY image
+ free(spu->imageyuy);
+ spu->imageyuy=NULL;
+ if (spu->scaled_imageu) // Free dvdnav SPU uv or GB alpha
+ free(spu->scaled_imageu);
free(spu);
}
}
--- spudec.c 2008-05-27 20:22:24.000000000 +0200
+++ spudec.c 2008-05-27 20:30:34.000000000 +0200
@@ -822,43 +822,63 @@
}
}
-void spu_scaled_approx(spudec_handle_t *spu, unsigned int dxs, unsigned int dys,
- unsigned int scalex, unsigned int scaley)
+void spu_scaled_approx(int width, int height, unsigned int dxs, unsigned int dys,
+ int src_width, int src_height, int src_stride,
+ int dst_width, int dst_height, int dst_stride,
+ unsigned int scalex, unsigned int scaley,
+ unsigned char *src_y, unsigned char *src_a,
+ unsigned char *src_u, unsigned char *src_v,
+ unsigned char *dst_y, unsigned char *dst_a,
+ unsigned char *dst_u, unsigned char *dst_v)
{
unsigned int x, y;
/* Intermediate antialiasing. */
- for (y = 0; y < spu->scaled_height; ++y) {
- const unsigned int unscaled_top = y * spu->orig_frame_height / dys;
- unsigned int unscaled_bottom = (y + 1) * spu->orig_frame_height / dys;
- if (unscaled_bottom >= spu->height)
- unscaled_bottom = spu->height - 1;
- for (x = 0; x < spu->scaled_width; ++x) {
- const unsigned int unscaled_left = x * spu->orig_frame_width / dxs;
- unsigned int unscaled_right = (x + 1) * spu->orig_frame_width / dxs;
+ for (y = 0; y < dst_height; ++y) {
+ const unsigned int unscaled_top = y * src_height / dys;
+ unsigned int unscaled_bottom = (y + 1) * src_height / dys;
+ if (unscaled_bottom >= height)
+ unscaled_bottom = height - 1;
+ for (x = 0; x < dst_width; ++x) {
+ const unsigned int unscaled_left = x * src_width / dxs;
+ unsigned int unscaled_right = (x + 1) * src_width / dxs;
unsigned int color = 0;
+ unsigned int coloru = 0;
+ unsigned int colorv = 0;
unsigned int alpha = 0;
unsigned int walkx, walky;
unsigned int base, tmp;
- if (unscaled_right >= spu->width)
- unscaled_right = spu->width - 1;
+ if (unscaled_right >= width)
+ unscaled_right = width - 1;
for (walky = unscaled_top; walky <= unscaled_bottom; ++walky)
for (walkx = unscaled_left; walkx <= unscaled_right; ++walkx) {
- base = walky * spu->stride + walkx;
- tmp = canon_alpha(spu->aimage[base]);
+ base = walky * src_stride + walkx;
+ tmp = canon_alpha(src_a[base]);
alpha += tmp;
- color += tmp * spu->image[base];
- }
- base = y * spu->scaled_stride + x;
- spu->scaled_image[base] = alpha ? color / alpha : 0;
- spu->scaled_aimage[base] =
+ color += tmp * src_y[base];
+ if(src_u)
+ coloru += tmp * src_u[base];
+ if(src_v)
+ colorv += tmp * src_v[base];
+ }
+ base = y * dst_stride + x;
+ dst_y[base] = alpha ? color / alpha : 0;
+ if(src_u)
+ dst_u[base] = alpha ? coloru / alpha : 0;
+ if(src_v)
+ dst_v[base] = alpha ? colorv / alpha : 0;
+ dst_a[base] =
alpha * (1 + unscaled_bottom - unscaled_top) * (1 + unscaled_right - unscaled_left);
/* spu->scaled_aimage[base] =
alpha * dxs * dys / spu->orig_frame_width / spu->orig_frame_height; */
- if (spu->scaled_aimage[base]) {
- spu->scaled_aimage[base] = 256 - spu->scaled_aimage[base];
- if (spu->scaled_aimage[base] + spu->scaled_image[base] > 255)
- spu->scaled_image[base] = 256 - spu->scaled_aimage[base];
+ if (dst_a[base]) {
+ dst_a[base] = 256 - dst_a[base];
+ if (dst_a[base] + dst_y[base] > 255)
+ dst_y[base] = 256 - dst_a[base];
+ if (src_u && dst_a[base] + dst_u[base] > 255)
+ dst_u[base] = 256 - dst_a[base];
+ if (src_v && dst_a[base] + dst_v[base] > 255)
+ dst_v[base] = 256 - dst_a[base];
}
}
}
@@ -1091,7 +1111,12 @@
dst_y, dst_a, dst_u, dst_v);
break;
case 1:
- spu_scaled_approx(spu,dxs,dys,scalex,scaley);
+ spu_scaled_approx(width, height, dxs, dys,
+ src_width, src_height, src_stride,
+ dst_width, dst_height, dst_stride,
+ scalex,scaley,
+ src_y, src_a, src_u, src_v,
+ dst_y, dst_a, dst_u, dst_v);
break;
case 2:
spu_scaled_full(spu,dxs,dys,scalex,scaley);
--- spudec.c 2008-05-27 20:35:59.000000000 +0200
+++ spudec.c 2008-05-27 20:44:16.000000000 +0200
@@ -917,8 +917,13 @@
}
}
-void spu_scaled_full(spudec_handle_t *spu, unsigned int dxs, unsigned int dys,
- unsigned int scalex, unsigned int scaley)
+void spu_scaled_full(int src_stride,
+ int dst_width, int dst_height, int dst_stride,
+ unsigned int scalex, unsigned int scaley,
+ unsigned char *src_y, unsigned char *src_a,
+ unsigned char *src_u, unsigned char *src_v,
+ unsigned char *dst_y, unsigned char *dst_a,
+ unsigned char *dst_u, unsigned char *dst_v)
{
unsigned int x, y;
@@ -963,7 +968,7 @@
unscaled_x_right. */
const double inv_scalex = (double) 0x100 / scalex;
const double inv_scaley = (double) 0x100 / scaley;
- for (y = 0; y < spu->scaled_height; ++y) {
+ for (y = 0; y < dst_height; ++y) {
const double unscaled_y = y * inv_scaley;
const double unscaled_y_bottom = unscaled_y + inv_scaley;
const unsigned int top_low_row = FFMIN(unscaled_y_bottom, unscaled_y + 1.0);
@@ -974,7 +979,7 @@
const double bottom = unscaled_y_bottom > top_low_row
? unscaled_y_bottom - floor(unscaled_y_bottom)
: 0.0;
- for (x = 0; x < spu->scaled_width; ++x) {
+ for (x = 0; x < dst_width; ++x) {
const double unscaled_x = x * inv_scalex;
const double unscaled_x_right = unscaled_x + inv_scalex;
const unsigned int left_right_column = FFMIN(unscaled_x_right, unscaled_x + 1.0);
@@ -986,6 +991,8 @@
? unscaled_x_right - floor(unscaled_x_right)
: 0.0;
double color = 0.0;
+ double coloru = 0.0;
+ double colorv = 0.0;
double alpha = 0.0;
double tmp;
unsigned int base;
@@ -997,35 +1004,51 @@
transformed color = sum(surface * alpha * color) / sum(surface * alpha)
*/
/* 1: top left part */
- base = spu->stride * (unsigned int) unscaled_y;
- tmp = left * top * canon_alpha(spu->aimage[base + (unsigned int) unscaled_x]);
+ base = src_stride * (unsigned int) unscaled_y;
+ tmp = left * top * canon_alpha(src_a[base + (unsigned int) unscaled_x]);
alpha += tmp;
- color += tmp * spu->image[base + (unsigned int) unscaled_x];
+ color += tmp * src_y[base + (unsigned int) unscaled_x];
+ if(src_u)
+ coloru += tmp * src_u[base + (unsigned int) unscaled_x];
+ if(src_v)
+ colorv += tmp * src_v[base + (unsigned int) unscaled_x];
/* 2: top center part */
if (width > 0) {
unsigned int walkx;
for (walkx = left_right_column; walkx < (unsigned int) unscaled_x_right; ++walkx) {
- base = spu->stride * (unsigned int) unscaled_y + walkx;
- tmp = /* 1.0 * */ top * canon_alpha(spu->aimage[base]);
+ base = src_stride * (unsigned int) unscaled_y + walkx;
+ tmp = /* 1.0 * */ top * canon_alpha(src_a[base]);
alpha += tmp;
- color += tmp * spu->image[base];
+ color += tmp * src_y[base];
+ if(src_u)
+ coloru += tmp * src_u[base];
+ if(src_v)
+ colorv += tmp * src_v[base];
}
}
/* 3: top right part */
if (right > 0.0) {
- base = spu->stride * (unsigned int) unscaled_y + (unsigned int) unscaled_x_right;
- tmp = right * top * canon_alpha(spu->aimage[base]);
+ base = src_stride * (unsigned int) unscaled_y + (unsigned int) unscaled_x_right;
+ tmp = right * top * canon_alpha(src_a[base]);
alpha += tmp;
- color += tmp * spu->image[base];
+ color += tmp * src_y[base];
+ if(src_u)
+ coloru += tmp * src_u[base];
+ if(src_u)
+ colorv += tmp * src_v[base];
}
/* 4: center left part */
if (height > 0) {
unsigned int walky;
for (walky = top_low_row; walky < (unsigned int) unscaled_y_bottom; ++walky) {
- base = spu->stride * walky + (unsigned int) unscaled_x;
- tmp = left /* * 1.0 */ * canon_alpha(spu->aimage[base]);
+ base = src_stride * walky + (unsigned int) unscaled_x;
+ tmp = left /* * 1.0 */ * canon_alpha(src_a[base]);
alpha += tmp;
- color += tmp * spu->image[base];
+ color += tmp * src_y[base];
+ if(src_u)
+ coloru += tmp * src_u[base];
+ if(src_u)
+ colorv += tmp * src_v[base];
}
}
/* 5: center part */
@@ -1033,11 +1056,15 @@
unsigned int walky;
for (walky = top_low_row; walky < (unsigned int) unscaled_y_bottom; ++walky) {
unsigned int walkx;
- base = spu->stride * walky;
+ base = src_stride * walky;
for (walkx = left_right_column; walkx < (unsigned int) unscaled_x_right; ++walkx) {
- tmp = /* 1.0 * 1.0 * */ canon_alpha(spu->aimage[base + walkx]);
+ tmp = /* 1.0 * 1.0 * */ canon_alpha(src_a[base + walkx]);
alpha += tmp;
- color += tmp * spu->image[base + walkx];
+ color += tmp * src_y[base + walkx];
+ if(src_u)
+ coloru += tmp * src_u[base];
+ if(src_u)
+ colorv += tmp * src_v[base];
}
}
}
@@ -1045,44 +1072,68 @@
if (right > 0.0 && height > 0) {
unsigned int walky;
for (walky = top_low_row; walky < (unsigned int) unscaled_y_bottom; ++walky) {
- base = spu->stride * walky + (unsigned int) unscaled_x_right;
- tmp = right /* * 1.0 */ * canon_alpha(spu->aimage[base]);
+ base = src_stride * walky + (unsigned int) unscaled_x_right;
+ tmp = right /* * 1.0 */ * canon_alpha(src_a[base]);
alpha += tmp;
- color += tmp * spu->image[base];
+ color += tmp * src_y[base];
+ if(src_u)
+ coloru += tmp * src_u[base];
+ if(src_u)
+ colorv += tmp * src_v[base];
}
}
/* 7: bottom left part */
if (bottom > 0.0) {
- base = spu->stride * (unsigned int) unscaled_y_bottom + (unsigned int) unscaled_x;
- tmp = left * bottom * canon_alpha(spu->aimage[base]);
+ base = src_stride * (unsigned int) unscaled_y_bottom + (unsigned int) unscaled_x;
+ tmp = left * bottom * canon_alpha(src_a[base]);
alpha += tmp;
- color += tmp * spu->image[base];
+ color += tmp * src_y[base];
+ if(src_u)
+ coloru += tmp * src_u[base];
+ if(src_u)
+ colorv += tmp * src_v[base];
}
/* 8: bottom center part */
if (width > 0 && bottom > 0.0) {
unsigned int walkx;
- base = spu->stride * (unsigned int) unscaled_y_bottom;
+ base = src_stride * (unsigned int) unscaled_y_bottom;
for (walkx = left_right_column; walkx < (unsigned int) unscaled_x_right; ++walkx) {
- tmp = /* 1.0 * */ bottom * canon_alpha(spu->aimage[base + walkx]);
+ tmp = /* 1.0 * */ bottom * canon_alpha(src_a[base + walkx]);
alpha += tmp;
- color += tmp * spu->image[base + walkx];
+ color += tmp * src_y[base + walkx];
+ if(src_u)
+ coloru += tmp * src_u[base];
+ if(src_u)
+ colorv += tmp * src_v[base];
}
}
/* 9: bottom right part */
if (right > 0.0 && bottom > 0.0) {
- base = spu->stride * (unsigned int) unscaled_y_bottom + (unsigned int) unscaled_x_right;
- tmp = right * bottom * canon_alpha(spu->aimage[base]);
+ base = src_stride * (unsigned int) unscaled_y_bottom + (unsigned int) unscaled_x_right;
+ tmp = right * bottom * canon_alpha(src_a[base]);
alpha += tmp;
- color += tmp * spu->image[base];
+ color += tmp * src_y[base];
+ if(src_u)
+ coloru += tmp * src_u[base];
+ if(src_u)
+ colorv += tmp * src_v[base];
}
/* Finally mix these transparency and brightness information suitably */
- base = spu->scaled_stride * y + x;
- spu->scaled_image[base] = alpha > 0 ? color / alpha : 0;
- spu->scaled_aimage[base] = alpha * scalex * scaley / 0x10000;
- if (spu->scaled_aimage[base]) {
- spu->scaled_aimage[base] = 256 - spu->scaled_aimage[base];
- if (spu->scaled_aimage[base] + spu->scaled_image[base] > 255)
- spu->scaled_image[base] = 256 - spu->scaled_aimage[base];
+ base = dst_stride * y + x;
+ dst_y[base] = alpha > 0 ? color / alpha : 0;
+ if(src_u)
+ dst_u[base] = alpha > 0 ? coloru / alpha : 0;
+ if(src_v)
+ dst_v[base] = alpha > 0 ? colorv / alpha : 0;
+ dst_a[base] = alpha * scalex * scaley / 0x10000;
+ if (dst_a[base]) {
+ dst_a[base] = 256 - dst_a[base];
+ if (dst_a[base] + dst_y[base] > 255)
+ dst_y[base] = 256 - dst_a[base];
+ if (src_u && dst_a[base] + dst_u[base] > 255)
+ dst_u[base] = 256 - dst_a[base];
+ if (src_v && dst_a[base] + dst_v[base] > 255)
+ dst_v[base] = 256 - dst_a[base];
}
}
}
@@ -1140,8 +1191,7 @@
unsigned char *src_y, unsigned char *src_a,
unsigned char *src_u, unsigned char *src_v,
unsigned char *dst_y, unsigned char *dst_a,
- unsigned char *dst_u, unsigned char *dst_v,
- spudec_handle_t *spu)
+ unsigned char *dst_u, unsigned char *dst_v)
{
switch(aamode&15) {
case 4:
@@ -1177,7 +1227,11 @@
dst_y, dst_a, dst_u, dst_v);
break;
case 2:
- spu_scaled_full(spu,dxs,dys,scalex,scaley);
+ spu_scaled_full(src_stride,
+ dst_width, dst_height, dst_stride,
+ scalex,scaley,
+ src_y, src_a, src_u, src_v,
+ dst_y, dst_a, dst_u, dst_v);
break;
}
}
@@ -1234,8 +1288,7 @@
spu->scaled_width, spu->scaled_height, spu->scaled_stride,
scalex, scaley,
spu->image, spu->aimage, NULL, NULL,
- spu->scaled_image, spu->scaled_aimage, NULL, NULL,
- spu);
+ spu->scaled_image, spu->scaled_aimage, NULL, NULL);
/* Kludge: draw_alpha needs width multiple of 8. */
if (spu->scaled_width < spu->scaled_stride)
for (y = 0; y < spu->scaled_height; ++y) {
--- spudec.c 2008-05-27 20:31:18.000000000 +0200
+++ spudec.c 2008-05-27 20:35:59.000000000 +0200
@@ -795,8 +795,10 @@
}
}
-void sws_spu_image(unsigned char *d1, unsigned char *d2, int dw, int dh, int ds,
- unsigned char *s1, unsigned char *s2, int sw, int sh, int ss)
+void sws_spu_image(unsigned char *d1, unsigned char *d2, unsigned char *d3, unsigned char *d4,
+ int dw, int dh, int ds,
+ unsigned char *s1, unsigned char *s2, unsigned char *s3, unsigned char *s4,
+ int sw, int sh, int ss)
{
struct SwsContext *ctx;
static SwsFilter filter;
@@ -815,6 +817,10 @@
ctx=sws_getContext(sw, sh, PIX_FMT_GRAY8, dw, dh, PIX_FMT_GRAY8, SWS_GAUSS, &filter, NULL, NULL);
sws_scale(ctx,&s1,&ss,0,sh,&d1,&ds);
+ if(s3)
+ sws_scale(ctx,&s3,&ss,0,sh,&d3,&ds);
+ if(s4)
+ sws_scale(ctx,&s4,&ss,0,sh,&d4,&ds);
for (i=ss*sh-1; i>=0; i--) if (!s2[i]) s2[i] = 255; //else s2[i] = 1;
sws_scale(ctx,&s2,&ss,0,sh,&d2,&ds);
for (i=ds*dh-1; i>=0; i--) if (d2[i]==0) d2[i] = 1; else if (d2[i]==255) d2[i] = 0;
@@ -1112,13 +1118,19 @@
free(table_y);
}
-void spu_scaled_sws(spudec_handle_t *spu, unsigned int dxs, unsigned int dys,
- unsigned int scalex, unsigned int scaley)
+
+void spu_scaled_sws(int width, int height, unsigned int dxs, unsigned int dys,
+ int src_width, int src_height, int src_stride,
+ int dst_width, int dst_height, int dst_stride,
+ unsigned int scalex, unsigned int scaley,
+ unsigned char *src_y, unsigned char *src_a,
+ unsigned char *src_u, unsigned char *src_v,
+ unsigned char *dst_y, unsigned char *dst_a,
+ unsigned char *dst_u, unsigned char *dst_v)
{
- sws_spu_image(spu->scaled_image, spu->scaled_aimage,
- spu->scaled_width, spu->scaled_height, spu->scaled_stride,
- spu->image, spu->aimage, spu->width, spu->height,
- spu->stride);
+ sws_spu_image(dst_y, dst_a, dst_u, dst_y,
+ dst_width, dst_height, dst_stride,
+ src_y, src_a, src_u, src_y, width, height, src_stride);
}
void aa_scaler(int aamode, int width, int height, int dxs, int dys,
@@ -1133,7 +1145,12 @@
{
switch(aamode&15) {
case 4:
- spu_scaled_sws(spu,dxs,dys,scalex,scaley);
+ spu_scaled_sws(width, height, dxs, dys,
+ src_width, src_height, src_stride,
+ dst_width, dst_height, dst_stride,
+ scalex,scaley,
+ src_y, src_a, src_u, src_v,
+ dst_y, dst_a, dst_u, dst_v);
break;
case 3:
spu_scaled_bilinear(width, height,
--- spudec.c 2008-05-27 20:44:16.000000000 +0200
+++ spudec.c 2008-05-27 20:59:50.000000000 +0200
@@ -651,13 +651,106 @@
}
}
+//
+// Convert Yuv image to YuY image
+//
+void spudec_create_yuy(void *this, int spu_scaled)
+{
+ spudec_handle_t *spu = this;
+ unsigned char *dptr;
+ unsigned char *daptr;
+ unsigned char *sptry;
+ unsigned char *sptru;
+ unsigned char *sptrv;
+ unsigned char *saptr;
+ unsigned char *saptruv;
+ int y,x;
+
+ if (spu_scaled) {
+ spu->strideyuy=spu->scaled_stride*2;
+ spu->imageyuy=malloc(spu->strideyuy*(spu->height+2)*2);
+ memset(spu->imageyuy,0,spu->strideyuy*(spu->height+2)*2);
+ spu->aimageyuy=spu->imageyuy+spu->strideyuy*spu->scaled_height;
+ for(y=0;y<spu->scaled_height;y++) {
+ dptr=spu->imageyuy+y*spu->strideyuy;
+ daptr=spu->aimageyuy+y*spu->strideyuy;
+ sptry=spu->scaled_image+y*spu->scaled_stride;
+ sptru=spu->scaled_imageu+y/2*spu->scaled_strideuv;
+ sptrv=spu->scaled_imagev+y/2*spu->scaled_strideuv;
+ saptr=spu->scaled_aimage+y*spu->scaled_stride;
+ saptruv=spu->scaled_aimageuv+y/2*spu->scaled_strideuv;
+ for(x=0;x<spu->scaled_widthuv-1;x++) {
+ *dptr++=*sptry++;
+ *dptr++=*sptrv++;
+ *dptr++=*sptry++;
+ *dptr++=*sptru++;
+ *daptr++=*saptr++;
+ *daptr++=*saptruv;
+ *daptr++=*saptr++;
+ *daptr++=*saptruv++;
+ }
+ }
+ } else {
+ spu->strideyuy=spu->stride*2;
+ spu->imageyuy=malloc(spu->strideyuy*(spu->height+2)*2);
+ memset(spu->imageyuy,0,spu->strideyuy*(spu->height+2)*2);
+ spu->aimageyuy=spu->imageyuy+spu->strideyuy*spu->height;
+ for(y=0;y<spu->height;y++) {
+ dptr=spu->imageyuy+y*spu->strideyuy;
+ daptr=spu->aimageyuy+y*spu->strideyuy;
+ sptry=spu->image+y*spu->stride;
+ sptru=spu->imageu+y/2*spu->strideuv;
+ sptrv=spu->imagev+y/2*spu->strideuv;
+ saptr=spu->aimage+y*spu->stride;
+ saptruv=spu->aimageuv+y/2*spu->strideuv;
+ for(x=0;x<spu->widthuv-1;x++) {
+ *dptr++=*sptry++;
+ *dptr++=*sptrv++;
+ *dptr++=*sptry++;
+ *dptr++=*sptru++;
+ *daptr++=*saptr++;
+ *daptr++=*saptruv;
+ *daptr++=*saptr++;
+ *daptr++=*saptruv++;
+ }
+ }
+ }
+}
+
+
void spudec_draw(void *this, void (*draw_alpha)(int x0,int y0, int w,int h, int dp, unsigned char* src, unsigned char *srca, int stride))
{
spudec_handle_t *spu = (spudec_handle_t *)this;
if (spu->start_pts <= spu->now_pts && spu->now_pts < spu->end_pts && spu->image)
{
+ switch(spu->colorspu) {
+ case COLORSPU_YUY:
+ if (!spu->imageyuy) spudec_create_yuy(spu,0);
+ if (spu->imageyuy)
+ draw_alpha(spu->start_col, spu->start_row, spu->width*2, spu->height/2,
+ DEST_PLANES_YUYV, spu->imageyuy, spu->aimageyuy, spu->strideyuy);
+ break;
+ case COLORSPU_YUV:
+ draw_alpha(spu->start_col, spu->start_row, spu->width, spu->height,
+ DEST_PLANES_Y, spu->image, spu->aimage, spu->stride);
+ draw_alpha(spu->start_coluv, spu->start_rowuv, spu->widthuv, spu->heightuv,
+ DEST_PLANES_U, spu->imageu, spu->aimageuv, spu->strideuv);
+ draw_alpha(spu->start_coluv, spu->start_rowuv, spu->widthuv, spu->heightuv,
+ DEST_PLANES_V, spu->imagev, spu->aimageuv, spu->strideuv);
+ break;
+ case COLORSPU_RGB:
+ case COLORSPU_BGR:
+ draw_alpha(spu->start_col, spu->start_row, spu->width, spu->height,
+ DEST_PLANES_BR, spu->imagev, spu->aimage, spu->stride);
+ draw_alpha(spu->start_col, spu->start_row, spu->width, spu->height,
+ DEST_PLANES_G, spu->imageu, spu->aimage, spu->stride);
+ draw_alpha(spu->start_col, spu->start_row, spu->width, spu->height,
+ DEST_PLANES_RB, spu->image, spu->aimage, spu->stride);
+ break;
+ default:
draw_alpha(spu->start_col, spu->start_row, spu->width, spu->height,
DEST_PLANES_Y, spu->image, spu->aimage, spu->stride);
+ }
spu->spu_changed = 0;
}
}
@@ -1251,8 +1344,34 @@
|| (spu->orig_frame_width == dxs && spu->orig_frame_height == dys))) {
if (spu->image)
{
+ switch(spu->colorspu) {
+ case COLORSPU_YUY:
+ if (!spu->imageyuy) spudec_create_yuy(spu,0);
+ if (spu->imageyuy)
+ draw_alpha(spu->start_col, spu->start_row, spu->width*2, spu->height/2,
+ DEST_PLANES_YUYV, spu->imageyuy, spu->aimageyuy, spu->strideyuy);
+ break;
+ case COLORSPU_YUV:
+ draw_alpha(spu->start_col, spu->start_row, spu->width, spu->height,
+ DEST_PLANES_Y, spu->image, spu->aimage, spu->stride);
+ draw_alpha(spu->start_coluv, spu->start_rowuv, spu->widthuv, spu->heightuv,
+ DEST_PLANES_U, spu->imageu, spu->aimageuv, spu->strideuv);
+ draw_alpha(spu->start_coluv, spu->start_rowuv, spu->widthuv, spu->heightuv,
+ DEST_PLANES_V, spu->imagev, spu->aimageuv, spu->strideuv);
+ break;
+ case COLORSPU_RGB:
+ case COLORSPU_BGR:
+ draw_alpha(spu->start_col, spu->start_row, spu->width, spu->height,
+ DEST_PLANES_BR, spu->imagev, spu->aimage, spu->stride);
+ draw_alpha(spu->start_col, spu->start_row, spu->width, spu->height,
+ DEST_PLANES_G, spu->imageu, spu->aimage, spu->stride);
+ draw_alpha(spu->start_col, spu->start_row, spu->width, spu->height,
+ DEST_PLANES_RB, spu->image, spu->aimage, spu->stride);
+ break;
+ default:
draw_alpha(spu->start_col, spu->start_row, spu->width, spu->height,
DEST_PLANES_Y, spu->image, spu->aimage, spu->stride);
+ }
spu->spu_changed = 0;
}
}
@@ -1267,11 +1386,23 @@
spu->scaled_start_row = spu->start_row * scaley / 0x100;
spu->scaled_width = spu->width * scalex / 0x100;
spu->scaled_height = spu->height * scaley / 0x100;
+ switch(spu->colorspu) {
+ case COLORSPU_YUV:
+ case COLORSPU_YUY:
+ spu->scaled_widthuv = spu->widthuv * scalex / 0x100;
+ spu->scaled_heightuv = spu->heightuv * scaley / 0x100;
+ spu->scaled_strideuv = (spu->scaled_widthuv + 7) & ~7;
+ spu->scaled_start_coluv = spu->start_coluv * scalex / 0x100;
+ spu->scaled_start_rowuv = spu->start_rowuv * scaley / 0x100;
+ break;
+ }
/* Kludge: draw_alpha needs width multiple of 8 */
spu->scaled_stride = (spu->scaled_width + 7) & ~7;
if (spu->scaled_image_size < spu->scaled_stride * spu->scaled_height) {
if (spu->scaled_image) {
free(spu->scaled_image);
+ if (spu->scaled_imageu)
+ free(spu->scaled_imageu);
spu->scaled_image_size = 0;
}
spu->scaled_image = malloc(2 * spu->scaled_stride * spu->scaled_height);
@@ -1280,15 +1411,67 @@
spu->scaled_aimage = spu->scaled_image + spu->scaled_image_size;
}
}
+ switch(spu->colorspu) {
+ case COLORSPU_YUV:
+ case COLORSPU_YUY:
+ spu->scaled_imageu = malloc(3 * spu->scaled_strideuv *
+ (spu->scaled_height+2));
+ if (spu->scaled_imageu) {
+ memset(spu->scaled_imageu,0,3 * spu->scaled_strideuv *
+ (spu->scaled_height+2));
+ spu->scaled_image_sizeuv = spu->scaled_strideuv *
+ (spu->scaled_heightuv+2);
+ spu->scaled_imagev = spu->scaled_imageu +
+ spu->scaled_image_sizeuv;
+ spu->scaled_aimageuv = spu->scaled_imagev +
+ spu->scaled_image_sizeuv;
+ }
+ break;
+ case COLORSPU_RGB:
+ case COLORSPU_BGR:
+ spu->scaled_imageu = malloc(3 * spu->scaled_stride * spu->scaled_height);
+ if (spu->scaled_imageu)
+ spu->scaled_imagev = spu->scaled_imageu + spu->scaled_image_size;
+ break;
+ }
if (spu->scaled_image) {
unsigned int y;
if (spu->scaled_width > 1 && spu->scaled_height > 1)
+ switch(spu->colorspu) {
+ case COLORSPU_YUV:
+ case COLORSPU_YUY:
+ if (spu->scaled_widthuv <= 1 || spu->scaled_heightuv <= 1) {
aa_scaler(spu_aamode&15, spu->width, spu->height, dxs, dys,
spu->orig_frame_width, spu->orig_frame_height,spu->stride,
spu->scaled_width, spu->scaled_height, spu->scaled_stride,
scalex, scaley,
spu->image, spu->aimage, NULL, NULL,
spu->scaled_image, spu->scaled_aimage, NULL, NULL);
+ aa_scaler(spu_aamode&15, spu->widthuv, spu->heightuv, dxs/2, dys/2,
+ spu->orig_frame_width/2, spu->orig_frame_height/2, spu->strideuv,
+ spu->scaled_widthuv, spu->scaled_heightuv, spu->scaled_strideuv,
+ scalex, scaley,
+ spu->imageu, spu->aimage, spu->imagev, NULL,
+ spu->scaled_imageu, spu->scaled_aimage, spu->scaled_imagev, NULL);
+ }
+ break;
+ case COLORSPU_RGB:
+ case COLORSPU_BGR:
+ aa_scaler(spu_aamode&15, spu->width, spu->height, dxs, dys,
+ spu->orig_frame_width, spu->orig_frame_height, spu->stride,
+ spu->scaled_width, spu->scaled_height, spu->scaled_stride,
+ scalex, scaley,
+ spu->image, spu->aimage, spu->imageu, spu->imagev,
+ spu->scaled_image, spu->scaled_aimage, spu->scaled_imageu, spu->scaled_imagev);
+ break;
+ default:
+ aa_scaler(spu_aamode&15, spu->width, spu->height, dxs, dys,
+ spu->orig_frame_width, spu->orig_frame_height, spu->stride,
+ spu->scaled_width, spu->scaled_height, spu->scaled_stride,
+ scalex, scaley,
+ spu->image, spu->aimage, NULL, NULL,
+ spu->scaled_image, spu->scaled_aimage, NULL, NULL);
+ }
/* Kludge: draw_alpha needs width multiple of 8. */
if (spu->scaled_width < spu->scaled_stride)
for (y = 0; y < spu->scaled_height; ++y) {
@@ -1297,6 +1480,16 @@
}
spu->scaled_frame_width = dxs;
spu->scaled_frame_height = dys;
+ if (spu->colorspu==COLORSPU_YUY || spu->colorspu==COLORSPU_YUV) {
+ if (spu->scaled_widthuv < spu->scaled_strideuv)
+ for (y = 0; y < spu->scaled_heightuv; ++y) {
+ memset(spu->scaled_aimageuv + y * spu->scaled_stride +
+ spu->scaled_widthuv, 0,
+ spu->scaled_strideuv - spu->scaled_widthuv);
+ }
+ spu->scaled_frame_widthuv = dxs/2;
+ spu->scaled_frame_heightuv = dys/2;
+ }
}
}
if (spu->scaled_image){
@@ -1305,18 +1498,60 @@
spu->scaled_start_row = dys*sub_pos/100;
if (spu->scaled_start_row + spu->scaled_height > dys)
spu->scaled_start_row = dys - spu->scaled_height;
+ if (spu->colorspu==COLORSPU_YUY || spu->colorspu==COLORSPU_YUV) {
+ spu->scaled_start_rowuv = (dys/2)*sub_pos/100;
+ if (spu->scaled_start_rowuv + spu->scaled_heightuv > (dys/2))
+ spu->scaled_start_rowuv = (dys/2) - spu->scaled_heightuv;
+ }
break;
case 1:
spu->scaled_start_row = dys*sub_pos/100 - spu->scaled_height/2;
if (sub_pos >= 50 && spu->scaled_start_row + spu->scaled_height > dys)
spu->scaled_start_row = dys - spu->scaled_height;
+ if (spu->colorspu==COLORSPU_YUY || spu->colorspu==COLORSPU_YUV) {
+ spu->scaled_start_rowuv = (dys/2)*sub_pos/100 - spu->scaled_heightuv/2;
+ if (sub_pos < 50) {
+ if (spu->scaled_start_rowuv < 0) spu->scaled_start_rowuv = 0;
+ } else {
+ if (spu->scaled_start_rowuv + spu->scaled_heightuv > (dys/2))
+ spu->scaled_start_rowuv = (dys/2) - spu->scaled_heightuv;
+ }
+ }
break;
case 2:
spu->scaled_start_row = dys*sub_pos/100 - spu->scaled_height;
+ if (spu->colorspu==COLORSPU_YUY || spu->colorspu==COLORSPU_YUV)
+ spu->scaled_start_rowuv = (dys/2)*sub_pos/100 - spu->scaled_heightuv;
break;
}
+ switch(spu->colorspu) {
+ case COLORSPU_YUY:
+ if (!spu->imageyuy) spudec_create_yuy(spu,1);
+ if (spu->imageyuy)
+ draw_alpha(spu->start_col, spu->start_row, spu->width*2, spu->height/2,
+ DEST_PLANES_YUYV, spu->imageyuy, spu->aimageyuy, spu->strideyuy);
+ break;
+ case COLORSPU_YUV:
draw_alpha(spu->scaled_start_col, spu->scaled_start_row, spu->scaled_width, spu->scaled_height,
DEST_PLANES_Y, spu->scaled_image, spu->scaled_aimage, spu->scaled_stride);
+ draw_alpha(spu->scaled_start_coluv, spu->scaled_start_rowuv, spu->scaled_widthuv, spu->scaled_heightuv,
+ DEST_PLANES_U, spu->scaled_imageu, spu->scaled_aimageuv, spu->scaled_strideuv);
+ draw_alpha(spu->scaled_start_coluv, spu->scaled_start_rowuv, spu->scaled_widthuv, spu->scaled_heightuv,
+ DEST_PLANES_V, spu->scaled_imagev, spu->scaled_aimageuv, spu->scaled_strideuv);
+ break;
+ case COLORSPU_RGB:
+ case COLORSPU_BGR:
+ draw_alpha(spu->scaled_start_col, spu->scaled_start_row, spu->scaled_width, spu->scaled_height,
+ DEST_PLANES_BR, spu->scaled_imagev, spu->scaled_aimage, spu->scaled_stride);
+ draw_alpha(spu->scaled_start_col, spu->scaled_start_row, spu->scaled_width, spu->scaled_height,
+ DEST_PLANES_G, spu->scaled_imageu, spu->scaled_aimage, spu->scaled_stride);
+ draw_alpha(spu->scaled_start_col, spu->scaled_start_row, spu->scaled_width, spu->scaled_height,
+ DEST_PLANES_RB, spu->scaled_image, spu->scaled_aimage, spu->scaled_stride);
+ break;
+ default:
+ draw_alpha(spu->scaled_start_col, spu->scaled_start_row, spu->scaled_width, spu->scaled_height,
+ DEST_PLANES_Y, spu->scaled_image, spu->scaled_aimage, spu->scaled_stride);
+ }
spu->spu_changed = 0;
}
}
--- spudec.c 2008-05-27 22:04:11.000000000 +0200
+++ spudec.c 2008-05-27 21:02:42.000000000 +0200
@@ -2032,3 +2032,39 @@
spu->hw_spu = hw_spu;
hw_spu->control(VOCTRL_SET_SPU_PALETTE,spu->global_palette);
}
+
+void spudec_set_spu_format(void *this, uint32_t fmt)
+{
+ spudec_handle_t *spu = (spudec_handle_t*)this;
+ if (!spu)
+ return;
+ switch(fmt) {
+ case IMGFMT_YV12:
+ case IMGFMT_I420:
+ case IMGFMT_IYUV:
+ case IMGFMT_YVU9:
+ case IMGFMT_IF09:
+ case IMGFMT_Y800:
+ case IMGFMT_Y8:
+ spu->colorspu=COLORSPU_YUV;
+ break;
+ case IMGFMT_YUY2:
+ spu->colorspu=COLORSPU_YUY;
+ break;
+ case IMGFMT_RGB15:
+ case IMGFMT_RGB16:
+ case IMGFMT_RGB24:
+ case IMGFMT_RGB32:
+ spu->colorspu=COLORSPU_RGB;
+ break;
+ case IMGFMT_BGR15:
+ case IMGFMT_BGR16:
+ case IMGFMT_BGR24:
+ case IMGFMT_BGR32:
+ spu->colorspu=COLORSPU_BGR;
+ break;
+ case 0:
+ default:
+ spu->colorspu=COLORSPU_Y;
+ }
+}
--- spudec.h 2008-05-27 22:05:52.000000000 +0200
+++ spudec.h 2008-05-27 21:02:42.000000000 +0200
@@ -19,5 +19,6 @@
int spudec_changed(void *this);
void spudec_calc_bbox(void *me, unsigned int dxs, unsigned int dys, unsigned int* bbox);
void spudec_set_forced_subs_only(void * const this, const unsigned int flag);
+void spudec_set_spu_format(void *this, uint32_t fmt);
#endif /* MPLAYER_SPUDEC_H */
--- spudec.c 2008-05-27 20:59:50.000000000 +0200
+++ spudec.c 2008-05-27 22:04:11.000000000 +0200
@@ -117,6 +117,11 @@
unsigned int forced_subs_only; /* flag: 0=display all subtitle, !0 display only forced subtitles */
unsigned int is_forced_sub; /* true if current subtitle is a forced subtitle */
colorspu_t colorspu; /* spu color mode */
+ uint32_t dvdnav_palette; /* dvdnav menu button palette */
+ unsigned int spu_sx; /* dvdnav menu item box */
+ unsigned int spu_ex;
+ unsigned int spu_sy;
+ unsigned int spu_ey;
} spudec_handle_t;
static void spudec_queue_packet(spudec_handle_t *this, packet_t *packet)
@@ -236,11 +241,145 @@
} else {
mp_msg(MSGT_SPUDEC, MSGL_FATAL, "Fatal: update_spu: malloc requested %d bytes\n", 2 * this->stride * this->height);
}
+//
+// Cut the sub to visible part UV planes
+//
+ unsigned char *imageu;
+ unsigned char *imagev;
+ switch (this->colorspu) {
+ case COLORSPU_YUV:
+ case COLORSPU_YUY:
+ for (fy = 0; fy < this->image_sizeuv && !this->aimageuv[fy]; fy++);
+ for (ly = this->strideuv * this->heightuv-1;
+ ly && !this->aimageuv[ly]; ly--);
+ first_y = fy / this->strideuv;
+ last_y = ly / this->strideuv;
+ this->start_rowuv += first_y;
+ // Some subtitles trigger this condition
+ if (last_y + 1 > first_y ) {
+ this->heightuv = last_y - first_y +1;
+ } else {
+ this->heightuv = 0;
+ this->image_sizeuv = 0;
+ return;
+ }
+ // printf("new h %d new start %d (sz %d st %d)---\n\n", this->height, this->start_row, this->image_size, this->stride);
+ imageu = malloc(3 * this->strideuv * this->heightuv);
+ if(imageu){
+ this->image_sizeuv = this->strideuv * this->heightuv;
+ imagev = imageu + this->image_sizeuv;
+ aimage = imagev + this->image_sizeuv;
+ memcpy(imageu, this->imageu + this->strideuv * first_y,
+ this->image_sizeuv);
+ memcpy(imagev, this->imagev + this->strideuv * first_y,
+ this->image_sizeuv);
+ memcpy(aimage, this->aimageuv + this->strideuv * first_y,
+ this->image_sizeuv);
+ free(this->imageu);
+ this->imageu = imageu;
+ this->imagev = imagev;
+ this->aimageuv = aimage;
+ } else {
+ mp_msg(MSGT_SPUDEC, MSGL_FATAL,
+ "Fatal: update_spu: malloc requested %d bytes\n",
+ 3 * this->strideuv * this->height);
+ }
+ break;
+ case COLORSPU_RGB:
+ case COLORSPU_BGR:
+ this->image_sizeuv = this->stride * this->height;
+ imageu = malloc(2 * this->stride * this->height);
+ if(imageu){
+ imagev = imageu + this->image_size;
+ memcpy(imageu, this->imageu + this->stride * first_y, this->image_size);
+ memcpy(imagev, this->imagev + this->stride * first_y, this->image_size);
+ free(this->imageu);
+ this->imageu = imageu;
+ this->imagev = imagev;
+ this->aimageuv = NULL;
+ } else {
+ mp_msg(MSGT_SPUDEC, MSGL_FATAL,
+ "Fatal: update_spu: malloc requested %d bytes\n",
+ 2 * this->stride * this->height);
+ }
+ break;
+ }
+}
+
+//
+// Fill to spu image buffer
+// y : image col
+// x : start pos in image row
+// len : fill length in image row
+// color : Y: (YUV,YUY,Y), Red: (RGB) or Blue: (BGR)
+// coloru: U: (YUV,YUY), Green: (RGB,BGR)
+// colorv: V: (YUV,YUY), Blue: (RGB) or Red (BGR)
+// alpha: alpha channel
+static void spudec_process_fill(spudec_handle_t *this, int x, int y, int len,
+ unsigned char color, unsigned char coloru, unsigned char colorv,
+ unsigned char alpha)
+{
+ unsigned int corrx, corry, corrl;
+
+ if (this->stride-x-len<0) return;
+ if (len<0) return;
+ switch (this->colorspu) {
+ case COLORSPU_YUV:
+ case COLORSPU_YUY:
+ corry=y & 0x01;
+ corrx=x & 0x01;
+ corrl=len & 0x01;
+ memset(this->image + y * this->stride + x, color, len);
+ memset(this->aimage + y * this->stride + x, alpha, len);
+ memset(this->imageu + (y-corry)/2 * this->strideuv + (x+corrx)/2, coloru,
+ (len-corrl)/2);
+ memset(this->imagev + (y-corry)/2 * this->strideuv + (x+corrx)/2, colorv,
+ (len-corrl)/2);
+ memset(this->aimageuv + (y-corry)/2 * this->strideuv + (x+corrx)/2, alpha,
+ (len-corrl)/2);
+ break;
+ case COLORSPU_RGB:
+ case COLORSPU_BGR:
+ memset(this->image + y * this->stride + x, color, len);
+ memset(this->imageu + y * this->stride + x, coloru, len);
+ memset(this->imagev + y * this->stride + x, colorv, len);
+ memset(this->aimage + y * this->stride + x, alpha, len);
+ break;
+ default:
+ memset(this->image + y * this->stride + x, color, len);
+ memset(this->aimage + y * this->stride + x, alpha, len);
+ break;
+ }
+}
+
+//
+// Convert yuv color to rgb color
+//
+void spu_yuv_to_rgb(unsigned int y,unsigned int u,unsigned int v,
+ unsigned int *r,unsigned int *g,unsigned int *b)
+{
+ int ty,tu,tv;
+ int tr,tg,tb;
+
+ ty=y;tv=u;tu=v;
+ tr = (298*(ty-16)+408*(tv-128))/256;
+ tg = (298*(ty-16)-100*(tu-128)-208*(tv-128))/256;
+ tb = (298*(ty-16)+516*(tu-128))/256;
+ if(tr>255) tr=255; if(tr<0) tr=0;
+ if(tg>255) tg=255; if(tg<0) tg=0;
+ if(tb>255) tb=255; if(tb<0) tb=0;
+ *r=tr; *g=tg; *b=tb;
+return;
}
static void spudec_process_data(spudec_handle_t *this, packet_t *packet)
{
unsigned int cmap[4], alpha[4];
+ unsigned int thpalette[4], thalpha[4]; /* dvdnav highlight menu palette */
+ unsigned int hcmap[4], halpha[4]; /* dvdnav highlight map */
+ unsigned int cmapu[4], cmapv[4];
+ unsigned int hcmapu[4], hcmapv[4];
+ unsigned int ty, tu, tv, tr, tg, tb;
unsigned int i, x, y;
this->scaled_frame_width = 0;
@@ -252,7 +391,136 @@
this->height = packet->height;
this->width = packet->width;
this->stride = packet->stride;
+ this->strideuv = packet->stride;
+
+ this->start_coluv = packet->start_col/2;
+ this->end_coluv = packet->end_col/2;
+ this->start_rowuv = packet->start_row/2;
+ this->end_rowuv = packet->end_row/2;
+ this->heightuv = packet->height/2+1;
+ this->widthuv = packet->width/2+1;
+
for (i = 0; i < 4; ++i) {
+ thalpha[i]=(this->dvdnav_palette >> ((3-i)*4)) & 0x0f;
+ thpalette[i]=(this->dvdnav_palette >> (16+(3-i)*4)) & 0x0f;
+ halpha[i] = mkalpha(thalpha[i]);
+ hcmap[i] = ((this->global_palette[thpalette[i]] >> 16) & 0xff);
+ alpha[i] = mkalpha(packet->alpha[i]);
+ if (this->custom && (this->cuspal[i] >> 31) != 0)
+ alpha[i] = 0;
+
+ switch(this->colorspu) {
+ case COLORSPU_YUV:
+ case COLORSPU_YUY:
+ if (alpha[i] == 0)
+ cmap[i] = cmapu[i] = cmapv[i] = 0;
+ else if (this->custom){
+ cmap[i] = ((this->cuspal[i] >> 16) & 0xff);
+ cmapu[i] = ((this->cuspal[i] >> 8) & 0xff);
+ cmapv[i] = ((this->cuspal[i] >> 0) & 0xff);
+ if (cmap[i] + alpha[i] > 255)
+ cmap[i] = 256 - alpha[i];
+ } else {
+ cmap[i] = ((this->global_palette[packet->palette[i]] >> 16) & 0xff);
+ cmapu[i] = ((this->global_palette[packet->palette[i]] >> 8) & 0xff);
+ cmapv[i] = ((this->global_palette[packet->palette[i]] >> 0) & 0xff);
+ if (cmap[i] + alpha[i] > 255)
+ cmap[i] = 256 - alpha[i];
+ }
+ if (halpha[i] == 0) {hcmap[i] = 0; hcmapu[i] = 0; hcmapv[i] = 0;} else {
+ if (hcmap[i] + halpha[i] > 255)
+ hcmap[i] = 256 - halpha[i];
+ hcmap[i] = ((this->global_palette[thpalette[i]] >> 16) & 0xff); // Y
+ hcmap[i] = ((0x100-halpha[i])*hcmap[i]) >> 8;
+ hcmapu[i] = ((this->global_palette[thpalette[i]] >> 8) & 0xff); // u
+ hcmapu[i] = ((0x100-halpha[i])*hcmapu[i]) >> 8;
+ hcmapv[i] = ((this->global_palette[thpalette[i]] >> 0) & 0xff); // v
+ hcmapv[i] = ((0x100-halpha[i])*hcmapv[i]) >> 8;
+ }
+ break;
+ case COLORSPU_RGB:
+ if (alpha[i] == 0)
+ cmap[i] = cmapu[i] = cmapv[i] = 0;
+ else if (this->custom){
+ ty = ((this->cuspal[i] >> 16) & 0xff);
+ tu = ((this->cuspal[i] >> 8) & 0xff);
+ tv = ((this->cuspal[i] >> 0) & 0xff);
+ spu_yuv_to_rgb(ty,tu,tv,&tr,&tg,&tb);
+ cmap[i] = tr; // Red
+ cmapu[i] = tg; // Green
+ cmapv[i] = tb; // Blue
+ cmap[i] = ((0x100-alpha[i])*cmap[i]) >> 8;
+ cmapu[i] = ((0x100-alpha[i])*cmapu[i]) >> 8;
+ cmapv[i] = ((0x100-alpha[i])*cmapv[i]) >> 8;
+ } else {
+ ty = ((this->global_palette[packet->palette[i]] >> 16) & 0xff);
+ tu = ((this->global_palette[packet->palette[i]] >> 8) & 0xff);
+ tv = ((this->global_palette[packet->palette[i]] >> 0) & 0xff);
+ spu_yuv_to_rgb(ty,tu,tv,&tr,&tg,&tb);
+ cmap[i] = tr; // Red
+ cmapu[i] = tg; // Green
+ cmapv[i] = tb; // Blue
+ cmap[i] = ((0x100-alpha[i])*cmap[i]) >> 8;
+ cmapu[i] = ((0x100-alpha[i])*cmapu[i]) >> 8;
+ cmapv[i] = ((0x100-alpha[i])*cmapv[i]) >> 8;
+ }
+ if (halpha[i] == 0) {hcmap[i] = 0; hcmapu[i] = 0; hcmapv[i] = 0;} else {
+ if (hcmap[i] + halpha[i] > 255)
+ hcmap[i] = 256 - halpha[i];
+ ty = ((this->global_palette[thpalette[i]] >> 16) & 0xff); // Y
+ tu = ((this->global_palette[thpalette[i]] >> 8) & 0xff); // u
+ tv = ((this->global_palette[thpalette[i]] >> 0) & 0xff); // v
+ spu_yuv_to_rgb(ty,tu,tv,&tr,&tg,&tb);
+ hcmap[i] = tr;
+ hcmapu[i] = tg;
+ hcmapv[i] = tb;
+ hcmap[i] = ((0x100-halpha[i])*hcmap[i]) >> 8;
+ hcmapu[i] = ((0x100-halpha[i])*hcmapu[i]) >> 8;
+ hcmapv[i] = ((0x100-halpha[i])*hcmapv[i]) >> 8;
+ }
+ break;
+ case COLORSPU_BGR:
+ if (alpha[i] == 0)
+ cmap[i] = cmapu[i] = cmapv[i] = 0;
+ else if (this->custom){
+ ty = ((this->cuspal[i] >> 16) & 0xff);
+ tu = ((this->cuspal[i] >> 8) & 0xff);
+ tv = ((this->cuspal[i] >> 0) & 0xff);
+ spu_yuv_to_rgb(ty,tu,tv,&tr,&tg,&tb);
+ cmap[i] = tb; // Red
+ cmapu[i] = tg; // Green
+ cmapv[i] = tr; // Blue
+ cmap[i] = ((0x100-alpha[i])*cmap[i]) >> 8;
+ cmapu[i] = ((0x100-alpha[i])*cmapu[i]) >> 8;
+ cmapv[i] = ((0x100-alpha[i])*cmapv[i]) >> 8;
+ } else {
+ ty = ((this->global_palette[packet->palette[i]] >> 16) & 0xff);
+ tu = ((this->global_palette[packet->palette[i]] >> 8) & 0xff);
+ tv = ((this->global_palette[packet->palette[i]] >> 0) & 0xff);
+ spu_yuv_to_rgb(ty,tu,tv,&tr,&tg,&tb);
+ cmap[i] = tb; // Red
+ cmapu[i] = tg; // Green
+ cmapv[i] = tr; // Blue
+ cmap[i] = ((0x100-alpha[i])*cmap[i]) >> 8;
+ cmapu[i] = ((0x100-alpha[i])*cmapu[i]) >> 8;
+ cmapv[i] = ((0x100-alpha[i])*cmapv[i]) >> 8;
+ }
+ if (halpha[i] == 0) {hcmap[i] = 0; hcmapu[i] = 0; hcmapv[i] = 0;} else {
+ if (hcmap[i] + halpha[i] > 255)
+ hcmap[i] = 256 - halpha[i];
+ ty = ((this->global_palette[thpalette[i]] >> 16) & 0xff); // Y
+ tu = ((this->global_palette[thpalette[i]] >> 8) & 0xff); // u
+ tv = ((this->global_palette[thpalette[i]] >> 0) & 0xff); // v
+ spu_yuv_to_rgb(ty,tu,tv,&tr,&tg,&tb);
+ hcmap[i] = tb;
+ hcmapu[i] = tg;
+ hcmapv[i] = tr;
+ hcmap[i] = ((0x100-halpha[i])*hcmap[i]) >> 8;
+ hcmapu[i] = ((0x100-halpha[i])*hcmapu[i]) >> 8;
+ hcmapv[i] = ((0x100-halpha[i])*hcmapv[i]) >> 8;
+ }
+ break;
+ default:
alpha[i] = mkalpha(packet->alpha[i]);
if (this->custom && (this->cuspal[i] >> 31) != 0)
alpha[i] = 0;
@@ -269,6 +537,7 @@
cmap[i] = 256 - alpha[i];
}
}
+ }
if (this->image_size < this->stride * this->height) {
if (this->image != NULL) {
@@ -292,6 +561,52 @@
memset(this->image + y * this->stride + this->width, 0, this->stride - this->width);
}
+ if (this->imageyuy) {
+ free(this->imageyuy);
+ this->imageyuy=NULL;
+ this->aimageyuy=NULL;
+ }
+ switch(this->colorspu) {
+ case COLORSPU_YUY:
+ case COLORSPU_YUV:
+ if (this->image_sizeuv < this->strideuv * this->heightuv) {
+ if (this->imageu != NULL) {
+ free(this->imageu);
+ this->image_sizeuv = 0;
+ }
+ this->imageu = malloc(3 * this->strideuv * this->heightuv);
+ if (this->imageu) {
+ this->image_sizeuv = this->strideuv * this->heightuv;
+ this->imagev = this->imageu + this->image_sizeuv;
+ this->aimageuv = this->imagev + this->image_sizeuv;
+ }
+ }
+ if (this->imageu == NULL) return;
+ memset(this->imageu,0,3 * this->strideuv * this->heightuv);
+ break;
+ case COLORSPU_RGB:
+ case COLORSPU_BGR:
+ if (this->image_sizeuv < this->stride * this->height) {
+ if (this->imageu != NULL) {
+ free(this->imageu);
+ this->image_sizeuv = 0;
+ }
+ this->imageu = malloc(2 * this->stride * this->height);
+ if (this->imageu) {
+ this->image_sizeuv = this->stride * this->height;
+ this->imagev = this->imageu + this->image_sizeuv;
+ this->aimageuv = this->imagev + this->image_sizeuv;
+ }
+ }
+ if (this->imageu == NULL) return;
+ memset(this->imageu,0,2 * this->stride * this->height);
+ break;
+ default:
+ if (this->imageu) free(this->imageu);
+ this->imageu=NULL;
+ this->image_sizeuv=0;
+ }
+
i = packet->current_nibble[1];
x = 0;
y = 0;
@@ -317,8 +632,71 @@
if (len > this->width - x || len == 0)
len = this->width - x;
/* FIXME have to use palette and alpha map*/
+ switch(this->colorspu) {
+ case COLORSPU_YUV:
+ case COLORSPU_YUY:
+ case COLORSPU_RGB:
+ case COLORSPU_BGR:
+ if (!this->spu_sx && !this->spu_sy &&!this->spu_ex && !this->spu_ey) {
+ spudec_process_fill(this, x, y, len,
+ cmap[color], cmapu[color],
+ cmapv[color], alpha[color]);
+ } else {
+ if (this->start_row+y>=this->spu_sy &&
+ this->start_row+y<=this->spu_ey) {
+ if (this->start_col+x>=this->spu_sx &&
+ this->start_col+x+len<=this->spu_ex)
+ spudec_process_fill(this, x, y, len,
+ hcmap[color], hcmapu[color],
+ hcmapv[color], halpha[color]);
+ else if(this->start_col+x<this->spu_sx &&
+ this->start_col+x+len>this->spu_sx &&
+ this->start_col+x+len<=this->spu_ex) {
+ spudec_process_fill(this, x, y, this->spu_sx-this->start_col-x,
+ cmap[color], cmapu[color],
+ cmapv[color], alpha[color]);
+ spudec_process_fill(this, this->spu_sx-this->start_col, y,
+ len+this->start_col+x-this->spu_sx,
+ hcmap[color], hcmapu[color],
+ hcmapv[color], halpha[color]);
+ } else if(this->start_col+x<this->spu_sx &&
+ this->start_col+x+len>this->spu_sx &&
+ this->start_col+x+len>this->spu_ex) {
+ spudec_process_fill(this, x, y, this->spu_sx-this->start_col-x,
+ cmap[color], cmapu[color],
+ cmapv[color], alpha[color]);
+ spudec_process_fill(this, this->spu_sx-this->start_col, y,
+ this->spu_ex-this->spu_sx,
+ hcmap[color], hcmapu[color],
+ hcmapv[color], halpha[color]);
+ spudec_process_fill(this, this->spu_ex-this->start_col, y,
+ x+len+this->start_col-this->spu_ex,
+ cmap[color], cmapu[color],
+ cmapv[color], alpha[color]);
+ } else if(this->start_col+x>=this->spu_sx &&
+ this->start_col+x<this->spu_ex &&
+ this->start_col+x+len>this->spu_ex) {
+ spudec_process_fill(this, x, y, this->spu_ex-this->start_col-x,
+ hcmap[color], hcmapu[color],
+ hcmapv[color], halpha[color]);
+ spudec_process_fill(this, this->spu_ex-this->start_col, y,
+ len+this->start_col+x-this->spu_ex,
+ cmap[color], cmapu[color],
+ cmapv[color], alpha[color]);
+ } else
+ spudec_process_fill(this, x, y, len,
+ cmap[color], cmapu[color],
+ cmapv[color], alpha[color]);
+ } else
+ spudec_process_fill(this, x, y, len,
+ cmap[color], cmapu[color],
+ cmapv[color], alpha[color]);
+ }
+ break;
+ default:
memset(this->image + y * this->stride + x, cmap[color], len);
memset(this->aimage + y * this->stride + x, alpha[color], len);
+ }
x += len;
if (x >= this->width) {
next_line(packet);
@@ -626,7 +1004,7 @@
packet_t *packet = spudec_dequeue_packet(spu);
spu->start_pts = packet->start_pts;
spu->end_pts = packet->end_pts;
- if (spu->auto_palette)
+ if (spu->auto_palette && spu->colorspu==COLORSPU_Y)
compute_palette(spu, packet);
spudec_process_data(spu, packet);
spudec_free_packet(packet);
--- spudec.c 2008-05-27 20:30:34.000000000 +0200
+++ spudec.c 2008-05-27 20:31:18.000000000 +0200
@@ -738,33 +738,60 @@
}
/* bilinear scale, similar to vobsub's code */
-static void scale_image(int x, int y, scale_pixel* table_x, scale_pixel* table_y, spudec_handle_t * spu)
+static void scale_image(int x, int y, scale_pixel* table_x, scale_pixel* table_y,
+ int src_stride, int dst_stride,
+ unsigned char *src_y, unsigned char *src_a,
+ unsigned char *src_u, unsigned char *src_v,
+ unsigned char *dst_y, unsigned char *dst_a,
+ unsigned char *dst_u, unsigned char *dst_v)
{
int alpha[4];
int color[4];
+ int coloru[4];
+ int colorv[4];
unsigned int scale[4];
- int base = table_y[y].position * spu->stride + table_x[x].position;
- int scaled = y * spu->scaled_stride + x;
- alpha[0] = canon_alpha(spu->aimage[base]);
- alpha[1] = canon_alpha(spu->aimage[base + 1]);
- alpha[2] = canon_alpha(spu->aimage[base + spu->stride]);
- alpha[3] = canon_alpha(spu->aimage[base + spu->stride + 1]);
- color[0] = spu->image[base];
- color[1] = spu->image[base + 1];
- color[2] = spu->image[base + spu->stride];
- color[3] = spu->image[base + spu->stride + 1];
+ int base = table_y[y].position * src_stride + table_x[x].position;
+ int scaled = y * dst_stride + x;
+ alpha[0] = canon_alpha(src_a[base]);
+ alpha[1] = canon_alpha(src_a[base + 1]);
+ alpha[2] = canon_alpha(src_a[base + src_stride]);
+ alpha[3] = canon_alpha(src_a[base + src_stride + 1]);
+ color[0] = src_y[base];
+ color[1] = src_y[base + 1];
+ color[2] = src_y[base + src_stride];
+ color[3] = src_y[base + src_stride + 1];
+ if(src_u) {
+ coloru[0] = src_u[base];
+ coloru[1] = src_u[base + 1];
+ coloru[2] = src_u[base + src_stride];
+ coloru[3] = src_u[base + src_stride + 1];
+ }
+ if(src_v) {
+ colorv[0] = src_v[base];
+ colorv[1] = src_v[base + 1];
+ colorv[2] = src_v[base + src_stride];
+ colorv[3] = src_v[base + src_stride + 1];
+ }
scale[0] = (table_x[x].left_up * table_y[y].left_up >> 16) * alpha[0];
if (table_y[y].left_up == 0x10000) // necessary to avoid overflow-case
scale[0] = table_x[x].left_up * alpha[0];
scale[1] = (table_x[x].right_down * table_y[y].left_up >>16) * alpha[1];
scale[2] = (table_x[x].left_up * table_y[y].right_down >> 16) * alpha[2];
scale[3] = (table_x[x].right_down * table_y[y].right_down >> 16) * alpha[3];
- spu->scaled_image[scaled] = (color[0] * scale[0] + color[1] * scale[1] + color[2] * scale[2] + color[3] * scale[3])>>24;
- spu->scaled_aimage[scaled] = (scale[0] + scale[1] + scale[2] + scale[3]) >> 16;
- if (spu->scaled_aimage[scaled]){
- spu->scaled_aimage[scaled] = 256 - spu->scaled_aimage[scaled];
- if(spu->scaled_aimage[scaled] + spu->scaled_image[scaled] > 255)
- spu->scaled_image[scaled] = 256 - spu->scaled_aimage[scaled];
+ dst_y[scaled] = (color[0] * scale[0] + color[1] * scale[1] + color[2] * scale[2] + color[3] * scale[3])>>24;
+ if(src_u)
+ dst_u[scaled] = (coloru[0] * scale[0] + coloru[1] * scale[1] + coloru[2] * scale[2] + coloru[3] * scale[3])>>24;
+ if(src_v)
+ dst_v[scaled] = (colorv[0] * scale[0] + colorv[1] * scale[1] + colorv[2] * scale[2] + colorv[3] * scale[3])>>24;
+ dst_a[scaled] = (scale[0] + scale[1] + scale[2] + scale[3]) >> 16;
+ if (dst_a[scaled]){
+ dst_a[scaled] = 256 - dst_a[scaled];
+ if(dst_a[scaled] + dst_y[scaled] > 255)
+ dst_y[scaled] = 256 - dst_a[scaled];
+ if(src_u && dst_a[scaled] + dst_u[scaled] > 255)
+ dst_u[scaled] = 256 - dst_a[scaled];
+ if(src_v && dst_a[scaled] + dst_v[scaled] > 255)
+ dst_v[scaled] = 256 - dst_a[scaled];
}
}
@@ -1055,23 +1082,32 @@
}
}
-void spu_scaled_bilinear(spudec_handle_t *spu, unsigned int dxs, unsigned int dys,
- unsigned int scalex, unsigned int scaley)
+void spu_scaled_bilinear(int width, int height,
+ int src_stride,
+ int dst_width, int dst_height, int dst_stride,
+ unsigned int scalex, unsigned int scaley,
+ unsigned char *src_y, unsigned char *src_a,
+ unsigned char *src_u, unsigned char *src_v,
+ unsigned char *dst_y, unsigned char *dst_a,
+ unsigned char *dst_u, unsigned char *dst_v)
{
unsigned int x, y;
scale_pixel *table_x;
scale_pixel *table_y;
- table_x = calloc(spu->scaled_width, sizeof(scale_pixel));
- table_y = calloc(spu->scaled_height, sizeof(scale_pixel));
+ table_x = calloc(dst_width, sizeof(scale_pixel));
+ table_y = calloc(dst_height, sizeof(scale_pixel));
if (!table_x || !table_y) {
mp_msg(MSGT_SPUDEC, MSGL_FATAL, "Fatal: spudec_draw_scaled: calloc failed\n");
}
- scale_table(0, 0, spu->width - 1, spu->scaled_width - 1, table_x);
- scale_table(0, 0, spu->height - 1, spu->scaled_height - 1, table_y);
- for (y = 0; y < spu->scaled_height; y++)
- for (x = 0; x < spu->scaled_width; x++)
- scale_image(x, y, table_x, table_y, spu);
+ scale_table(0, 0, width - 1, dst_width - 1, table_x);
+ scale_table(0, 0, height - 1, dst_height - 1, table_y);
+ for (y = 0; y < dst_height; y++)
+ for (x = 0; x < dst_width; x++)
+ scale_image(x, y, table_x, table_y,
+ src_stride, dst_stride,
+ src_y, src_a, src_u, src_v,
+ dst_y, dst_a, dst_u, dst_v);
free(table_x);
free(table_y);
}
@@ -1100,7 +1136,12 @@
spu_scaled_sws(spu,dxs,dys,scalex,scaley);
break;
case 3:
- spu_scaled_bilinear(spu,dxs,dys,scalex,scaley);
+ spu_scaled_bilinear(width, height,
+ src_stride,
+ dst_width, dst_height, dst_stride,
+ scalex,scaley,
+ src_y, src_a, src_u, src_v,
+ dst_y, dst_a, dst_u, dst_v);
break;
case 0:
spu_scaled_none(dxs, dys,
_______________________________________________
MPlayer-dev-eng mailing list
MPlayer-dev-eng@xxxxxxxxxxxx
https://lists.mplayerhq.hu/mailman/listinfo/mplayer-dev-eng