From dc4e6262caacbdb7c36b82ba28b0157d00e466f1 Mon Sep 17 00:00:00 2001 From: Petri Hintukainen Date: Fri, 15 Jun 2012 11:18:52 +0300 Subject: Check allocated Xv iamge size. Adjust frame size if allocated frame is smaller than requested. Based on patch from http://bugs.xine-project.org/show_bug.cgi?id=108 --- src/video_out/video_out_xcbxv.c | 17 +++++++++++++---- src/video_out/video_out_xv.c | 17 +++++++++++++---- 2 files changed, 26 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/video_out/video_out_xcbxv.c b/src/video_out/video_out_xcbxv.c index a627c802b..68c39830b 100644 --- a/src/video_out/video_out_xcbxv.c +++ b/src/video_out/video_out_xcbxv.c @@ -100,6 +100,7 @@ typedef struct { unsigned int xv_pitches[3]; unsigned int xv_offsets[3]; + int req_width, req_height; } xv_frame_t; @@ -360,8 +361,8 @@ static void xv_update_frame_format (vo_driver_t *this_gen, width = (width + 7) & ~0x7; } - if ((frame->width != width) - || (frame->height != height) + if ((frame->req_width != width) + || (frame->req_height != height) || (frame->format != format)) { /* printf ("video_out_xcbxv: updating frame to %d x %d (ratio=%d, format=%08x)\n",width,height,ratio_code,format); */ @@ -390,13 +391,21 @@ static void xv_update_frame_format (vo_driver_t *this_gen, frame->vo_frame.base[2] = frame->image + frame->xv_offsets[1]; } - frame->width = width; - frame->height = height; + /* allocated frame size may not match requested size */ + frame->req_width = width; + frame->req_height = height; + frame->width = frame->xv_width; + frame->height = frame->xv_height; frame->format = format; pthread_mutex_unlock(&this->main_mutex); } + if (frame->vo_frame.width > frame->width) + frame->vo_frame.width = frame->width; + if (frame->vo_frame.height > frame->height) + frame->vo_frame.height = frame->height; + frame->ratio = ratio; } diff --git a/src/video_out/video_out_xv.c b/src/video_out/video_out_xv.c index 0fd8ca89a..bea6e75e6 100644 --- a/src/video_out/video_out_xv.c +++ b/src/video_out/video_out_xv.c @@ -103,6 +103,7 @@ typedef struct { XvImage *image; XShmSegmentInfo shminfo; + int req_width, req_height; } xv_frame_t; @@ -444,8 +445,8 @@ static void xv_update_frame_format (vo_driver_t *this_gen, width = (width + 7) & ~0x7; } - if ((frame->width != width) - || (frame->height != height) + if ((frame->req_width != width) + || (frame->req_height != height) || (frame->format != format)) { /* printf ("video_out_xv: updating frame to %d x %d (ratio=%d, format=%08x)\n",width,height,ratio_code,format); */ @@ -476,13 +477,21 @@ static void xv_update_frame_format (vo_driver_t *this_gen, frame->vo_frame.base[2] = frame->image->data + frame->image->offsets[1]; } - frame->width = width; - frame->height = height; + /* allocated frame size may not match requested size */ + frame->req_width = width; + frame->req_height = height; + frame->width = frame->image->width; + frame->height = frame->image->height; frame->format = format; UNLOCK_DISPLAY(this); } + if (frame->vo_frame.width > frame->width) + frame->vo_frame.width = frame->width; + if (frame->vo_frame.height > frame->height) + frame->vo_frame.height = frame->height; + frame->ratio = ratio; } -- cgit v1.2.3 From 52732e443424511ffc285b009f999cf00fbfa090 Mon Sep 17 00:00:00 2001 From: Petri Hintukainen Date: Fri, 15 Jun 2012 10:22:46 +0300 Subject: image: fix decoding images with odd width --- src/libxinevdec/image.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/libxinevdec/image.c b/src/libxinevdec/image.c index 5e166382b..b63cfa265 100644 --- a/src/libxinevdec/image.c +++ b/src/libxinevdec/image.c @@ -102,7 +102,7 @@ static void image_decode_data (video_decoder_t *this_gen, buf_element_t *buf) { this->index += buf->size; if (buf->decoder_flags & BUF_FLAG_FRAME_END) { - int width, height, i; + int width, height, i, x, y, img_stride; int status; MagickWand *wand; uint8_t *img_buf, *img_buf_ptr; @@ -133,9 +133,10 @@ static void image_decode_data (video_decoder_t *this_gen, buf_element_t *buf) { return; } - width = MagickGetImageWidth(wand) & ~1; /* must be even for init_yuv_planes */ + width = MagickGetImageWidth(wand); height = MagickGetImageHeight(wand); img_buf = malloc(width * height * 3); + img_stride = 3 * width; #if MAGICK_VERSION < 0x671 MagickGetImagePixels(wand, 0, 0, width, height, "RGB", CharPixel, img_buf); DestroyMagickWand(wand); @@ -154,10 +155,13 @@ static void image_decode_data (video_decoder_t *this_gen, buf_element_t *buf) { /* * rgb data -> yuv_planes */ + width &= ~1; /* must be even for init_yuv_planes */ init_yuv_planes(&yuv_planes, width, height); img_buf_ptr = img_buf; - for (i=0; i < width*height; i++) { + i = 0; + for (y = 0; y < height; y++) { + for (x = 0; x < width; x++) { uint8_t r = *(img_buf_ptr++); uint8_t g = *(img_buf_ptr++); uint8_t b = *(img_buf_ptr++); @@ -165,6 +169,9 @@ static void image_decode_data (video_decoder_t *this_gen, buf_element_t *buf) { yuv_planes.y[i] = COMPUTE_Y(r, g, b); yuv_planes.u[i] = COMPUTE_U(r, g, b); yuv_planes.v[i] = COMPUTE_V(r, g, b); + i++; + } + img_buf_ptr += img_stride - 3 * width; } free(img_buf); -- cgit v1.2.3 From 6eca0da170fd8d83bb3b611ea579b27a7c84b12a Mon Sep 17 00:00:00 2001 From: Petri Hintukainen Date: Fri, 15 Jun 2012 10:25:46 +0300 Subject: image decoders: crop image if allocated frame is smaller than requested --- src/libxinevdec/gdkpixbuf.c | 22 +++++++++++++++++----- src/libxinevdec/image.c | 20 +++++++++++++++----- 2 files changed, 32 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/libxinevdec/gdkpixbuf.c b/src/libxinevdec/gdkpixbuf.c index 8815edabe..7ec2069ea 100644 --- a/src/libxinevdec/gdkpixbuf.c +++ b/src/libxinevdec/gdkpixbuf.c @@ -132,9 +132,25 @@ static void image_decode_data (video_decoder_t *this_gen, buf_element_t *buf) { lprintf("image loaded successfully\n"); + /* + * alloc video frame + */ + img = this->stream->video_out->get_frame (this->stream->video_out, width, height, + (double)width / (double)height, + XINE_IMGFMT_YUY2, + VO_BOTH_FIELDS); + + /* crop if allocated frame is smaller than requested */ + if (width > img->width) + width = img->width; + if (height > img->height) + height = img->height; + img->ratio = (double)width / (double)height; + /* * rgb data -> yuv_planes */ + width &= ~1; /* must be even for init_yuv_planes */ init_yuv_planes(&yuv_planes, width, height); n_channels = gdk_pixbuf_get_n_channels (pixbuf); @@ -155,12 +171,8 @@ static void image_decode_data (video_decoder_t *this_gen, buf_element_t *buf) { gdk_pixbuf_unref (pixbuf); /* - * alloc and draw video frame + * draw video frame */ - img = this->stream->video_out->get_frame (this->stream->video_out, width, - height, (double)width/(double)height, - XINE_IMGFMT_YUY2, - VO_BOTH_FIELDS); img->pts = buf->pts; img->duration = 3600; img->bad_frame = 0; diff --git a/src/libxinevdec/image.c b/src/libxinevdec/image.c index b63cfa265..4a872655e 100644 --- a/src/libxinevdec/image.c +++ b/src/libxinevdec/image.c @@ -152,6 +152,20 @@ static void image_decode_data (video_decoder_t *this_gen, buf_element_t *buf) { lprintf("image loaded successfully\n"); + /* + * alloc video frame and set cropping + */ + img = this->stream->video_out->get_frame (this->stream->video_out, width, height, + (double)width / (double)height, + XINE_IMGFMT_YUY2, + VO_BOTH_FIELDS); + + if (width > img->width) + width = img->width; + if (height > img->height) + height = img->height; + img->ratio = (double)width / (double)height; + /* * rgb data -> yuv_planes */ @@ -176,12 +190,8 @@ static void image_decode_data (video_decoder_t *this_gen, buf_element_t *buf) { free(img_buf); /* - * alloc and draw video frame + * draw video frame */ - img = this->stream->video_out->get_frame (this->stream->video_out, width, - height, (double)width/(double)height, - XINE_IMGFMT_YUY2, - VO_BOTH_FIELDS); img->pts = buf->pts; img->duration = 3600; img->bad_frame = 0; -- cgit v1.2.3