This is a combination of commit d24a252a15e48ba154e52e73292cede6b151550a and 6cc3cc71cda657e17fa924b2f11f0fb8a096ad62 from upstream, adapted to work with 1.7.1. Works to fix bugs with recent uvc kernel drivers (tested on 3.16.2). James 2014 diff -ur guvcview-src-1.7.1/src/v4l2uvc.c guvcview-new/src/v4l2uvc.c --- guvcview-src-1.7.1/src/v4l2uvc.c 2013-07-22 21:00:46.000000000 +0700 +++ guvcview-new/src/v4l2uvc.c 2014-10-09 02:13:49.000000000 +0700 @@ -643,8 +643,8 @@ //rgb or bgr (8-8-8) // alloc a temp buffer for converting to YUYV // rgb buffer - tmpbuf_size = width * height * 3; - vd->tmpbuffer = g_new0(unsigned char, tmpbuf_size); + //tmpbuf_size = width * height * 3; + //vd->tmpbuffer = g_new0(unsigned char, tmpbuf_size); framebuf_size = framesizeIn; vd->framebuffer = g_new0(unsigned char, framebuf_size); @@ -878,6 +878,8 @@ { int ret = VDIN_OK; int framesizeIn =(width * height << 1);//2 bytes per pixel + int max_size = framesizeIn; + switch (format) { case V4L2_PIX_FMT_JPEG: @@ -899,52 +901,112 @@ break; case V4L2_PIX_FMT_UYVY: - memcpy(vd->tmpbuffer, vd->mem[vd->buf.index],vd->buf.bytesused); + /* + * check vd->buf.bytesused some drivers (or libusb) + * seem to return a bigger value than the format requires + */ + if(vd->buf.bytesused < max_size) + max_size = vd->buf.bytesused; + memcpy(vd->tmpbuffer, vd->mem[vd->buf.index], max_size); uyvy_to_yuyv(vd->framebuffer, vd->tmpbuffer, width, height); break; case V4L2_PIX_FMT_YVYU: - memcpy(vd->tmpbuffer, vd->mem[vd->buf.index],vd->buf.bytesused); + /* + * check vd->buf.bytesused some drivers (or libusb) + * seem to return a bigger value than the format requires + */ + if(vd->buf.bytesused < max_size) + max_size = vd->buf.bytesused; + memcpy(vd->tmpbuffer, vd->mem[vd->buf.index], max_size); yvyu_to_yuyv(vd->framebuffer, vd->tmpbuffer, width, height); break; case V4L2_PIX_FMT_YYUV: - memcpy(vd->tmpbuffer, vd->mem[vd->buf.index],vd->buf.bytesused); + /* + * check vd->buf.bytesused some drivers (or libusb) + * seem to return a bigger value than the format requires + */ + if(vd->buf.bytesused < max_size) + max_size = vd->buf.bytesused; + memcpy(vd->tmpbuffer, vd->mem[vd->buf.index], max_size); yyuv_to_yuyv(vd->framebuffer, vd->tmpbuffer, width, height); break; case V4L2_PIX_FMT_YUV420: - memcpy(vd->tmpbuffer, vd->mem[vd->buf.index],vd->buf.bytesused); + /* + * check vd->buf.bytesused some drivers (or libusb) + * seem to return a bigger value than the format requires + */ + if(vd->buf.bytesused < max_size) + max_size = vd->buf.bytesused; + memcpy(vd->tmpbuffer, vd->mem[vd->buf.index], max_size); yuv420_to_yuyv(vd->framebuffer, vd->tmpbuffer, width, height); break; case V4L2_PIX_FMT_YVU420: - memcpy(vd->tmpbuffer, vd->mem[vd->buf.index],vd->buf.bytesused); + /* + * check vd->buf.bytesused some drivers (or libusb) + * seem to return a bigger value than the format requires + */ + if(vd->buf.bytesused < max_size) + max_size = vd->buf.bytesused; + memcpy(vd->tmpbuffer, vd->mem[vd->buf.index], max_size); yvu420_to_yuyv(vd->framebuffer, vd->tmpbuffer, width, height); break; case V4L2_PIX_FMT_NV12: - memcpy(vd->tmpbuffer, vd->mem[vd->buf.index],vd->buf.bytesused); + /* + * check vd->buf.bytesused some drivers (or libusb) + * seem to return a bigger value than the format requires + */ + if(vd->buf.bytesused < max_size) + max_size = vd->buf.bytesused; + memcpy(vd->tmpbuffer, vd->mem[vd->buf.index], max_size); nv12_to_yuyv(vd->framebuffer, vd->tmpbuffer, width, height); break; case V4L2_PIX_FMT_NV21: - memcpy(vd->tmpbuffer, vd->mem[vd->buf.index],vd->buf.bytesused); + /* + * check vd->buf.bytesused some drivers (or libusb) + * seem to return a bigger value than the format requires + */ + if(vd->buf.bytesused < max_size) + max_size = vd->buf.bytesused; + memcpy(vd->tmpbuffer, vd->mem[vd->buf.index], max_size); nv21_to_yuyv(vd->framebuffer, vd->tmpbuffer, width, height); break; case V4L2_PIX_FMT_NV16: - memcpy(vd->tmpbuffer, vd->mem[vd->buf.index],vd->buf.bytesused); + /* + * check vd->buf.bytesused some drivers (or libusb) + * seem to return a bigger value than the format requires + */ + if(vd->buf.bytesused < max_size) + max_size = vd->buf.bytesused; + memcpy(vd->tmpbuffer, vd->mem[vd->buf.index], max_size); nv16_to_yuyv(vd->framebuffer, vd->tmpbuffer, width, height); break; case V4L2_PIX_FMT_NV61: - memcpy(vd->tmpbuffer, vd->mem[vd->buf.index],vd->buf.bytesused); + /* + * check vd->buf.bytesused some drivers (or libusb) + * seem to return a bigger value than the format requires + */ + if(vd->buf.bytesused < max_size) + max_size = vd->buf.bytesused; + memcpy(vd->tmpbuffer, vd->mem[vd->buf.index], max_size); nv61_to_yuyv(vd->framebuffer, vd->tmpbuffer, width, height); break; case V4L2_PIX_FMT_Y41P: - memcpy(vd->tmpbuffer, vd->mem[vd->buf.index],vd->buf.bytesused); + /* + * check vd->buf.bytesused some drivers (or libusb) + * seem to return a bigger value than the format requires + */ + if(vd->buf.bytesused < max_size) + max_size = vd->buf.bytesused; + memcpy(vd->tmpbuffer, vd->mem[vd->buf.index], max_size); y41p_to_yuyv(vd->framebuffer, vd->tmpbuffer, width, height); break; @@ -964,17 +1026,35 @@ break; case V4L2_PIX_FMT_SPCA501: - memcpy(vd->tmpbuffer, vd->mem[vd->buf.index],vd->buf.bytesused); + /* + * check vd->buf.bytesused some drivers (or libusb) + * seem to return a bigger value than the format requires + */ + if(vd->buf.bytesused < max_size) + max_size = vd->buf.bytesused; + memcpy(vd->tmpbuffer, vd->mem[vd->buf.index], max_size); s501_to_yuyv(vd->framebuffer, vd->tmpbuffer, width, height); break; case V4L2_PIX_FMT_SPCA505: - memcpy(vd->tmpbuffer, vd->mem[vd->buf.index],vd->buf.bytesused); + /* + * check vd->buf.bytesused some drivers (or libusb) + * seem to return a bigger value than the format requires + */ + if(vd->buf.bytesused < max_size) + max_size = vd->buf.bytesused; + memcpy(vd->tmpbuffer, vd->mem[vd->buf.index], max_size); s505_to_yuyv(vd->framebuffer, vd->tmpbuffer, width, height); break; case V4L2_PIX_FMT_SPCA508: - memcpy(vd->tmpbuffer, vd->mem[vd->buf.index],vd->buf.bytesused); + /* + * check vd->buf.bytesused some drivers (or libusb) + * seem to return a bigger value than the format requires + */ + if(vd->buf.bytesused < max_size) + max_size = vd->buf.bytesused; + memcpy(vd->tmpbuffer, vd->mem[vd->buf.index], max_size); s508_to_yuyv(vd->framebuffer, vd->tmpbuffer, width, height); break; @@ -1022,12 +1102,28 @@ break; case V4L2_PIX_FMT_RGB24: - memcpy(vd->tmpbuffer, vd->mem[vd->buf.index], vd->buf.bytesused); - rgb2yuyv(vd->tmpbuffer, vd->framebuffer, width, height); + /* + * check vd->buf.bytesused some drivers (or libusb) + * seem to return a bigger value than the format requires + */ + // max_size = width * height * 3; + //if(vd->buf.bytesused < max_size) + // max_size = vd->buf.bytesused; + //memcpy(vd->tmpbuffer, vd->mem[vd->buf.index], max_size); + //rgb2yuyv(vd->tmpbuffer, vd->framebuffer, width, height); + rgb2yuyv(vd->mem[vd->buf.index], vd->framebuffer, width, height); break; case V4L2_PIX_FMT_BGR24: - memcpy(vd->tmpbuffer, vd->mem[vd->buf.index],vd->buf.bytesused); - bgr2yuyv(vd->tmpbuffer, vd->framebuffer, width, height); + /* + * check vd->buf.bytesused some drivers (or libusb) + * seem to return a bigger value than the format requires + */ + // max_size = width * height * 3; + //if(vd->buf.bytesused < max_size) + // max_size = vd->buf.bytesused; + //memcpy(vd->tmpbuffer, vd->mem[vd->buf.index], max_size); + //bgr2yuyv(vd->tmpbuffer, vd->framebuffer, width, height); + bgr2yuyv(vd->mem[vd->buf.index], vd->framebuffer, width, height); break; default: