Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f52dc448 authored by Lubomir Rintel's avatar Lubomir Rintel Committed by Mauro Carvalho Chehab
Browse files

[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>
parent a34cacab
Loading
Loading
Loading
Loading
+13 −2
Original line number Diff line number Diff line
@@ -89,6 +89,7 @@ struct usbtv {
	/* Number of currently processed frame, useful find
	 * out when a new one begins. */
	u32 frame_id;
	int chunks_done;

	int iso_size;
	unsigned int sequence;
@@ -242,8 +243,13 @@ static void usbtv_image_chunk(struct usbtv *usbtv, u32 *chunk)
		return;

	/* Beginning of a frame. */
	if (chunk_no == 0)
	if (chunk_no == 0) {
		usbtv->frame_id = frame_id;
		usbtv->chunks_done = 0;
	}

	if (usbtv->frame_id != frame_id)
		return;

	spin_lock_irqsave(&usbtv->buflock, flags);
	if (list_empty(&usbtv->bufs)) {
@@ -258,16 +264,21 @@ static void usbtv_image_chunk(struct usbtv *usbtv, u32 *chunk)

	/* Copy the chunk data. */
	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_CHUNKS-1) {
		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.sequence = usbtv->sequence++;
		v4l2_get_timestamp(&buf->vb.v4l2_buf.timestamp);
		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);
	}