diff options
-rw-r--r-- | src/video_out/video_out_xshm.c | 36 | ||||
-rw-r--r-- | src/video_out/yuv2rgb.c | 77 | ||||
-rw-r--r-- | src/video_out/yuv2rgb.h | 7 | ||||
-rw-r--r-- | src/video_out/yuv2rgb_mlib.c | 18 | ||||
-rw-r--r-- | src/video_out/yuv2rgb_mmx.c | 20 |
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; */ |