PID Filter - Demultiplexer
From LinuxTVWiki
| Line 10: | Line 10: | ||
== PID Filter Sample Code (the easy way) == | == PID Filter Sample Code (the easy way) == | ||
| + | |||
| + | You need to implement a <tt>pid_is_enabled(unsigned short pid)</tt> function if you want to use this code. This implementation can be trivial: simply keep a PID table of 2^13 bits where every bit is set to '1' if this particular PID is enabled and '0' if it is disabled. The entire table has a size of 8kbit (1kByte). <tt>pid_is_enabled(unsigned short pid)</tt> simply tests if the bit on position '<pid>' is set. | ||
| + | |||
| + | You can also organize you filters in a linked list and traverse this every time, but you don't need to do it that complicated... | ||
| + | |||
| + | Here the code: | ||
<tt> | <tt> | ||
Revision as of 20:43, 1 November 2004
Contents |
Introduction
A raw MPEG2 Transport Stream consists data of all the services transmitted on a particular transponder. The task on the receiver side is to filter out the interesting packets and schedule them to their target decoders: Audio packets to the audio-decoder, video packets to the video decoder, subtitle packets to the subtitle decoder etc...
MPEG2 TS packets are identified by the Packet ID, the PID. This is a 13-bit number located in the 2nd and 3rd byte of a TS packet.
PID Filter Algorithm
The algorithm is easy: we simply check the 13 PID bits and look whether this PID is enabled in our PID filter list.
PID Filter Sample Code (the easy way)
You need to implement a pid_is_enabled(unsigned short pid) function if you want to use this code. This implementation can be trivial: simply keep a PID table of 2^13 bits where every bit is set to '1' if this particular PID is enabled and '0' if it is disabled. The entire table has a size of 8kbit (1kByte). pid_is_enabled(unsigned short pid) simply tests if the bit on position '<pid>' is set.
You can also organize you filters in a linked list and traverse this every time, but you don't need to do it that complicated...
Here the code:
static inline
unsigned short ts_pid (const unsigned char *ts_packet)
{
return ((ts_packet[1] & 0x1f) << 8) + ts_packet[2];
}
static
void pidfilter_process_ts_packet (const unsigned char ts_packet[188])
{
unsigned short pid = ts_pid(ts_packet);
if (pid_is_enabled(pid))
pass_packet_to_decoder(ts_packet);
}
PID Filter Sample Code (with sanity checks)
This slightly extended version of the above code contains additional sanity checks that have been useful in the past:
static inline
unsigned short ts_pid (const unsigned char *ts_packet)
{
return ((ts_packet[1] & 0x1f) << 8) + ts_packet[2];
}
static
void pidfilter_process_ts_packet (const unsigned char ts_packet[188])
{
unsigned short pid = ts_pid(ts_packet);
unsigned char scrambling_control;
/**
* check TS error indicator bit and discard broken packets...
*/
if (ts_packet[1] & 0x80) {
bad_packet_counter++;
return;
}
/**
* this makes no sense - however, some transponders like to send
* packets with scrambling bits set which contain gaga data (??).
*
* In any case no scrambled packets should arrive in the demux,
* CSA descramblers are located before this stage of the pipeline,
* so simply discard this garbage...
*/
scrambling_control = (ts_packet[3] >> 6) & 0x03;
if (scrambling_control != 0)
return 0;
if (pid_is_enabled(pid))
pass_packet_to_decoder(ts_packet);
}
Section Filtering
Most DVB Hardware decoders provide so called Section Filters, these allow to specify which MPEG and DVB section tables we want to receive in a particular queue.
But in practice these tables are organized in a way that we want to update our clock, EPG state and DSM-CC caroussels continously and enable all section filters on a particular PID in most cases. So it's questionable whether it makes sense to implement a similiar solution in future designs, simple PID filtering is usually sufficient.
The MPEG table decoder receives now all tables of an enabled PID, these are usually related anyways.