usbtv: discard redundant video fields
PATCH 1/1 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.
--- drivers/media/usb/usbtv/usbtv-video.c | 33 +++++++++++++++++++-------------- drivers/media/usb/usbtv/usbtv.h | 1 + 2 files changed, 20 insertions(+), 14 deletions(-)
drivers/media/usb/usbtv/usbtv-video.c +19 -14
@@ -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 ; - - buf->vb.field =V4L2_FIELD_INTERLACED ; - buf->vb.sequence = usbtv->sequence++; -v4l2_get_timestamp (&buf->vb.timestamp); -vb2_set_plane_payload (&buf->vb.vb2_buf,0 , size); -vb2_buffer_done (&buf->vb.vb2_buf, state); -list_del (&buf->list); +/* 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++; +v4l2_get_timestamp (&buf->vb.timestamp); +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);
@@ -640,6 +644,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); }
drivers/media/usb/usbtv/usbtv.h +1 -0
@@ -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 ];
Signature · 1 line
2.6.4
Quoted 9 lines · Nikola Forró
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ó <[email protected]>
Thanks,
Lubo