Linux OV511 Driver:
Technical Notes Vol. 5
Subject:  OV518 Isochronous Packet Format
2001/02/24, driver version 1.34 (experimental)

Note: The following information is subject to change, and may be superceded by future tech. notes without notice.

The OV518 uses a different (undocumented) isochronous packet format than the OV511. This immediately apparant in that the OV511 parsing code in ov511_move_data() does not find a Start of Frame (SOF) or End of Frame (EOF) packet. However, one can see the packet headers using the printph=1 module parameter, and by using a USB sniffer. This document will attempt to uncover the secrets of the OV511 packet format.


The first task in decoding the data format is to see what the camera is putting out, and try to find patterns (like an SOF/EOF header) in it. Using a packet sniffer, I managed to find a complete (compressed?) image frame. It begins as follows:

00 00 00 00 03 00 55 e0 ab 48 69 68 00 00 00 00
The first number is a 16-bit offset. For comparison. here is what appears to be an SOF packet from the Linux driver:
00 00 00 00 03 00 65 f0 00 00 00
I am guessing that the first four bytes are always zero and are used to identify an SOF packet. The OV518 most likely ensures that the image data never produces this pattern by changing the LSB of one of the four bytes to 1 if necessary. Thus, this can be used to reliably detect SOF.

Next comes the 5th and 6th bytes, which also have the same value in both cases (3 and 0). These could be flags, or they could be part of the SOF identifier.

The next two bytes seem to be flags, since they are nearly the same, but still have three different bits between them. The first of these bytes looks very much like the "frame header byte" from the OV511. The only difference in the chip configurations that I can find is that compression was enabled in Windows. Windows may have been using the GBR422 color format, too (Linux uses YUV420).

The remaining four bytes seem to be an additional, separate, header based on the fact that it appears by itself often in the data below. Strangely, they don't appear in the Linux version, but then, neither do any other data. In any case, we can now identify an SOF packet with some certainty.


The next task is to find and decode the EOF packet format. Finding it is fairly easy, since we know the size of each packet (896 bytes, or 380 in hex). Here is the end of the first packet and the beginning of the second under Windows:

a0 51 45 14 e4 ea 29 0d 25 2d 25 28 00 00 00 00
ad 4d 34 bd 00 00 00 00 ab 48 69 7b 00 00 00 00
ab 48 69 68 00 00 00 00 ab 48 69 68 00 00 00 00
ab 48 69 7b d1 48 2a 2e ab 48 69 68 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
The repitition in the data is too perfect to be just a coincidence. The 'ab 48 69 68' sequence appears here quite a few times. Nearly all of the second packet, which starts at 380h, is zero. It looks like the image frame came to an end slightly after the beginning of the second packet, and wasted a whole packet in the process. It is probably not possible for a packet to be both SOF and EOF anyway, though.

The end of the second packet is definitely something special:

00 00 00 00 00 00 00 00 00 00 00 00 55 e0 16 48
0f 1f 1f 3f 1f 1f 3f 1f 3f 7f 7f 3f 1f 3f 7f 3f
3f 3f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f ff ff ff
1f 3f 3f 3f 3f 3f 7f 3f 3f 7f 7f 3f 7f 7f 7f 7f
7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f ff ff ff
ab 48 69 68 00 00 00 00 ab 48 69 68 a7 0e b4 86
5a 43 45 2d 20 a2 9b 2f 4a 60 a2 93 bd 2d 06 81
First, we have '55 e0' again, which was in the SOF header. Immediately after that is '16 48', which is the contents of OV518 registers 39h and 3ah, respectively, at 352x288. This is probably a size tag, just like the OV511 had after its EOF headers, except that this is at the end of the frame.

After this, we have a 64-byte table of some sort. This is the same size as the quantization tables and the zigzag table in the OV511, so this might be a dynamically-generated version of either one of those.

At the beginning of the next packet, instead of an SOF header as one would expect, we get the same four-byte sequence seen at the end of the first packet. Perhaps these data are not a new frame per se, but instead some sort of differential encoding of the next frame. I tend to doubt this, based on the fact that the OV518 function calls in the OV511 compression code that I have look basically the same as the OV511 calls, and because the next frame is roughly the same as the first in terms of length and content.

Analysis of the rest of the data:

Conspicuously missing is the packet numbering that the OV511 had. Since all of the alternate sizes are even numbers, it looks like this feature was removed. However, the OV518 docs claim that the alternates can have an extra byte, presumably for a packet number. I don't see how this could be enabled without re-enumerating the device, though.

Continuing on past the second frame, we find a large stretch of nothing but zeros. There isn't even a header. Perhaps frames are being dropped to regulate the frame rate. This is stupid, because it doesn't save any USB bandwidth. The best this can do is save CPU utilization.

At the beginning of the 15th packet, data begin to appear again:

00 00 00 00 03 00 54 e0 ab 48 69 68 a4 a8 bb d1
4b 49 4b 42 d2 1a 28 a0 51 4d 6e 94 ca 29 29 68
a2 8a 4a 5a 41 45 45 45 14 51 4e 1d 69 0d 25 14
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Note that the header this time has a '54' instead of a '55'. Perhaps bit zero of this byte is an odd/even flag, as it was in the OV511.

After this, the data becomes very "spread out", with blocks of solid data from 8 to 80 bytes in length, separated by large runs of zeros. I guess the compression has finally kicked in at this point. Strangely, I didn't see any SOF or EOF markers anywhere in there.

Copyright © 2001 Mark McClelland

Version History:
Date Version Change
2001/02/24 1.0 Initial Release