MPEG-2 Frame Aligner
From LinuxTVWiki
m (fixed links) |
m (MPEG2 Frame Aligner moved to MPEG-2 Frame Aligner: name) |
Latest revision as of 22:05, 6 January 2008
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++;
}
}