dvb/linuxtv-dvb/doc HOWTO-use-the-demux-api HOWTO-use-the-frontend-api README.valgrind convert.sh valgrind-2.1.0-dvb.patch
Thomas Schmidt
pkg-vdr-dvb-changes@lists.alioth.debian.org
Sun, 23 May 2004 09:09:06 +0000
Update of /cvsroot/pkg-vdr-dvb/dvb/linuxtv-dvb/doc
In directory haydn:/tmp/cvs-serv7693/dvb/linuxtv-dvb/doc
Added Files:
HOWTO-use-the-demux-api HOWTO-use-the-frontend-api
README.valgrind convert.sh valgrind-2.1.0-dvb.patch
Log Message:
added files from release 1.1.1
--- NEW FILE: HOWTO-use-the-frontend-api ---
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 DVB frontend?
the term 'frontend' refers to this part of the DVB adapter which receives
an MPEG transport stream and will feed it later into the Demultiplexer.
Whenever you want to receive MPEG streams via satellite, antenna or cable
you have to set up your frontend first.
When you watch on your DVB card or into your SetTopBox the frontend is usually
the combination of a demodulator chip and a small silver metal box with the
HF electronic. Usually the demodulator is built into this metal box.
-------------------------------------------------------------------------------
What do you have to do to set up your frontend?
First you should try to determine the type of your frontend.
#include <linux/dvb/frontend.h>
struct dvb_frontend_info info;
int fd;
if ((fd = open ("/dev/dvb/adapter0/frontend0", O_RDWR)) < 0) {
perror ("open failed");
return -1;
}
ioctl (fd, FE_GET_INFO, &info);
Now the info.type field contains either FE_QPSK for a satellite frontend,
FE_QAM for a cable frontend or FE_OFDM for a terrestrial frontend.
The info.name field contains a human readable vendor string of your frontend.
You might want to show this in your GUI to make support easier.
The info struct also contains the frequency limits, frontend capabilities,
the frequency and symbol rate tolerance the AFC or timing recovery loop can
compensate and some fields you are not interested in.
-------------------------------------------------------------------------------
How to set up a cable or terrestrial frontend?
Fill a dvb_frontend_parameters struct according to the data in your channel
list. For cable frontends, you have to fill the qam field of the union, for
terrestrial frontends it's the ofdm field.
Apply it using the FE_SET_FRONTEND_PARAMETERS ioctl. That's all.
-------------------------------------------------------------------------------
How to set up a satellite frontend?
Before you set the frontend parameters you have to setup DiSEqC switches and
the LNB. Modern LNB's switch their polarisation depending of the DC component
of their input (13V for vertical polarisation, 18V for horizontal). When they
see a 22kHz signal at their input they switch into the high band and use a
somewhat higher intermediate frequency to downconvert the signal.
When your satellite equipment contains a DiSEqC switch device to switch
between different satellites you have to send the according DiSEqC commands,
usually command 0x38. Take a look into the DiSEqC spec available at
http://www.eutelsat.org/ for the complete list of commands.
The burst signal is used in old equipments and by cheap satellite A/B
switches.
Voltage, burst and 22kHz tone have to be consistent to the values encoded in
the DiSEqC commands.
The complete sequence to set up switch and LNB according to the DiSEqC spec
looks like this:
- stop continous tone
- setup polarisation voltage
- wait at least 15ms.
- send your DiSEqC commands using the FE_DISEQC_SEND_MASTER_CMD ioctl
- wait another 15ms
- send burst
- wait 15ms
- start the 22kHz tone when you tune to a transponder in the high band
You can copy'n'paste this code sniplets from szap.c or diseqc.c, both
test programs are distributed with the linuxtv DVB driver source. All
DiSEqC related ioctls are passed to the frontend device filedescriptor.
Depending on the equipment setup, you may or may not have to repeat the
DiSEqC commands (only commands, not the whole sequence) for cascaded devices
and can pack committed/uncommitted switch messages. See the DiSEqC spec for
details.
In an advanced program, you probably want to send this sequence using an
asynchonous thread. Since sleep() and similiar calls are pthread
cancellation points, it's really simple to stop a running DiSEqC thread
before submitting a new sequence.
Now you have set up switch and LNB, a valid RF signal of the requested
satellite should be at the input of the demodulator.
Fill a dvb_frontend_parameters struct using the qpsk field in the union and
apply it using the FE_SET_FRONTEND_PARAMETERS ioctl.
-------------------------------------------------------------------------------
How do I check the frontend status?
You can perform a poll()/select() on the frontend file descriptor. Whenever
one of the frontend status bits toggles the poll returns. Now you can
submit the FE_GET_EVENT ioctl to receive the new status bits. When you used
one of the XXX_AUTO parameters you might want to use the event.parameters
field to determine the correct tuned parameters and update your channel list.
If you want to simulate the old FE_FAILURE_EV frontend event behaviour you
should check the FE_TIMEDOUT bit, this will be set when the tuning was not
successful within a few seconds.
When you get a FE_REINIT event the frontend was reinitialized. You should
send the DiSEqC sequence again if you use a QPSK frontend.
The FE_READ_SIGNAL_STRENGTH ioctl will fill the signal strength into the
16 LSBs of the passed argument. The signal strength range is from 0 (bad)
to 65535 (too good to be true).
FE_READ_SNR returns the signal noise ratio. range 0 (bad) to 65535 (not real).
For both the signal strength and signal noise ratio a value of about 60-70%
means a good signal.
Not all FE_READ_XXX ioctl()s are supported by all hardware. Check the ioctl
return value, if it's less than 0 this ioctl is not supported.
-------------------------------------------------------------------------------
What does FE_ENABLE_HIGH_LNB_VOLTAGE?
some STBs (the dbox2 for example) support somewhat higher LNB voltages than
13 and 18V. They add about 0.5V to compensate voltage drop on long cables.
This ioctl is not supported on all boxes. You probably want to show an extra
menu item in your GUI when this ioctl returns a zero value.
-------------------------------------------------------------------------------
How to do powermanagement, the FE_SET_POWER_STATE ioctls are gone?
An open() call on the frontend device powers up and initializes the
demodulator and switches on LNB power if necessairy. The DiSEqC bus won't
be resetted, do this manually if you think you need to.
Some seconds after the device is closed (and was not opened by a new process)
LNB power and the demodulator are shut down into sleep mode.
You can configure the shutdown timeout using the shutdown_timeout module
parameter. To disable power management set shutdown_timeout=0.
-------------------------------------------------------------------------------
--- NEW FILE: valgrind-2.1.0-dvb.patch ---
diff -rupN valgrind-2.1.0.orig/coregrind/vg_syscalls.c valgrind-2.1.0/coregrind/vg_syscalls.c
--- valgrind-2.1.0.orig/coregrind/vg_syscalls.c 2003-12-12 08:46:54.000000000 +0100
+++ valgrind-2.1.0/coregrind/vg_syscalls.c 2004-02-04 17:30:14.000000000 +0100
@@ -2739,6 +2739,237 @@ PRE(ioctl)
case CDROM_CLEAR_OPTIONS: /* 0x5321 */
break;
+ /* DVB (Digital Video Broadcasting) related stuff
+ * http://linuxtv.org/
+ */
+ case AUDIO_STOP:
+ case AUDIO_PLAY:
+ case AUDIO_PAUSE:
+ case AUDIO_CONTINUE:
+ case AUDIO_SELECT_SOURCE:
+ case AUDIO_SET_MUTE:
+ case AUDIO_SET_AV_SYNC:
+ case AUDIO_SET_BYPASS_MODE:
+ case AUDIO_CHANNEL_SELECT:
+ break;
+ case AUDIO_GET_STATUS:
+ SYSCALL_TRACK( pre_mem_write,tid, "ioctl(AUDIO_GET_STATUS)", arg3,
+ sizeof(audio_status_t));
+ break;
+ case AUDIO_GET_CAPABILITIES:
+ SYSCALL_TRACK( pre_mem_write,tid, "ioctl(AUDIO_GET_CAPABILITIES)", arg3,
+ sizeof(unsigned int));
+ break;
+ case AUDIO_CLEAR_BUFFER:
+ case AUDIO_SET_ID:
+ break;
+ case AUDIO_SET_MIXER:
+ SYSCALL_TRACK( pre_mem_read,tid, "ioctl(AUDIO_SET_MIXER)", arg3,
+ sizeof(audio_mixer_t));
+ break;
+ case AUDIO_SET_STREAMTYPE:
+ case AUDIO_SET_EXT_ID:
+ break;
+ case AUDIO_SET_ATTRIBUTES:
+ SYSCALL_TRACK( pre_mem_read,tid, "ioctl(AUDIO_SET_ATTRIBUTES)", arg3,
+ sizeof(audio_attributes_t));
+ break;
+ case AUDIO_SET_KARAOKE:
+ SYSCALL_TRACK( pre_mem_read,tid, "ioctl(AUDIO_SET_KARAOKE)", arg3,
+ sizeof(audio_karaoke_t));
+ break;
+ case CA_RESET:
+ break;
+ case CA_GET_CAP:
+ SYSCALL_TRACK( pre_mem_write,tid, "ioctl(CA_GET_CAP)", arg3,
+ sizeof(ca_caps_t));
+ break;
+ case CA_GET_SLOT_INFO:
+ SYSCALL_TRACK( pre_mem_write,tid, "ioctl(CA_GET_SLOT_INFO)", arg3,
+ sizeof(ca_slot_info_t));
+ break;
+ case CA_GET_DESCR_INFO:
+ SYSCALL_TRACK( pre_mem_write,tid, "ioctl(CA_GET_DESCR_INFO)", arg3,
+ sizeof(ca_descr_info_t));
+ break;
+ case CA_GET_MSG:
+ SYSCALL_TRACK( pre_mem_write,tid, "ioctl(CA_GET_MSG)", arg3,
+ sizeof(ca_msg_t));
+ break;
+ case CA_SEND_MSG:
+ SYSCALL_TRACK( pre_mem_read,tid, "ioctl(CA_SEND_MSG)", arg3,
+ sizeof(ca_msg_t));
+ break;
+ case CA_SET_DESCR:
+ SYSCALL_TRACK( pre_mem_read,tid, "ioctl(CA_SET_DESCR)", arg3,
+ sizeof(ca_descr_t));
+ break;
+ case CA_SET_PID:
+ SYSCALL_TRACK( pre_mem_read,tid, "ioctl(CA_SET_PID)", arg3,
+ sizeof(ca_pid_t));
+ break;
+ case DMX_START:
+ case DMX_STOP:
+ break;
+ case DMX_SET_FILTER:
+ SYSCALL_TRACK( pre_mem_read,tid, "ioctl(DMX_SET_FILTER)", arg3,
+ sizeof(struct dmx_sct_filter_params));
+ break;
+ case DMX_SET_PES_FILTER:
+ SYSCALL_TRACK( pre_mem_read,tid, "ioctl(DMX_SET_PES_FILTER)", arg3,
+ sizeof(struct dmx_pes_filter_params));
+ break;
+ case DMX_SET_BUFFER_SIZE:
+ break;
+ case DMX_GET_EVENT:
+ SYSCALL_TRACK( pre_mem_write,tid, "ioctl(DMX_GET_EVENT)", arg3,
+ sizeof(struct dmx_event));
+ break;
+ case DMX_GET_PES_PIDS:
+ SYSCALL_TRACK( pre_mem_write,tid, "ioctl(DMX_GET_PES_PIDS)", arg3,
+ 5 * sizeof(uint16_t));
+ break;
+ case DMX_GET_CAPS:
+ SYSCALL_TRACK( pre_mem_write,tid, "ioctl(DMX_GET_CAPS)", arg3,
+ sizeof(dmx_caps_t));
+ break;
+ case DMX_GET_STC:
+ SYSCALL_TRACK( pre_mem_write,tid, "ioctl(DMX_GET_STC)", arg3,
+ sizeof(struct dmx_stc));
+ break;
+ case DMX_SET_SOURCE:
+ SYSCALL_TRACK( pre_mem_read,tid, "ioctl(DMX_SET_SOURCE)", arg3,
+ sizeof(dmx_source_t));
+ break;
+ case FE_GET_INFO:
+ SYSCALL_TRACK( pre_mem_write,tid, "ioctl(FE_GET_INFO)", arg3,
+ sizeof(struct dvb_frontend_info));
+ break;
+ case FE_DISEQC_RESET_OVERLOAD:
+ break;
+ case FE_DISEQC_SEND_MASTER_CMD:
+ SYSCALL_TRACK( pre_mem_read,tid, "ioctl(FE_DISEQC_SEND_MASTER_CMD)", arg3,
+ sizeof(struct dvb_diseqc_master_cmd));
+ break;
+ case FE_DISEQC_RECV_SLAVE_REPLY:
+ SYSCALL_TRACK( pre_mem_write,tid, "ioctl(FE_DISEQC_RECV_SLAVE_REPLY)", arg3,
+ sizeof(struct dvb_diseqc_slave_reply));
+ break;
+ case FE_DISEQC_SEND_BURST:
+ case FE_SET_TONE:
+ case FE_SET_VOLTAGE:
+ case FE_ENABLE_HIGH_LNB_VOLTAGE:
+ break;
+ case FE_READ_STATUS:
+ SYSCALL_TRACK( pre_mem_write,tid, "ioctl(FE_READ_STATUS)", arg3,
+ sizeof(fe_status_t));
+ break;
+ case FE_READ_BER:
+ SYSCALL_TRACK( pre_mem_write,tid, "ioctl(FE_READ_BER)", arg3,
+ sizeof(uint32_t));
+ break;
+ case FE_READ_SIGNAL_STRENGTH:
+ SYSCALL_TRACK( pre_mem_write,tid, "ioctl(FE_READ_SIGNAL_STRENGTH)", arg3,
+ sizeof(uint16_t));
+ break;
+ case FE_READ_SNR:
+ SYSCALL_TRACK( pre_mem_write,tid, "ioctl(FE_READ_SNR)", arg3,
+ sizeof(uint16_t));
+ break;
+ case FE_READ_UNCORRECTED_BLOCKS:
+ SYSCALL_TRACK( pre_mem_write,tid, "ioctl(FE_READ_UNCORRECTED_BLOCKS)", arg3,
+ sizeof(uint32_t));
+ break;
+ case FE_SET_FRONTEND:
+ SYSCALL_TRACK( pre_mem_read,tid, "ioctl(FE_SET_FRONTEND)", arg3,
+ sizeof(struct dvb_frontend_parameters));
+ break;
+ case FE_GET_FRONTEND:
+ SYSCALL_TRACK( pre_mem_write,tid, "ioctl(FE_GET_FRONTEND)", arg3,
+ sizeof(struct dvb_frontend_parameters));
+ break;
+ case FE_GET_EVENT:
+ SYSCALL_TRACK( pre_mem_write,tid, "ioctl(FE_GET_EVENT)", arg3,
+ sizeof(struct dvb_frontend_event));
+ break;
+ case NET_ADD_IF:
+ SYSCALL_TRACK( pre_mem_read,tid, "ioctl(NET_ADD_IF (pid, uint16_t))",
+ (int) &(((struct dvb_net_if *) arg3)->pid),
+ sizeof(((struct dvb_net_if *) arg3)->pid));
+ SYSCALL_TRACK( pre_mem_write,tid, "ioctl(NET_ADD_IF (if_num, uint16_t))",
+ (int) &(((struct dvb_net_if *) arg3)->if_num),
+ sizeof(((struct dvb_net_if *) arg3)->if_num));
+ break;
+ case NET_REMOVE_IF:
+ break;
+ case NET_GET_IF:
+ SYSCALL_TRACK( pre_mem_read,tid, "ioctl(NET_GET_IF (if_num, uint16_t))",
+ (int) &(((struct dvb_net_if *) arg3)->if_num),
+ sizeof(((struct dvb_net_if *) arg3)->if_num));
+ SYSCALL_TRACK( pre_mem_write,tid, "ioctl(NET_GET_IF (pid, uint16_t))",
+ (int) &(((struct dvb_net_if *) arg3)->pid),
+ sizeof(((struct dvb_net_if *) arg3)->pid));
+ break;
+ case OSD_SEND_CMD:
+ SYSCALL_TRACK( pre_mem_read,tid, "ioctl(OSD_SEND_CMD)", arg3,
+ sizeof(osd_cmd_t));
+ break;
+ case VIDEO_STOP:
+ case VIDEO_PLAY:
+ case VIDEO_FREEZE:
+ case VIDEO_CONTINUE:
+ case VIDEO_SELECT_SOURCE:
+ case VIDEO_SET_BLANK:
+ break;
+ case VIDEO_GET_STATUS:
+ SYSCALL_TRACK( pre_mem_write,tid, "ioctl(VIDEO_GET_STATUS)", arg3,
+ sizeof(struct video_status));
+ break;
+ case VIDEO_GET_EVENT:
+ SYSCALL_TRACK( pre_mem_write,tid, "ioctl(VIDEO_GET_EVENT)", arg3,
+ sizeof(struct video_event));
+ break;
+ case VIDEO_SET_DISPLAY_FORMAT:
+ break;
+ case VIDEO_STILLPICTURE:
+ SYSCALL_TRACK( pre_mem_read,tid, "ioctl(VIDEO_STILLPICTURE)", arg3,
+ sizeof(struct video_still_picture));
+ break;
+ case VIDEO_FAST_FORWARD:
+ case VIDEO_SLOWMOTION:
+ break;
+ case VIDEO_GET_CAPABILITIES:
+ SYSCALL_TRACK( pre_mem_write,tid, "ioctl(VIDEO_GET_CAPABILITIES)", arg3,
+ sizeof(unsigned int));
+ break;
+ case VIDEO_CLEAR_BUFFER:
+ case VIDEO_SET_ID:
+ case VIDEO_SET_STREAMTYPE:
+ case VIDEO_SET_FORMAT:
+ case VIDEO_SET_SYSTEM:
+ break;
+ case VIDEO_SET_HIGHLIGHT:
+ SYSCALL_TRACK( pre_mem_read,tid, "ioctl(VIDEO_SET_HIGHLIGHT)", arg3,
+ sizeof(video_highlight_t));
+ break;
+ case VIDEO_SET_SPU:
+ SYSCALL_TRACK( pre_mem_read,tid, "ioctl(VIDEO_SET_SPU)", arg3,
+ sizeof(video_spu_t));
+ break;
+ case VIDEO_SET_SPU_PALETTE:
+ SYSCALL_TRACK( pre_mem_read,tid, "ioctl(VIDEO_SET_SPU_PALETTE)", arg3,
+ sizeof(video_spu_palette_t));
+ break;
+ case VIDEO_GET_NAVI:
+ SYSCALL_TRACK( pre_mem_write,tid, "ioctl(VIDEO_GET_NAVI)", arg3,
+ sizeof(video_navi_pack_t));
+ break;
+#if 0
+ /* FIXME: conflicts with NET_REMOVE_IF - both are _IO('o', 53) */
+ case VIDEO_SET_ATTRIBUTES:
+ break;
+#endif
+
/* We don't have any specific information on it, so
try to do something reasonable based on direction and
size bits. The encoding scheme is described in
@@ -3092,6 +3323,197 @@ POST(ioctl)
case CDROM_CLEAR_OPTIONS: /* 0x5321 */
break;
+ /* DVB (Digital Video Broadcasting) related stuff
+ * http://linuxtv.org/
+ */
+ case AUDIO_STOP:
+ case AUDIO_PLAY:
+ case AUDIO_PAUSE:
+ case AUDIO_CONTINUE:
+ case AUDIO_SELECT_SOURCE:
+ case AUDIO_SET_MUTE:
+ case AUDIO_SET_AV_SYNC:
+ case AUDIO_SET_BYPASS_MODE:
+ case AUDIO_CHANNEL_SELECT:
+ break;
+ case AUDIO_GET_STATUS:
+ if (res == 0)
+ VG_TRACK( post_mem_write,arg3, sizeof(audio_status_t));
+ break;
+ case AUDIO_GET_CAPABILITIES:
+ if (res == 0)
+ VG_TRACK( post_mem_write,arg3, sizeof(unsigned int));
+ break;
+ case AUDIO_CLEAR_BUFFER:
+ case AUDIO_SET_ID:
+ break;
+ case AUDIO_SET_MIXER:
+ break;
+ case AUDIO_SET_STREAMTYPE:
+ case AUDIO_SET_EXT_ID:
+ break;
+ case AUDIO_SET_ATTRIBUTES:
+ break;
+ case AUDIO_SET_KARAOKE:
+ break;
+ case CA_RESET:
+ break;
+ case CA_GET_CAP:
+ if (res == 0)
+ VG_TRACK( post_mem_write,arg3, sizeof(ca_caps_t));
+ break;
+ case CA_GET_SLOT_INFO:
+ if (res == 0)
+ VG_TRACK( post_mem_write,arg3, sizeof(ca_slot_info_t));
+ break;
+ case CA_GET_DESCR_INFO:
+ if (res == 0)
+ VG_TRACK( post_mem_write,arg3, sizeof(ca_descr_info_t));
+ break;
+ case CA_GET_MSG:
+ if (res == 0)
+ VG_TRACK( post_mem_write,arg3, sizeof(ca_msg_t));
+ break;
+ case CA_SEND_MSG:
+ break;
+ case CA_SET_DESCR:
+ break;
+ case CA_SET_PID:
+ break;
+ case DMX_START:
+ case DMX_STOP:
+ break;
+ case DMX_SET_FILTER:
+ break;
+ case DMX_SET_PES_FILTER:
+ break;
+ case DMX_SET_BUFFER_SIZE:
+ break;
+ case DMX_GET_EVENT:
+ if (res == 0)
+ VG_TRACK( post_mem_write,arg3, sizeof(struct dmx_event));
+ break;
+ case DMX_GET_PES_PIDS:
+ if (res == 0)
+ VG_TRACK( post_mem_write,arg3, 5*sizeof(uint16_t));
+ break;
+ case DMX_GET_CAPS:
+ if (res == 0)
+ VG_TRACK( post_mem_write,arg3, sizeof(dmx_caps_t));
+ break;
+ case DMX_GET_STC:
+ if (res == 0)
+ VG_TRACK( post_mem_write,arg3, sizeof(struct dmx_stc));
+ break;
+ case DMX_SET_SOURCE:
+ break;
+ case FE_GET_INFO:
+ if (res == 0)
+ VG_TRACK( post_mem_write,arg3, sizeof(struct dvb_frontend_info));
+ break;
+ case FE_DISEQC_RESET_OVERLOAD:
+ break;
+ case FE_DISEQC_SEND_MASTER_CMD:
+ break;
+ case FE_DISEQC_RECV_SLAVE_REPLY:
+ if (res == 0)
+ VG_TRACK( post_mem_write,arg3, sizeof(struct dvb_diseqc_slave_reply));
+ break;
+ case FE_DISEQC_SEND_BURST:
+ case FE_SET_TONE:
+ case FE_SET_VOLTAGE:
+ case FE_ENABLE_HIGH_LNB_VOLTAGE:
+ break;
+ case FE_READ_STATUS:
+ if (res == 0)
+ VG_TRACK( post_mem_write,arg3, sizeof(fe_status_t));
+ break;
+ case FE_READ_BER:
+ if (res == 0)
+ VG_TRACK( post_mem_write,arg3, sizeof(uint32_t));
+ break;
+ case FE_READ_SIGNAL_STRENGTH:
+ if (res == 0)
+ VG_TRACK( post_mem_write,arg3, sizeof(uint16_t));
+ break;
+ case FE_READ_SNR:
+ if (res == 0)
+ VG_TRACK( post_mem_write,arg3, sizeof(uint16_t));
+ break;
+ case FE_READ_UNCORRECTED_BLOCKS:
+ if (res == 0)
+ VG_TRACK( post_mem_write,arg3, sizeof(uint32_t));
+ break;
+ case FE_SET_FRONTEND:
+ break;
+ case FE_GET_FRONTEND:
+ if (res == 0)
+ VG_TRACK( post_mem_write,arg3, sizeof(struct dvb_frontend_parameters));
+ break;
+ case FE_GET_EVENT:
+ if (res == 0)
+ VG_TRACK( post_mem_write,arg3, sizeof(struct dvb_frontend_event));
+ break;
+ case NET_ADD_IF:
+ if (res == 0)
+ VG_TRACK( post_mem_write,arg3, sizeof(struct dvb_net_if));
+ break;
+ case NET_REMOVE_IF:
+ break;
+ case NET_GET_IF:
+ if (res == 0)
+ VG_TRACK( post_mem_write,arg3, sizeof(struct dvb_net_if));
+ break;
+ case OSD_SEND_CMD:
+ break;
+ case VIDEO_STOP:
+ case VIDEO_PLAY:
+ case VIDEO_FREEZE:
+ case VIDEO_CONTINUE:
+ case VIDEO_SELECT_SOURCE:
+ case VIDEO_SET_BLANK:
+ break;
+ case VIDEO_GET_STATUS:
+ if (res == 0)
+ VG_TRACK( post_mem_write,arg3, sizeof(struct video_status));
+ break;
+ case VIDEO_GET_EVENT:
+ if (res == 0)
+ VG_TRACK( post_mem_write,arg3, sizeof(struct video_event));
+ break;
+ case VIDEO_SET_DISPLAY_FORMAT:
+ break;
+ case VIDEO_STILLPICTURE:
+ break;
+ case VIDEO_FAST_FORWARD:
+ case VIDEO_SLOWMOTION:
+ break;
+ case VIDEO_GET_CAPABILITIES:
+ if (res == 0)
+ VG_TRACK( post_mem_write,arg3, sizeof(unsigned int));
+ break;
+ case VIDEO_CLEAR_BUFFER:
+ case VIDEO_SET_ID:
+ case VIDEO_SET_STREAMTYPE:
+ case VIDEO_SET_FORMAT:
+ case VIDEO_SET_SYSTEM:
+ break;
+ case VIDEO_SET_HIGHLIGHT:
+ break;
+ case VIDEO_SET_SPU:
+ break;
+ case VIDEO_SET_SPU_PALETTE:
+ break;
+ case VIDEO_GET_NAVI:
+ if (res == 0)
+ VG_TRACK( post_mem_write,arg3, sizeof(video_navi_pack_t));
+ break;
+#if 0
+ /* FIXME: conflicts with NET_REMOVE_IF - both are _IO('o', 53) */
+ case VIDEO_SET_ATTRIBUTES:
+ break;
+#endif
+
/* We don't have any specific information on it, so
try to do something reasonable based on direction and
size bits. The encoding scheme is described in
diff -rupN valgrind-2.1.0.orig/coregrind/vg_unsafe.h valgrind-2.1.0/coregrind/vg_unsafe.h
--- valgrind-2.1.0.orig/coregrind/vg_unsafe.h 2003-11-19 23:07:14.000000000 +0100
+++ valgrind-2.1.0/coregrind/vg_unsafe.h 2004-02-04 17:08:31.000000000 +0100
@@ -93,6 +93,13 @@
#include <sys/poll.h>
+#include <linux/dvb/audio.h>
+#include <linux/dvb/ca.h>
+#include <linux/dvb/dmx.h>
+#include <linux/dvb/frontend.h>
+#include <linux/dvb/net.h>
+#include <linux/dvb/osd.h>
+#include <linux/dvb/video.h>
/*--------------------------------------------------------------------*/
/*--- end vg_unsafe.h ---*/
--- NEW FILE: HOWTO-use-the-demux-api ---
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 you 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
packet 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 (if these deocders exist in hardware or firmware).
DMX_PES_TELETEXT usually means VBI insertion by the PAL/NTSC encoder for display
on a connected TV set. If you want to avoid sending the data to one of the
decoders, use pes_type = DMX_PES_OTHER.
You must open the demux device once for each PES filter you want to set.
E.g. if you want audio and video, you must have two distinct file descriptors
for the two filters.
DMX_PES_PCR is used by the decoder to achieve a correct timing syncronisation
between the 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 PES data.
When you want to receive transport stream packets use DMX_OUT_TS_TAP and
read the stream from /dev/dvb/adapterX/dvrY. The dvr device gives you
a multiplex of all filtered PES data with DMX_OUT_TS_TAP. E.g. if you
want to record video and audio, open demuxX twice and set two PEs filters
with DMX_OUT_TS_TAP, and open dvrX once to read the TS.
[ The current API does not allow you to specify you an input/output
routing for section filters. So you can't get multiplexed section
data from the dvr device. ]
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.
The filter comprises 16 bytes covering byte 0 and byte 3..17 in a section,
thus excluding bytes 1 and 2 (the length field of a section).
-------------------------------------------------------------------------------
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.
-------------------------------------------------------------------------------
--- NEW FILE: convert.sh ---
#!/bin/sh
# this script will help you to convert sources written for an
# ancient version of the DVB API to the current DVB API (version 3)
# (mostly namespace cleanups)
if test -z $1 || ! test -d $1 ; then
echo usage: $0 \<original directory\>
exit -1
fi
echo clone $1 to $1.new
TOPDIR=`pwd`
cd $TOPDIR/$1
for x in `find . -type d` ; do
echo mkdir -p $TOPDIR/$1.new/$x
mkdir -p $TOPDIR/$1.new/$x
done
for x in `find . -type f` ; do
echo patch $TOPDIR/$1/$x
echo \ \ \ to $TOPDIR/$1.new/$x...
cat $TOPDIR/$1/$x | sed \
-e "s/_OST_OSD_H_/_DVBOSD_H_/g" \
-e "s/_OST_CA_H_/_CA_H_/g" \
-e "s/ca_slot_info_s/ca_slot_info/g" \
-e "s/ca_descr_info_s/ca_descr_info/g" \
-e "s/ca_cap_t/ca_caps_t/g" \
-e "s/ca_cap_s/ca_caps/g" \
-e "s/ca_msg_s/ca_msg/g" \
-e "s/ca_descr_s/ca_descr/g" \
-e "s/_OST_NET_H_/_DVBNET_H_/g" \
-e "s/_OST_AUDIO_H_/_DVBAUDIO_H_/g" \
-e "s/audioStreamSource_t/audio_stream_source_t/g" \
-e "s/audioPlayState_t/audio_play_state_t/g" \
-e "s/audioChannelSelect_t/audio_channel_select_t/g" \
-e "s/audioStatus/audio_status/g" \
-e "s/AVSyncState/AV_sync_state/g" \
-e "s/muteState/mute_state/g" \
-e "s/playState/play_state/g" \
-e "s/channelSelect/channel_select/g" \
-e "s/bypassMode/bypass_mode/g" \
-e "s/audioMixer/audio_mixer/g" \
-e "s/audioKaraoke/audio_karaoke/g" \
-e "s/audioAttributes_t/audio_attributes_t/g" \
-e "s/_OST_VIDEO_H_/_DVBVIDEO_H_/g" \
-e "s/videoFormat/video_format/g" \
-e "s/videoSystem_t/video_system_t/g" \
-e "s/videoDisplayFormat_t/video_displayformat_t/g" \
-e "s/videoStreamSource_t/video_stream_source_t/g" \
-e "s/videoPlayState_t/video_play_state_t/g" \
-e "s/videoEvent/video_event/g" \
-e "s/videoStatus/video_status/g" \
-e "s/videoBlank/video_blank/g" \
-e "s/playState/play_state/g" \
-e "s/streamSource/stream_source/g" \
-e "s/displayFormat/display_format/g" \
-e "s/videoDisplayStillPicture/video_still_picture/g" \
-e "s/videoHighlight/video_highlight/g" \
-e "s/videoSPUPalette/video_spu_palette/g" \
-e "s/videoSPU/video_spu/g" \
-e "s/streamID/stream_id/g" \
-e "s/videoNaviPack/video_navi_pack/g" \
-e "s/videoAttributes_t/video_attributes_t/g" \
-e "s/_OST_DMX_H_/_DMX_H_/g" \
-e "s/dmxOutput_t/dmx_output_t/g" \
-e "s/dmxInput_t/dmx_input_t/g" \
-e "s/dmxPesType_t/dmx_pes_type_t/g" \
-e "s/dmxScramblingStatus_t/dmx_scrambling_status_t/g" \
-e "s/dmxFilter/dmx_filter/g" \
-e "s/dmxSctFilterParams/dmx_sct_filter_params/g" \
-e "s/dmxPesFilterParams/dmx_pes_filter_params/g" \
-e "s/dmxEvent/dmx_event/g" \
-e "s/dmxCaps_t/dmx_caps_t/g" \
-e "s/dmxCaps_s/dmx_caps/g" \
-e "s/dmxSource_t/dmx_source_t/g" \
-e "s/EBUFFEROVERFLOW/EOVERFLOW/g" \
-e "s/dvb_pid_t/uint16_t/g" \
-e "s/pesType/pes_type/g" \
-e "s/_FRONTEND_H_/_FRONTEND_H_/g" \
-e "s/FrontendType/fe_type_t/g" \
-e "s/FrontendCapabilities/fe_caps_t/g" \
-e "s/SecVoltage/fe_sec_voltage_t/g" \
-e "s/SecToneMode/fe_sec_tone_mode_t/g" \
-e "s/SecMiniCmd/fe_sec_mini_cmd_t/g" \
-e "s/FrontendStatus/fe_status_t/g" \
-e "s/SpectralInversion/fe_spectral_inversion_t/g" \
-e "s/CodeRate/fe_code_rate_t/g" \
-e "s/Modulation/fe_modulation_t/g" \
-e "s/TransmitMode/fe_transmit_mode_t/g" \
-e "s/BandWidth/fe_bandwidth_t/g" \
-e "s/GuardInterval/fe_guard_interval_t/g" \
-e "s/Hierarchy/fe_hierarchy_t/g" \
-e "s/DmxDevInit/dvb_dmxdev_init/g" \
-e "s/DmxDevRelease/dvb_dmxdev_release/g" \
-e "s/DmxDevFile2Filter/dvb_dmxdev_file_to_filter/g" \
-e "s/DmxDevFile2DVR/dvb_dmxdev_file_to_dvr/g" \
-e "s/DmxDevBufferInit/dvb_dmxdev_buffer_init/g" \
-e "s/DmxDevBufferWrite/dvb_dmxdev_buffer_write/g" \
-e "s/DmxDevBufferRead/dvb_dmxdev_buffer_read/g" \
-e "s/DmxDevFilterStop/dvb_dmxdev_filter_stop/g" \
-e "s/DmxDevSetBufferSize/dvb_dmxdev_set_buffer_size/g" \
-e "s/DmxDevFilterTimeout/dvb_dmxdev_filter_timeout/g" \
-e "s/DmxDevFilterTimer/dvb_dmxdev_filter_timer/g" \
-e "s/DmxDevSectionCallback/dvb_dmxdev_section_callback/g" \
-e "s/DmxDevTSCallback/dvb_dmxdev_ts_callback/g" \
-e "s/DmxDevFeedStop/dvb_dmxdev_feed_stop/g" \
-e "s/DmxDevFeedStart/dvb_dmxdev_feed_start/g" \
-e "s/DmxDevFeedRestart/dvb_dmxdev_feed_restart/g" \
-e "s/DmxDevFilterStateSet/dvb_dmxdev_filter_state_set/g" \
-e "s/DmxDevPesFilterSet/dvb_dmxdev_pes_filter_set/g" \
-e "s/DmxDevFilterSet/dvb_dmxdev_filter_set/g" \
-e "s/DmxDevFilterReset/dvb_dmxdev_filter_reset/g" \
-e "s/DmxDevFilterAlloc/dvb_dmxdev_filter_alloc/g" \
-e "s/DmxDevFilterFree/dvb_dmxdev_filter_free/g" \
-e "s/DmxDevFilterStart/dvb_dmxdev_filter_start/g" \
-e "s/DmxDevDVRStateSet/dvb_dmxdev_dvr_state_set/g" \
-e "s/DmxDevReadSec/dvb_dmxdev_read_sec/g" \
-e "s/DvbDmxInit/dvb_dmx_init/g" \
-e "s/DvbDmxRelease/dvb_dmx_release/g" \
-e "s/DvbDmxSWFilterPacket/dvb_dmx_swfilter_packet/g" \
-e "s/DvbDmxSWFilter/dvb_dmx_swfilter/g" \
-e "s/dvb_dmx_swfilterPayload/dvb_dmx_swfilter_payload/g" \
-e "s/dvb_dmx_swfilterSectionFilter/dvb_dmx_swfilter_sectionfilter/g" \
-e "s/dvb_dmx_swfilterSectionFeed/dvb_dmx_swfilter_section_feed/g" \
-e "s/dvb_dmx_swfilterSectionPacket/dvb_dmx_swfilter_section_packet/g" \
-e "s/dvb_dmx_swfilter_packetType/dvb_dmx_swfilter_packet_type/g" \
-e "s/DvbDmxFilterAlloc/dvb_dmx_filter_alloc/g" \
-e "s/DvbDmxFeedAlloc/dvb_dmx_feed_alloc/g" \
-e "s/\<init_ipack\>/dvb_filter_ipack_init/g" \
-e "s/\<reset_ipack\>/dvb_filter_ipack_reset/g" \
-e "s/\<free_ipack\>/dvb_filter_ipack_free/g" \
-e "s/\<send_ipack_rest\>/dvb_filter_ipack_flush/g" \
-e "s/\<instant_repack\>/dvb_filter_instant_repack/g" \
-e "s/\<pes2ts\>/dvb_filter_pes2ts/g" \
-e "s/\<generic_usercopy\>/video_usercopy/g" \
-e "s/\<dvb_device_t\>/struct dvb_device/g" \
-e "s/\<dvb_adapter_t\>/struct dvb_adapter/g" \
-e "s/\<dvb_adapter_s\>/dvb_adapter/g" \
-e "s/\<dvb_demux_t\>/struct dvb_demux/g" \
-e "s/struct dvb_demux_s/struct dvb_demux/g" \
-e "s/dvb_demux_filter_t/struct dvb_demux_filter/g" \
-e "s/struct dvb_demux_filter_s/struct dvb_demux_filter/g" \
-e "s/dvb_demux_feed_t/struct dvb_demux_feed/g" \
-e "s/struct dvb_demux_feed_s/struct dvb_demux_feed/g" \
> $TOPDIR/$1.new/$x
chmod --reference=$TOPDIR/$1/$x $TOPDIR/$1.new/$x
done
--- NEW FILE: README.valgrind ---
valgrind-2.1.0-dvb.patch enables checking correct usage
of the the Linux DVB API ioctls with valgrind
(http://valgrind.kde.org/). Or, more to the point,
it allows you to check your DVB software with valgrind
without getting all those "unknown ioctl" warnings.
Notes:
- only frontend and demux ioctls are currently implemented
- some ioctls take structs as arguments; due to padding, valgrind
will complain about uninitialized data passed to the ioctl unless
you memset() the whole struct to some defined value
(the valgrind patch could be improved to handle this better)
Johannes Stezenbach <js@convergence.de>