|
@@ -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;
|
|
|
}
|
|
|
}
|