mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2025-02-17 12:46:33 +07: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] =
|
static const unsigned char pac_sof_marker[5] =
|
||||||
{ 0xff, 0xff, 0x00, 0xff, 0x96 };
|
{ 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,
|
static unsigned char *pac_find_sof(struct gspca_dev *gspca_dev,
|
||||||
unsigned char *m, int len)
|
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 */
|
/* Search for the SOF marker (fixed part) in the header */
|
||||||
for (i = 0; i < len; i++) {
|
for (i = 0; i < len; i++) {
|
||||||
if (m[i] == pac_sof_marker[sd->sof_read]) {
|
switch (sd->sof_read) {
|
||||||
sd->sof_read++;
|
case 0:
|
||||||
if (sd->sof_read == sizeof(pac_sof_marker)) {
|
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,
|
PDEBUG(D_FRAM,
|
||||||
"SOF found, bytes to analyze: %u."
|
"SOF found, bytes to analyze: %u."
|
||||||
" Frame starts at byte #%u",
|
" Frame starts at byte #%u",
|
||||||
len, i + 1);
|
len, i + 1);
|
||||||
sd->sof_read = 0;
|
sd->sof_read = 0;
|
||||||
return m + i + 1;
|
return m + i + 1;
|
||||||
|
break;
|
||||||
|
case 0xff:
|
||||||
|
sd->sof_read = 2;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
sd->sof_read = 0;
|
||||||
}
|
}
|
||||||
} else {
|
break;
|
||||||
|
default:
|
||||||
sd->sof_read = 0;
|
sd->sof_read = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user