summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGuenter Bartsch <guenter@users.sourceforge.net>2001-07-17 19:37:21 +0000
committerGuenter Bartsch <guenter@users.sourceforge.net>2001-07-17 19:37:21 +0000
commitd433cfadf1ec1a6f042727d3818d86aecd513586 (patch)
tree47ce7536357ae6544efa5049aa7661a3ce92cb70 /src
parentf071561aa3974d8d7ceba6fdab13668e92f624fd (diff)
downloadxine-lib-d433cfadf1ec1a6f042727d3818d86aecd513586.tar.gz
xine-lib-d433cfadf1ec1a6f042727d3818d86aecd513586.tar.bz2
yuy2 -> rgb conversion routines in C (no mlib/mmx yet)
CVS patchset: 299 CVS date: 2001/07/17 19:37:21
Diffstat (limited to 'src')
-rw-r--r--src/libw32dll/w32codec.c30
-rw-r--r--src/video_out/video_out_xshm.c49
-rw-r--r--src/video_out/yuv2rgb.c429
-rw-r--r--src/video_out/yuv2rgb.h5
4 files changed, 471 insertions, 42 deletions
diff --git a/src/libw32dll/w32codec.c b/src/libw32dll/w32codec.c
index 44030ce84..5e7b75856 100644
--- a/src/libw32dll/w32codec.c
+++ b/src/libw32dll/w32codec.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: w32codec.c,v 1.10 2001/07/14 16:55:11 guenter Exp $
+ * $Id: w32codec.c,v 1.11 2001/07/17 19:37:21 guenter Exp $
*
* routines for using w32 codecs
*
@@ -325,21 +325,29 @@ static void w32v_decode_data (video_decoder_t *this_gen, buf_element_t *buf) {
img->bFrameBad = 0;
if (img->copy) {
-#warning: need to check 'dest' stuff for the YUY2 case
/* note: dest stuff works with video_out_xshm & YV12 */
int height = abs(this->o_bih.biHeight);
int stride = this->o_bih.biWidth;
- uint8_t* dest[3];
+ uint8_t* src[3];
- dest[0] = img->base[0];
- dest[2] = dest[0] + height * this->o_bih.biWidth;
- dest[1] = dest[2] + height * this->o_bih.biWidth / 4;
- while ((height -= 16) >= 0) {
- img->copy(img, dest);
- dest[0] += 16 * stride;
- dest[1] += 4 * stride;
- dest[2] += 4 * stride;
+ if (this->outfmt == IMGFMT_YUY2) {
+ src[0] = img->base[0];
+
+ while ((height -= 16) >= 0) {
+ img->copy(img, src);
+ src[0] += 32 * stride;
+ }
+ } else {
+ src[0] = img->base[0];
+ src[2] = src[0] + height * this->o_bih.biWidth;
+ src[1] = src[2] + height * this->o_bih.biWidth / 4;
+ while ((height -= 16) >= 0) {
+ img->copy(img, src);
+ src[0] += 16 * stride;
+ src[1] += 4 * stride;
+ src[2] += 4 * stride;
+ }
}
}
diff --git a/src/video_out/video_out_xshm.c b/src/video_out/video_out_xshm.c
index 4f760eca9..485f4042a 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.18 2001/07/16 09:18:24 jkeil Exp $
+ * $Id: video_out_xshm.c,v 1.19 2001/07/17 19:37:21 guenter Exp $
*
* video_out_xshm.c, X11 shared memory extension interface for xine
*
@@ -71,9 +71,9 @@ typedef struct xshm_frame_s {
XImage *image;
uint8_t *rgb_dst;
int stripe_inc;
- int y_off, uv_off;
XShmSegmentInfo shminfo;
+ int format;
} xshm_frame_t;
typedef struct xshm_driver_s {
@@ -320,7 +320,7 @@ static inline uint64_t rdtsc()
*/
static uint32_t xshm_get_capabilities (vo_driver_t *this_gen) {
- return VO_CAP_COPIES_IMAGE | VO_CAP_YV12;
+ return VO_CAP_COPIES_IMAGE | VO_CAP_YV12 | VO_CAP_YUY2;
}
static void xshm_frame_copy (vo_frame_t *vo_img, uint8_t **src) {
@@ -332,11 +332,15 @@ static void xshm_frame_copy (vo_frame_t *vo_img, uint8_t **src) {
uint32_t cycles;
#endif
-
- this->yuv2rgb->yuv2rgb_fun (this->yuv2rgb, frame->rgb_dst,
- src[0]+frame->y_off,
- src[1]+frame->uv_off,
- src[2]+frame->uv_off);
+ if (frame->format == IMGFMT_YV12) {
+ this->yuv2rgb->yuv2rgb_fun (this->yuv2rgb, frame->rgb_dst,
+ src[0], src[1], src[2]);
+ } else {
+
+ this->yuv2rgb->yuy22rgb_fun (this->yuv2rgb, frame->rgb_dst,
+ src[0]);
+
+ }
#ifdef DETAILED_TIMING
cycles = rdtsc() - tsc;
@@ -347,7 +351,7 @@ static void xshm_frame_copy (vo_frame_t *vo_img, uint8_t **src) {
}
static void xshm_frame_field (vo_frame_t *vo_img, int which_field) {
- /* FIXME: implement */
+
xshm_frame_t *frame = (xshm_frame_t *) vo_img ;
xshm_driver_t *this = (xshm_driver_t *) vo_img->instance->driver;
@@ -355,8 +359,6 @@ static void xshm_frame_field (vo_frame_t *vo_img, int which_field) {
case 1:
frame->rgb_dst = frame->image->data;
frame->stripe_inc = 2*this->stripe_height * frame->image->bytes_per_line;
- frame->y_off = 0;
- frame->uv_off = 0;
yuv2rgb_setup (this->yuv2rgb,
this->delivered_width,
16,
@@ -370,8 +372,6 @@ static void xshm_frame_field (vo_frame_t *vo_img, int which_field) {
case 2:
frame->rgb_dst = frame->image->data + frame->image->bytes_per_line ;
frame->stripe_inc = 2*this->stripe_height * frame->image->bytes_per_line;
- frame->y_off = 0; /* this->delivered_width; FIXME ?!*/
- frame->uv_off = 0; /* this->delivered_width/2; */
yuv2rgb_setup (this->yuv2rgb,
this->delivered_width,
16,
@@ -383,8 +383,6 @@ static void xshm_frame_field (vo_frame_t *vo_img, int which_field) {
break;
case 3:
frame->rgb_dst = frame->image->data;
- frame->y_off = 0;
- frame->uv_off = 0;
break;
}
}
@@ -555,7 +553,8 @@ static void xshm_update_frame_format (vo_driver_t *this_gen,
|| (frame->rgb_height != this->output_height)
|| (frame->width != width)
|| (frame->height != height)
- || (frame->ratio_code != ratio_code)) {
+ || (frame->ratio_code != ratio_code)
+ || (frame->format != format)) {
int image_size;
@@ -570,7 +569,7 @@ static void xshm_update_frame_format (vo_driver_t *this_gen,
/*
printf ("video_out_xshm: updating frame to %d x %d\n",
this->output_width,this->output_height);
- */
+ */
XLockDisplay (this->display);
@@ -593,11 +592,17 @@ static void xshm_update_frame_format (vo_driver_t *this_gen,
XUnlockDisplay (this->display);
- image_size = width * height;
- frame->vo_frame.base[0] = xmalloc_aligned(16,image_size);
- frame->vo_frame.base[1] = xmalloc_aligned(16,image_size/4);
- frame->vo_frame.base[2] = xmalloc_aligned(16,image_size/4);
-
+ if (format == IMGFMT_YV12) {
+ image_size = width * height;
+ frame->vo_frame.base[0] = xmalloc_aligned(16,image_size);
+ frame->vo_frame.base[1] = xmalloc_aligned(16,image_size/4);
+ frame->vo_frame.base[2] = xmalloc_aligned(16,image_size/4);
+ } else {
+ image_size = width * height;
+ frame->vo_frame.base[0] = xmalloc_aligned(16,image_size*2);
+ }
+
+ frame->format = format;
frame->width = width;
frame->height = height;
diff --git a/src/video_out/yuv2rgb.c b/src/video_out/yuv2rgb.c
index 13459459b..9ef123542 100644
--- a/src/video_out/yuv2rgb.c
+++ b/src/video_out/yuv2rgb.c
@@ -141,6 +141,60 @@ static void scale_line (uint8_t *source, uint8_t *dest,
}
}
+
+static void scale_line_2 (uint8_t *source, uint8_t *dest,
+ int width, int step) {
+ int p1;
+ int p2;
+ int dx;
+
+ p1 = *source; source+=2;
+ p2 = *source; source+=2;
+ dx = 0;
+
+ while (width) {
+
+ *dest = (p1 * (32768 - dx) + p2 * dx) / 32768;
+
+ dx += step;
+ while (dx > 32768) {
+ dx -= 32768;
+ p1 = p2;
+ p2 = *source;
+ source+=2;
+ }
+
+ dest ++;
+ width --;
+ }
+}
+
+static void scale_line_4 (uint8_t *source, uint8_t *dest,
+ int width, int step) {
+ int p1;
+ int p2;
+ int dx;
+
+ p1 = *source; source+=4;
+ p2 = *source; source+=4;
+ dx = 0;
+
+ while (width) {
+
+ *dest = (p1 * (32768 - dx) + p2 * dx) / 32768;
+
+ dx += step;
+ while (dx > 32768) {
+ dx -= 32768;
+ p1 = p2;
+ p2 = *source;
+ source+=4;
+ }
+
+ dest ++;
+ width --;
+ }
+}
#define RGB(i) \
@@ -151,7 +205,7 @@ static void scale_line (uint8_t *source, uint8_t *dest,
b = this->table_bU[U];
#define DST1(i) \
- Y = py_1[2*i]; \
+ Y = py_1[2*i]; \
dst_1[2*i] = r[Y] + g[Y] + b[Y]; \
Y = py_1[2*i+1]; \
dst_1[2*i+1] = r[Y] + g[Y] + b[Y];
@@ -695,8 +749,8 @@ static int div_round (int dividend, int divisor)
return -((-dividend + (divisor>>1)) / divisor);
}
-static void yuv2rgb_c_init (yuv2rgb_t *this, int mode)
-{
+static void yuv2rgb_setup_tables (yuv2rgb_t *this, int mode)
+{
int i;
uint8_t table_Y[1024];
uint32_t * table_32 = 0;
@@ -721,8 +775,6 @@ static void yuv2rgb_c_init (yuv2rgb_t *this, int mode)
switch (mode) {
case MODE_32_RGB:
case MODE_32_BGR:
- this->yuv2rgb_fun = yuv2rgb_c_32;
-
table_32 = malloc ((197 + 2*682 + 256 + 132) * sizeof (uint32_t));
entry_size = sizeof (uint32_t);
@@ -742,8 +794,6 @@ static void yuv2rgb_c_init (yuv2rgb_t *this, int mode)
case MODE_24_RGB:
case MODE_24_BGR:
- this->yuv2rgb_fun = (mode==MODE_24_RGB) ? yuv2rgb_c_24_rgb : yuv2rgb_c_24_bgr;
-
table_8 = malloc ((256 + 2*232) * sizeof (uint8_t));
entry_size = sizeof (uint8_t);
@@ -757,8 +807,6 @@ static void yuv2rgb_c_init (yuv2rgb_t *this, int mode)
case MODE_16_BGR:
case MODE_15_RGB:
case MODE_16_RGB:
- this->yuv2rgb_fun = yuv2rgb_c_16;
-
table_16 = malloc ((197 + 2*682 + 256 + 132) * sizeof (uint16_t));
entry_size = sizeof (uint16_t);
@@ -809,6 +857,359 @@ static void yuv2rgb_c_init (yuv2rgb_t *this, int mode)
}
}
+static void yuv2rgb_c_init (yuv2rgb_t *this, int mode)
+{
+ switch (mode) {
+ case MODE_32_RGB:
+ case MODE_32_BGR:
+ this->yuv2rgb_fun = yuv2rgb_c_32;
+ break;
+
+ case MODE_24_RGB:
+ case MODE_24_BGR:
+ this->yuv2rgb_fun = (mode==MODE_24_RGB) ? yuv2rgb_c_24_rgb : yuv2rgb_c_24_bgr;
+ break;
+
+ case MODE_15_BGR:
+ case MODE_16_BGR:
+ case MODE_15_RGB:
+ case MODE_16_RGB:
+ this->yuv2rgb_fun = yuv2rgb_c_16;
+ break;
+
+ default:
+ fprintf (stderr, "mode %d not supported by yuv2rgb\n", mode);
+ exit (1);
+ }
+
+}
+
+
+/*
+ * yuy2 stuff
+ */
+
+static void yuy22rgb_c_32 (yuv2rgb_t *this, uint8_t * _dst, uint8_t * _p)
+{
+ int U, V, Y;
+ uint8_t * py_1, * pu, * pv;
+ uint32_t * r, * g, * b;
+ uint32_t * dst_1;
+ int width, height;
+ int dy;
+
+ /* FIXME: implement unscaled version */
+
+ scale_line_4 (_p+1, this->u_buffer,
+ this->dest_width >> 1, this->step_dx);
+ scale_line_4 (_p+3, this->v_buffer,
+ this->dest_width >> 1, this->step_dx);
+ scale_line_2 (_p, this->y_buffer,
+ this->dest_width, this->step_dx);
+
+ dy = 0;
+ height = this->source_height;
+
+ for (;;) {
+ dst_1 = (uint32_t*)_dst;
+ py_1 = this->y_buffer;
+ pu = this->u_buffer;
+ pv = this->v_buffer;
+
+ width = this->dest_width >> 3;
+
+ do {
+
+ RGB(0);
+ DST1(0);
+
+ RGB(1);
+ DST1(1);
+
+ RGB(2);
+ DST1(2);
+
+ RGB(3);
+ DST1(3);
+
+ pu += 4;
+ pv += 4;
+ py_1 += 8;
+ dst_1 += 8;
+ } while (--width);
+
+ dy += this->step_dy;
+ _dst += this->rgb_stride;
+
+ while (dy < 32768) {
+
+ memcpy (_dst, (uint8_t*)_dst-this->rgb_stride, this->dest_width*4);
+
+ dy += this->step_dy;
+ _dst += this->rgb_stride;
+ }
+
+ if (--height <= 0)
+ break;
+
+ dy -= 32768;
+ _p += this->y_stride*2;
+
+ scale_line_4 (_p+1, this->u_buffer,
+ this->dest_width >> 1, this->step_dx);
+ scale_line_4 (_p+3, this->v_buffer,
+ this->dest_width >> 1, this->step_dx);
+ scale_line_2 (_p, this->y_buffer,
+ this->dest_width, this->step_dx);
+ }
+}
+
+static void yuy22rgb_c_24_rgb (yuv2rgb_t *this, uint8_t * _dst, uint8_t * _p)
+{
+ int U, V, Y;
+ uint8_t * py_1, * pu, * pv;
+ uint8_t * r, * g, * b;
+ uint8_t * dst_1;
+ int width, height;
+ int dy;
+
+ /* FIXME: implement unscaled version */
+
+ scale_line_4 (_p+1, this->u_buffer,
+ this->dest_width >> 1, this->step_dx);
+ scale_line_4 (_p+3, this->v_buffer,
+ this->dest_width >> 1, this->step_dx);
+ scale_line_2 (_p, this->y_buffer,
+ this->dest_width, this->step_dx);
+
+ dy = 0;
+ height = this->source_height;
+
+ for (;;) {
+ dst_1 = _dst;
+ py_1 = this->y_buffer;
+ pu = this->u_buffer;
+ pv = this->v_buffer;
+
+ width = this->dest_width >> 3;
+
+ do {
+ RGB(0);
+ DST1RGB(0);
+
+ RGB(1);
+ DST1RGB(1);
+
+ RGB(2);
+ DST1RGB(2);
+
+ RGB(3);
+ DST1RGB(3);
+
+ pu += 4;
+ pv += 4;
+ py_1 += 8;
+ dst_1 += 24;
+ } while (--width);
+
+ dy += this->step_dy;
+ _dst += this->rgb_stride;
+
+ while (dy < 32768) {
+
+ memcpy (_dst, (uint8_t*)_dst-this->rgb_stride, this->dest_width*3);
+
+ dy += this->step_dy;
+ _dst += this->rgb_stride;
+ }
+
+ if (--height <= 0)
+ break;
+
+ dy -= 32768;
+ _p += this->y_stride*2;
+
+ scale_line_4 (_p+1, this->u_buffer,
+ this->dest_width >> 1, this->step_dx);
+ scale_line_4 (_p+3, this->v_buffer,
+ this->dest_width >> 1, this->step_dx);
+ scale_line_2 (_p, this->y_buffer,
+ this->dest_width, this->step_dx);
+ }
+}
+
+static void yuy22rgb_c_24_bgr (yuv2rgb_t *this, uint8_t * _dst, uint8_t * _p)
+{
+ int U, V, Y;
+ uint8_t * py_1, * pu, * pv;
+ uint8_t * r, * g, * b;
+ uint8_t * dst_1;
+ int width, height;
+ int dy;
+
+ /* FIXME: implement unscaled version */
+
+ scale_line_4 (_p+1, this->u_buffer,
+ this->dest_width >> 1, this->step_dx);
+ scale_line_4 (_p+3, this->v_buffer,
+ this->dest_width >> 1, this->step_dx);
+ scale_line_2 (_p, this->y_buffer,
+ this->dest_width, this->step_dx);
+
+ dy = 0;
+ height = this->source_height;
+
+ for (;;) {
+ dst_1 = _dst;
+ py_1 = this->y_buffer;
+ pu = this->u_buffer;
+ pv = this->v_buffer;
+
+ width = this->dest_width >> 3;
+
+ do {
+ RGB(0);
+ DST1BGR(0);
+
+ RGB(1);
+ DST1BGR(1);
+
+ RGB(2);
+ DST1BGR(2);
+
+ RGB(3);
+ DST1BGR(3);
+
+ pu += 4;
+ pv += 4;
+ py_1 += 8;
+ dst_1 += 24;
+ } while (--width);
+
+ dy += this->step_dy;
+ _dst += this->rgb_stride;
+
+ while (dy < 32768) {
+
+ memcpy (_dst, (uint8_t*)_dst-this->rgb_stride, this->dest_width*3);
+
+ dy += this->step_dy;
+ _dst += this->rgb_stride;
+ }
+
+ if (--height <= 0)
+ break;
+
+ dy -= 32768;
+ _p += this->y_stride*2;
+
+ scale_line_4 (_p+1, this->u_buffer,
+ this->dest_width >> 1, this->step_dx);
+ scale_line_4 (_p+3, this->v_buffer,
+ this->dest_width >> 1, this->step_dx);
+ scale_line_2 (_p, this->y_buffer,
+ this->dest_width, this->step_dx);
+ }
+}
+
+static void yuy22rgb_c_16 (yuv2rgb_t *this, uint8_t * _dst, uint8_t * _p)
+{
+ int U, V, Y;
+ uint8_t * py_1, * pu, * pv;
+ uint16_t * r, * g, * b;
+ uint16_t * dst_1;
+ int width, height;
+ int dy;
+
+ /* FIXME: implement unscaled version */
+
+ scale_line_4 (_p+1, this->u_buffer,
+ this->dest_width >> 1, this->step_dx);
+ scale_line_4 (_p+3, this->v_buffer,
+ this->dest_width >> 1, this->step_dx);
+ scale_line_2 (_p, this->y_buffer,
+ this->dest_width, this->step_dx);
+
+ dy = 0;
+ height = this->source_height;
+
+ for (;;) {
+ dst_1 = (uint16_t*)_dst;
+ py_1 = this->y_buffer;
+ pu = this->u_buffer;
+ pv = this->v_buffer;
+
+ width = this->dest_width >> 3;
+
+ do {
+ RGB(0);
+ DST1(0);
+
+ RGB(1);
+ DST1(1);
+
+ RGB(2);
+ DST1(2);
+
+ RGB(3);
+ DST1(3);
+
+ pu += 4;
+ pv += 4;
+ py_1 += 8;
+ dst_1 += 8;
+ } while (--width);
+
+ dy += this->step_dy;
+ _dst += this->rgb_stride;
+
+ while (dy < 32768) {
+
+ memcpy (_dst, (uint8_t*)_dst-this->rgb_stride, this->dest_width*2);
+
+ dy += this->step_dy;
+ _dst += this->rgb_stride;
+ }
+
+ if (--height <= 0)
+ break;
+
+ dy -= 32768;
+ _p += this->y_stride*2;
+
+ scale_line_4 (_p+1, this->u_buffer,
+ this->dest_width >> 1, this->step_dx);
+ scale_line_4 (_p+3, this->v_buffer,
+ this->dest_width >> 1, this->step_dx);
+ scale_line_2 (_p, this->y_buffer,
+ this->dest_width, this->step_dx);
+ }
+}
+
+static void yuy22rgb_c_init (yuv2rgb_t *this, int mode)
+{
+ switch (mode) {
+ case MODE_32_RGB:
+ case MODE_32_BGR:
+ this->yuy22rgb_fun = yuy22rgb_c_32;
+ break;
+
+ case MODE_24_RGB:
+ case MODE_24_BGR:
+ this->yuv2rgb_fun = (mode==MODE_24_RGB) ? yuy22rgb_c_24_rgb : yuy22rgb_c_24_bgr;
+ break;
+ case MODE_15_BGR:
+ case MODE_16_BGR:
+ case MODE_15_RGB:
+ case MODE_16_RGB:
+ this->yuy22rgb_fun = yuy22rgb_c_16;
+ break;
+
+ default:
+ printf ("yuv2rgb: mode %d not supported for yuy2\n", mode);
+ }
+}
+
yuv2rgb_t *yuv2rgb_init (int mode) {
#ifdef ARCH_X86
@@ -823,6 +1224,8 @@ yuv2rgb_t *yuv2rgb_init (int mode) {
this->y_chunk = this->u_buffer = NULL;
this->y_chunk = this->v_buffer = NULL;
+ yuv2rgb_setup_tables(this, mode);
+
/*
* auto-probe for the best yuv2rgb function
*/
@@ -851,5 +1254,13 @@ yuv2rgb_t *yuv2rgb_init (int mode) {
printf ("yuv2rgb: no accelerated colorspace conversion found\n");
yuv2rgb_c_init (this, mode);
}
+
+ /*
+ * auto-probe for the best yuy22rgb function
+ */
+
+ /* FIXME: implement mmx/mlib functions */
+ yuy22rgb_c_init (this, mode);
+
return this;
}
diff --git a/src/video_out/yuv2rgb.h b/src/video_out/yuv2rgb.h
index 8ff6fbc9c..6e84bd923 100644
--- a/src/video_out/yuv2rgb.h
+++ b/src/video_out/yuv2rgb.h
@@ -27,6 +27,11 @@ struct yuv2rgb_s {
void (*yuv2rgb_fun) (yuv2rgb_t *this, uint8_t * image, uint8_t * py,
uint8_t * pu, uint8_t * pv) ;
+ /*
+ * this is the function to call for the yuy2->rgb and scaling process
+ */
+ void (*yuy22rgb_fun) (yuv2rgb_t *this, uint8_t * image, uint8_t * p);
+
/* private stuff below */
uint32_t matrix_coefficients;