MPEG-2 Frame Aligner
Introduction
Most hardware does not provides aligned MPEG-2 data streams, also the linux-dvb API's DVR device can get out of sync if the MPEG-2 TS data stream is interrupted, e.g. due to DMA buffer overflows or if the demod delivers partial packets in case of uncorrectable block errors.
MPEG-2 TS packets can be 188 (without FEC data) or 204 bytes long (including 16 FEC bytes).
Algorithm
The MPEG-2 Frame Aligner can get implemented as simple state machine, whenever we are in an "out-of-sync"-state we check all followig bytes until we encounter a MPEG-2 TS Sync Byte (0x47). From then on we check every 188 or 204 bytes if the next 0x47-sync-byte is present. If so the packet is passed to the PID filter
Sample Code
The following sample code works for 188-byte packets. This code is taken from the LinuxDVB kernel driver (originally written by Florian Schirmer) and thus GPL'd.
A more generic and robust version based on a state machine should not be too hard to implement and would be able to synchronize both 188- and 204-byte-packets. Please let us know when you feel in the mood to implement+test this, we'll be happy to help whereever possible.
struct framealigner { char tsbuf[188]; int tsbufp; }; void framealigner_process_ts_data (struct framealigner *fa, const char *buf, unsigned int count) { unsigned int p = 0, i, j; if ((i = fa->tsbufp)) { if (count < (j=188-i)) { memcpy(&fa->tsbuf[i], buf, count); fa->tsbufp += count; return; } memcpy(&fa->tsbuf[i], buf, j); pidfilter_ts_packet(fa->tsbuf); fa->tsbufp = 0; p += j; } while (p < count) { if (buf[p] == 0x47) { if (count-p >= 188) { pidfilter_process_ts_packet(buf+p); p += 188; } else { i = count - p; memcpy(fa->tsbuf, buf+p, i); fa->tsbufp = i; return; } } else p++; } }