summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/video_out/video_out_xshm.c36
-rw-r--r--src/video_out/yuv2rgb.c77
-rw-r--r--src/video_out/yuv2rgb.h7
-rw-r--r--src/video_out/yuv2rgb_mlib.c18
-rw-r--r--src/video_out/yuv2rgb_mmx.c20
5 files changed, 90 insertions, 68 deletions
diff --git a/src/video_out/video_out_xshm.c b/src/video_out/video_out_xshm.c
index 857c3a2d8..116c52b7b 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.100 2002/12/21 12:56:51 miguelfreitas Exp $
+ * $Id: video_out_xshm.c,v 1.101 2003/01/24 17:04:37 esnel Exp $
*
* video_out_xshm.c, X11 shared memory extension interface for xine
*
@@ -84,7 +84,6 @@ typedef struct xshm_frame_s {
yuv2rgb_t *yuv2rgb; /* yuv2rgb converter set up for this frame */
uint8_t *rgb_dst;
int yuv_stride;
- int stripe_height, stripe_inc;
} xshm_frame_t;
@@ -310,18 +309,6 @@ static void xshm_frame_copy (vo_frame_t *vo_img, uint8_t **src) {
vo_img->copy_called = 1;
- if ((char *) frame->rgb_dst + frame->stripe_inc > (char *) frame->image->data
- + frame->image->bytes_per_line * frame->image->height) {
- /* frame->rgb_dst can walk off the end of the frame's image data when
- * xshm_frame_field, which resets it, is not called properly. This can
- * happen with corrupt MPEG streams
- * FIXME: Is there a way to ensure frame->rgb_dst validity?
- */
-#ifdef LOG
- printf("video_out_xshm: corrupt value of frame->rgb_dst -- skipping\n");
-#endif
- return;
- }
#ifdef LOG
printf ("video_out_xshm: copy... (format %d)\n", frame->format);
#endif
@@ -336,7 +323,6 @@ static void xshm_frame_copy (vo_frame_t *vo_img, uint8_t **src) {
}
- frame->rgb_dst += frame->stripe_inc;
#ifdef LOG
printf ("video_out_xshm: copy...done\n");
#endif
@@ -350,17 +336,16 @@ static void xshm_frame_field (vo_frame_t *vo_img, int which_field) {
switch (which_field) {
case VO_TOP_FIELD:
frame->rgb_dst = (uint8_t *)frame->image->data;
- frame->stripe_inc = 2*frame->stripe_height * frame->image->bytes_per_line;
break;
case VO_BOTTOM_FIELD:
frame->rgb_dst = (uint8_t *)frame->image->data + frame->image->bytes_per_line ;
- frame->stripe_inc = 2*frame->stripe_height * frame->image->bytes_per_line;
break;
case VO_BOTH_FIELDS:
frame->rgb_dst = (uint8_t *)frame->image->data;
- frame->stripe_inc = frame->stripe_height * frame->image->bytes_per_line;
break;
}
+
+ frame->yuv2rgb->next_slice (frame->yuv2rgb, NULL);
}
static void xshm_frame_dispose (vo_frame_t *vo_img) {
@@ -423,8 +408,8 @@ static void xshm_compute_rgb_size (xshm_driver_t *this, xshm_frame_t *frame) {
vo_scale_compute_output_size( &frame->sc );
/* avoid problems in yuv2rgb */
- if (frame->sc.output_height < ((frame->sc.delivered_height + 15) >> 4))
- frame->sc.output_height = ((frame->sc.delivered_height + 15) >> 4);
+ if (frame->sc.output_height < 1)
+ frame->sc.output_height = 1;
if (frame->sc.output_width < 8)
frame->sc.output_width = 8;
if (frame->sc.output_width & 1) /* yuv2rgb_mlib needs an even YUV2 width */
@@ -561,12 +546,9 @@ static void xshm_update_frame_format (vo_driver_t *this_gen,
frame->chunk[2] = NULL;
}
- frame->stripe_height = 16 * frame->sc.output_height / frame->sc.delivered_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
/*
@@ -578,22 +560,22 @@ static void xshm_update_frame_format (vo_driver_t *this_gen,
case VO_BOTTOM_FIELD:
frame->yuv2rgb->configure (frame->yuv2rgb,
frame->sc.delivered_width,
- 16,
+ frame->sc.delivered_height,
2*frame->vo_frame.pitches[0],
2*frame->vo_frame.pitches[1],
frame->sc.output_width,
- frame->stripe_height,
+ frame->sc.output_height,
frame->image->bytes_per_line*2);
frame->yuv_stride = frame->image->bytes_per_line*2;
break;
case VO_BOTH_FIELDS:
frame->yuv2rgb->configure (frame->yuv2rgb,
frame->sc.delivered_width,
- 16,
+ frame->sc.delivered_height,
frame->vo_frame.pitches[0],
frame->vo_frame.pitches[1],
frame->sc.output_width,
- frame->stripe_height,
+ frame->sc.output_height,
frame->image->bytes_per_line);
frame->yuv_stride = frame->image->bytes_per_line;
break;
diff --git a/src/video_out/yuv2rgb.c b/src/video_out/yuv2rgb.c
index 9e4cfc47e..f6bb6be18 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.34 2002/10/10 14:05:19 jkeil Exp $
+ * $Id: yuv2rgb.c,v 1.35 2003/01/24 17:04:39 esnel Exp $
*/
#include "config.h"
@@ -69,6 +69,31 @@ static void *my_malloc_aligned (size_t alignment, size_t size, void **chunk) {
}
+static int yuv2rgb_next_slice (yuv2rgb_t *this, uint8_t **dest) {
+ int y0, y1;
+
+ if (dest == NULL) {
+ this->slice_offset = 0;
+ this->slice_height = 16;
+ return 0;
+ }
+ if (this->slice_height == this->source_height) {
+ return this->dest_height;
+ }
+
+ y0 = (this->slice_offset * this->dest_height) / this->source_height;
+ y1 = ((this->slice_offset + this->slice_height) * this->dest_height) / this->source_height;
+ *dest += (this->rgb_stride * y0);
+
+ if ((this->slice_offset + this->slice_height) >= this->source_height) {
+ this->slice_offset = 0;
+ return (this->dest_height - y0);
+ } else {
+ this->slice_offset += this->slice_height;
+ return (y1 - y0);
+ }
+}
+
static int yuv2rgb_configure (yuv2rgb_t *this,
int source_width, int source_height,
int y_stride, int uv_stride,
@@ -88,7 +113,9 @@ static int yuv2rgb_configure (yuv2rgb_t *this,
this->dest_width = dest_width;
this->dest_height = dest_height;
this->rgb_stride = rgb_stride;
-
+ this->slice_height = source_height;
+ this->slice_offset = 0;
+
if (this->y_chunk) {
free (this->y_chunk);
this->y_buffer = this->y_chunk = NULL;
@@ -1367,7 +1394,7 @@ static void yuv2rgb_c_32 (yuv2rgb_t *this, uint8_t * _dst,
this->dest_width, this->step_dx);
dy = 0;
- dst_height = this->dest_height;
+ dst_height = this->next_slice (this, &_dst);
for (height = 0;; ) {
dst_1 = (uint32_t*)_dst;
@@ -1431,7 +1458,7 @@ static void yuv2rgb_c_32 (yuv2rgb_t *this, uint8_t * _dst,
} while( dy>=32768);
}
} else {
- height = this->source_height >> 1;
+ height = this->next_slice (this, &_dst) >> 1;
do {
dst_1 = (uint32_t*)_dst;
dst_2 = (void*)( (uint8_t *)_dst + this->rgb_stride );
@@ -1498,7 +1525,7 @@ static void yuv2rgb_c_24_rgb (yuv2rgb_t *this, uint8_t * _dst,
this->dest_width, this->step_dx);
dy = 0;
- dst_height = this->dest_height;
+ dst_height = this->next_slice (this, &_dst);
for (height = 0;; ) {
dst_1 = _dst;
@@ -1562,7 +1589,7 @@ static void yuv2rgb_c_24_rgb (yuv2rgb_t *this, uint8_t * _dst,
} while (dy>=32768);
}
} else {
- height = this->source_height >> 1;
+ height = this->next_slice (this, &_dst) >> 1;
do {
dst_1 = _dst;
dst_2 = (void*)( (uint8_t *)_dst + this->rgb_stride );
@@ -1629,7 +1656,7 @@ static void yuv2rgb_c_24_bgr (yuv2rgb_t *this, uint8_t * _dst,
this->dest_width, this->step_dx);
dy = 0;
- dst_height = this->dest_height;
+ dst_height = this->next_slice (this, &_dst);
for (height = 0;; ) {
dst_1 = _dst;
@@ -1694,7 +1721,7 @@ static void yuv2rgb_c_24_bgr (yuv2rgb_t *this, uint8_t * _dst,
}
} else {
- height = this->source_height >> 1;
+ height = this->next_slice (this, &_dst) >> 1;
do {
dst_1 = _dst;
dst_2 = (void*)( (uint8_t *)_dst + this->rgb_stride );
@@ -1760,7 +1787,7 @@ static void yuv2rgb_c_16 (yuv2rgb_t *this, uint8_t * _dst,
this->dest_width, this->step_dx);
dy = 0;
- dst_height = this->dest_height;
+ dst_height = this->next_slice (this, &_dst);
for (height = 0;; ) {
dst_1 = (uint16_t*)_dst;
@@ -1824,7 +1851,7 @@ static void yuv2rgb_c_16 (yuv2rgb_t *this, uint8_t * _dst,
} while( dy>=32768);
}
} else {
- height = this->source_height >> 1;
+ height = this->next_slice (this, &_dst) >> 1;
do {
dst_1 = (uint16_t*)_dst;
dst_2 = (void*)( (uint8_t *)_dst + this->rgb_stride );
@@ -1890,7 +1917,7 @@ static void yuv2rgb_c_8 (yuv2rgb_t *this, uint8_t * _dst,
this->dest_width, this->step_dx);
dy = 0;
- dst_height = this->dest_height;
+ dst_height = this->next_slice (this, &_dst);
for (height = 0;; ) {
dst_1 = (uint8_t*)_dst;
@@ -1954,7 +1981,7 @@ static void yuv2rgb_c_8 (yuv2rgb_t *this, uint8_t * _dst,
} while( dy>=32768 );
}
} else {
- height = this->source_height >> 1;
+ height = this->next_slice (this, &_dst) >> 1;
do {
dst_1 = (uint8_t*)_dst;
dst_2 = (void*)( (uint8_t *)_dst + this->rgb_stride );
@@ -2009,7 +2036,7 @@ static void yuv2rgb_c_gray (yuv2rgb_t *this, uint8_t * _dst,
scale_line_func_t scale_line = this->scale_line;
dy = 0;
- dst_height = this->dest_height;
+ dst_height = this->next_slice (this, &_dst);
for (;;) {
scale_line (_py, _dst, this->dest_width, this->step_dx);
@@ -2035,7 +2062,7 @@ static void yuv2rgb_c_gray (yuv2rgb_t *this, uint8_t * _dst,
*/
}
} else {
- for (height = this->source_height; --height >= 0; ) {
+ for (height = this->next_slice (this, &_dst); --height >= 0; ) {
xine_fast_memcpy(_dst, _py, this->dest_width);
_dst += this->rgb_stride;
_py += this->y_stride;
@@ -2065,7 +2092,7 @@ static void yuv2rgb_c_palette (yuv2rgb_t *this, uint8_t * _dst,
this->dest_width, this->step_dx);
dy = 0;
- dst_height = this->dest_height;
+ dst_height = this->next_slice (this, &_dst);
for (height = 0;; ) {
dst_1 = _dst;
@@ -2129,7 +2156,7 @@ static void yuv2rgb_c_palette (yuv2rgb_t *this, uint8_t * _dst,
} while( dy>=32768 );
}
} else {
- height = this->source_height >> 1;
+ height = this->next_slice (this, &_dst) >> 1;
do {
dst_1 = _dst;
dst_2 = _dst + this->rgb_stride;
@@ -2539,7 +2566,7 @@ static void yuy22rgb_c_32 (yuv2rgb_t *this, uint8_t * _dst, uint8_t * _p)
this->dest_width, this->step_dx);
dy = 0;
- height = this->dest_height;
+ height = this->next_slice (this, &_dst) >> 1;
for (;;) {
dst_1 = (uint32_t*)_dst;
@@ -2618,7 +2645,7 @@ static void yuy22rgb_c_24_rgb (yuv2rgb_t *this, uint8_t * _dst, uint8_t * _p)
this->dest_width, this->step_dx);
dy = 0;
- height = this->dest_height;
+ height = this->next_slice (this, &_dst) >> 1;
for (;;) {
dst_1 = _dst;
@@ -2696,7 +2723,7 @@ static void yuy22rgb_c_24_bgr (yuv2rgb_t *this, uint8_t * _dst, uint8_t * _p)
this->dest_width, this->step_dx);
dy = 0;
- height = this->dest_height;
+ height = this->next_slice (this, &_dst) >> 1;
for (;;) {
dst_1 = _dst;
@@ -2770,7 +2797,7 @@ static void yuy22rgb_c_16 (yuv2rgb_t *this, uint8_t * _dst, uint8_t * _p)
this->dest_width, this->step_dx);
dy = 0;
- height = this->dest_height;
+ height = this->next_slice (this, &_dst) >> 1;
for (;;) {
dst_1 = (uint16_t*)_dst;
@@ -2844,7 +2871,7 @@ static void yuy22rgb_c_8 (yuv2rgb_t *this, uint8_t * _dst, uint8_t * _p)
this->dest_width, this->step_dx);
dy = 0;
- height = this->dest_height;
+ height = this->next_slice (this, &_dst) >> 1;
for (;;) {
dst_1 = _dst;
@@ -2908,7 +2935,7 @@ static void yuy22rgb_c_gray (yuv2rgb_t *this, uint8_t * _dst, uint8_t * _p)
if (this->do_scale) {
dy = 0;
- height = this->dest_height;
+ height = this->next_slice (this, &_dst) >> 1;
for (;;) {
scale_line_2 (_p, _dst, this->dest_width, this->step_dx);
@@ -2931,7 +2958,7 @@ static void yuy22rgb_c_gray (yuv2rgb_t *this, uint8_t * _dst, uint8_t * _p)
dy &= 32767;
}
} else {
- for (height = this->source_height; --height >= 0; ) {
+ for (height = this->next_slice (this, &_dst); --height >= 0; ) {
dst = _dst;
y = _p;
for (width = this->source_width; --width >= 0; ) {
@@ -2961,7 +2988,7 @@ static void yuy22rgb_c_palette (yuv2rgb_t *this, uint8_t * _dst, uint8_t * _p)
this->dest_width, this->step_dx);
dy = 0;
- height = this->dest_height;
+ height = this->next_slice (this, &_dst) >> 1;
for (;;) {
dst_1 = _dst;
@@ -3076,6 +3103,7 @@ yuv2rgb_t *yuv2rgb_create_converter (yuv2rgb_factory_t *factory) {
this->yuv2rgb_single_pixel_fun = factory->yuv2rgb_single_pixel_fun;
this->configure = yuv2rgb_configure;
+ this->next_slice = yuv2rgb_next_slice;
return this;
}
@@ -3176,4 +3204,3 @@ yuv2rgb_factory_t* yuv2rgb_factory_init (int mode, int swapped,
return this;
}
-
diff --git a/src/video_out/yuv2rgb.h b/src/video_out/yuv2rgb.h
index 5b9c3f6a0..b27c45bdc 100644
--- a/src/video_out/yuv2rgb.h
+++ b/src/video_out/yuv2rgb.h
@@ -52,6 +52,11 @@ struct yuv2rgb_s {
int rgb_stride);
/*
+ * start a new field or frame if dest is NULL
+ */
+ int (*next_slice) (yuv2rgb_t *this, uint8_t **dest);
+
+ /*
* this is the function to call for the yuv2rgb and scaling process
*/
yuv2rgb_fun_t yuv2rgb_fun;
@@ -74,6 +79,7 @@ struct yuv2rgb_s {
int y_stride, uv_stride;
int dest_width, dest_height;
int rgb_stride;
+ int slice_height, slice_offset;
int step_dx, step_dy;
int do_scale;
@@ -147,5 +153,6 @@ void mmx_yuv2rgb_set_gamma(int gamma);
void yuv2rgb_init_mmxext (yuv2rgb_factory_t *this);
void yuv2rgb_init_mmx (yuv2rgb_factory_t *this);
void yuv2rgb_init_mlib (yuv2rgb_factory_t *this);
+int yuv2rgb_slice (yuv2rgb_t *this, uint8_t **dest);
#endif
diff --git a/src/video_out/yuv2rgb_mlib.c b/src/video_out/yuv2rgb_mlib.c
index d0ebd598b..a8fbd7c44 100644
--- a/src/video_out/yuv2rgb_mlib.c
+++ b/src/video_out/yuv2rgb_mlib.c
@@ -81,7 +81,7 @@ static void mlib_yuv420_rgb24 (yuv2rgb_t *this,
if (this->do_scale) {
dy = 0;
- dst_height = this->dest_height;
+ dst_height = this->next_slice (this, &image);
assert((this->dest_width&1) == 0); /* mlib needs an even YUV2 width */
for (;;) {
@@ -137,9 +137,11 @@ static void mlib_yuv420_rgb24 (yuv2rgb_t *this,
dy -= 32768;
}
} else {
+ this->next_slice (this, &image);
+
mlib_stat = mlib_VideoColorYUV2RGB420(image, py, pu, pv,
this->source_width,
- this->source_height,
+ this->slice_height,
this->rgb_stride,
this->y_stride,
this->uv_stride);
@@ -156,7 +158,7 @@ static void mlib_yuv420_argb32 (yuv2rgb_t *this,
if (this->do_scale) {
dy = 0;
- dst_height = this->dest_height;
+ dst_height = this->next_slice (this, &image);
assert((this->dest_width&1) == 0); /* mlib needs an even YUV2 width */
for (;;) {
@@ -212,9 +214,11 @@ static void mlib_yuv420_argb32 (yuv2rgb_t *this,
dy -= 32768;
}
} else {
+ this->next_slice (this, &image);
+
mlib_stat = mlib_VideoColorYUV2ARGB420(image, py, pu, pv,
this->source_width,
- this->source_height,
+ this->slice_height,
this->rgb_stride,
this->y_stride,
this->uv_stride);
@@ -231,7 +235,7 @@ static void mlib_yuv420_abgr32 (yuv2rgb_t *this,
if (this->do_scale) {
dy = 0;
- dst_height = this->dest_height;
+ dst_height = this->next_slice (this, &image);
assert((this->dest_width&1) == 0); /* mlib needs an even YUV2 width */
for (;;) {
@@ -287,9 +291,11 @@ static void mlib_yuv420_abgr32 (yuv2rgb_t *this,
dy -= 32768;
}
} else {
+ this->next_slice (this, &image);
+
mlib_stat = mlib_VideoColorYUV2ABGR420(image, py, pu, pv,
this->source_width,
- this->source_height,
+ this->slice_height,
this->rgb_stride,
this->y_stride,
this->uv_stride);
diff --git a/src/video_out/yuv2rgb_mmx.c b/src/video_out/yuv2rgb_mmx.c
index 0686cc2d1..3de843500 100644
--- a/src/video_out/yuv2rgb_mmx.c
+++ b/src/video_out/yuv2rgb_mmx.c
@@ -383,8 +383,8 @@ static inline void yuv420_rgb16 (yuv2rgb_t *this,
int y_stride = this->y_stride;
int uv_stride = this->uv_stride;
int width = this->source_width;
- int height = this->source_height;
- int dst_height = this->dest_height;
+ int height = this->slice_height;
+ int dst_height = this->next_slice (this, &image);
uint8_t *img;
width >>= 3;
@@ -494,8 +494,8 @@ static inline void yuv420_rgb15 (yuv2rgb_t *this,
int y_stride = this->y_stride;
int uv_stride = this->uv_stride;
int width = this->source_width;
- int height = this->source_height;
- int dst_height = this->dest_height;
+ int height = this->slice_height;
+ int dst_height = this->next_slice (this, &image);
uint8_t *img;
width >>= 3;
@@ -603,8 +603,8 @@ static inline void yuv420_rgb24 (yuv2rgb_t *this,
int y_stride = this->y_stride;
int uv_stride = this->uv_stride;
int width = this->source_width;
- int height = this->source_height;
- int dst_height = this->dest_height;
+ int height = this->slice_height;
+ int dst_height = this->next_slice (this, &image);
uint8_t *img;
/* rgb_stride -= 4 * this->dest_width; */
@@ -714,8 +714,8 @@ static inline void yuv420_argb32 (yuv2rgb_t *this,
int y_stride = this->y_stride;
int uv_stride = this->uv_stride;
int width = this->source_width;
- int height = this->source_height;
- int dst_height = this->dest_height;
+ int height = this->slice_height;
+ int dst_height = this->next_slice (this, &image);
uint8_t *img;
/* rgb_stride -= 4 * this->dest_width; */
@@ -824,8 +824,8 @@ static inline void yuv420_abgr32 (yuv2rgb_t *this,
int y_stride = this->y_stride;
int uv_stride = this->uv_stride;
int width = this->source_width;
- int height = this->source_height;
- int dst_height = this->dest_height;
+ int height = this->slice_height;
+ int dst_height = this->next_slice (this, &image);
uint8_t *img;
/* rgb_stride -= 4 * this->dest_width; */