[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-ID: <4AC90BBF.9040803@freemail.hu>
Date: Sun, 04 Oct 2009 22:55:27 +0200
From: Németh Márton <nm127@...email.hu>
To: Jean-Francois Moine <moinejf@...e.fr>,
Thomas Kaiser <thomas@...ser-linux.li>,
Kyle Guinn <elyk03@...il.com>,
Theodore Kilgore <kilgota@...urn.edu>
CC: V4L Mailing List <linux-media@...r.kernel.org>,
LKML <linux-kernel@...r.kernel.org>,
ltp-list@...ts.sourceforge.net
Subject: [PATCH] pac_common: redesign function for finding Start Of Frame
From: Márton Németh <nm127@...email.hu>
The original implementation of pac_find_sof() does not always find
the Start Of Frame (SOF) marker. Replace it with a state machine
based design.
The change was tested with Labtec Webcam 2200.
Signed-off-by: Márton Németh <nm127@...email.hu>
---
--- linux-2.6.32-rc1.orig/drivers/media/video/gspca/pac_common.h 2009-09-10 00:13:59.000000000 +0200
+++ linux-2.6.32-rc1/drivers/media/video/gspca/pac_common.h 2009-10-04 21:49:19.000000000 +0200
@@ -33,6 +33,45 @@
static const unsigned char pac_sof_marker[5] =
{ 0xff, 0xff, 0x00, 0xff, 0x96 };
+/*
+ The following state machine finds the SOF marker sequence
+ 0xff, 0xff, 0x00, 0xff, 0x96 in a byte stream.
+
+ +----------+
+ | 0: START |<---------------\
+ +----------+<-\ |
+ | \---/otherwise |
+ v 0xff |
+ +----------+ otherwise |
+ | 1 |--------------->*
+ | | ^
+ +----------+ |
+ | |
+ v 0xff |
+ +----------+<-\0xff |
+ /->| |--/ |
+ | | 2 |--------------->*
+ | | | otherwise ^
+ | +----------+ |
+ | | |
+ | v 0x00 |
+ | +----------+ |
+ | | 3 | |
+ | | |--------------->*
+ | +----------+ otherwise ^
+ | | |
+ 0xff | v 0xff |
+ | +----------+ |
+ \--| 4 | |
+ | |----------------/
+ +----------+ otherwise
+ |
+ v 0x96
+ +----------+
+ | FOUND |
+ +----------+
+*/
+
static unsigned char *pac_find_sof(struct gspca_dev *gspca_dev,
unsigned char *m, int len)
{
@@ -41,17 +80,54 @@ static unsigned char *pac_find_sof(struc
/* Search for the SOF marker (fixed part) in the header */
for (i = 0; i < len; i++) {
- if (m[i] == pac_sof_marker[sd->sof_read]) {
- sd->sof_read++;
- if (sd->sof_read == sizeof(pac_sof_marker)) {
+ switch (sd->sof_read) {
+ case 0:
+ if (m[i] == 0xff)
+ sd->sof_read = 1;
+ break;
+ case 1:
+ if (m[i] == 0xff)
+ sd->sof_read = 2;
+ else
+ sd->sof_read = 0;
+ break;
+ case 2:
+ switch (m[i]) {
+ case 0x00:
+ sd->sof_read = 3;
+ break;
+ case 0xff:
+ /* stay in this state */
+ break;
+ default:
+ sd->sof_read = 0;
+ }
+ break;
+ case 3:
+ if (m[i] == 0xff)
+ sd->sof_read = 4;
+ else
+ sd->sof_read = 0;
+ break;
+ case 4:
+ switch (m[i]) {
+ case 0x96:
+ /* Pattern found */
PDEBUG(D_FRAM,
"SOF found, bytes to analyze: %u."
" Frame starts at byte #%u",
len, i + 1);
sd->sof_read = 0;
return m + i + 1;
+ break;
+ case 0xff:
+ sd->sof_read = 2;
+ break;
+ default:
+ sd->sof_read = 0;
}
- } else {
+ break;
+ default:
sd->sof_read = 0;
}
}
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Powered by blists - more mailing lists