mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-18 09:44:18 +08:00
V4L/DVB (13192): gspca - pac_common: redesign function for finding Start Of Frame
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. Acked-by: Hans de Goede <hdegoede@redhat.com> Signed-off-by: Marton Nemeth <nm127@freemail.hu> Signed-off-by: Jean-Francois Moine <moinejf@free.fr> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
This commit is contained in:
parent
760c466c66
commit
e0d49e2d3a
@ -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(struct gspca_dev *gspca_dev,
|
||||
|
||||
/* 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;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user