diff options
| -rw-r--r-- | drivers/media/video/em28xx/em28xx-cards.c | 4 | ||||
| -rw-r--r-- | drivers/media/video/em28xx/em28xx-core.c | 5 | ||||
| -rw-r--r-- | drivers/media/video/em28xx/em28xx-video.c | 40 | ||||
| -rw-r--r-- | drivers/media/video/em28xx/em28xx.h | 3 |
4 files changed, 42 insertions, 10 deletions
diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c index c9e420e8a614..9011a498e5b3 100644 --- a/drivers/media/video/em28xx/em28xx-cards.c +++ b/drivers/media/video/em28xx/em28xx-cards.c | |||
| @@ -2502,6 +2502,10 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev, | |||
| 2502 | if (em28xx_hint_sensor(dev) < 0) | 2502 | if (em28xx_hint_sensor(dev) < 0) |
| 2503 | dev->board.is_webcam = 0; | 2503 | dev->board.is_webcam = 0; |
| 2504 | 2504 | ||
| 2505 | /* It makes no sense to use de-interlacing mode on webcams */ | ||
| 2506 | if (dev->board.is_webcam) | ||
| 2507 | dev->progressive = 1; | ||
| 2508 | |||
| 2505 | /* Do board specific init and eeprom reading */ | 2509 | /* Do board specific init and eeprom reading */ |
| 2506 | em28xx_card_setup(dev); | 2510 | em28xx_card_setup(dev); |
| 2507 | 2511 | ||
diff --git a/drivers/media/video/em28xx/em28xx-core.c b/drivers/media/video/em28xx/em28xx-core.c index 5b78e199abd1..339fffdf6bce 100644 --- a/drivers/media/video/em28xx/em28xx-core.c +++ b/drivers/media/video/em28xx/em28xx-core.c | |||
| @@ -720,7 +720,10 @@ int em28xx_resolution_set(struct em28xx *dev) | |||
| 720 | { | 720 | { |
| 721 | int width, height; | 721 | int width, height; |
| 722 | width = norm_maxw(dev); | 722 | width = norm_maxw(dev); |
| 723 | height = norm_maxh(dev) >> 1; | 723 | height = norm_maxh(dev); |
| 724 | |||
| 725 | if (!dev->progressive) | ||
| 726 | height >>= norm_maxh(dev); | ||
| 724 | 727 | ||
| 725 | em28xx_set_outfmt(dev); | 728 | em28xx_set_outfmt(dev); |
| 726 | 729 | ||
diff --git a/drivers/media/video/em28xx/em28xx-video.c b/drivers/media/video/em28xx/em28xx-video.c index 92ee9c644328..ab079d9256c4 100644 --- a/drivers/media/video/em28xx/em28xx-video.c +++ b/drivers/media/video/em28xx/em28xx-video.c | |||
| @@ -194,15 +194,24 @@ static void em28xx_copy_video(struct em28xx *dev, | |||
| 194 | startread = p; | 194 | startread = p; |
| 195 | remain = len; | 195 | remain = len; |
| 196 | 196 | ||
| 197 | /* Interlaces frame */ | 197 | if (dev->progressive) |
| 198 | if (buf->top_field) | ||
| 199 | fieldstart = outp; | 198 | fieldstart = outp; |
| 200 | else | 199 | else { |
| 201 | fieldstart = outp + bytesperline; | 200 | /* Interlaces two half frames */ |
| 201 | if (buf->top_field) | ||
| 202 | fieldstart = outp; | ||
| 203 | else | ||
| 204 | fieldstart = outp + bytesperline; | ||
| 205 | } | ||
| 202 | 206 | ||
| 203 | linesdone = dma_q->pos / bytesperline; | 207 | linesdone = dma_q->pos / bytesperline; |
| 204 | currlinedone = dma_q->pos % bytesperline; | 208 | currlinedone = dma_q->pos % bytesperline; |
| 205 | offset = linesdone * bytesperline * 2 + currlinedone; | 209 | |
| 210 | if (dev->progressive) | ||
| 211 | offset = linesdone * bytesperline + currlinedone; | ||
| 212 | else | ||
| 213 | offset = linesdone * bytesperline * 2 + currlinedone; | ||
| 214 | |||
| 206 | startwrite = fieldstart + offset; | 215 | startwrite = fieldstart + offset; |
| 207 | lencopy = bytesperline - currlinedone; | 216 | lencopy = bytesperline - currlinedone; |
| 208 | lencopy = lencopy > remain ? remain : lencopy; | 217 | lencopy = lencopy > remain ? remain : lencopy; |
| @@ -376,7 +385,7 @@ static inline int em28xx_isoc_copy(struct em28xx *dev, struct urb *urb) | |||
| 376 | em28xx_isocdbg("Video frame %d, length=%i, %s\n", p[2], | 385 | em28xx_isocdbg("Video frame %d, length=%i, %s\n", p[2], |
| 377 | len, (p[2] & 1) ? "odd" : "even"); | 386 | len, (p[2] & 1) ? "odd" : "even"); |
| 378 | 387 | ||
| 379 | if (!(p[2] & 1)) { | 388 | if (dev->progressive || !(p[2] & 1)) { |
| 380 | if (buf != NULL) | 389 | if (buf != NULL) |
| 381 | buffer_filled(dev, dma_q, buf); | 390 | buffer_filled(dev, dma_q, buf); |
| 382 | get_next_buf(dma_q, &buf); | 391 | get_next_buf(dma_q, &buf); |
| @@ -689,7 +698,10 @@ static int vidioc_g_fmt_vid_cap(struct file *file, void *priv, | |||
| 689 | f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; | 698 | f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; |
| 690 | 699 | ||
| 691 | /* FIXME: TOP? NONE? BOTTOM? ALTENATE? */ | 700 | /* FIXME: TOP? NONE? BOTTOM? ALTENATE? */ |
| 692 | f->fmt.pix.field = dev->interlaced ? | 701 | if (dev->progressive) |
| 702 | f->fmt.pix.field = V4L2_FIELD_NONE; | ||
| 703 | else | ||
| 704 | f->fmt.pix.field = dev->interlaced ? | ||
| 693 | V4L2_FIELD_INTERLACED : V4L2_FIELD_TOP; | 705 | V4L2_FIELD_INTERLACED : V4L2_FIELD_TOP; |
| 694 | 706 | ||
| 695 | mutex_unlock(&dev->lock); | 707 | mutex_unlock(&dev->lock); |
| @@ -753,7 +765,11 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv, | |||
| 753 | f->fmt.pix.bytesperline = (dev->width * fmt->depth + 7) >> 3; | 765 | f->fmt.pix.bytesperline = (dev->width * fmt->depth + 7) >> 3; |
| 754 | f->fmt.pix.sizeimage = f->fmt.pix.bytesperline * height; | 766 | f->fmt.pix.sizeimage = f->fmt.pix.bytesperline * height; |
| 755 | f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; | 767 | f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; |
| 756 | f->fmt.pix.field = V4L2_FIELD_INTERLACED; | 768 | if (dev->progressive) |
| 769 | f->fmt.pix.field = V4L2_FIELD_NONE; | ||
| 770 | else | ||
| 771 | f->fmt.pix.field = dev->interlaced ? | ||
| 772 | V4L2_FIELD_INTERLACED : V4L2_FIELD_TOP; | ||
| 757 | 773 | ||
| 758 | return 0; | 774 | return 0; |
| 759 | } | 775 | } |
| @@ -1659,6 +1675,7 @@ static int em28xx_v4l2_open(struct file *filp) | |||
| 1659 | struct em28xx *dev; | 1675 | struct em28xx *dev; |
| 1660 | enum v4l2_buf_type fh_type; | 1676 | enum v4l2_buf_type fh_type; |
| 1661 | struct em28xx_fh *fh; | 1677 | struct em28xx_fh *fh; |
| 1678 | enum v4l2_field field; | ||
| 1662 | 1679 | ||
| 1663 | dev = em28xx_get_device(minor, &fh_type, &radio); | 1680 | dev = em28xx_get_device(minor, &fh_type, &radio); |
| 1664 | 1681 | ||
| @@ -1700,8 +1717,13 @@ static int em28xx_v4l2_open(struct file *filp) | |||
| 1700 | 1717 | ||
| 1701 | dev->users++; | 1718 | dev->users++; |
| 1702 | 1719 | ||
| 1720 | if (dev->progressive) | ||
| 1721 | field = V4L2_FIELD_NONE; | ||
| 1722 | else | ||
| 1723 | field = V4L2_FIELD_INTERLACED; | ||
| 1724 | |||
| 1703 | videobuf_queue_vmalloc_init(&fh->vb_vidq, &em28xx_video_qops, | 1725 | videobuf_queue_vmalloc_init(&fh->vb_vidq, &em28xx_video_qops, |
| 1704 | NULL, &dev->slock, fh->type, V4L2_FIELD_INTERLACED, | 1726 | NULL, &dev->slock, fh->type, field, |
| 1705 | sizeof(struct em28xx_buffer), fh); | 1727 | sizeof(struct em28xx_buffer), fh); |
| 1706 | 1728 | ||
| 1707 | mutex_unlock(&dev->lock); | 1729 | mutex_unlock(&dev->lock); |
diff --git a/drivers/media/video/em28xx/em28xx.h b/drivers/media/video/em28xx/em28xx.h index 45bd513f62dc..8c2dc38bca9f 100644 --- a/drivers/media/video/em28xx/em28xx.h +++ b/drivers/media/video/em28xx/em28xx.h | |||
| @@ -484,6 +484,9 @@ struct em28xx { | |||
| 484 | int sensor_xres, sensor_yres; | 484 | int sensor_xres, sensor_yres; |
| 485 | int sensor_xtal; | 485 | int sensor_xtal; |
| 486 | 486 | ||
| 487 | /* Allows progressive (e. g. non-interlaced) mode */ | ||
| 488 | int progressive; | ||
| 489 | |||
| 487 | /* Vinmode/Vinctl used at the driver */ | 490 | /* Vinmode/Vinctl used at the driver */ |
| 488 | int vinmode, vinctl; | 491 | int vinmode, vinctl; |
| 489 | 492 | ||
