diff options
-rw-r--r-- | src/libmpeg2/decode.c | 2 | ||||
-rw-r--r-- | src/video_out/video_out_xshm.c | 103 | ||||
-rw-r--r-- | src/video_out/yuv2rgb.c | 30 | ||||
-rw-r--r-- | src/video_out/yuv2rgb.h | 6 | ||||
-rw-r--r-- | src/video_out/yuv2rgb_mmx.c | 105 | ||||
-rw-r--r-- | src/xine-engine/video_out.c | 4 |
6 files changed, 168 insertions, 82 deletions
diff --git a/src/libmpeg2/decode.c b/src/libmpeg2/decode.c index 66594fd86..dfbf3073f 100644 --- a/src/libmpeg2/decode.c +++ b/src/libmpeg2/decode.c @@ -123,7 +123,7 @@ static inline int parse_chunk (mpeg2dec_t * mpeg2dec, int code, /* find out if we want to skip this frame */ mpeg2dec->drop_frame = 0; - picture->skip_non_intra_dct = (mpeg2dec->frames_to_drop>0) ; + /* picture->skip_non_intra_dct = (mpeg2dec->frames_to_drop>0) ; */ switch (picture->picture_coding_type) { case B_TYPE: diff --git a/src/video_out/video_out_xshm.c b/src/video_out/video_out_xshm.c index a68944048..cce76baf7 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.3 2001/06/04 15:04:13 guenter Exp $ + * $Id: video_out_xshm.c,v 1.4 2001/06/10 01:26:46 guenter Exp $ * * video_out_xshm.c, X11 shared memory extension interface for xine * @@ -65,8 +65,11 @@ typedef struct xshm_frame_s { int width, height; int rgb_width, rgb_height; + int ratio_code; XImage *image; + uint8_t *rgb_dst; + int stripe_inc; XShmSegmentInfo shminfo; } xshm_frame_t; @@ -101,6 +104,7 @@ typedef struct xshm_driver_s { int output_height; int output_xoffset; int output_yoffset; + int stripe_height; int user_ratio; @@ -297,10 +301,19 @@ static uint32_t xshm_get_capabilities (vo_driver_t *this_gen) { } static void xshm_frame_copy (vo_frame_t *vo_img, uint8_t **src) { - /* FIXME: implement */ - + xshm_frame_t *frame = (xshm_frame_t *) vo_img ; + xshm_driver_t *this = (xshm_driver_t *) vo_img->instance->driver; + if (! frame->stripe_inc) { + printf ("ALARM 1\n"); + } + if (! frame->image) { + printf ("ALARM 2\n"); + } + this->yuv2rgb->yuv2rgb_fun (this->yuv2rgb, frame->rgb_dst, + src[0], src[1], src[2]); + frame->rgb_dst += frame->stripe_inc; } static void xshm_frame_field (vo_frame_t *vo_img, int which_field) { @@ -351,6 +364,7 @@ static void xshm_calc_output_size (xshm_driver_t *this) { double image_ratio, desired_ratio; double corr_factor; int ideal_width, ideal_height; + int dest_width, dest_height; /* * aspect ratio calculation @@ -413,9 +427,32 @@ static void xshm_calc_output_size (xshm_driver_t *this) { ideal_height *=2; } + ideal_width &= 0xFFFFFE0; + this->calc_dest_size (ideal_width, ideal_height, - &this->output_width, &this->output_height); + &dest_width, &dest_height); + + + /* + * make the frames fit into the given destination area + */ + + if ( ((double) dest_width / this->ratio_factor) < dest_height ) { + + this->output_width = dest_width ; + this->output_height = (double) dest_width / this->ratio_factor ; + this->output_xoffset = 0; + this->output_yoffset = (dest_height - this->output_height) / 2; + } else { + + this->output_width = (double) dest_height * this->ratio_factor ; + this->output_height = dest_height; + + this->output_xoffset = (dest_width - this->output_width) / 2; + this->output_yoffset = 0; + + } } static void xshm_update_frame_format (vo_driver_t *this_gen, @@ -426,30 +463,21 @@ static void xshm_update_frame_format (vo_driver_t *this_gen, xshm_driver_t *this = (xshm_driver_t *) this_gen; xshm_frame_t *frame = (xshm_frame_t *) frame_gen; - if ( (width != this->delivered_width) || (height != this->delivered_width) - || (ratio_code != this->delivered_ratio_code) ) { + if ((frame->rgb_width != this->output_width) + || (frame->rgb_height != this->output_height) + || (frame->width != width) + || (frame->height != height) + || (frame->ratio_code != ratio_code)) { + + int image_size; this->delivered_width = width; this->delivered_height = height; this->delivered_ratio_code = ratio_code; xshm_calc_output_size (this); - /* - yuv2rgb_setup (this->yuv2rgb, - this->delivered_width, - this->delivered_height, - this->delivered_width, - this->delivered_width/2, - this->output_width, - this->output_height, - this->output_width*this->bytes_per_pixel); - */ - } - - if ((frame->width != this->output_width) - || (frame->height != this->output_height)) { - int image_size; + this->stripe_height = 16 * this->output_height / this->delivered_height; /* printf ("video_out_xshm: updating frame to %d x %d\n", @@ -465,12 +493,18 @@ static void xshm_update_frame_format (vo_driver_t *this_gen, if (frame->image) { dispose_ximage (this, &frame->shminfo, frame->image); + + /* FIXME: free yuv (base) memory !!!!! */ + + frame->image = NULL; } frame->image = create_ximage (this, &frame->shminfo, this->output_width, this->output_height); + 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); @@ -481,8 +515,24 @@ static void xshm_update_frame_format (vo_driver_t *this_gen, frame->rgb_width = this->output_width; frame->rgb_height = this->output_height; + + frame->ratio_code = ratio_code; - XUnlockDisplay (this->display); + yuv2rgb_setup (this->yuv2rgb, + this->delivered_width, + 16, + this->delivered_width, + this->delivered_width/2, + this->output_width, + this->stripe_height, + frame->image->bytes_per_line); + + printf ("alloc image done\n"); + } + + if (frame->image) { + frame->rgb_dst = frame->image->data; + frame->stripe_inc = this->stripe_height * frame->image->bytes_per_line; } } @@ -515,15 +565,15 @@ static void xshm_display_frame (vo_driver_t *this_gen, vo_frame_t *frame_gen) { XShmPutImage(this->display, this->drawable, this->gc, frame->image, - 0, 0, frame->rgb_width, frame->rgb_height, + 0, 0, this->output_xoffset, this->output_yoffset, frame->rgb_width, frame->rgb_height, True); - + this->expecting_event = 1; } else { XPutImage(this->display, this->drawable, this->gc, frame->image, - 0, 0, frame->rgb_width, frame->rgb_height, + 0, 0, 0, 0, frame->rgb_width, frame->rgb_height); } @@ -557,6 +607,9 @@ static int xshm_set_property (vo_driver_t *this_gen, if (value>ASPECT_DVB) value = ASPECT_AUTO; this->user_ratio = value; + + xshm_calc_output_size (this); + } else { printf ("video_out_xshm: tried to set unsupported property %d\n", property); } diff --git a/src/video_out/yuv2rgb.c b/src/video_out/yuv2rgb.c index 05af7a88b..c75537264 100644 --- a/src/video_out/yuv2rgb.c +++ b/src/video_out/yuv2rgb.c @@ -60,13 +60,29 @@ static void yuv2rgb_c (yuv2rgb_t *this, uint8_t *image, } while (--height); } +static void *my_malloc_aligned (size_t alignment, size_t size, void **chunk) { + + void *pMem; + + pMem = xmalloc (size+alignment); + + *chunk = pMem; + + while ((int) pMem % alignment) + pMem++; + + return pMem; +} + + int yuv2rgb_setup (yuv2rgb_t *this, int source_width, int source_height, int y_stride, int uv_stride, int dest_width, int dest_height, int rgb_stride) { - + printf ("yuv2rgb setup (%d x %d => %d x %d)\n", source_width, source_height, + dest_width, dest_height); this->source_width = source_width; this->source_height = source_height; this->y_stride = y_stride; @@ -83,17 +99,17 @@ int yuv2rgb_setup (yuv2rgb_t *this, this->step_dx = source_width * 32768 / dest_width; this->step_dy = source_height * 32768 / dest_height; - if (this->y_buffer) free (this->y_buffer); - if (this->u_buffer) free (this->u_buffer); - if (this->v_buffer) free (this->v_buffer); + if (this->y_chunk) free (this->y_chunk); + if (this->u_chunk) free (this->u_chunk); + if (this->v_chunk) free (this->v_chunk); - this->y_buffer = xmalloc_aligned (16, dest_width); + this->y_buffer = my_malloc_aligned (16, dest_width, &this->y_chunk); if (!this->y_buffer) return 0; - this->u_buffer = xmalloc_aligned (16, dest_width); + this->u_buffer = my_malloc_aligned (16, dest_width, &this->u_chunk); if (!this->u_buffer) return 0; - this->v_buffer = xmalloc_aligned (16, dest_width); + this->v_buffer = my_malloc_aligned (16, dest_width, &this->v_chunk); if (!this->v_buffer) return 0; } diff --git a/src/video_out/yuv2rgb.h b/src/video_out/yuv2rgb.h index 51de2ae01..b966eca82 100644 --- a/src/video_out/yuv2rgb.h +++ b/src/video_out/yuv2rgb.h @@ -36,9 +36,9 @@ struct yuv2rgb_s { int rgb_stride; int step_dx, step_dy; int do_scale; - uint8_t *y_buffer; - uint8_t *u_buffer; - uint8_t *v_buffer; + uint8_t *y_buffer, *y_chunk; + uint8_t *u_buffer, *u_chunk; + uint8_t *v_buffer, *v_chunk; void *table_rV[256]; void *table_gU[256]; diff --git a/src/video_out/yuv2rgb_mmx.c b/src/video_out/yuv2rgb_mmx.c index 8ab3b050d..1f9adc20e 100644 --- a/src/video_out/yuv2rgb_mmx.c +++ b/src/video_out/yuv2rgb_mmx.c @@ -315,8 +315,8 @@ static inline void yuv420_rgb16 (yuv2rgb_t *this, int uv_stride = this->uv_stride; int width = this->source_width; int height = this->source_height; + uint8_t *img; - rgb_stride -= 2 * this->dest_width; width >>= 3; if (!this->do_scale) { @@ -325,14 +325,14 @@ static inline void yuv420_rgb16 (yuv2rgb_t *this, do { - i = width; + i = width; img = image; do { mmx_yuv2rgb (py, pu, pv); - mmx_unpack_16rgb (image, cpu); + mmx_unpack_16rgb (img, cpu); py += 8; pu += 4; pv += 4; - image += 16; + img += 16; } while (--i); py += y_stride; @@ -349,49 +349,56 @@ static inline void yuv420_rgb16 (yuv2rgb_t *this, } else { uint8_t *y_buf, *u_buf, *v_buf; + int dy = 0; scale_line (pu, this->u_buffer, this->dest_width >> 1, this->step_dx); scale_line (pv, this->v_buffer, this->dest_width >> 1, this->step_dx); - + scale_line (py, this->y_buffer, + this->dest_width, this->step_dx); do { y_buf = this->y_buffer; u_buf = this->u_buffer; v_buf = this->v_buffer; - scale_line (py, y_buf, - this->dest_width, this->step_dx); - - - i = this->dest_width >> 3; + i = this->dest_width >> 3; img = image; do { /* printf ("i : %d\n",i); */ mmx_yuv2rgb (y_buf, u_buf, v_buf); - mmx_unpack_16rgb (image, cpu); + mmx_unpack_16rgb (img, cpu); y_buf += 8; u_buf += 4; v_buf += 4; - image += 16; + img += 16; } while (--i); - py += y_stride; + dy += this->step_dy; image += rgb_stride; - if (height & 1) { - pu += uv_stride; - pv += uv_stride; - - scale_line (pu, this->u_buffer, - this->dest_width >> 1, this->step_dx); - scale_line (pv, this->v_buffer, - this->dest_width >> 1, this->step_dx); - - } - - } while (--height); + if (dy>32768) { + dy -= 32768; + + py += y_stride; + + scale_line (py, this->y_buffer, + this->dest_width, this->step_dx); + + if (height & 1) { + pu += uv_stride; + pv += uv_stride; + + scale_line (pu, this->u_buffer, + this->dest_width >> 1, this->step_dx); + scale_line (pv, this->v_buffer, + this->dest_width >> 1, this->step_dx); + + } + height--; + } + } while (height>0); } } @@ -405,8 +412,9 @@ static inline void yuv420_argb32 (yuv2rgb_t *this, int uv_stride = this->uv_stride; int width = this->source_width; int height = this->source_height; + uint8_t *img; - rgb_stride -= 4 * this->dest_width; + /* rgb_stride -= 4 * this->dest_width; */ width >>= 3; if (!this->do_scale) { @@ -414,14 +422,14 @@ static inline void yuv420_argb32 (yuv2rgb_t *this, uv_stride -= width >> 1; do { - i = width; + i = width; img = image; do { mmx_yuv2rgb (py, pu, pv); - mmx_unpack_32rgb (image, cpu); + mmx_unpack_32rgb (img, cpu); py += 8; pu += 4; pv += 4; - image += 32; + img += 32; } while (--i); py += y_stride; @@ -436,11 +444,14 @@ static inline void yuv420_argb32 (yuv2rgb_t *this, } while (--height); } else { uint8_t *y_buf, *u_buf, *v_buf; + int dy = 0; scale_line (pu, this->u_buffer, this->dest_width >> 1, this->step_dx); scale_line (pv, this->v_buffer, this->dest_width >> 1, this->step_dx); + scale_line (py, this->y_buffer, + this->dest_width, this->step_dx); do { @@ -448,37 +459,43 @@ static inline void yuv420_argb32 (yuv2rgb_t *this, u_buf = this->u_buffer; v_buf = this->v_buffer; - scale_line (py, y_buf, - this->dest_width, this->step_dx); - - i = this->dest_width >> 3; + i = this->dest_width >> 3; img=image; do { /* printf ("i : %d\n",i); */ mmx_yuv2rgb (y_buf, u_buf, v_buf); - mmx_unpack_32rgb (image, cpu); + mmx_unpack_32rgb (img, cpu); y_buf += 8; u_buf += 4; v_buf += 4; - image += 32; + img += 32; } while (--i); - py += y_stride; + dy += this->step_dy; image += rgb_stride; - if (height & 1) { - pu += uv_stride; - pv += uv_stride; + if (dy>32768) { + dy -= 32768; - scale_line (pu, this->u_buffer, - this->dest_width >> 1, this->step_dx); - scale_line (pv, this->v_buffer, - this->dest_width >> 1, this->step_dx); + py += y_stride; + scale_line (py, this->y_buffer, + this->dest_width, this->step_dx); + + if (height & 1) { + pu += uv_stride; + pv += uv_stride; + + scale_line (pu, this->u_buffer, + this->dest_width >> 1, this->step_dx); + scale_line (pv, this->v_buffer, + this->dest_width >> 1, this->step_dx); + } + height--; } - } while (--height); + } while (height>0); } } diff --git a/src/xine-engine/video_out.c b/src/xine-engine/video_out.c index 4f363fc7d..833446e7d 100644 --- a/src/xine-engine/video_out.c +++ b/src/xine-engine/video_out.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.c,v 1.14 2001/06/09 18:40:41 guenter Exp $ + * $Id: video_out.c,v 1.15 2001/06/10 01:26:46 guenter Exp $ * */ @@ -382,7 +382,7 @@ static int vo_frame_draw (vo_frame_t *img) { cur_vpts = this->metronom->get_current_time(this->metronom); diff = pic_vpts - cur_vpts; - frames_to_skip = (-1 * diff) / this->pts_per_frame + 1; + frames_to_skip = ((-1 * diff) / this->pts_per_frame + 1) * 2; xprintf (VERBOSE|VIDEO,"video_out:: delivery diff : %d\n",diff); |