Commit 6ee0faa5 authored by Lubomir Rintel's avatar Lubomir Rintel Committed by Mauro Carvalho Chehab

[media] usbtv: Throw corrupted frames away

Ignore out of order data and mark incomplete buffers as errored.
This gets rid of annoying flicker due to occassional garbage from hardware.
Signed-off-by: default avatarLubomir Rintel <lkundrak@v3.sk>
Cc: Hans Verkuil <hans.verkuil@cisco.com>
Cc: Mauro Carvalho Chehab <mchehab@redhat.com>
Cc: linux-kernel@vger.kernel.org
Cc: linux-media@vger.kernel.org
Signed-off-by: default avatarHans Verkuil <hans.verkuil@cisco.com>
Signed-off-by: default avatarMauro Carvalho Chehab <m.chehab@samsung.com>
Cc: stable@vger.kernel.org
parent 30800724
...@@ -88,6 +88,7 @@ struct usbtv { ...@@ -88,6 +88,7 @@ struct usbtv {
/* Number of currently processed frame, useful find /* Number of currently processed frame, useful find
* out when a new one begins. */ * out when a new one begins. */
u32 frame_id; u32 frame_id;
int chunks_done;
enum { enum {
USBTV_COMPOSITE_INPUT, USBTV_COMPOSITE_INPUT,
...@@ -299,8 +300,13 @@ static void usbtv_image_chunk(struct usbtv *usbtv, u32 *chunk) ...@@ -299,8 +300,13 @@ static void usbtv_image_chunk(struct usbtv *usbtv, u32 *chunk)
return; return;
/* Beginning of a frame. */ /* Beginning of a frame. */
if (chunk_no == 0) if (chunk_no == 0) {
usbtv->frame_id = frame_id; usbtv->frame_id = frame_id;
usbtv->chunks_done = 0;
}
if (usbtv->frame_id != frame_id)
return;
spin_lock_irqsave(&usbtv->buflock, flags); spin_lock_irqsave(&usbtv->buflock, flags);
if (list_empty(&usbtv->bufs)) { if (list_empty(&usbtv->bufs)) {
...@@ -315,16 +321,21 @@ static void usbtv_image_chunk(struct usbtv *usbtv, u32 *chunk) ...@@ -315,16 +321,21 @@ static void usbtv_image_chunk(struct usbtv *usbtv, u32 *chunk)
/* Copy the chunk data. */ /* Copy the chunk data. */
usbtv_chunk_to_vbuf(frame, &chunk[1], chunk_no, odd); usbtv_chunk_to_vbuf(frame, &chunk[1], chunk_no, odd);
usbtv->chunks_done++;
/* Last chunk in a frame, signalling an end */ /* Last chunk in a frame, signalling an end */
if (odd && chunk_no == USBTV_CHUNKS-1) { if (odd && chunk_no == USBTV_CHUNKS-1) {
int size = vb2_plane_size(&buf->vb, 0); int size = vb2_plane_size(&buf->vb, 0);
enum vb2_buffer_state state = usbtv->chunks_done ==
USBTV_CHUNKS ?
VB2_BUF_STATE_DONE :
VB2_BUF_STATE_ERROR;
buf->vb.v4l2_buf.field = V4L2_FIELD_INTERLACED; buf->vb.v4l2_buf.field = V4L2_FIELD_INTERLACED;
buf->vb.v4l2_buf.sequence = usbtv->sequence++; buf->vb.v4l2_buf.sequence = usbtv->sequence++;
v4l2_get_timestamp(&buf->vb.v4l2_buf.timestamp); v4l2_get_timestamp(&buf->vb.v4l2_buf.timestamp);
vb2_set_plane_payload(&buf->vb, 0, size); vb2_set_plane_payload(&buf->vb, 0, size);
vb2_buffer_done(&buf->vb, VB2_BUF_STATE_DONE); vb2_buffer_done(&buf->vb, state);
list_del(&buf->list); list_del(&buf->list);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment