mirror of
https://github.com/edk2-porting/linux-next.git
synced 2024-12-23 12:43:55 +08:00
[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: Nikola Forró <nikola.forro@gmail.com> Acked-by: Lubomir Rintel <lkundrak@v3.sk> Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
This commit is contained in:
parent
9f1830206d
commit
80fa4f07fd
@ -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->chunks_done++;
|
||||
|
||||
/* Last chunk in a frame, signalling an end */
|
||||
if (odd && chunk_no == usbtv->n_chunks-1) {
|
||||
int size = vb2_plane_size(&buf->vb.vb2_buf, 0);
|
||||
enum vb2_buffer_state state = usbtv->chunks_done ==
|
||||
usbtv->n_chunks ?
|
||||
VB2_BUF_STATE_DONE :
|
||||
VB2_BUF_STATE_ERROR;
|
||||
/* Last chunk in a field */
|
||||
if (chunk_no == usbtv->n_chunks-1) {
|
||||
/* Last chunk in a frame, signalling an end */
|
||||
if (odd && !usbtv->last_odd) {
|
||||
int size = vb2_plane_size(&buf->vb.vb2_buf, 0);
|
||||
enum vb2_buffer_state state = usbtv->chunks_done ==
|
||||
usbtv->n_chunks ?
|
||||
VB2_BUF_STATE_DONE :
|
||||
VB2_BUF_STATE_ERROR;
|
||||
|
||||
buf->vb.field = V4L2_FIELD_INTERLACED;
|
||||
buf->vb.sequence = usbtv->sequence++;
|
||||
buf->vb.vb2_buf.timestamp = ktime_get_ns();
|
||||
vb2_set_plane_payload(&buf->vb.vb2_buf, 0, size);
|
||||
vb2_buffer_done(&buf->vb.vb2_buf, state);
|
||||
list_del(&buf->list);
|
||||
buf->vb.field = V4L2_FIELD_INTERLACED;
|
||||
buf->vb.sequence = usbtv->sequence++;
|
||||
buf->vb.vb2_buf.timestamp = ktime_get_ns();
|
||||
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);
|
||||
@ -639,6 +643,7 @@ static int usbtv_start_streaming(struct vb2_queue *vq, unsigned int count)
|
||||
if (usbtv->udev == NULL)
|
||||
return -ENODEV;
|
||||
|
||||
usbtv->last_odd = 1;
|
||||
usbtv->sequence = 0;
|
||||
return usbtv_start(usbtv);
|
||||
}
|
||||
|
@ -95,6 +95,7 @@ struct usbtv {
|
||||
int width, height;
|
||||
int n_chunks;
|
||||
int iso_size;
|
||||
int last_odd;
|
||||
unsigned int sequence;
|
||||
struct urb *isoc_urbs[USBTV_ISOC_TRANSFERS];
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user