Skip to content

Commit

Permalink
[media] em28xx: fix capture type setting in em28xx_urb_data_copy_vbi()
Browse files Browse the repository at this point in the history
Set capture type to 1 (video start) when the video frame start header is
detected. This bug didn't cause any trouble, because this type of header is
never received in vbi mode.
Fix it, because we want to use this function with disabled vbi in the future.
Also start with capture type -1 to avoid processing of corrupted/incomplete
frame data which is usually received at streaming start (especially when
USB bulk transfers are used).

Signed-off-by: Frank Schäfer <fschaefer.oss@googlemail.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
  • Loading branch information
Frank Schaefer authored and Mauro Carvalho Chehab committed Dec 22, 2012
1 parent 3610f58 commit 0455eeb
Show file tree
Hide file tree
Showing 2 changed files with 11 additions and 17 deletions.
26 changes: 10 additions & 16 deletions drivers/media/usb/em28xx/em28xx-video.c
Original file line number Diff line number Diff line change
Expand Up @@ -593,7 +593,7 @@ static inline int em28xx_urb_data_copy_vbi(struct em28xx *dev, struct urb *urb)
dev->capture_type = 0;
dev->vbi_read = 0;
em28xx_isocdbg("VBI START HEADER!!!\n");
dev->cur_field = p[2];
dev->top_field = !(p[2] & 1);
p += 4;
len -= 4;
} else if (p[0] == 0x88 && p[1] == 0x88 &&
Expand All @@ -603,6 +603,8 @@ static inline int em28xx_urb_data_copy_vbi(struct em28xx *dev, struct urb *urb)
len -= 4;
} else if (p[0] == 0x22 && p[1] == 0x5a) {
/* start video */
dev->capture_type = 1;
dev->top_field = !(p[2] & 1);
p += 4;
len -= 4;
}
Expand All @@ -619,8 +621,7 @@ static inline int em28xx_urb_data_copy_vbi(struct em28xx *dev, struct urb *urb)
em28xx_isocdbg("dev->vbi_read > vbi_size\n");
} else if ((dev->vbi_read + len) < vbi_size) {
/* This entire frame is VBI data */
if (dev->vbi_read == 0 &&
(!(dev->cur_field & 1))) {
if (dev->vbi_read == 0 && dev->top_field) {
/* Brand new frame */
if (vbi_buf != NULL)
vbi_buffer_filled(dev,
Expand All @@ -636,12 +637,8 @@ static inline int em28xx_urb_data_copy_vbi(struct em28xx *dev, struct urb *urb)

if (dev->vbi_read == 0) {
vbi_dma_q->pos = 0;
if (vbi_buf != NULL) {
if (dev->cur_field & 1)
vbi_buf->top_field = 0;
else
vbi_buf->top_field = 1;
}
if (vbi_buf != NULL)
vbi_buf->top_field = dev->top_field;
}

dev->vbi_read += len;
Expand All @@ -662,7 +659,7 @@ static inline int em28xx_urb_data_copy_vbi(struct em28xx *dev, struct urb *urb)

if (dev->capture_type == 1) {
dev->capture_type = 2;
if (dev->progressive || !(dev->cur_field & 1)) {
if (dev->progressive || dev->top_field) {
if (buf != NULL)
buffer_filled(dev, dma_q, buf);
get_next_buf(dma_q, &buf);
Expand All @@ -671,12 +668,8 @@ static inline int em28xx_urb_data_copy_vbi(struct em28xx *dev, struct urb *urb)
else
outp = videobuf_to_vmalloc(&buf->vb);
}
if (buf != NULL) {
if (dev->cur_field & 1)
buf->top_field = 0;
else
buf->top_field = 1;
}
if (buf != NULL)
buf->top_field = dev->top_field;

dma_q->pos = 0;
}
Expand Down Expand Up @@ -774,6 +767,7 @@ buffer_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb,
urb_init = 1;

if (urb_init) {
dev->capture_type = -1;
if (em28xx_vbi_supported(dev) == 1)
rc = em28xx_init_usb_xfer(dev, EM28XX_ANALOG_MODE,
dev->analog_xfer_bulk,
Expand Down
2 changes: 1 addition & 1 deletion drivers/media/usb/em28xx/em28xx.h
Original file line number Diff line number Diff line change
Expand Up @@ -563,7 +563,7 @@ struct em28xx {
/* vbi related state tracking */
int capture_type;
int vbi_read;
unsigned char cur_field;
unsigned char top_field:1;
unsigned int vbi_width;
unsigned int vbi_height; /* lines per field */

Expand Down

0 comments on commit 0455eeb

Please sign in to comment.