diff options
Diffstat (limited to 'dvb-spec')
-rw-r--r-- | dvb-spec/HOWTO-use-the-demux-api | 190 |
1 files changed, 190 insertions, 0 deletions
diff --git a/dvb-spec/HOWTO-use-the-demux-api b/dvb-spec/HOWTO-use-the-demux-api new file mode 100644 index 000000000..2f1fe8c3d --- /dev/null +++ b/dvb-spec/HOWTO-use-the-demux-api @@ -0,0 +1,190 @@ + +------------------------------------------------------------------------------- + +What has changed since the old Nokia OST API? + + file naming: + - /dev/ost directory is now called /dev/dvb + - each DVB adapter has it's own directory /dev/dvb/adapterX + - here you'll find a number of frontend devices /dev/dvb/adapterX/dmxY + - driver header directory is located now in /usr/include/linux/dvb/ + - we have a linux/dvb/version.h file, this is included by all headers which + don't use the original OST API anymore + + struct naming: + - we follow the kernel naming scheme and try to get the namespace clean, + these changes are mostly syntactical + + new feature: + - section filters have a mode field now, you can set not-equal filters + where you will get only notified when the related bits change + +------------------------------------------------------------------------------- + +How to determine the API version? + + Check in your configure script for #include <linux/dvb/version.h>, + include it and check the DVB_API_VERSION #define. + + Currently we use version 3, it will be incremented whenever an API change + meets the CVS main branch. + +------------------------------------------------------------------------------- + +What is a demultiplexer? + + The demultiplexer in your DVB system cares about the routing of an MPEG2 + stream you feed into the DVB adapter either by read/write system calls, + by using stream inputs of the demultiplexer or the frontend(s). + + Using the demux API you can set up the stream routing and set up filters to + filter the interesting parts of the input streams only. + +------------------------------------------------------------------------------- + +I have set up the frontend and now I want to see some video! +What do I have to do? + + When you have an MPEG video decoder on board we can set up the demultiplexer + to feed the related PES packets into the MPEG decoder: + + #include <linux/dvb/dmx.h> + + struct dmx_pes_filter_params pesfilter; + + if ((fd = open("/dev/dvb/adapter0/demux0", O_RDWR) < 0) { + perror ("open failed"); + return -1; + } + + pesfilter.pid = pid; + pesfilter.input = DMX_IN_FRONTEND; + pesfilter.output = DMX_OUT_DECODER; + pesfilter.pes_type = DMX_PES_VIDEO; + pesfilter.flags = DMX_IMMEDIATE_START; + + if (ioctl(fd, DMX_SET_PES_FILTER, &pesfilter) < 0) { + perror ("ioctl DMX_SET_PES_FILTER failed"); + return -1; + } + + This will unpack the payload from all transport stream packets with + payload ID <pid> and feed it into the MPEG decoder. When pes_type is set + to DMX_PES_VIDEO it will be handled as video data. Other types are + DMX_PES_AUDIO, DMX_PES_TELETEXT, DMX_PES_SUBTITLE which will be fed into + the corresponding decoders. + + Open such a PES filter for each substream you want to decode. + + DMX_PES_PCR is used by the decoder to achieve a correct timing syncronisation + for the partial audio/video/... substreams. + + Note that you have to keep the frontend and demux filedescriptor open until + you are not interested in the stream anymore. Old API versions did not shut + down the demodulator and decoder, new driver versions can be configured to + power down after the device is closed. + +------------------------------------------------------------------------------- + +I want to record a stream to disk! How? + + Set up a filter for each substream you want to record as above but set + the pesfilter.output field to DMX_OUT_TAP. Then you can use read() calls + to receive the PES packets. + + When you want to receive transport stream packets use DMX_OUT_TS_TAP and + read the stream from /dev/dvb/adapter0/dvr0. + + Don't forget to keep all device filedescriptors you use open. + +------------------------------------------------------------------------------- + +I want to play back a recorded stream from disk! How? + + Just do the opposite as above. pesfilter.input is now DMX_IN_DVR. + Write your transport stream into the dvr device. + +------------------------------------------------------------------------------- + +What the heck are section filters? + + On some pid's in an MPEG2 stream data is transmitted in form of sections. + These sections describe the stream content, provider data, service + information and other things. + + Here a short list of some pid's where section data is transmitted on DVB + streams: + + 0x00 PAT (Program Association Table - refers to PMT's) + 0x10 NIT (Network Information Table - frequency lists etc) + 0x11 SDT (Service Description Table - service names etc) + 0x12 EIT (Event Information Table - event descriptions etc) + 0x14 TDT/TOT (Time and Date Table, Time Offset Table - time and timezone) + + For a complete list look into the ITU H222.0 (MPEG2) and ETSI EN300468 + standards, there you also find some informations how to parse these sections. + + When you want to receive this data the simple way you can set up a section + filter. + +------------------------------------------------------------------------------- + +How to set up a section filter? + + #include <linux/dvb/dmx.h> + + struct dmx_sct_filter_params sctfilter; + + if ((fd = open("/dev/dvb/adapter0/demux0", O_RDWR) < 0) { + perror ("open failed"); + return -1; + } + + memset(&sctfilter, 0, sizeof(struct dmx_sct_filter_params)); + + sctfilter.pid = pid; + sctfilter.flags = DMX_IMMEDIATE_START; + + if (ioctl(fd, DMX_SET_FILTER, &sctfilter) < 0) { + perror ("ioctl DMX_SET_FILTER failed"); + return -1; + } + + Now start subsequent read() calls to receive your sections and parse them. + Your read-buffer should be at least 4096 bytes if you want to receive complete + sections, otherwise you have to put the parts together manually. + + If your read() call returns -EOVERFLOW you were not fast enough to read/ + process the section data, the internal driver ringbuffer was overflown. + + This error is usually not critical since section data is transmitted + periodically. Anyway, you can adjust the ringbuffer size with the + DMX_SET_BUFFER_SIZE ioctl. + +------------------------------------------------------------------------------- + +How to do table id filtering? + + The struct dmx_sct_filter_params contains two fields filter.filter and + filter.mask. set those mask bits to '1' which should be equal to the filter + bits you set: + + /* set up a TDT filter, table id 0x70 */ + sctfilter.pid = pid; + sctfilter.filter.filter[0] = 0x70; + sctfilter.filter.mask[0] = 0xff; + sctfilter.flags = DMX_IMMEDIATE_START; + + Then submit the DMX_SET_FILTER ioctl. + +------------------------------------------------------------------------------- + +What are not-equal filters? + + When you want to get notified about a new version of a section you can set + up a not-equal filter. Set those filter.mode bits to '1' for which the filter + should pass a section when the corresponding section bit is not equal to the + corresponding filter bit. + +------------------------------------------------------------------------------- + |