Commit 80fa4f07 authored by Nikola Forró's avatar Nikola Forró Committed by Mauro Carvalho Chehab

[media] usbtv: discard redundant video fields

There are many dropped fields with some sources, leading to many
redundant fields without counterparts. When this redundant field
is odd, a new frame is pushed containing this odd field interleaved
with whatever was left in the buffer, causing video artifacts.

Do not push a new frame after processing every odd field, but do it
only after those which come after an even field.
Signed-off-by: default avatarNikola Forró <nikola.forro@gmail.com>
Acked-by: default avatarLubomir Rintel <lkundrak@v3.sk>
Signed-off-by: default avatarHans Verkuil <hans.verkuil@cisco.com>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@osg.samsung.com>
parent 9f183020
...@@ -312,20 +312,24 @@ static void usbtv_image_chunk(struct usbtv *usbtv, __be32 *chunk) ...@@ -312,20 +312,24 @@ static void usbtv_image_chunk(struct usbtv *usbtv, __be32 *chunk)
usbtv_chunk_to_vbuf(frame, &chunk[1], chunk_no, odd); usbtv_chunk_to_vbuf(frame, &chunk[1], chunk_no, odd);
usbtv->chunks_done++; usbtv->chunks_done++;
/* Last chunk in a frame, signalling an end */ /* Last chunk in a field */
if (odd && chunk_no == usbtv->n_chunks-1) { if (chunk_no == usbtv->n_chunks-1) {
int size = vb2_plane_size(&buf->vb.vb2_buf, 0); /* Last chunk in a frame, signalling an end */
enum vb2_buffer_state state = usbtv->chunks_done == if (odd && !usbtv->last_odd) {
usbtv->n_chunks ? int size = vb2_plane_size(&buf->vb.vb2_buf, 0);
VB2_BUF_STATE_DONE : enum vb2_buffer_state state = usbtv->chunks_done ==
VB2_BUF_STATE_ERROR; usbtv->n_chunks ?
VB2_BUF_STATE_DONE :
buf->vb.field = V4L2_FIELD_INTERLACED; VB2_BUF_STATE_ERROR;
buf->vb.sequence = usbtv->sequence++;
buf->vb.vb2_buf.timestamp = ktime_get_ns(); buf->vb.field = V4L2_FIELD_INTERLACED;
vb2_set_plane_payload(&buf->vb.vb2_buf, 0, size); buf->vb.sequence = usbtv->sequence++;
vb2_buffer_done(&buf->vb.vb2_buf, state); buf->vb.vb2_buf.timestamp = ktime_get_ns();
list_del(&buf->list); vb2_set_plane_payload(&buf->vb.vb2_buf, 0, size);
vb2_buffer_done(&buf->vb.vb2_buf, state);
list_del(&buf->list);
}
usbtv->last_odd = odd;
} }
spin_unlock_irqrestore(&usbtv->buflock, flags); spin_unlock_irqrestore(&usbtv->buflock, flags);
...@@ -639,6 +643,7 @@ static int usbtv_start_streaming(struct vb2_queue *vq, unsigned int count) ...@@ -639,6 +643,7 @@ static int usbtv_start_streaming(struct vb2_queue *vq, unsigned int count)
if (usbtv->udev == NULL) if (usbtv->udev == NULL)
return -ENODEV; return -ENODEV;
usbtv->last_odd = 1;
usbtv->sequence = 0; usbtv->sequence = 0;
return usbtv_start(usbtv); return usbtv_start(usbtv);
} }
......
...@@ -95,6 +95,7 @@ struct usbtv { ...@@ -95,6 +95,7 @@ struct usbtv {
int width, height; int width, height;
int n_chunks; int n_chunks;
int iso_size; int iso_size;
int last_odd;
unsigned int sequence; unsigned int sequence;
struct urb *isoc_urbs[USBTV_ISOC_TRANSFERS]; struct urb *isoc_urbs[USBTV_ISOC_TRANSFERS];
......
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