MPEG-2 Frame Aligner: Difference between revisions

From LinuxTVWiki
Jump to navigation Jump to search
No edit summary
 
 
(2 intermediate revisions by 2 users not shown)
Line 1: Line 1:
== Introduction ==
== Introduction ==


Most hardware does not provides aligned MPEG2 data streams, also the linux-dvb API's DVR device can get out of sync if the MPEG2 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.
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.


MPEG2 TS packets can be 188 (without FEC data) or 204 bytes long (including 16 FEC bytes).
MPEG-2 TS packets can be 188 (without FEC data) or 204 bytes long (including 16 FEC bytes).


== Algorithm ==
== Algorithm ==


The MPEG2 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 MPEG2 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_-_Demultiplexer|PID filter]]
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_-_Demultiplexer|PID filter]]


== Sample Code ==
== Sample Code ==
Line 56: Line 56:
}
}
</tt>
</tt>

[[Category:Technology]]

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