summaryrefslogtreecommitdiff
path: root/dvb-spec
diff options
context:
space:
mode:
authorrjkm <devnull@localhost>2001-09-16 22:27:03 -0300
committerrjkm <devnull@localhost>2001-09-16 22:27:03 -0300
commit9034551a3bbc76b79a152806c781b1b8e8ea3a9a (patch)
tree31fe111120a3102afe9ea193836907a2c3a63fc7 /dvb-spec
parentc2ca96fee8c574074c67c9da023e4165f2f9b2e3 (diff)
downloadmediapointer-dvb-s2-9034551a3bbc76b79a152806c781b1b8e8ea3a9a.tar.gz
mediapointer-dvb-s2-9034551a3bbc76b79a152806c781b1b8e8ea3a9a.tar.bz2
new API docs
Diffstat (limited to 'dvb-spec')
-rw-r--r--dvb-spec/dvbapi/Makefile30
-rw-r--r--dvb-spec/dvbapi/audio.tex436
-rw-r--r--dvb-spec/dvbapi/bibsection.sty29
-rw-r--r--dvb-spec/dvbapi/ca.tex127
-rw-r--r--dvb-spec/dvbapi/cimlogo.psi122
-rw-r--r--dvb-spec/dvbapi/demux.tex392
-rw-r--r--dvb-spec/dvbapi/devices.tex12
-rw-r--r--dvb-spec/dvbapi/dvbapi.tex166
-rw-r--r--dvb-spec/dvbapi/dvbstb.fig59
-rw-r--r--dvb-spec/dvbapi/examples.tex365
-rwxr-xr-xdvb-spec/dvbapi/fig2pstex6
-rwxr-xr-xdvb-spec/dvbapi/getbb12
-rw-r--r--dvb-spec/dvbapi/intro.tex192
-rw-r--r--dvb-spec/dvbapi/kdapi.tex1007
-rw-r--r--dvb-spec/dvbapi/sec.tex282
-rw-r--r--dvb-spec/dvbapi/title.tex24
-rw-r--r--dvb-spec/dvbapi/video.tex684
17 files changed, 3945 insertions, 0 deletions
diff --git a/dvb-spec/dvbapi/Makefile b/dvb-spec/dvbapi/Makefile
new file mode 100644
index 000000000..fe9827cff
--- /dev/null
+++ b/dvb-spec/dvbapi/Makefile
@@ -0,0 +1,30 @@
+all: dvbapi.ps dvbapi.pdf
+
+TEXS= dvbapi.tex devices.tex video.tex audio.tex ca.tex sec.tex frontend.tex \
+ intro.tex title.tex dvbstb.ps
+
+dvbapi.pdf: dvbapi.dvi
+ dvipdf $< $@
+
+dvbapi.ps: dvbapi.dvi
+ dvips -o $@ $<
+
+dvbapi.dvi: dvbapi.bbl $(TEXS)
+ -latex dvbapi
+ -bibtex dvbapi
+ -makeindex dvbapi
+ -latex dvbapi
+ -latex dvbapi
+
+dvbapi.bbl: $(TEXS)
+ -latex dvbapi
+ -bibtex dvbapi
+ -makeindex dvbapi
+
+%.ps: %.fig
+ ./fig2pstex $<
+
+clean:
+ rm -f dvbapi.dvi
+ rm -f *.aux *.bbl *.blg *.idx *.ilg *.ind *.log *.out *.toc
+ rm -f *.pdf *.pst *.ps
diff --git a/dvb-spec/dvbapi/audio.tex b/dvb-spec/dvbapi/audio.tex
new file mode 100644
index 000000000..8c5b4fe82
--- /dev/null
+++ b/dvb-spec/dvbapi/audio.tex
@@ -0,0 +1,436 @@
+\devsec{DVB Audio Device}
+
+The DVB audio device controls the MPEG2 audio decoder of the DVB hardware.
+It can be accessed through \texttt{/dev/ost/audio}.
+
+
+\devsubsec{Audio Data Types}
+
+This section describes the structures, data types and defines used when
+talking to the audio device.
+
+\devsubsubsec{audioStreamSource\_t}
+\label{audiostreamsource}
+The audio stream source is set through the AUDIO\_SELECT\_SOURCE
+call and can take the following values, depending on whether we are
+replaying from an internal (demuxer) or external (user write) source.
+\begin{verbatim}
+typedef enum {
+ AUDIO_SOURCE_DEMUX,
+ AUDIO_SOURCE_MEMORY
+} audioStreamSource_t;
+\end{verbatim}
+AUDIO\_SOURCE\_DEMUX selects the demultiplexer (fed
+either by the frontend or the DVR device) as the source of
+the video stream.
+If AUDIO\_SOURCE\_MEMORY is selected the stream
+comes from the application through the \texttt{write()}
+system call.
+
+\devsubsubsec{audioPlayState\_t}
+The following values can be returned by the AUDIO\_GET\_STATUS call
+representing the state of audio playback.
+\label{audioplaystate}
+\begin{verbatim}
+typedef enum {
+ AUDIO_STOPPED,
+ AUDIO_PLAYING,
+ AUDIO_PAUSED
+} audioPlayState_t;
+\end{verbatim}
+
+\devsubsubsec{audioChannelSelect\_t}
+\label{audiochannelselect}
+The audio channel selected via AUDIO\_CHANNEL\_SELECT is determined by
+the following values.
+\begin{verbatim}
+typedef enum {
+ AUDIO_STEREO,
+ AUDIO_MONO_LEFT,
+ AUDIO_MONO_RIGHT,
+} audioChannelSelect_t;
+\end{verbatim}
+
+\devsubsubsec{audioStatus\_t}
+\label{audiostatus}
+The AUDIO\_GET\_STATUS call returns the following structure informing
+about various states of the playback operation.
+\begin{verbatim}
+typedef struct audioStatus {
+ boolean AVSyncState;
+ boolean muteState;
+ audioPlayState_t playState;
+ audioStreamSource_t streamSource;
+ audioChannelSelect_t channelSelect;
+ boolean bypassMode;
+} audioStatus_t;
+\end{verbatim}
+
+\devsubsubsec{audioMixer\_t}
+\label{audiomixer}
+The following structure is used by the AUDIO\_SET\_MIXER call to set
+the audio volume.
+\begin{verbatim}
+typedef struct audioMixer {
+ unsigned int volume_left;
+ unsigned int volume_right;
+} audioMixer_t;
+\end{verbatim}
+
+\devsubsubsec{audio encodings}
+\label{audiotypes}
+A call to AUDIO\_GET\_CAPABILITIES returns an unsigned integer with
+the following bits set according to the hardwares capabilities.
+\begin{verbatim}
+#define AUDIO_CAP_DTS 1
+#define AUDIO_CAP_LPCM 2
+#define AUDIO_CAP_MP1 4
+#define AUDIO_CAP_MP2 8
+#define AUDIO_CAP_MP3 16
+#define AUDIO_CAP_AAC 32
+#define AUDIO_CAP_OGG 64
+#define AUDIO_CAP_SDDS 128
+#define AUDIO_CAP_AC3 256
+\end{verbatim}
+
+
+\devsubsubsec{audio karaoke}
+\label{audiokaraoke}
+The ioctl AUDIO\_SET\_KARAOKE uses the following format:
+\begin{verbatim}
+typedef
+struct audioKaraoke{ /* if Vocal1 or Vocal2 are non-zero, they get mixed */
+ int vocal1; /* into left and right t at 70% each */
+ int vocal2; /* if both, Vocal1 and Vocal2 are non-zero, Vocal1 gets */
+ int melody; /* mixed into the left channel and */
+ /* Vocal2 into the right channel at 100% each. */
+ /* if Melody is non-zero, the melody channel gets mixed */ /* into left and right */
+} audioKaraoke_t;
+\end{verbatim}
+
+\devsubsubsec{audio attributes}
+\label{aattrib}
+The following attributes can be set by a call to AUDIO\_SET\_ATTRIBUTES:
+\begin{verbatim}
+typedef uint16_t audioAttributes_t;
+/* bits: descr. */
+/* 15-13 audio coding mode (0=ac3, 2=mpeg1, 3=mpeg2ext, 4=LPCM, 6=DTS, */
+/* 12 multichannel extension */
+/* 11-10 audio type (0=not spec, 1=language included) */
+/* 9- 8 audio application mode (0=not spec, 1=karaoke, 2=surround) */
+/* 7- 6 Quantization / DRC (mpeg audio: 1=DRC exists)(lpcm: 0=16bit, */
+/* 5- 4 Sample frequency fs (0=48kHz, 1=96kHz) */
+/* 2- 0 number of audio channels (n+1 channels) */
+\end{verbatim}
+
+
+\clearpage
+
+\devsubsec{Audio Function Calls}
+
+\function{open()}{
+ int open(const char *deviceName, int flags);}{
+ This system call opens a named audio device (e.g. /dev/ost/audio) for subsequent
+ use. When an open() call has succeeded, the device will be ready for use.
+ The significance of blocking or non-blocking mode is described in the
+ documentation for functions where there is a difference. It does not affect
+ the semantics of the open() call itself. A device opened in blocking mode can
+ later be put into non-blocking mode (and vice versa) using the F\_SETFL command
+ of the fcntl system call. This is a standard system call, documented in the
+ Linux manual page for fcntl.
+ Only one user can open the Audio Device in O\_RDWR mode. All other attempts to
+ open the device in this mode will fail, and an error code will be returned.
+ If the Audio Device is opened in O\_RDONLY mode, the only ioctl call that can
+ be used is AUDIO\_GET\_STATUS. All other call will return with an error code.
+ }{
+ const char *deviceName & Name of specific audio device.\\
+ int flags & A bit-wise OR of the following flags:\\
+ & \hspace{1em} O\_RDONLY read-only access\\
+ & \hspace{1em} O\_RDWR read/write access\\
+ & \hspace{1em} O\_NONBLOCK open in non-blocking mode \\
+ & \hspace{1em} (blocking mode is the default)\\
+ }{
+ ENODEV & Device driver not loaded/available.\\
+ EINTERNAL & Internal error.\\
+ EBUSY & Device or resource busy.\\
+ EINVAL & Invalid argument.\\
+}
+
+\function{close()}{
+ int close(int fd);}{
+ This system call closes a previously opened audio device.
+ }{
+ int fd & File descriptor returned by a previous call to open().\\
+ }{
+ EBADF & fd is not a valid open file descriptor.\\
+}
+
+\function{write()}{
+ size\_t write(int fd, const void *buf, size\_t count);}{
+ This system call can only be used if AUDIO\_SOURCE\_MEMORY is selected
+ in the ioctl call AUDIO\_SELECT\_SOURCE.
+ The data provided shall be in PES format.
+ If O\_NONBLOCK is not specified the function will block until buffer space is
+ available. The amount of data to be transferred is implied by count.
+ }{
+ int fd & File descriptor returned by a previous call to open().\\
+ void *buf & Pointer to the buffer containing the PES data.\\
+ size\_t count& Size of buf.\\
+ }{
+ EPERM& Mode AUDIO\_SOURCE\_MEMORY not selected.\\
+ ENOMEM& Attempted to write more data than the internal buffer can hold.\\
+ EBADF& fd is not a valid open file descriptor.\\
+}
+
+\ifunction{AUDIO\_STOP}{
+ int ioctl(int fd, int request = AUDIO\_STOP);}{
+ This ioctl call asks the Audio Device to stop playing the current stream.
+ }{
+ int fd & File descriptor returned by a previous call to open().\\
+ int request& Equals AUDIO\_STOP for this command.
+ }{
+ EBADF& fd is not a valid open file descriptor \\
+ EINTERNAL & Internal error.
+}
+
+\ifunction{AUDIO\_PLAY}{
+ int ioctl(int fd, int request = AUDIO\_PLAY);}{
+ This ioctl call asks the Audio Device to start playing an audio stream
+ from the selected source.
+ }{
+ int fd & File descriptor returned by a previous call to open().\\
+ int request& Equals AUDIO\_PLAY for this command.
+ }{
+ EBADF& fd is not a valid open file descriptor \\
+ EINTERNAL & Internal error.
+}
+
+\ifunction{AUDIO\_PAUSE}{
+ int ioctl(int fd, int request = AUDIO\_PAUSE);}{
+ This ioctl call suspends the audio stream being played.
+ Decoding and playing are paused.
+ It is then possible to restart again decoding and playing process of the
+ audio stream using AUDIO\_CONTINUE command.\\
+ If AUDIO\_SOURCE\_MEMORY is selected in the ioctl call
+ AUDIO\_SELECT\_SOURCE, the DVB-subsystem will not decode (consume)
+ any more data until the ioctl call
+ AUDIO\_CONTINUE or AUDIO\_PLAY is performed.
+ }{
+ int fd & File descriptor returned by a previous call to open().\\
+ int request& Equals AUDIO\_PAUSE for this command.
+ }{
+ EBADF& fd is not a valid open file descriptor.\\
+ EINTERNAL & Internal error.
+}
+
+\ifunction{AUDIO\_SELECT\_SOURCE}{
+ int ioctl(int fd, int request = AUDIO\_SELECT\_SOURCE,
+ audioStreamSource\_t source);}{
+ This ioctl call informs the audio device which source shall be used for the
+ input data. The possible sources are demux or memory.
+ If AUDIO\_SOURCE\_MEMORY
+ is selected, the data is fed to the Audio Device through the write command.
+ }{
+ int fd & File descriptor returned by a previous call to open().\\
+ int request & Equals AUDIO\_SELECT\_SOURCE for this command.\\
+ audioStreamSource\_t source& Indicates the source that shall be used for the
+ Audio stream.
+ }{
+ EBADF& fd is not a valid open file descriptor.\\
+ EINTERNAL & Internal error.\\
+ EINVAL & Illegal input parameter.
+}
+
+\ifunction{AUDIO\_SET\_MUTE}{
+ int ioctl(int fd, int request = AUDIO\_SET\_MUTE, boolean state);}{
+ This ioctl call asks the audio device to mute the stream that is
+ currently being played.
+ }{
+ int fd & File descriptor returned by a previous call to open().\\
+ int request & Equals AUDIO\_SET\_MUTE for this command.\\
+ boolean state & Indicates if audio device shall mute or not.\\
+ &TRUE Audio Mute\\
+ &FALSE Audio Un-mute\\
+ }{
+ EBADF& fd is not a valid open file descriptor.\\
+ EINTERNAL & Internal error.\\
+ EINVAL & Illegal input parameter.
+}
+
+\ifunction{AUDIO\_SET\_AV\_SYNC}{
+ int ioctl(int fd, int request = AUDIO\_SET\_AV\_SYNC, boolean state);}{
+ This ioctl call asks the Audio Device to turn ON or OFF A/V synchronization.
+ }{
+ int fd & File descriptor returned by a previous call to open().\\
+ int request & Equals AUDIO\_AV\_SYNC for this command.\\
+ boolean state& Tells the DVB subsystem if A/V
+ synchronization shall be ON or OFF.\\
+ & TRUE AV-sync ON \\
+ & FALSE AV-sync OFF\\
+ }{
+ EBADF& fd is not a valid open file descriptor.\\
+ EINTERNAL & Internal error.\\
+ EINVAL & Illegal input parameter.
+}
+
+\ifunction{AUDIO\_SET\_BYPASS\_MODE}{
+ int ioctl(int fd, int request = AUDIO\_SET\_BYPASS\_MODE, boolean mode);}{
+ This ioctl call asks the Audio Device to bypass the Audio decoder and forward
+ the stream without decoding. This mode shall be used if streams that can't be
+ handled by the DVB system shall be decoded.
+ Dolby DigitalTM streams are automatically forwarded by the DVB
+ subsystem if the hardware can handle it.
+ }{
+ int fd & File descriptor returned by a previous call to open().\\
+ int request & Equals AUDIO\_SET\_BYPASS\_MODE for this command.\\
+ boolean mode& Enables or disables the decoding of the current
+ Audio stream in the DVB subsystem.\\
+ &TRUE Bypass is disabled\\
+ &FALSE Bypass is enabled\\
+ }{
+ EBADF& fd is not a valid open file descriptor.\\
+ EINTERNAL & Internal error.\\
+ EINVAL & Illegal input parameter.
+}
+
+\ifunction{AUDIO\_CHANNEL\_SELECT}{
+ int ioctl(int fd, int request = AUDIO\_CHANNEL\_SELECT,
+ audioChannelSelect\_t);}{
+ This ioctl call asks the Audio Device to select the requested channel
+ if possible.
+ }{
+ int fd & File descriptor returned by a previous call to open().\\
+ int request & Equals AUDIO\_CHANNEL\_SELECT for this command.\\
+ audioChannelSelect\_t ch &
+ Select the output format of the audio (mono left/right, stereo).
+ }{
+ EBADF& fd is not a valid open file descriptor.\\
+ EINTERNAL & Internal error.\\
+ EINVAL & Illegal input parameter ch.
+}
+
+\ifunction{AUDIO\_GET\_STATUS}{
+ int ioctl(int fd, int request = AUDIO\_GET\_STATUS,
+ struct audioStatus *status);}{
+ This ioctl call asks the Audio Device to return the current state
+ of the Audio Device.
+ }{
+ int fd & File descriptor returned by a previous call to open().\\
+ int request & Equals AUDIO\_GET\_STATUS for this command.\\
+ struct audioStatus *status & Returns the current state of Audio Device.
+ }{
+ EBADF& fd is not a valid open file descriptor.\\
+ EINTERNAL & Internal error.\\
+ EFAULT & status points to invalid address.
+}
+
+\ifunction{AUDIO\_GET\_CAPABILITIES}{
+ int ioctl(int fd, int request = AUDIO\_GET\_CAPABILITIES,
+ unsigned int *cap);}{
+ This ioctl call asks the Audio Device to tell us about the
+ decoding capabilities of the audio hardware.
+ }{
+ int fd & File descriptor returned by a previous call to open().\\
+ int request & Equals AUDIO\_GET\_CAPABILITIES for this command.\\
+ unsigned int *cap & Returns a bit array of supported sound formats.
+ }{
+ EBADF& fd is not a valid open file descriptor.\\
+ EINTERNAL & Internal error.\\
+ EFAULT & cap points to an invalid address.
+}
+
+\ifunction{AUDIO\_CLEAR\_BUFFER}{
+ int ioctl(int fd, int request = AUDIO\_CLEAR\_BUFFER);}{
+ This ioctl call asks the Audio Device to clear all software
+ and hardware buffers of the audio decoder device.
+ }{
+ int fd & File descriptor returned by a previous call to open().\\
+ int request & Equals AUDIO\_CLEAR\_BUFFER for this command.
+ }{
+ EBADF& fd is not a valid open file descriptor.\\
+ EINTERNAL & Internal error.
+}
+
+\ifunction{AUDIO\_SET\_ID}{
+ int ioctl(int fd, int request = AUDIO\_SET\_ID, int id);}{
+ This ioctl selects which sub-stream is to be decoded if a program or
+ system stream is sent to the video device.
+ }{
+ int fd & File descriptor returned by a previous call to open().\\
+ int request & Equals AUDIO\_SET\_ID for this command.\\
+ int id& audio sub-stream id
+ }{
+ EBADF& fd is not a valid open file descriptor.\\
+ EINTERNAL & Internal error.\\
+ EINVAL & Invalid sub-stream id.
+}
+
+\ifunction{AUDIO\_SET\_MIXER}{
+ int ioctl(int fd, int request = AUDIO\_SET\_MIXER, audioMixer\_t *mix);}{
+ This ioctl lets you adjust the mixer settings of the audio decoder.
+ }{
+ int fd & File descriptor returned by a previous call to open().\\
+ int request & Equals AUDIO\_SET\_ID for this command.\\
+ audioMixer\_t *mix& mixer settings.
+ }{
+ EBADF& fd is not a valid open file descriptor.\\
+ EINTERNAL & Internal error.\\
+ EFAULT & mix points to an invalid address.
+}
+
+\ifunction{AUDIO\_SET\_STREAMTYPE}{
+ int ioctl(fd, int request = AUDIO\_SET\_STREAMTYPE, int type);}{
+ This ioctl tells the driver which kind of audio stream to expect.
+ This is useful if the stream offers several audio sub-streams
+ like MPEG2 audio and AC3.
+ }{
+ int fd & File descriptor returned by a previous call to open().\\
+ int request & Equals AUDIO\_SET\_STREAMTYPE for this command.\\
+ int type & stream type\\
+ }{
+ EBADF& fd is not a valid open file descriptor \\
+ EINVAL& type is not a valid or supported stream type.\\
+}
+
+
+\ifunction{AUDIO\_SET\_EXT\_ID}{
+ int ioctl(fd, int request = AUDIO\_SET\_EXT\_ID, int id);}{
+ This ioctl can be used to set the audio sub\_stream\_id for DVD playback
+ }{
+ int fd & File descriptor returned by a previous call to open().\\
+ int request & Equals AUDIO\_SET\_EXT\_ID for this command.\\
+ int id & audio sub\_stream\_id\\
+ }{
+ EBADF& fd is not a valid open file descriptor \\
+ EINVAL& id is not a valid id.\\
+}
+
+\ifunction{AUDIO\_SET\_ATTRIBUTES}{
+ int ioctl(fd, int request = AUDIO\_SET\_ATTRIBUTES, audioAttributes\_t attr );}{
+ This ioctl is intended for DVD playback and allows you to set
+ certain information about the audio stream.
+ }{
+ int fd & File descriptor returned by a previous call to open().\\
+ int request & Equals AUDIO\_SET\_ATTRIBUTES for this command.\\
+ iaudioAttributes\_t attr & audio attributes according to section \ref{aattrib}\\
+ }{
+ EBADF& fd is not a valid open file descriptor \\
+ EINVAL& attr is not a valid or supported attribute setting.\\
+}
+
+\ifunction{AUDIO\_SET\_KARAOKE}{
+ int ioctl(fd, int request = AUDIO\_SET\_STREAMTYPE, audioKaraoke\_t *karaoke);}{
+ This ioctl allows one to set the mixer settings for a karaoke DVD.
+ }{
+ int fd & File descriptor returned by a previous call to open().\\
+ int request & Equals AUDIO\_SET\_STREAMTYPE for this command.\\
+ audioKaraoke\_t *karaoke & karaoke settings according to section \ref{audiokaraoke}.\\
+ }{
+ EBADF & fd is not a valid open file descriptor \\
+ EINVAL& karaoke is not a valid or supported karaoke setting.\\
+}
+
+%%% Local Variables:
+%%% mode: latex
+%%% TeX-master: "dvbapi"
+%%% End:
diff --git a/dvb-spec/dvbapi/bibsection.sty b/dvb-spec/dvbapi/bibsection.sty
new file mode 100644
index 000000000..7f9eedc6a
--- /dev/null
+++ b/dvb-spec/dvbapi/bibsection.sty
@@ -0,0 +1,29 @@
+\def\thebibliography#1{\chapter*{\bibname\@mkboth
+ {\uppercase{\bibname}}{\uppercase{\bibname}}}
+ \setcounter{chapter}{0}
+ \setcounter{section}{0}
+ \def\thechapter{Bib}
+ \def\thesection{\Alph{section}}
+ \edef\biblab{#1}
+ \addcontentsline{toc}{chapter}{\bibname}
+ }
+
+\def\bibtitle#1#2{\expandafter\def\csname bibtitle#1\endcsname{
+ \bibsection{#2}} }
+
+\def\bibsection#1{\section{#1}
+ \begin{list}
+ {\@biblabel{\arabic{enumiv}}}{\settowidth\labelwidth{\@biblabel{\biblab}}%
+ \leftmargin\labelwidth
+ \advance\leftmargin\labelsep
+ \usecounter{enumiv}%
+ \let\p@enumiv\@empty
+ \def\theenumiv{\arabic{enumiv}}}%
+ \def\newblock{\hskip .11em plus.33em minus.07em}%
+ \sloppy\clubpenalty4000\widowpenalty4000
+ \sfcode`\.=\@m}
+
+\def\endbibsection{\end{list}}
+
+\def\endthebibliography{\endbibsection}
+
diff --git a/dvb-spec/dvbapi/ca.tex b/dvb-spec/dvbapi/ca.tex
new file mode 100644
index 000000000..eba512b1b
--- /dev/null
+++ b/dvb-spec/dvbapi/ca.tex
@@ -0,0 +1,127 @@
+\devsec{DVB CA Device}
+
+The DVB CA device controls the conditional access hardware.
+It can be accessed through \texttt{/dev/ost/ca}.
+
+
+\devsubsec{CA Data Types}
+
+\devsubsubsec{ca\_slot\_info\_t}
+\label{caslotinfo}
+
+\begin{verbatim}
+/* slot interface types and info */
+
+typedef struct ca_slot_info_s {
+ int num; /* slot number */
+
+ int type; /* CA interface this slot supports */
+#define CA_CI 1 /* CI high level interface */
+#define CA_CI_LINK 2 /* CI link layer level interface */
+#define CA_CI_PHYS 4 /* CI physical layer level interface */
+#define CA_SC 128 /* simple smart card interface */
+
+ unsigned int flags;
+#define CA_CI_MODULE_PRESENT 1 /* module (or card) inserted */
+#define CA_CI_MODULE_READY 2
+} ca_slot_info_t;
+\end{verbatim}
+
+\devsubsubsec{ca\_descr\_info\_t}
+\label{cadescrinfo}
+
+\begin{verbatim}
+typedef struct ca_descr_info_s {
+ unsigned int num; /* number of available descramblers (keys) */
+ unsigned int type; /* type of supported scrambling system */
+#define CA_ECD 1
+#define CA_NDS 2
+#define CA_DSS 4
+} ca_descr_info_t;
+\end{verbatim}
+
+\devsubsubsec{ca\_cap\_t}
+\label{cacap}
+
+\begin{verbatim}
+typedef struct ca_cap_s {
+ unsigned int slot_num; /* total number of CA card and module slots */
+ unsigned int slot_type; /* OR of all supported types */
+ unsigned int descr_num; /* total number of descrambler slots (keys) */
+ unsigned int descr_type;/* OR of all supported types */
+} ca_cap_t;
+\end{verbatim}
+
+
+\devsubsubsec{ca\_msg\_t}
+\label{camsg}
+
+\begin{verbatim}
+/* a message to/from a CI-CAM */
+typedef struct ca_msg_s {
+ unsigned int index;
+ unsigned int type;
+ unsigned int length;
+ unsigned char msg[256];
+} ca_msg_t;
+\end{verbatim}
+
+
+\devsubsubsec{ca\_descr\_t}
+\label{cadescr}
+
+\begin{verbatim}
+typedef struct ca_descr_s {
+ unsigned int index;
+ unsigned int parity;
+ unsigned char cw[8];
+} ca_descr_t;
+\end{verbatim}
+
+\clearpage
+
+\devsubsec{CA Function Calls}
+
+\function{open()}{
+ int open(const char *deviceName, int flags);}{
+ This system call opens a named ca device (e.g. /dev/ost/ca)
+ for subsequent use.
+
+ When an open() call has succeeded, the device will be ready for use.
+ The significance of blocking or non-blocking mode is described in
+ the documentation for functions where there is a difference.
+ It does not affect the semantics of the open() call itself.
+ A device opened in blocking mode can later be put into non-blocking mode
+ (and vice versa) using the F\_SETFL command of the fcntl system
+ call.
+ This is a standard system call, documented in the Linux manual
+ page for fcntl.
+ Only one user can open the CA Device in O\_RDWR mode. All other attempts to
+ open the device in this mode will fail, and an error code will be returned.
+ }{
+ const char *deviceName & Name of specific video device.\\
+ int flags & A bit-wise OR of the following flags:\\
+ & \hspace{1em} O\_RDONLY read-only access\\
+ & \hspace{1em} O\_RDWR read/write access\\
+ & \hspace{1em} O\_NONBLOCK open in non-blocking mode \\
+ & \hspace{1em} (blocking mode is the default)\\
+ }{
+ ENODEV & Device driver not loaded/available.\\
+ EINTERNAL & Internal error.\\
+ EBUSY & Device or resource busy.\\
+ EINVAL & Invalid argument.\\
+}
+
+\function{close()}{
+ int close(int fd);}{
+ This system call closes a previously opened audio device.
+ }{
+ int fd & File descriptor returned by a previous call to open().\\
+ }{
+ EBADF & fd is not a valid open file descriptor.\\
+}
+
+%%% Local Variables:
+%%% mode: latex
+%%% TeX-master: "dvbapi"
+%%% End:
diff --git a/dvb-spec/dvbapi/cimlogo.psi b/dvb-spec/dvbapi/cimlogo.psi
new file mode 100644
index 000000000..b7b089a49
--- /dev/null
+++ b/dvb-spec/dvbapi/cimlogo.psi
@@ -0,0 +1,122 @@
+%!PS-Adobe-2.0 EPSF-2.0
+%%Title: /home/rjkm/dvbapi/cimlogo.ps
+%%Creator: XV Version 3.10a Rev: 12/29/94 (PNG patch 1.2) - by John Bradley
+%%BoundingBox: 275 411 309 440
+%%Pages: 1
+%%DocumentFonts:
+%%EndComments
+%%EndProlog
+
+%%Page: 1 1
+
+% remember original state
+/origstate save def
+
+% build a temporary dictionary
+20 dict begin
+
+% define string to hold a scanline's worth of data
+/pix 45 string def
+
+% define space for color conversions
+/grays 45 string def % space for gray scale line
+/npixls 0 def
+/rgbindx 0 def
+
+% lower left corner
+275 411 translate
+
+% size of image (on paper, in 1/72inch coords)
+33.76800 28.51200 scale
+
+45 38 8 % dimensions of data
+[45 0 0 -38 0 38] % mapping matrix
+{currentfile pix readhexstring pop}
+image
+
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffff000000ffffffffffffffffffffff
+ffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffff0000000000ffffffffffffffffffff
+ffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffff000000000000ffffffffffffffffff
+ffffffffffffffffff
+ffffffffffffffffffffffffffff00ffffffffffff0000000000ffffffffffffffffffff
+ffffffffffffffffff
+ffffffffffffffffffffff0000000000ffffffff000000000000ffffffffffffffffffff
+ffffffffffffffffff
+ffffffffffffffffff0000000000000000ffffff000000000000ffffffffffffffffffff
+ffffffffffffffffff
+ffffffffffffffff0000000000000000ffffffff000000000000ffffffffffffffffffff
+ffffffffffffffffff
+ffffffffffffff000000000000000000ffffff000000000000ffffffffffffffffffffff
+ffffffffffffffffff
+ffffffffffff0000000000000000ffffffffff000000000000ffffff00000000ffffffff
+ffffffffffffffffff
+ffffffffff00000000000000ffffffffffffff0000000000ffffff0000000000ffffffff
+ffffffffffffffffff
+ffffffffff000000000000ffffffffffffff000000000000ffffff000000000000ffffff
+ffffffffffffffffff
+ffffffff00000000000000ffffffffffffff000000000000ffffffff000000000000ffff
+ffffffffffffffffff
+ffffffff000000000000ffffffffffffffff000000000000ffffffff000000000000ffff
+ffffffffffffffffff
+ffffffff0000000000ffffffffffffffff000000000000ffffffffffff0000000000ffff
+ffffffffffffffffff
+ffffff000000000000ffffffffffffffff000000000000ffffffffffff0000000000ffff
+ffffffffffffffffff
+ffffff0000000000ffffffffffffffffff000000000000ffffffffffff000000000000ff
+ffffffffffffffffff
+ffffff0000000000ffffffffffffffffff0000000000ffffffffffffff000000000000ff
+ffffffffffffffffff
+ffffff0000000000ffffffffffffffff000000000000ffffffffffffffff0000000000ff
+ffffffffffffffffff
+ffffff0000000000ffffffffffffffff000000000000ffffffffffffff000000000000ff
+ffffffffffffffffff
+ffffff0000000000ffffffffffffffff0000000000ffffffffffffffffff0000000000ff
+ffffffffffffffffff
+ffffff0000000000ffffffffffffff000000000000ffffffffffffffff000000000000ff
+ffffffffffffffffff
+ffffff0000000000ffffffffffffff000000000000ffffffffffffffff0000000000ffff
+ffffffffffffffffff
+ffffff000000000000ffffffffffffff00000000ffffffffffffffffff0000000000ffff
+ffffffffffffffffff
+ffffffff0000000000ffffffffffffffff0000ffffffffffffffffff000000000000ffff
+ffffffffffffffffff
+ffffffff000000000000ffffffffffffffffffffffffffffffffffff000000000000ffff
+ffffffffffffffffff
+ffffffff000000000000ffffffffffffffffffffffffffffffffff000000000000ffffff
+ffffffffffffffffff
+ffffffffff00000000000000ffffffffffffffffffffffffffff000000000000ffffffff
+ff0000000000ffffff
+ffffffffff0000000000000000ffffffffffffffffffffffff00000000000000ffffffff
+00000000000000ffff
+ffffffffffff000000000000000000ffffffffffffffff0000000000000000ffffffffff
+00000000000000ffff
+ffffffffffffff0000000000000000000000000000000000000000000000ffffffffffff
+0000000000000000ff
+ffffffffffffffff000000000000000000000000000000000000000000ffffffffffffff
+00000000000000ffff
+ffffffffffffffffffff0000000000000000000000000000000000ffffffffffffffffff
+00000000000000ffff
+ffffffffffffffffffffffff00000000000000000000000000ffffffffffffffffffffff
+ff0000000000ffffff
+ffffffffffffffffffffffffffffff00ff0000000000ffffffffffffffffffffffffffff
+ffffff0000ffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffff
+
+showpage
+
+% stop using temporary dictionary
+end
+
+% restore original state
+origstate restore
+
+%%Trailer
diff --git a/dvb-spec/dvbapi/demux.tex b/dvb-spec/dvbapi/demux.tex
new file mode 100644
index 000000000..541ee633a
--- /dev/null
+++ b/dvb-spec/dvbapi/demux.tex
@@ -0,0 +1,392 @@
+\devsec{DVB Demux Device}
+
+The DVB demux device controls the filters of the DVB hardware/software.
+It can be accessed through \texttt{/dev/ost/demux}.
+
+\devsubsec{Demux Data Types}
+
+\begin{verbatim}
+typedef uint16_t dvb_pid_t;
+\end{verbatim}
+
+
+\devsubsubsec{dmxOutput\_t}
+\label{dmxoutput}
+
+\begin{verbatim}
+typedef enum
+{
+ DMX_OUT_DECODER,
+ DMX_OUT_TAP,
+ DMX_OUT_TS_TAP
+} dmxOutput_t;
+\end{verbatim}
+/* Output multiplexed into a new TS */
+/* (to be retrieved by reading from the */
+/* logical DVR device). */
+
+
+\devsubsubsec{dmxInput\_t}
+\label{dmxinput}
+
+\begin{verbatim}
+typedef enum
+{
+ DMX_IN_FRONTEND, /* Input from a front-end device. */
+ DMX_IN_DVR /* Input from the logical DVR device. */
+} dmxInput_t;
+\end{verbatim}
+
+
+\devsubsubsec{dmxPesType\_t}
+\label{dmxpestype}
+
+\begin{verbatim}
+typedef enum
+{
+ DMX_PES_AUDIO,
+ DMX_PES_VIDEO,
+ DMX_PES_TELETEXT,
+ DMX_PES_SUBTITLE,
+ DMX_PES_PCR,
+ DMX_PES_OTHER
+} dmxPesType_t;
+\end{verbatim}
+
+
+\devsubsubsec{dmxEvent\_t}
+\label{dmxeventt}
+
+\begin{verbatim}
+typedef enum
+{
+ DMX_SCRAMBLING_EV,
+ DMX_FRONTEND_EV
+} dmxEvent_t;
+\end{verbatim}
+
+
+\devsubsubsec{dmxScramblingStatus\_t}
+\label{dmxscramblingstatus}
+
+\begin{verbatim}
+typedef enum
+{
+ DMX_SCRAMBLING_OFF,
+ DMX_SCRAMBLING_ON
+} dmxScramblingStatus_t;
+\end{verbatim}
+
+
+\devsubsubsec{dmxFilter\_t}
+\label{dmxfilter}
+
+\begin{verbatim}
+typedef struct dmxFilter
+{
+ uint8_t filter[DMX_FILTER_SIZE];
+ uint8_t mask[DMX_FILTER_SIZE];
+} dmxFilter_t;
+\end{verbatim}
+
+
+\devsubsubsec{dmxSctFilterParams}
+\label{dmxsctfilterparams}
+
+\begin{verbatim}
+struct dmxSctFilterParams
+{
+ dvb_pid_t pid;
+ dmxFilter_t filter;
+ uint32_t timeout;
+ uint32_t flags;
+#define DMX_CHECK_CRC 1
+#define DMX_ONESHOT 2
+#define DMX_IMMEDIATE_START 4
+};
+\end{verbatim}
+
+
+\devsubsubsec{dmxPesFilterParams}
+\label{dmxpesfilterparams}
+
+\begin{verbatim}
+struct dmxPesFilterParams
+{
+ dvb_pid_t pid;
+ dmxInput_t input;
+ dmxOutput_t output;
+ dmxPesType_t pesType;
+ uint32_t flags;
+};
+\end{verbatim}
+
+
+\devsubsubsec{dmxEvent}
+\label{dmxevent}
+
+\begin{verbatim}
+struct dmxEvent
+{
+ dmxEvent_t event;
+ time_t timeStamp;
+ union
+ {
+ dmxScramblingStatus_t scrambling;
+ } u;
+};
+\end{verbatim}
+
+\clearpage
+
+\devsubsec{Demux Function Calls}
+\function{open()}{
+ int open(const char *deviceName, int flags);}{
+ This system call, used with a device name of /dev/ost/demuxn, where n
+ denotes the specific demux device to be opened, allocates a new filter
+ and returns a handle which can be used for subsequent control of that
+ filter. This call has to be made for each filter to be used, i.e. every
+ returned file descriptor is a reference to a single filter.
+ /dev/ost/dvrn is a logical device to be used for retrieving Transport
+ Streams for digital video recording. n identifies the physical demux
+ device that provides the actual DVR functionality. When reading from
+ this device a transport stream containing the packets from all PES
+ filters set in the corresponding demux device (/dev/ost/demuxn)
+ having the output set to DMX\_OUT\_TS\_TAP. A recorded Transport Stream
+ is replayed by writing to this device.
+% This device can only be opened in read-write mode.
+
+ The significance of blocking or non-blocking mode is described in the
+ documentation for functions where there is a difference. It does not
+ affect the semantics of the open() call itself. A device opened in
+ blocking mode can later be put into non-blocking mode
+ (and vice versa) using the F\_SETFL command of the fcntl system call.
+ }{
+ const char *deviceName & Name of demux device.\\
+ int flags & A bit-wise OR of the following flags:\\
+ & \hspace{1em} O\_RDWR read/write access\\
+ & \hspace{1em} O\_NONBLOCK open in non-blocking mode \\
+ & \hspace{1em} (blocking mode is the default)\\
+ }{
+ ENODEV & Device driver not loaded/available.\\
+ EINVAL & Invalid argument.\\
+ EMFILE & ``Too many open files'', i.e. no more filters available.\\
+ ENOMEM & The driver failed to allocate enough memory.\\
+}
+
+\function{close()}{
+ int close(int fd);}{
+ This system call deactivates and deallocates a filter that was previously
+ allocated via the open() call.
+ }{
+ int fd & File descriptor returned by a previous call to open().\\
+ }{
+ EBADF & fd is not a valid open file descriptor.\\
+}
+
+\function{read()}{
+ size\_t read(int fd, void *buf, size\_t count);
+ }{
+ This system call returns filtered data, which might be section or PES
+ data. The filtered data is transferred from the driver's internal circular
+ buffer to buf. The maximum amount of data to be transferred is implied by
+ count.\\
+ When returning section data the driver always tries to return a complete
+ single section (even though buf would provide buffer space for more data).
+ If the size of the buffer is smaller than the section as much as possible
+ will be returned, and the remaining data will be provided in subsequent
+ calls.\\
+ The size of the internal buffer is 2 * 4096 bytes (the size of two maximum
+ sized sections) by default. The size of this buffer may be changed by
+ using the DMX\_SET\_BUFFER\_SIZE function. If the buffer is not large enough,
+ or if the read operations are not performed fast enough, this may result
+ in a buffer overflow error. In this case EBUFFEROVERFLOW will be returned,
+ and the circular buffer will be emptied.
+ This call is blocking if there is no data to return, i.e. the process
+ will be put to sleep waiting for data, unless the O\_NONBLOCK flag is
+ specified.\\
+ Note that in order to be able to read, the filtering process has to be
+ started by defining either a section or a PES filter by means of the
+ ioctl functions, and then starting the filtering process via the DMX\_START
+ ioctl function or by setting the DMX\_IMMEDIATE\_START flag.
+ If the reading is done from a logical DVR demux device, the data will
+ constitute a Transport Stream including the packets from all PES filters
+ in the corresponding demux device /dev/ost/demuxn having the output set
+ to DMX\_OUT\_TS\_TAP.
+ }{
+ int fd & File descriptor returned by a previous call to open().\\
+ void *buf & Pointer to the buffer to be used for returned filtered data.\\
+ size\_t count & Size of buf.\\
+ }{
+ EWOULDBLOCK & No data to return and O\_NONBLOCK was specified.\\
+ EBADF & fd is not a valid open file descriptor.\\
+ ECRC & Last section had a CRC error - no data returned.
+ The buffer is flushed.\\
+ EBUFFEROVERFLOW & \\
+& The filtered data was not read from the buffer in
+ due time, resulting in non-read data being lost.
+ The buffer is flushed.\\
+ ETIMEDOUT & The section was not loaded within the stated
+ timeout period. See ioctl DMX\_SET\_FILTER for
+ how to set a timeout.\\
+ EFAULT & The driver failed to write to the callers buffer
+ due to an invalid *buf pointer.\\
+}
+
+\function{write()}{
+ ssize\_t write(int fd, const void *buf, size\_t count);
+ }{
+ This system call is only provided by the logical device /dev/ost/dvrn,
+ where n identifies the physical demux device that provides the actual
+ DVR functionality. It is used for replay of a digitally recorded
+ Transport Stream. Matching filters have to be defined in the
+ corresponding physical demux device, /dev/ost/demuxn.
+ The amount of data to be transferred is implied by count.
+ }{
+ int fd & File descriptor returned by a previous call to open().\\
+ void *buf & Pointer to the buffer containing the Transport Stream.\\
+ size\_t count & Size of buf.\\
+ }{
+ EWOULDBLOCK & No data was written. This might happen if
+ O\_NONBLOCK was specified and there is no more
+ buffer space available (if O\_NONBLOCK is not
+ specified the function will block until buffer
+ space is available).\\
+ EBUSY & This error code indicates that there are
+ conflicting requests. The corresponding demux
+ device is setup to receive data from the front-
+ end. Make sure that these filters are stopped
+ and that the filters with input set to DMX\_IN\_DVR
+ are started.\\
+ EBADF & fd is not a valid open file descriptor.\\
+}
+
+\ifunction{DMX\_START}{
+ int ioctl( int fd, int request = DMX\_START);
+ }{
+ This ioctl call is used to start the actual filtering operation
+ defined via the ioctl calls DMX\_SET\_FILTER or DMX\_SET\_PES\_FILTER.
+ }{
+ int fd & File descriptor returned by a previous call to open().\\
+ int request & Equals DMX\_START for this command.\\
+ }{
+ EBADF & fd is not a valid file descriptor.\\
+ EINVAL & Invalid argument, i.e. no filtering parameters
+ provided via the DMX\_SET\_FILTER or
+ DMX\_SET\_PES\_FILTER functions.\\
+ EBUSY & This error code indicates that there are
+ conflicting requests. There are active filters
+ filtering data from another input source. Make
+ sure that these filters are stopped before starting
+ this filter.\\
+}
+
+\ifunction{DMX\_STOP}{
+ int ioctl( int fd, int request = DMX\_STOP);
+ }{
+ This ioctl call is used to stop the actual filtering operation defined
+ via the ioctl calls DMX\_SET\_FILTER or DMX\_SET\_PES\_FILTER and started via
+ the DMX\_START command.
+ }{
+ int fd & File descriptor returned by a previous call to open().\\
+ int request & Equals DMX\_STOP for this command.\\
+ }{
+ EBADF & fd is not a valid file descriptor.\\
+}
+
+\ifunction{DMX\_SET\_FILTER}{
+ int ioctl( int fd, int request = DMX\_SET\_FILTER, struct dmxSctFilterParams *params);
+ }{
+ This ioctl call sets up a filter according to the filter and mask
+ parameters provided. A timeout may be defined stating number of seconds
+ to wait for a section to be loaded. A value of 0 means that no timeout
+ should be applied. Finally there is a flag field where it is possible to
+ state whether a section should be CRC-checked, whether the filter should
+ be a "one-shot" filter, i.e. if the filtering operation should be stopped
+ after the first section is received, and whether the filtering operation
+ should be started immediately (without waiting for a DMX\_START ioctl call).
+ If a filter was previously set-up, this filter will be canceled, and the
+ receive buffer will be flushed.
+ }{
+ int fd & File descriptor returned by a previous call to open().\\
+ int request & Equals DMX\_SET\_FILTER for this command.\\
+ struct dmxSctFilterParams *params
+ & Pointer to structure containing filter parameters.\\
+ }{
+ EBADF & fd is not a valid file descriptor.\\
+ EINVAL & Invalid argument.\\
+}
+
+\ifunction{DMX\_SET\_PES\_FILTER}{
+ int ioctl( int fd, int request = DMX\_SET\_PES\_FILTER,
+ struct dmxPesFilterParams *params);
+ }{
+ This ioctl call sets up a PES filter according to the parameters provided.
+ By a PES filter is meant a filter that is based just on the packet
+ identifier (PID), i.e. no PES header or payload filtering capability is
+ supported.\\
+ The transport stream destination for the filtered output may be set. Also
+ the PES type may be stated in order to be able to e.g. direct a video
+ stream directly to the video decoder. Finally there is a flag field where
+ it is possible to state whether the filtering operation should be started
+ immediately (without waiting for a DMX\_START ioctl call).
+ If a filter was previously set-up, this filter will be cancelled, and the
+ receive buffer will be flushed.
+ }{
+ int fd & File descriptor returned by a previous call to open().\\
+ int request & Equals DMX\_SET\_PES\_FILTER for this command.\\
+ struct dmxPesFilterParams *params
+ & Pointer to structure containing filter parameters.\\
+ }{
+ EBADF & fd is not a valid file descriptor.\\
+ EINVAL & Invalid argument.\\
+ EBUSY & This error code indicates that there are
+ conflicting requests. There are active filters
+ filtering data from another input source. Make
+ sure that these filters are stopped before starting
+ this filter.\\
+}
+
+\ifunction{DMX\_SET\_BUFFER\_SIZE}{
+ int ioctl( int fd, int request = DMX\_SET\_BUFFER\_SIZE, unsigned long size);
+ }{
+ This ioctl call is used to set the size of the circular buffer used
+ for filtered data. The default size is two maximum sized sections, i.e.
+ if this function is not called a buffer size of 2 * 4096 bytes will be
+ used.
+ }{
+ int fd & File descriptor returned by a previous call to open().\\
+ int request & Equals DMX\_SET\_BUFFER\_SIZE for this command.\\
+ unsigned long size & Size of circular buffer.\\
+ }{
+ EBADF & fd is not a valid file descriptor.\\
+ ENOMEM & The driver was not able to allocate a buffer of the requested size.\\
+}
+
+\ifunction{DMX\_GET\_EVENT}{
+ int ioctl( int fd, int request = DMX\_GET\_EVENT, struct dmxEvent *ev);
+ }{
+ This ioctl call returns an event if available. If an event is not
+ available, the behavior depends on whether the device is in blocking or
+ non-blocking mode. In the latter case, the call fails immediately with
+ errno set to EWOULDBLOCK. In the former case, the call blocks until an
+ event becomes available.\\
+ The standard Linux poll() and/or select() system calls can be used with
+ the device file descriptor to watch for new events. For select(), the
+ file descriptor should be included in the exceptfds argument, and for
+ poll(), POLLPRI should be specified as the wake-up condition.
+ Only the latest event for each filter is saved.
+ }{
+ int fd & File descriptor returned by a previous call to open().\\
+ int request & Equals DMX\_GET\_EVENT for this command.\\
+ struct dmxEvent *ev & Pointer to the location where the event is to be stored.\\
+ }{
+ EBADF & fd is not a valid file descriptor.\\
+ EFAULT & ev points to an invalid address.\\
+ EWOULDBLOCK & There is no event pending, and the device is in non-blocking mode.\\
+}
+
+%%% Local Variables:
+%%% mode: latex
+%%% TeX-master: "dvbapi"
+%%% End:
diff --git a/dvb-spec/dvbapi/devices.tex b/dvb-spec/dvbapi/devices.tex
new file mode 100644
index 000000000..9c561e853
--- /dev/null
+++ b/dvb-spec/dvbapi/devices.tex
@@ -0,0 +1,12 @@
+\input{video.tex}
+\input{audio.tex}
+\input{frontend.tex}
+\input{sec.tex}
+\input{demux.tex}
+\input{ca.tex}
+\input{kdapi.tex}
+
+%%% Local Variables:
+%%% mode: latex
+%%% TeX-master: "dvbapi"
+%%% End:
diff --git a/dvb-spec/dvbapi/dvbapi.tex b/dvb-spec/dvbapi/dvbapi.tex
new file mode 100644
index 000000000..f9fcb841c
--- /dev/null
+++ b/dvb-spec/dvbapi/dvbapi.tex
@@ -0,0 +1,166 @@
+\documentclass[10pt]{book}
+\usepackage[dvips,colorlinks=true]{hyperref}
+
+\usepackage{times}
+
+%\usepackage[hang]{caption}
+\usepackage{fancyheadings}
+%\usepackage{lucidabr}
+%\usepackage{fancybox}
+\usepackage{array}
+\usepackage{graphicx}
+%\usepackage{latexsym}
+%\usepackage{pstricks,pst-node,pst-tree}
+%\usepackage{verbatim}
+%\usepackage{rotating}
+%\usepackage{pdftex}
+%\usepackage{color}
+%\usepackage{subfigure}
+%\usepackage{wrapfig}
+
+\newcommand{\devsec}[1]{\chapter{#1}}
+\newcommand{\devsubsec}[1]{\section{#1}}
+\newcommand{\devsubsubsec}[1]{\subsection{#1}}
+\newcommand{\function}[5]{
+ \subsection{#1}
+
+ \noindent DESCRIPTION
+ \medskip
+
+ \begin{tabular}[h]{p{11cm}}
+ #3
+ \end{tabular}
+
+ \medskip
+ \noindent SYNOPSIS
+ \medskip
+
+ \begin{tabular}[h]{p{11cm}}
+ {\tt #2}
+ \end{tabular}
+
+ %\item[]
+\medskip
+\noindent PARAMETERS
+\medskip
+
+ \begin{tabular}[h]{p{3cm}p{8cm}}
+ #4
+ \end{tabular}
+
+ %\item[]
+\medskip
+\noindent ERRORS
+\medskip
+
+ \begin{tabular}[h]{p{3cm}p{8cm}}
+ #5
+ \end{tabular}
+
+ %\end{itemize}
+
+\medskip
+}
+\def\ifunction#1#2#3#4#5{\function{#1\index{#1}}{#2}{#3}{#4}{#5}}
+
+\newcommand{\kfunction}[5]{
+ \subsection{#1}
+ \noindent DESCRIPTION
+ \medskip
+
+ \begin{tabular}[h]{p{11cm}}
+ #3
+ \end{tabular}
+
+ \medskip
+ \noindent SYNOPSIS
+ \medskip
+
+ \begin{tabular}[h]{p{11cm}}
+ {\tt #2}
+ \end{tabular}
+
+ %\item[]
+\medskip
+\noindent PARAMETERS
+\medskip
+
+ \begin{tabular}[h]{p{3cm}p{8cm}}
+ #4
+ \end{tabular}
+
+ %\item[]
+\medskip
+\noindent RETURNS
+\medskip
+
+ \begin{tabular}[h]{p{3cm}p{8cm}}
+ #5
+ \end{tabular}
+
+ %\end{itemize}
+
+\medskip
+}
+\def\kifunction#1#2#3#4#5{\kfunction{#1\index{#1}}{#2}{#3}{#4}{#5}}
+
+
+%\usepackage{index}
+%\makeindex
+
+
+\begin{document}
+
+\input{title.tex}
+
+\cleardoublepage
+
+\pagenumbering{roman}
+\pagestyle{fancyplain}
+
+
+\tableofcontents
+%\listoffigures
+%\listoftables
+
+\cleardoublepage
+
+\pagenumbering{arabic}
+
+\renewcommand{\chaptermark}[1]{\markboth{\uppercase{#1}}{}}
+\renewcommand{\sectionmark}[1]{\markright{\thesection.\ #1}{}}
+\lhead[\fancyplain{}{\bfseries \thepage}]{\bfseries \rightmark}
+\rhead[\fancyplain{}{\bfseries \leftmark}]{\bfseries \thepage}
+\cfoot{\copyright 2001 convergence integrated media GmbH}
+
+\input{intro.tex}
+
+\input{devices.tex}
+
+\input{examples.tex}
+
+\cleardoublepage
+
+\appendix
+
+\cleardoublepage
+
+\thispagestyle{plain}\chaptermark{Bibliography}
+\addcontentsline{toc}{chapter}{Bibliography}
+\bibliographystyle{bibsec}
+\bibliography{main}
+
+\cleardoublepage
+
+\thispagestyle{plain}\chaptermark{Subject Index}
+\addcontentsline{toc}{chapter}{Subject Index}
+%\printindex
+
+\cleardoublepage
+
+\end{document}
+
+%%% Local Variables:
+%%% mode: latex
+%%% TeX-master: t
+%%% End:
diff --git a/dvb-spec/dvbapi/dvbstb.fig b/dvb-spec/dvbapi/dvbstb.fig
new file mode 100644
index 000000000..0a6bbadc3
--- /dev/null
+++ b/dvb-spec/dvbapi/dvbstb.fig
@@ -0,0 +1,59 @@
+#FIG 3.2
+Landscape
+Center
+Metric
+A4
+100.00
+Single
+-2
+1200 2
+2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5
+ 1620 360 2520 360 2520 900 1620 900 1620 360
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2
+ 1 1 1.00 60.00 120.00
+ 1260 1080 1620 630
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2
+ 1 1 1.00 60.00 120.00
+ 2520 630 2880 630
+2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5
+ 2880 360 3780 360 3780 900 2880 900 2880 360
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2
+ 0 0 1.00 60.00 120.00
+ 4590 900 3330 1170
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2
+ 0 0 1.00 60.00 120.00
+ 4590 900 4590 1170
+2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5
+ 4140 360 5040 360 5040 900 4140 900 4140 360
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2
+ 1 1 1.00 60.00 120.00
+ 3780 630 4140 630
+2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5
+ 4140 1170 5040 1170 5040 1710 4140 1710 4140 1170
+2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5
+ 2880 1170 3780 1170 3780 1710 2880 1710 2880 1170
+2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5
+ 1620 1170 2520 1170 2520 1710 1620 1710 1620 1170
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2
+ 0 0 1.00 60.00 120.00
+ 1620 1440 1260 1080
+2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5
+ 1350 225 5175 225 5175 1845 1350 1845 1350 225
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2
+ 1 1 1.00 60.00 120.00
+ 3240 1710 3960 2070
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2
+ 1 1 1.00 60.00 120.00
+ 4590 1710 3960 2070
+2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5
+ 3510 2070 4410 2070 4410 2610 3510 2610 3510 2070
+2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5
+ 360 810 1260 810 1260 1350 360 1350 360 810
+4 0 0 50 0 0 12 0.0000 4 135 675 1755 675 Frontend\001
+4 0 0 50 0 0 12 0.0000 4 135 690 4275 675 Demuxer\001
+4 0 0 50 0 0 12 0.0000 4 135 450 4365 1485 Video\001
+4 0 0 50 0 0 12 0.0000 4 135 450 3105 1485 Audio\001
+4 0 0 50 0 0 12 0.0000 4 135 345 1890 1485 SEC\001
+4 0 0 50 0 0 12 0.0000 4 135 255 3195 675 CA\001
+4 0 0 50 0 0 12 0.0000 4 135 645 495 1125 Antenna\001
+4 0 0 50 0 0 12 0.0000 4 135 240 3870 2385 TV\001
diff --git a/dvb-spec/dvbapi/examples.tex b/dvb-spec/dvbapi/examples.tex
new file mode 100644
index 000000000..d2786a6f6
--- /dev/null
+++ b/dvb-spec/dvbapi/examples.tex
@@ -0,0 +1,365 @@
+\chapter{Examples}
+In this section we would like to present some examples for using the DVB API.
+
+\section{Tuning}
+We will start with a generic tuning subroutine that uses the frontend
+and SEC, as well as the demux devices. The example is given for QPSK
+tuners, but can easily be adjusted for QAM.
+
+{\small
+\begin{verbatim}
+#include <sys/ioctl.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <time.h>
+#include <unistd.h>
+
+#include <ost/dmx.h>
+#include <ost/frontend.h>
+#include <ost/sec.h>
+#include <sys/poll.h>
+
+#define DMX "/dev/ost/demux"
+#define QPSK "/dev/ost/qpskfe"
+#define SEC "/dev/ost/sec"
+
+/* routine for checking if we have a signal */
+int has_signal(int front)
+{
+ feStatus stat;
+
+ if ( front < 0 ){
+ if((front = open(QPSK,O_RDWR)) < 0){
+ perror("FRONTEND DEVICE: ");
+ return -1;
+ }
+ }
+
+ FEReadStatus(front, &stat);
+ if (stat & FE_HAS_SIGNAL)
+ return 0;
+ else {
+ printf("Tuning failed\n");
+ return -1;
+ }
+}
+
+/* tune qpsk */
+/* freq: frequency of transponder */
+/* vpid, apid, tpid: PIDs of video, audio and teletext TS packets */
+/* diseqc: DiSEqC address of the used LNB */
+/* pol: Polarisation */
+/* srate: Symbol Rate */
+/* fec. FEC */
+/* lnb_lof1: local frequency of lower LNB band */
+/* lnb_lof2: local frequency of upper LNB band */
+/* lnb_slof: switch frequency of LNB */
+
+int set_qpsk_channel(int freq, int vpid, int apid, int tpid,
+ int diseqc, int pol, int srate, int fec, int lnb_lof1,
+ int lnb_lof2, int lnb_slof)
+{
+ struct secCommand scmd;
+ struct secCmdSequence scmds;
+ struct dmxPesFilterParams pesFilterParams;
+ struct qpskParameters qpsk;
+ struct pollfd pfd[1];
+ struct qpskEvent event;
+ int front, sec, demux1, demux2, demux3;
+
+ /* Open all the necessary the devices */
+
+ if((front = open(QPSK,O_RDWR)) < 0){
+ perror("FRONTEND DEVICE: ");
+ return -1;
+ }
+
+ if((sec = open(SEC,O_RDWR)) < 0){
+ perror("SEC DEVICE: ");
+ return -1;
+ }
+
+ if ((demux1 = open(DMX, O_RDWR|O_NONBLOCK)) < 0){
+ perror("DEMUX DEVICE: ");
+ return -1;
+ }
+
+ if ((demux2 = open(DMX, O_RDWR|O_NONBLOCK)) < 0){
+ perror("DEMUX DEVICE: ");
+ return -1;
+ }
+
+ if ((demux3 = open(DMX, O_RDWR|O_NONBLOCK)) < 0){
+ perror("DEMUX DEVICE: ");
+ return -1;
+ }
+
+ /* Set the frequency of the transponder, taking into account the
+ local frequencies of the LNB */
+
+ if (freq < lnb_slof) {
+ qpsk.iFrequency = (freq - lnb_lof1);
+ scmds.continuousTone = SEC_TONE_OFF;
+ } else {
+ qpsk.iFrequency = (freq - lnb_lof2);
+ scmds.continuousTone = SEC_TONE_ON;
+ }
+
+ /* Set the polarity of the transponder by setting the correct
+ voltage on the universal LNB */
+
+ if (pol) scmds.voltage = SEC_VOLTAGE_18;
+ else scmds.voltage = SEC_VOLTAGE_13;
+
+ /* In case we have a DiSEqC, set it to the correct address */
+
+ scmd.type=0;
+ scmd.u.diseqc.addr=0x10;
+ scmd.u.diseqc.cmd=0x38;
+ scmd.u.diseqc.numParams=1;
+ scmd.u.diseqc.params[0] = 0xF0 | ((diseqc * 4) & 0x0F) |
+ (scmds.continuousTone == SEC_TONE_ON ? 1 : 0) |
+ (scmds.voltage==SEC_VOLTAGE_18 ? 2 : 0);
+
+ scmds.miniCommand=SEC_MINI_NONE;
+ scmds.numCommands=1;
+ scmds.commands=&scmd;
+
+ /* Send the data to the SEC device to prepare the LNB for tuning */
+ if (ioctl(sec, SEC_SEND_SEQUENCE, &scmds) < 0){
+ perror("SEC SEND: ");
+ return -1;
+ }
+
+ /* Set symbol rate and FEC */
+
+ qpsk.SymbolRate = srate;
+ qpsk.FEC_inner = fec;
+
+ /* Now send it all to the frontend device */
+ if (ioctl(front, QPSK_TUNE, &qpsk) < 0){
+ perror("QPSK TUNE: ");
+ return -1;
+ }
+
+ /* poll for QPSK event to check if tuning worked */
+ pfd[0].fd = front;
+ pfd[0].events = POLLIN;
+
+ if (poll(pfd,1,3000)){
+ if (pfd[0].revents & POLLIN){
+ printf("Getting QPSK event\n");
+ if ( ioctl(front, QPSK_GET_EVENT, &event)
+
+ == -EBUFFEROVERFLOW){
+ perror("qpsk get event");
+ return -1;
+ }
+ printf("Received ");
+ switch(event.type){
+ case FE_UNEXPECTED_EV:
+ printf("unexpected event\n");
+ return -1;
+ case FE_FAILURE_EV:
+ printf("failure event\n");
+ return -1;
+ case FE_COMPLETION_EV:
+ printf("completion event\n");
+ }
+ }
+ }
+
+
+ /* Set the filters for video, audio and teletext demuxing */
+
+ pesFilterParams.pid = vpid;
+ pesFilterParams.input = DMX_IN_FRONTEND;
+ pesFilterParams.output = DMX_OUT_DECODER;
+ pesFilterParams.pesType = DMX_PES_VIDEO;
+ pesFilterParams.flags = DMX_IMMEDIATE_START;
+ if (ioctl(demux1, DMX_SET_PES_FILTER, &pesFilterParams) < 0){
+ perror("set_vpid");
+ return -1;
+ }
+
+ pesFilterParams.pid = apid;
+ pesFilterParams.input = DMX_IN_FRONTEND;
+ pesFilterParams.output = DMX_OUT_DECODER;
+ pesFilterParams.pesType = DMX_PES_AUDIO;
+ pesFilterParams.flags = DMX_IMMEDIATE_START;
+ if (ioctl(demux2, DMX_SET_PES_FILTER, &pesFilterParams) < 0){
+ perror("set_apid");
+ return -1;
+ }
+
+ pesFilterParams.pid = tpid;
+ pesFilterParams.input = DMX_IN_FRONTEND;
+ pesFilterParams.output = DMX_OUT_DECODER;
+ pesFilterParams.pesType = DMX_PES_TELETEXT;
+ pesFilterParams.flags = DMX_IMMEDIATE_START;
+ if (ioctl(demux3, DMX_SET_PES_FILTER, &pesFilterParams) < 0){
+ perror("set_tpid");
+ return -1;
+ }
+
+ /* check if we have a signal */
+ return has_signal(front);
+}
+
+\end{verbatim}
+}
+The program assumes that you are using a universal LNB and a standard
+DiSEqC switch with up to 4 addresses. Of course, you could build in
+some more checking if tuning was successful and maybe try to repeat
+the tuning process. Depending on the external hardware, i.e. LNB and
+DiSEqC switch, and weather conditions this may be necessary.
+
+
+\section{The DVR device}
+The following program code shows how to use the DVR device for
+recording.
+
+{\small
+\begin{verbatim}
+#include <sys/ioctl.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <time.h>
+#include <unistd.h>
+
+#include <ost/dmx.h>
+#include <ost/video.h>
+#include <sys/poll.h>
+#define DVR "/dev/ost/dvr"
+#define AUDIO "/dev/ost/audio"
+#define VIDEO "/dev/ost/video"
+
+#define BUFFY (188*20)
+#define MAX_LENGTH (1024*1024*5) /* record 5MB */
+
+
+/* switch the demuxes to recording, assuming the transponder is tuned */
+
+/* demux1, demux2: file descriptor of video and audio filters */
+/* vpid, apid: PIDs of video and audio channels */
+
+int switch_to_record(int demux1, int demux2, uint16_t vpid, uint16_t apid)
+{
+ struct dmxPesFilterParams pesFilterParams;
+
+ if (demux1 < 0){
+ if ((demux1=open(DMX, O_RDWR|O_NONBLOCK))
+ < 0){
+ perror("DEMUX DEVICE: ");
+ return -1;
+ }
+ }
+
+ if (demux2 < 0){
+ if ((demux2=open(DMXdemuxs, O_RDWR|O_NONBLOCK))
+ < 0){
+ perror("DEMUX DEVICE: ");
+ return -1;
+ }
+ }
+
+ pesFilterParams.pid = vpid;
+ pesFilterParams.input = DMX_IN_FRONTEND;
+ pesFilterParams.output = DMX_OUT_TS_TAP;
+ pesFilterParams.pesType = DMX_PES_VIDEO;
+ pesFilterParams.flags = DMX_IMMEDIATE_START;
+ if (ioctl(demux1, DMX_SET_PES_FILTER, &pesFilterParams) < 0){
+ perror("DEMUX DEVICE");
+ return -1;
+ }
+ pesFilterParams.pid = apid;
+ pesFilterParams.input = DMX_IN_FRONTEND;
+ pesFilterParams.output = DMX_OUT_TS_TAP;
+ pesFilterParams.pesType = DMX_PES_AUDIO;
+ pesFilterParams.flags = DMX_IMMEDIATE_START;
+ if (ioctl(demux2, DMX_SET_PES_FILTER, &pesFilterParams) < 0){
+ perror("DEMUX DEVICE");
+ return -1;
+ }
+ return 0;
+}
+
+/* start recording MAX_LENGTH , assuming the transponder is tuned */
+
+/* demux1, demux2: file descriptor of video and audio filters */
+/* vpid, apid: PIDs of video and audio channels */
+int record_dvr(int demux1, int demux2, uint16_t vpid, uint16_t apid)
+{
+ int i;
+ int len;
+ int written;
+ uint8_t buf[BUFFY];
+ uint64_t length;
+ struct pollfd pfd[1];
+ int dvr, dvr_out;
+
+ /* open dvr device */
+ if ((dvr = open(DVR, O_RDONLY|O_NONBLOCK)) < 0){
+ perror("DVR DEVICE");
+ return -1;
+ }
+
+ /* switch video and audio demuxes to dvr */
+ printf ("Switching dvr on\n");
+ i = switch_to_record(demux1, demux2, vpid, apid);
+ printf("finished: ");
+
+ printf("Recording %2.0f MB of test file in TS format\n",
+ MAX_LENGTH/(1024.0*1024.0));
+ length = 0;
+
+ /* open output file */
+ if ((dvr_out = open(DVR_FILE,O_WRONLY|O_CREAT
+ |O_TRUNC, S_IRUSR|S_IWUSR
+ |S_IRGRP|S_IWGRP|S_IROTH|
+ S_IWOTH)) < 0){
+ perror("Can't open file for dvr test");
+ return -1;
+ }
+
+ pfd[0].fd = dvr;
+ pfd[0].events = POLLIN;
+
+ /* poll for dvr data and write to file */
+ while (length < MAX_LENGTH ) {
+ if (poll(pfd,1,1)){
+ if (pfd[0].revents & POLLIN){
+ len = read(dvr, buf, BUFFY);
+ if (len < 0){
+ perror("recording");
+ return -1;
+ }
+ if (len > 0){
+ written = 0;
+ while (written < len)
+ written +=
+ write (dvr_out,
+ buf, len);
+ length += len;
+ printf("written %2.0f MB\r",
+ length/1024./1024.);
+ }
+ }
+ }
+ }
+ return 0;
+}
+
+\end{verbatim}
+}
+%%% Local Variables:
+%%% mode: latex
+%%% TeX-master: "dvbapi"
+%%% TeX-master: t
+%%% End:
diff --git a/dvb-spec/dvbapi/fig2pstex b/dvb-spec/dvbapi/fig2pstex
new file mode 100755
index 000000000..bf62eb7ec
--- /dev/null
+++ b/dvb-spec/dvbapi/fig2pstex
@@ -0,0 +1,6 @@
+#!/bin/sh
+f=`basename $1 .fig`
+fig2dev -L pstex $f.fig $f.ps
+fig2dev -L pstex_t -p $f.ps $f.fig $f.pst2
+./getbb $f.pst2 $f.ps > $f.pst
+rm $f.pst2 \ No newline at end of file
diff --git a/dvb-spec/dvbapi/getbb b/dvb-spec/dvbapi/getbb
new file mode 100755
index 000000000..004714d3a
--- /dev/null
+++ b/dvb-spec/dvbapi/getbb
@@ -0,0 +1,12 @@
+#!/bin/sh
+f=`grep BoundingBox $2 | cut -d' ' -f2,3,4,5`
+g=`\
+echo $2" llx=";(echo $f|cut -d' ' -f1 );\
+echo " lly=";(echo $f|cut -d' ' -f2 );\
+echo " urx=";(echo $f|cut -d' ' -f3 );\
+echo " ury=";(echo $f|cut -d' ' -f4 );\
+echo " rwi=";(echo $f|cut -d' ' -f3 );\
+echo "0"
+`
+h=`echo $g| sed "s/= /=/g" | sed "s/ 0/0/g"`
+cat $1 | sed "s/psfile=$2/psfile=$h/"
diff --git a/dvb-spec/dvbapi/intro.tex b/dvb-spec/dvbapi/intro.tex
new file mode 100644
index 000000000..acb6b4b85
--- /dev/null
+++ b/dvb-spec/dvbapi/intro.tex
@@ -0,0 +1,192 @@
+\chapter{Introduction}
+%\addcontentsline{toc}{part}{Introduction}
+%\chaptermark{Introduction}
+\section{What you need to know}
+The reader of this document is required to have some knowledge in the
+area of digital video broadcasting (DVB) and should be familiar with
+part I of ISO/IEC 13818, i.e you should know what a
+program/transport stream (PS/TS) is and what is meant by a packetized elementary
+stream (PES) or an I-frame.
+
+It is also necessary to know how to access unix/linux devices and how
+to use ioctl calls. This also includes the knowledge of C or C++.
+\section{History}
+
+The first API for DVB cards we used at Convergence in late 1999
+was an extension of the Video4Linux API which was primarily
+developed for frame grabber cards.
+As such it was not really well suited to be used for DVB cards and
+their new features like recording MPEG streams and filtering several
+section and PES data streams at the same time.
+
+In early 2000, we were approached by Nokia with a proposal for a new
+standard Linux DVB API.
+As a commitment to the development of terminals based on open standards,
+Nokia and Convergence made it available to all Linux developers and
+published it on \texttt{http://www.linuxtv.org/} in September 2000.
+Convergence is the maintainer of the Linux DVB API.
+Together with the LinuxTV community (i.e. you, the reader of this document),
+the Linux DVB API will be constantly reviewed and improved upon.
+With the Linux driver for the Siemens/Hauppauge DVB PCI card Convergence
+provides a first implementation of the Linux DVB API.
+
+
+\section{Overview}
+
+\begin{figure}[htbp]
+ \begin{center}
+ \includegraphics{dvbstb.ps}
+ \caption{Components of a DVB card/STB}
+ \label{fig:dvbstb}
+ \end{center}
+\end{figure}
+
+
+A DVB PCI card or DVB set-top-box (STB) usually consists of the following
+main hardware components:
+\begin{itemize}
+\item Frontend consisting of tuner and DVB demodulator
+
+Here the raw signal reaches the DVB hardware from a satellite dish or antenna
+or directly from cable. The frontend down-converts and demodulates
+this signal into an MPEG transport stream (TS).
+
+\item SEC for controlling external hardware like LNBs and antennas
+
+This part of the hardware can send signals back through the satellite
+cable to control the polarization of the LNB, to switch between
+different LNBs or even to control the movements of a dish rotor.
+
+
+\item Conditional Access (CA) hardware like CI adapters and smartcard slots
+
+The complete TS is passed through the CA hardware. Programs to which
+the user has access (controlled by the smart card) are decoded in real
+time and re-inserted into the TS.
+
+\item Demultiplexer which filters the incoming DVB stream
+
+The demultiplexer splits the TS into its components like audio and video
+streams. Besides usually several of such audio and video streams it also
+contains data strams with information about the programs offered in this
+or other streams of the same provider.
+
+\item MPEG2 audio and video decoder
+
+The main targets of the demultiplexer are the MPEG2 audio and video
+decoders. After decoding the pass on the uncompressed audio
+and video to the computer screen or (through a PAL/NTSC encoder) to
+a TV set.
+\end{itemize}
+Figure \ref{fig:dvbstb} shows a crude schematic of the control and data flow
+between those components.
+
+On a DVB PCI card not all of these have to be present since some
+functionality can be provided by the main CPU of the PC (e.g. MPEG picture
+and sound decoding) or is not needed (e.g. for data-only uses like
+``internet over satellite'').
+Also not every card or STB provides conditional access hardware.
+
+\section{Linux DVB Devices}
+
+The Linux DVB API lets you control these hardware components
+through currently six Unix-style character devices for
+video, audio, frontend, SEC, demux and CA.
+The video and audio devices control the MPEG2 decoder hardware,
+the frontend device the tuner and the DVB demodulator.
+External hardware like DiSEqC switches and rotors can be controlled
+through the SEC device.
+The demux device gives you control over the PES and section filters
+of the hardware. If the hardware does not support filtering these filters
+can be implemented in software.
+Finally, the CA device controls all the conditional access capabilities
+of the hardware. It can depend on the individual security requirements
+of the platform, if and how many of the CA functions are made available
+to the application through this device.
+
+All devices can be found in the \texttt{/dev} tree under
+\texttt{/dev/ost}, where OST stands for Open Standards Terminal.
+The individual devices are called
+\begin{itemize}
+\item \texttt{/dev/ost/audio},
+\item \texttt{/dev/ost/video},
+\item \texttt{/dev/ost/qpskfe},
+\item \texttt{/dev/ost/qamfe},
+\item \texttt{/dev/ost/sec},
+\item \texttt{/dev/ost/demux},
+\item \texttt{/dev/ost/ca},
+\end{itemize}
+but we will omit the ``\texttt{/dev/ost/}'' in the further dicussion of
+these devices.
+
+%Thus, the \texttt{audio} and \texttt{video} devices directly control
+%the MPEG2 decoder audio and video decoder, respectively.
+%Depending on the kind of frontend present (satellite, cable or
+%terrestrial), it will be controlled either through the
+%\texttt{qpsk} or \texttt{qamfe} device.
+%DiSEqC or other kinds of control signals can be sent to the
+%antenna hardware through the \texttt{sec} device.
+
+If more than one card is present in the system the other cards
+can be accessed through the corresponding devices with the
+card's number appended. \texttt{/dev/ost/demux0} (which
+is identical to \texttt{/dev/ost/demux}) would, e.g., control the
+demultiplexer of the first card, while \texttt{/dev/ost/demux1}
+would control the demultiplexer of the second card, and so on.
+
+More details about the data structures and function calls of
+all the devices are described in the following chapters.
+
+
+\section{DVB Devices with Devfs}
+
+Recent Linux kernel versions support a special file system called
+\textsl{devfs} which is a replacement for the traditional
+device directory.
+With devfs a Linux DVB driver will only create those device file entries
+which actually exist.
+It also makes dealing with more complex DVB hardware much easier.
+The device structure described above is not well suited to deal
+with multiple DVB cards with more than one frontend or demultiplexer.
+Consider, e.g., two DVB cards, one with two frontends and
+one demultiplexer, the other with one frontend and two demultiplexers.
+If we just assign them consecutive numbers, there would be a demultiplexer
+and a frontend which do notbelong to the same card but have
+the same number.
+
+With \textsl{devfs} we propose a different scheme for the device names.
+The root directory for all DVB cards will be \texttt{/dev/dvb}.
+Each card gets assigned a sub-directory with the name \texttt{/dev/card0},
+\texttt{/dev/card1}, etc.
+The files created in these sub-directories will correspond directly to the
+hardware actually present on the card.
+Thus, if the first card has one QAM frontend, one demultiplexer
+and otherwise no other hardware,
+only \texttt{/dev/dvb/card0/qamfe0} and \texttt{/dev/dvb/card0/demux0}
+will be created.
+When a second DVB-S card with one frontend (including SEC) device,
+two demultiplexers and an MPEG2 audio/video decoder is added, the
+complete \texttt{/dev/dvb} tree will look like this:
+
+\begin{verbatim}
+/dev/dvb/card0/qam0
+ demux0
+
+/dev/dvb/card1/video0
+ audio0
+ demux0
+ demux1
+ qpskfe0
+ sec0
+\end{verbatim}
+
+
+\section{Using the Devices}
+
+\dots
+
+
+%%% Local Variables:
+%%% mode: latex
+%%% TeX-master: "dvbapi"
+%%% End:
diff --git a/dvb-spec/dvbapi/kdapi.tex b/dvb-spec/dvbapi/kdapi.tex
new file mode 100644
index 000000000..6cee25c85
--- /dev/null
+++ b/dvb-spec/dvbapi/kdapi.tex
@@ -0,0 +1,1007 @@
+\devsec{Kernel Demux API}
+
+The kernel demux API
+
+\devsubsec{Kernel Demux Data Types}
+
+\devsubsubsec{dmx\_success\_t}
+\label{dmxsuccesst}
+
+\begin{verbatim}
+typedef enum {
+ DMX_OK = 0, /* Received Ok */
+ DMX_LENGTH_ERROR, /* Incorrect length */
+ DMX_OVERRUN_ERROR, /* Receiver ring buffer overrun */
+ DMX_CRC_ERROR, /* Incorrect CRC */
+ DMX_FRAME_ERROR, /* Frame alignment error */
+ DMX_FIFO_ERROR, /* Receiver FIFO overrun */
+ DMX_MISSED_ERROR /* Receiver missed packet */
+} dmx_success_t;
+\end{verbatim}
+
+
+\devsubsubsec{TS filter types}
+\label{tsfiltertypes}
+
+\begin{verbatim}
+/*--------------------------------------------------------------------------*/
+/* TS packet reception */
+/*--------------------------------------------------------------------------*/
+
+/* TS filter type for set_type() */
+
+#define TS_PACKET 1 /* send TS packets (188 bytes) to callback (default) */
+#define TS_PAYLOAD_ONLY 2 /* in case TS_PACKET is set, only send the TS
+ payload (<=184 bytes per packet) to callback */
+#define TS_DECODER 4 /* send stream to built-in decoder (if present) */
+\end{verbatim}
+
+
+\devsubsubsec{dmx\_ts\_pes\_t}
+\label{dmxtspest}
+
+The structure
+/\begin{verbatim}
+typedef enum
+{
+ DMX_TS_PES_AUDIO, /* also send packets to audio decoder (if it exists) */
+ DMX_TS_PES_VIDEO, /* ... */
+ DMX_TS_PES_TELETEXT,
+ DMX_TS_PES_SUBTITLE,
+ DMX_TS_PES_PCR,
+ DMX_TS_PES_OTHER,
+} dmx_ts_pes_t;
+\end{verbatim}
+describes the PES type for filters which write to
+a built-in decoder.
+The correspond (and should be kept identical) to the types in
+the demux device.
+
+\begin{verbatim}
+struct dmx_ts_feed_s {
+ int is_filtering; /* Set to non-zero when filtering in progress */
+ struct dmx_demux_s* parent; /* Back-pointer */
+ void* priv; /* Pointer to private data of the API client */
+ int (*set) (struct dmx_ts_feed_s* feed,
+ __u16 pid,
+ size_t callback_length,
+ size_t circular_buffer_size,
+ int descramble,
+ struct timespec timeout);
+ int (*start_filtering) (struct dmx_ts_feed_s* feed);
+ int (*stop_filtering) (struct dmx_ts_feed_s* feed);
+ int (*set_type) (struct dmx_ts_feed_s* feed,
+ int type,
+ dmx_ts_pes_t pes_type);
+};
+
+typedef struct dmx_ts_feed_s dmx_ts_feed_t;
+\end{verbatim}
+
+\begin{verbatim}
+/*--------------------------------------------------------------------------*/
+/* PES packet reception (not supported yet) */
+/*--------------------------------------------------------------------------*/
+
+typedef struct dmx_pes_filter_s {
+ struct dmx_pes_s* parent; /* Back-pointer */
+ void* priv; /* Pointer to private data of the API client */
+} dmx_pes_filter_t;
+\end{verbatim}
+
+\begin{verbatim}
+typedef struct dmx_pes_feed_s {
+ int is_filtering; /* Set to non-zero when filtering in progress */
+ struct dmx_demux_s* parent; /* Back-pointer */
+ void* priv; /* Pointer to private data of the API client */
+ int (*set) (struct dmx_pes_feed_s* feed,
+ __u16 pid,
+ size_t circular_buffer_size,
+ int descramble,
+ struct timespec timeout);
+ int (*start_filtering) (struct dmx_pes_feed_s* feed);
+ int (*stop_filtering) (struct dmx_pes_feed_s* feed);
+ int (*allocate_filter) (struct dmx_pes_feed_s* feed,
+ dmx_pes_filter_t** filter);
+ int (*release_filter) (struct dmx_pes_feed_s* feed,
+ dmx_pes_filter_t* filter);
+} dmx_pes_feed_t;
+\end{verbatim}
+
+
+\begin{verbatim}
+\label{sectionfilter}
+typedef struct {
+ __u8 filter_value [DMX_MAX_FILTER_SIZE];
+ __u8 filter_mask [DMX_MAX_FILTER_SIZE];
+ struct dmx_section_feed_s* parent; /* Back-pointer */
+ void* priv; /* Pointer to private data of the API client */
+} dmx_section_filter_t;
+\end{verbatim}
+
+\begin{verbatim}
+struct dmx_section_feed_s {
+ int is_filtering; /* Set to non-zero when filtering in progress */
+ struct dmx_demux_s* parent; /* Back-pointer */
+ void* priv; /* Pointer to private data of the API client */
+ int (*set) (struct dmx_section_feed_s* feed,
+ __u16 pid,
+ size_t circular_buffer_size,
+ int descramble,
+ int check_crc);
+ int (*allocate_filter) (struct dmx_section_feed_s* feed,
+ dmx_section_filter_t** filter);
+ int (*release_filter) (struct dmx_section_feed_s* feed,
+ dmx_section_filter_t* filter);
+ int (*start_filtering) (struct dmx_section_feed_s* feed);
+ int (*stop_filtering) (struct dmx_section_feed_s* feed);
+};
+typedef struct dmx_section_feed_s dmx_section_feed_t;
+
+/*--------------------------------------------------------------------------*/
+/* Callback functions */
+/*--------------------------------------------------------------------------*/
+
+typedef int (*dmx_ts_cb) ( __u8 * buffer1,
+ size_t buffer1_length,
+ __u8 * buffer2,
+ size_t buffer2_length,
+ dmx_ts_feed_t* source,
+ dmx_success_t success);
+
+typedef int (*dmx_section_cb) ( __u8 * buffer1,
+ size_t buffer1_len,
+ __u8 * buffer2,
+ size_t buffer2_len,
+ dmx_section_filter_t * source,
+ dmx_success_t success);
+
+typedef int (*dmx_pes_cb) ( __u8 * buffer1,
+ size_t buffer1_len,
+ __u8 * buffer2,
+ size_t buffer2_len,
+ dmx_pes_filter_t* source,
+ dmx_success_t success);
+
+/*--------------------------------------------------------------------------*/
+/* DVB Front-End */
+/*--------------------------------------------------------------------------*/
+
+typedef enum {
+ DMX_OTHER_FE = 0,
+ DMX_SATELLITE_FE,
+ DMX_CABLE_FE,
+ DMX_TERRESTRIAL_FE,
+ DMX_LVDS_FE,
+ DMX_ASI_FE, /* DVB-ASI interface */
+ DMX_MEMORY_FE
+} dmx_frontend_source_t;
+
+typedef struct {
+ /* The following char* fields point to NULL terminated strings */
+ char* id; /* Unique front-end identifier */
+ char* vendor; /* Name of the front-end vendor */
+ char* model; /* Name of the front-end model */
+ struct list_head connectivity_list; /* List of front-ends that can
+ be connected to a particular
+ demux */
+ void* priv; /* Pointer to private data of the API client */
+ dmx_frontend_source_t source;
+} dmx_frontend_t;
+
+/*--------------------------------------------------------------------------*/
+/* MPEG-2 TS Demux */
+/*--------------------------------------------------------------------------*/
+
+/*
+ * Flags OR'ed in the capabilites field of struct dmx_demux_s.
+ */
+
+#define DMX_TS_FILTERING 1
+#define DMX_PES_FILTERING 2
+#define DMX_SECTION_FILTERING 4
+#define DMX_MEMORY_BASED_FILTERING 8 /* write() available */
+#define DMX_CRC_CHECKING 16
+#define DMX_TS_DESCRAMBLING 32
+#define DMX_SECTION_PAYLOAD_DESCRAMBLING 64
+#define DMX_MAC_ADDRESS_DESCRAMBLING 128
+\end{verbatim}
+
+\devsubsubsec{demux\_demux\_t}
+\label{demuxdemuxt}
+
+\begin{verbatim}
+/*
+ * DMX_FE_ENTRY(): Casts elements in the list of registered
+ * front-ends from the generic type struct list_head
+ * to the type * dmx_frontend_t
+ *.
+*/
+
+#define DMX_FE_ENTRY(list) list_entry(list, dmx_frontend_t, connectivity_list)
+
+struct dmx_demux_s {
+ /* The following char* fields point to NULL terminated strings */
+ char* id; /* Unique demux identifier */
+ char* vendor; /* Name of the demux vendor */
+ char* model; /* Name of the demux model */
+ __u32 capabilities; /* Bitfield of capability flags */
+ dmx_frontend_t* frontend; /* Front-end connected to the demux */
+ struct list_head reg_list; /* List of registered demuxes */
+ void* priv; /* Pointer to private data of the API client */
+ int users; /* Number of users */
+ int (*open) (struct dmx_demux_s* demux);
+ int (*close) (struct dmx_demux_s* demux);
+ int (*write) (struct dmx_demux_s* demux, const char* buf, size_t count);
+ int (*allocate_ts_feed) (struct dmx_demux_s* demux,
+ dmx_ts_feed_t** feed,
+ dmx_ts_cb callback);
+ int (*release_ts_feed) (struct dmx_demux_s* demux,
+ dmx_ts_feed_t* feed);
+ int (*allocate_pes_feed) (struct dmx_demux_s* demux,
+ dmx_pes_feed_t** feed,
+ dmx_pes_cb callback);
+ int (*release_pes_feed) (struct dmx_demux_s* demux,
+ dmx_pes_feed_t* feed);
+ int (*allocate_section_feed) (struct dmx_demux_s* demux,
+ dmx_section_feed_t** feed,
+ dmx_section_cb callback);
+ int (*release_section_feed) (struct dmx_demux_s* demux,
+ dmx_section_feed_t* feed);
+ int (*descramble_mac_address) (struct dmx_demux_s* demux,
+ __u8* buffer1,
+ size_t buffer1_length,
+ __u8* buffer2,
+ size_t buffer2_length,
+ __u16 pid);
+ int (*descramble_section_payload) (struct dmx_demux_s* demux,
+ __u8* buffer1,
+ size_t buffer1_length,
+ __u8* buffer2, size_t buffer2_length,
+ __u16 pid);
+ int (*add_frontend) (struct dmx_demux_s* demux,
+ dmx_frontend_t* frontend);
+ int (*remove_frontend) (struct dmx_demux_s* demux,
+ dmx_frontend_t* frontend);
+ struct list_head* (*get_frontends) (struct dmx_demux_s* demux);
+ int (*connect_frontend) (struct dmx_demux_s* demux,
+ dmx_frontend_t* frontend);
+ int (*disconnect_frontend) (struct dmx_demux_s* demux);
+
+
+ /* added because js cannot keep track of these himself */
+ int (*get_pes_pids) (struct dmx_demux_s* demux, __u16 *pids);
+};
+typedef struct dmx_demux_s dmx_demux_t;
+\end{verbatim}
+
+
+\devsubsubsec{Demux directory}
+\label{demuxdir}
+
+\begin{verbatim}
+/*
+ * DMX_DIR_ENTRY(): Casts elements in the list of registered
+ * demuxes from the generic type struct list_head* to the type dmx_demux_t
+ *.
+ */
+
+#define DMX_DIR_ENTRY(list) list_entry(list, dmx_demux_t, reg_list)
+
+int dmx_register_demux (dmx_demux_t* demux);
+int dmx_unregister_demux (dmx_demux_t* demux);
+struct list_head* dmx_get_demuxes (void);
+\end{verbatim}
+
+\clearpage
+
+\devsubsec{Demux Directory API}
+
+The demux directory is a Linux kernel-wide facility for registering and
+accessing the MPEG-2 TS demuxes in the system. Run-time registering and
+unregistering of demux drivers is possible using this API.
+
+All demux drivers in the directory implement the abstract interface dmx\_demux\_t.
+
+\kifunction{dmx\_register\_demux()}{
+ int dmx\_register\_demux ( dmx\_demux\_t *demux )
+ }{
+ This function makes a demux driver interface available to the Linux kernel.
+ It is usually called by the init\_module() function of the kernel module that
+ contains the demux driver. The caller of this function is responsible for
+ allocating dynamic or static memory for the demux structure and for initializing
+ its fields before calling this function.
+ The memory allocated for the demux structure must not be freed before calling
+ dmx\_unregister\_demux(),
+ }{
+ dmx\_demux\_t* demux & Pointer to the demux structure.
+ }{
+ 0 & The function was completed without errors.\\
+ -EEXIST & A demux with the same value of the id field
+ already stored in the directory.\\
+ -ENOSPC & No space left in the directory.
+}
+
+\kifunction{dmx\_unregister\_demux()}{
+ int dmx\_unregister\_demux ( dmx\_demux\_t *demux )
+ }{
+ This function is called to indicate that the given demux interface is no longer
+ available. The caller of this function is responsible for freeing the memory of
+ the demux structure, if it was dynamically allocated before calling
+ dmx\_register\_demux().
+ The cleanup\_module() function of the kernel module that contains the demux
+ driver should call this function. Note that this function fails if the demux
+ is currently in use, i.e., release\_demux() has not been called for the
+ interface.
+ }{
+ dmx\_demux\_t* demux & Pointer to the demux structure which is to be unregistered.
+ }{
+ 0 & The function was completed without errors.\\
+ ENODEV & The specified demux is not registered in the demux directory.\\
+ EBUSY & The specified demux is currently in use.
+}
+
+\kifunction{dmx\_get\_demuxes()}{
+ struct list\_head *dmx\_get\_demuxes ()
+ }{
+ Provides the caller with the list of registered demux interfaces, using the
+ standard list structure defined in the include file linux/list.h.
+ The include file demux.h defines the macro DMX\_DIR\_ENTRY() for converting an
+ element of the generic type struct list\_head* to the type dmx\_demux\_t*.
+ The caller must not free the memory of any of the elements obtained via this
+ function call.
+ }{
+ none
+ }{
+ struct list\_head * &
+ A list of demux interfaces, or NULL in the case of an empty list.
+}
+
+\clearpage
+
+\devsubsec{Demux API}
+
+The demux API should be implemented for each demux in the system. It is used to
+select the TS source of a demux and to manage the demux resources. When the
+demux client allocates a resource via the demux API, it receives a pointer
+to the API of that resource.
+
+Each demux receives its TS input from a DVB front-end or from memory, as
+set via the demux API. In a system with more than one front-end, the API can
+be used to select one of the DVB front-ends as a TS source for a demux, unless
+this is fixed in the HW platform. The demux API only controls front-ends
+regarding their connections with demuxes; the APIs used to set the other
+front-end parameters, such as tuning, are not defined in this document.
+
+The functions that implement the abstract interface demux should be defined
+static or module private and registered to the Demux Directory for external
+access. It is not necessary to implement every function in the demux\_t struct,
+however (for example, a demux interface might support Section filtering, but
+not TS or PES filtering). The API client is expected to check the value of any
+function pointer before calling the function: the value of NULL means ``function
+not available''.
+
+Whenever the functions of the demux API modify shared data, the possibilities
+of lost update and race condition problems should be addressed, e.g. by
+protecting parts of code with mutexes. This is especially important on
+multi-processor hosts.
+
+Note that functions called from a bottom half context must not sleep, at least
+in the 2.2.x kernels. Even a simple memory allocation can result in a kernel
+thread being put to sleep if swapping is needed. For example, the Linux kernel
+calls the functions of a network device interface from a bottom half context.
+Thus, if a demux API function is called from network device code, the function
+must not sleep.
+
+\kfunction{open()}{
+ int open ( demux\_t* demux );
+ }{
+ This function reserves the demux for use by the caller and, if necessary,
+ initializes the demux. When the demux is no longer needed, the function close()
+ should be called.
+ It should be possible for multiple clients to access the demux at the same time.
+ Thus, the function implementation should increment the demux usage count when
+ open() is called and decrement it when close() is called.
+ }{
+ demux\_t* demux & Pointer to the demux API and instance data.
+ }{
+ 0 & The function was completed without errors.\\
+ -EUSERS & Maximum usage count reached.\\
+ -EINVAL & Bad parameter.
+}
+
+\kfunction{close()}{
+ int close(demux\_t* demux);
+ }{
+ This function reserves the demux for use by the caller and, if necessary,
+ initializes the demux. When the demux is no longer needed, the function close()
+ should be called.
+ It should be possible for multiple clients to access the demux at the same time.
+ Thus, the function implementation should increment the demux usage count when
+ open() is called and decrement it when close() is called.
+ }{
+ demux\_t* demux & Pointer to the demux API and instance data.
+ }{
+ 0 & The function was completed without errors.\\
+ -ENODEV & The demux was not in use.\\
+ -EINVAL & Bad parameter.
+}
+
+\kfunction{write()}{
+ int write(demux\_t* demux, const char* buf, size\_t count);
+ }{
+ This function provides the demux driver with a memory buffer containing TS
+ packets. Instead of receiving TS packets from the DVB front-end, the demux
+ driver software will read packets from memory. Any clients of this demux
+ with active TS, PES or Section filters will receive filtered data via the Demux
+ callback API (see 0). The function returns when all the data in the buffer has
+ been consumed by the demux.
+ Demux hardware typically cannot read TS from memory. If this is the case,
+ memory-based filtering has to be implemented entirely in software.
+ }{
+ demux\_t* demux & Pointer to the demux API and instance data.\\
+ const char* buf & Pointer to the TS data in kernel-space memory.\\
+ size\_t length & Length of the TS data.
+ }{
+ 0 & The function was completed without errors.\\
+ -ENOSYS & The command is not implemented.\\
+ -EINVAL & Bad parameter.
+}
+
+\kifunction{allocate\_ts\_feed()}{
+ int allocate\_ts\_feed(dmx\_demux\_t* demux,
+ dmx\_ts\_feed\_t** feed, dmx\_ts\_cb callback);
+ }{
+ Allocates a new TS feed, which is used to filter the TS packets carrying a
+ certain PID.
+ The TS feed normally corresponds to a hardware PID filter on the demux chip.
+ }{
+ demux\_t* demux & Pointer to the demux API and instance data.\\
+ dmx\_ts\_feed\_t** feed & Pointer to the TS feed API and instance data.\\
+ dmx\_ts\_cb callback & Pointer to the callback function for
+ passing received TS packet
+ }{
+ 0 & The function was completed without errors.\\
+ -EBUSY & No more TS feeds available.\\
+ -ENOSYS & The command is not implemented.\\
+ -EINVAL & Bad parameter.
+}
+
+\kifunction{release\_ts\_feed()}{
+ int release\_ts\_feed(dmx\_demux\_t* demux, dmx\_ts\_feed\_t* feed);
+ }{
+ Releases the resources allocated with allocate\_ts\_feed(). Any filtering in progress
+ on the TS feed should be stopped before calling this function.
+ }{
+ demux\_t* demux & Pointer to the demux API and instance data.\\
+ dmx\_ts\_feed\_t* feed & Pointer to the TS feed API and instance data.
+ }{
+ 0 & The function was completed without errors.\\
+ -EINVAL & Bad parameter.
+}
+
+\kifunction{allocate\_section\_feed()}{
+ int allocate\_section\_feed(dmx\_demux\_t* demux, dmx\_section\_feed\_t **feed,
+ dmx\_section\_cb callback);
+ }{
+ Allocates a new section feed, i.e. a demux resource for filtering and
+ receiving sections.
+ On platforms with hardware support for section filtering, a section feed is directly
+ mapped to the demux HW. On other platforms, TS packets are first PID filtered in
+ hardware and a hardware section filter then emulated in software.
+ The caller obtains an API pointer of type dmx\_section\_feed\_t as an out parameter.
+ Using this API the caller can set filtering parameters and start receiving sections.
+ }{
+ demux\_t *demux & Pointer to the demux API and instance data.\\
+ dmx\_section\_feed\_t **feed & Pointer to the section feed API and instance data.\\
+ dmx\_section\_cb callback & Pointer to the callback function for
+ passing received sections.
+ }{
+ 0 & The function was completed without errors.\\
+ -EBUSY & No more section feeds available.\\
+ -ENOSYS & The command is not implemented.\\
+ -EINVAL & Bad parameter.
+}
+
+
+\kifunction{release\_section\_feed()}{
+ int release\_section\_feed(dmx\_demux\_t* demux, dmx\_section\_feed\_t *feed);
+ }{
+ Releases the resources allocated with allocate\_section\_feed(), including allocated
+ filters.
+ Any filtering in progress on the section feed should be stopped before calling
+ this function.
+ }{
+ demux\_t *demux & Pointer to the demux API and instance data.\\
+ dmx\_section\_feed\_t *feed & Pointer to the section feed API and instance data.
+ }{
+ 0 & The function was completed without errors.\\
+ -EINVAL & Bad parameter.
+}
+
+\kifunction{descramble\_mac\_address()}{
+ int descramble\_mac\_address(dmx\_demux\_t* demux,
+ \_\_u8 *buffer1, size\_t buffer1\_length,
+ \_\_u8 *buffer2, size\_t buffer2\_length, \_\_u16 pid);
+ }{
+ This function runs a descrambling algorithm on the destination MAC address field of a
+ DVB Datagram Section, replacing the original address with its un-encrypted version.
+ Otherwise, the description on the function descramble\_section\_payload() applies
+ also to this function.
+ }{
+ dmx\_demux\_t *demux & Pointer to the demux API and instance data.\\
+ \_\_u8 *buffer1 & Pointer to the first byte of the section.\\
+ size\_t buffer1\_length & Length of the section data, including headers and CRC,
+ in buffer1.\\
+ \_\_u8* buffer2 & Pointer to the tail of the section data, or NULL. The pointer has a
+ non-NULL value if the section wraps
+ past the end of a circular buffer.\\
+ size\_t buffer2\_length & Length of the section data,
+ including headers and CRC, in buffer2.\\
+ \_\_u16 pid & The PID on which the section was received. Useful for obtaining the
+ descrambling key, e.g. from a DVB Common Access facility.
+ }{
+ 0 & The function was completed without errors.\\
+ -ENOSYS & No descrambling facility available.\\
+ -EINVAL & Bad parameter.
+}
+
+\kifunction{descramble\_section\_payload()}{
+ int descramble\_section\_payload(dmx\_demux\_t* demux,
+ \_\_u8 *buffer1, size\_t buffer1\_length, \_\_u8 *buffer2, size\_t
+ buffer2\_length, \_\_u16 pid);
+ }{
+ This function runs a descrambling algorithm on the payload of a DVB Datagram
+ Section, replacing the original payload with its un-encrypted version.
+ The function will
+ be called from the demux API implementation; the API client need
+ not call this function directly.
+ Section-level scrambling algorithms are currently standardized only for DVB-RCC
+ (return channel over 2-directional cable TV network) systems. For all other DVB
+ networks, encryption schemes are likely to be proprietary to each data broadcaster.
+ Thus, it is expected that this function pointer will have the value of NULL
+ (i.e., function not available) in most demux API implementations.
+ Nevertheless, it should be possible
+ to use the function pointer as a hook for dynamically adding a ``plug-in''
+ descrambling facility to a demux driver.\\
+ While this function is not needed with hardware-based section descrambling, the
+ descramble\_section\_payload function pointer can be used to override the default
+ hardware-based descrambling algorithm: if the function pointer has a non-NULL value,
+ the corresponding function should be used instead of any descrambling hardware.
+ }{
+ dmx\_demux\_t *demux & Pointer to the demux API and instance data.\\
+ \_\_u8 *buffer1 & Pointer to the first byte of the section.\\
+ size\_t buffer1\_length & Length of the section data, including headers and CRC, in
+ buffer1.\\
+ \_\_u8 *buffer2 & Pointer to the tail of the section data, or NULL. The pointer has a
+ non-NULL value if the section wraps
+ past the end of a circular buffer.\\
+ size\_t buffer2\_length & Length of the section data, including headers and CRC, in
+ buffer2.\\
+ \_\_u16 pid & The PID on which the section was received. Useful for obtaining the
+ descrambling key, e.g. from a DVB Common Access facility.
+ }{
+ 0 & The function was completed without errors.\\
+ -ENOSYS & No descrambling facility available.\\
+ -EINVAL & Bad parameter.
+}
+
+\kifunction{add\_frontend()}{
+ int add\_frontend(dmx\_demux\_t *demux, dmx\_frontend\_t *frontend);
+ }{
+ Registers a connectivity between a demux and a front-end, i.e., indicates that the
+ demux can be connected via a call to connect\_frontend() to use the given front-end
+ as a TS source. The client of this function has to allocate dynamic or static
+ memory for
+ the frontend structure and initialize its fields before calling this function.
+ This function is normally called during the driver initialization.
+ The caller must not free
+ the memory of the frontend struct before successfully calling remove\_frontend().
+ }{
+ dmx\_demux\_t* demux & Pointer to the demux API and instance data.\\
+ dmx\_frontend\_t* frontend & Pointer to the front-end instance data.
+ }{
+ 0 & The function was completed without errors.\\
+ -EEXIST & A front-end with the same value of the id field already registered.\\
+ -EINUSE & The demux is in use.\\
+ -ENOMEM & No more front-ends can be added.\\
+ -EINVAL & Bad parameter.
+}
+
+\kifunction{remove\_frontend()}{
+ int remove\_frontend(dmx\_demux\_t* demux, dmx\_frontend\_t* frontend);
+ }{
+ Indicates that the given front-end, registered by a call to add\_frontend(), can no
+ longer be connected as a TS source by this demux. The function should be called
+ when a front-end driver or a demux driver is removed from the system. If the front-end
+ is in use, the function fails with the return value of -EBUSY.
+ After successfully calling this function, the caller can free the memory of
+ the frontend struct if it was dynamically allocated before the add\_frontend()
+ operation.
+ }{
+ dmx\_demux\_t* demux & Pointer to the demux API and instance data.\\
+ dmx\_frontend\_t* frontend & Pointer to the front-end instance data.
+ }{
+ 0 & The function was completed without errors.\\
+ -EINVAL & Bad parameter.\\
+ -EBUSY & The front-end is in use, i.e. a call to
+ connect\_frontend() has not been followed by
+ a call to disconnect\_frontend().
+}
+
+\kifunction{get\_frontends()}{
+ struct list\_head* get\_frontends(dmx\_demux\_t* demux);
+ }{
+ Provides the APIs of the front-ends that have been registered for this demux. Any of
+ the front-ends obtained with this call can be used as a parameter for
+ connect\_frontend().\\
+ The include file demux.h contains the macro DMX\_FE\_ENTRY() for converting an
+ element of the generic type struct list\_head* to the type dmx\_frontend\_t*.
+ The caller must not free the memory of any of the elements obtained via this function
+ call.
+ }{
+ dmx\_demux\_t* demux & Pointer to the demux API and instance data.
+ }{
+ dmx\_demux\_t* & A list of front-end interfaces, or NULL in the case of an empty list.
+}
+
+
+\kifunction{connect\_frontend()}{
+ int connect\_frontend(dmx\_demux\_t* demux, dmx\_frontend\_t* frontend);
+ }{
+ Connects the TS output of the front-end to the input of the demux. A demux can only
+ be connected to a front-end registered to the demux with the function
+ add\_frontend().\\
+ It may or may not be possible to connect multiple demuxes to the same front-end,
+ depending on the capabilities of the HW platform. When not used, the front-end should
+ be released by calling disconnect\_frontend().
+ }{
+ dmx\_demux\_t* demux & Pointer to the demux API and instance data.\\
+ dmx\_frontend\_t* frontend & Pointer to the front-end instance data.
+ }{
+ 0 & The function was completed without errors.\\
+ -EINVAL & Bad parameter.\\
+ -EBUSY & The front-end is in use.
+}
+
+\kifunction{disconnect\_frontend()}{
+ int disconnect\_frontend(dmx\_demux\_t* demux);
+ }{
+ Disconnects the demux and a front-end previously connected by a
+ connect\_frontend() call.
+ }{
+ dmx\_demux\_t* demux & Pointer to the demux API and instance data.
+ }{
+ 0 & The function was completed without errors.\\
+ -EINVAL & Bad parameter.
+}
+
+\clearpage
+
+\devsubsec{Demux Callback API}
+
+This kernel-space API comprises the callback functions that deliver filtered data to the
+demux client. Unlike the other APIs, these API functions are provided by the client and
+called from the demux code.
+
+The function pointers of this abstract interface are not packed into a structure
+as in the
+other demux APIs, because the callback functions are registered and used
+independent of each other. As an example, it is possible for the API client to provide
+several callback functions for receiving TS packets and no callbacks for PES packets
+or sections.
+
+The functions that implement the callback API need not be re-entrant: when a demux
+driver calls one of these functions, the driver is not allowed to call the
+function again before the original call returns.
+If a callback is triggered by a hardware interrupt, it is
+recommended to use the Linux ``bottom half'' mechanism or start a tasklet instead of
+making the callback function call directly from a hardware interrupt.
+
+\kifunction{dmx\_ts\_cb()}{
+ int dmx\_ts\_cb(\_\_u8* buffer1, size\_t buffer1\_length,
+ \_\_u8* buffer2, size\_t buffer2\_length,
+ dmx\_ts\_feed\_t* source, dmx\_success\_t success);
+ }{
+ This function, provided by the client of the demux API, is called from the
+ demux code. The function is only called when filtering on this TS feed has
+ been enabled using the start\_filtering() function. \\
+ Any TS packets that match the filter settings are copied to a circular buffer.
+ The filtered TS packets are delivered to the client using this callback
+ function. The size of the circular buffer is controlled by the
+ circular\_buffer\_size parameter of the set() function in the TS Feed API. It is
+ expected that the buffer1 and buffer2 callback parameters point to addresses
+ within the circular buffer, but other implementations are also
+ possible. Note that the called party should not try to free the memory the
+ buffer1 and buffer2 parameters point to.\\
+ When this function is called, the buffer1 parameter typically points to the
+ start of the first undelivered TS packet within a circular buffer. The buffer2
+ buffer parameter is normally NULL, except when the received TS packets have
+ crossed the last address of the circular buffer and "wrapped" to the beginning
+ of the buffer. In the latter case the buffer1 parameter would contain an
+ address within the circular buffer, while the buffer2 parameter would contain
+ the first address of the circular buffer.\\
+ The number of bytes delivered with this function (i.e. buffer1\_length +
+ buffer2\_length) is usually equal to the value of callback\_length parameter given
+ in the set() function, with one exception: if a timeout occurs before receiving
+ callback\_length bytes of TS data, any undelivered packets are immediately
+ delivered to the client by calling this function. The timeout duration is
+ controlled by the set() function in the TS Feed API.\\
+ If a TS packet is received with errors that could not be fixed by the TS-level
+ forward error correction (FEC), the Transport\_error\_indicator flag of the TS
+ packet header should be set. The TS packet should not be discarded, as the
+ error can possibly be corrected by a higher layer protocol.
+ If the called party is slow in processing the callback, it is possible that
+ the circular buffer eventually fills up. If this happens, the demux driver
+ should discard any TS packets received while the buffer is full. The error
+ should be indicated to the client on the next callback by setting the success
+ parameter to the value of DMX\_OVERRUN\_ERROR.\\
+ The type of data returned to the callback can be selected by the
+ new function int (*set\_type) (struct dmx\_ts\_feed\_s* feed, int type,
+ dmx\_ts\_pes\_t pes\_type) which is part of the dmx\_ts\_feed\_s struct
+ (also cf. to the include file ost/demux.h)
+ The type parameter decides if the raw TS packet (TS\_PACKET) or just the
+ payload (TS\_PACKET|TS\_PAYLOAD\_ONLY) should be returned.
+ If additionally the TS\_DECODER bit is set the stream will also be sent
+ to the hardware MPEG decoder. In this case, the second flag decides
+ as what kind of data the stream should be interpreted.
+ The possible choices are one of DMX\_TS\_PES\_AUDIO, DMX\_TS\_PES\_VIDEO,
+ DMX\_TS\_PES\_TELETEXT, DMX\_TS\_PES\_SUBTITLE, DMX\_TS\_PES\_PCR, or
+ DMX\_TS\_PES\_OTHER.
+ }{
+ \_\_u8* buffer1 & Pointer to the start of the filtered TS packets.\\
+ size\_t buffer1\_length & Length of the TS data in buffer1.\\
+ \_\_u8* buffer2 & Pointer to the tail of the filtered TS packets, or NULL.\\
+ size\_t buffer2\_length & Length of the TS data in buffer2.\\
+ dmx\_ts\_feed\_t* source & Indicates which TS feed is the source of the callback.\\
+ dmx\_success\_t success & Indicates if there was an error in TS reception.
+ }{
+ 0 & Continue filtering.\\
+ -1& Stop filtering - has the same effect as a call
+ to stop\_filtering() on the TS Feed API.
+}
+
+\kifunction{dmx\_section\_cb()}{
+ int dmx\_section\_cb(\_\_u8* buffer1, size\_t buffer1\_length, \_\_u8* buffer2,
+ size\_t buffer2\_length, dmx\_section\_filter\_t* source,
+ dmx\_success\_t success);
+ }{
+ This function, provided by the client of the demux API, is called from the demux code.
+ The function is only called when filtering of sections has been enabled using the
+ function start\_filtering() of the section feed API.
+ When the demux driver has received a complete section that matches at least one
+ section filter, the client is notified via this callback function. Normally this function is
+ called for each received section; however, it is also possible to deliver multiple sections
+ with one callback, for example when the system load is high.
+ If an error occurs while receiving a section, this function should be called with the
+ corresponding error type set in the success field, whether or not there is data to
+ deliver.
+ The Section Feed implementation should maintain a circular buffer for received sections.
+ However, this is not necessary if the Section Feed API is implemented as a client of
+ the TS Feed API, because the TS Feed implementation then buffers the
+ received data.
+ The size of the circular buffer can be configured using the set() function in the
+ Section Feed API. If there is no room in the circular buffer when a new section is
+ received, the section must be discarded. If this happens, the value of the success
+ parameter should be DMX\_OVERRUN\_ERROR on the next callback.
+ }{
+ \_\_u8* buffer1 & Pointer to the start of the filtered section, e.g.
+ within the circular buffer of the demux driver.\\
+ size\_t buffer1\_length & Length of the filtered section data in buffer1,
+ including headers and CRC.\\
+ \_\_u8* buffer2 & Pointer to the tail of the filtered section data, or
+ NULL. Useful to handle the wrapping of a circular
+ buffer.\\
+ size\_t buffer2\_length & Length of the filtered section data in buffer2,
+ including headers and CRC.\\
+ dmx\_section\_filter\_t* filter & Indicates the filter that triggered the callback.\\
+ dmx\_success\_t success & Indicates if there was an error in section reception.
+ }{
+ 0 & Continue filtering.\\
+ -1& Stop filtering - has the same effect as a call
+ to stop\_filtering() on the Section Feed API.
+}
+
+\clearpage
+
+\devsubsec{TS Feed API}
+
+A TS feed is typically mapped to a hardware PID filter on the demux chip. Using this
+API, the client can set the filtering properties to start/stop filtering TS packets on a
+particular TS feed. The API is defined as an abstract interface of the type
+dmx\_ts\_feed\_t.
+
+The functions that implement the interface should be defined static or module
+private. The client can get the handle of a TS feed API by calling the function
+allocate\_ts\_feed() in the demux API.
+
+\kifunction{set()}{
+ int set ( dmx\_ts\_feed\_t* feed, \_\_u16 pid, size\_t callback\_length,
+ size\_t circular\_buffer\_size, int descramble, struct timespec timeout);
+ }{
+ This function sets the parameters of a TS feed.
+ Any filtering in progress on the TS feed
+ must be stopped before calling this function.
+ }{
+ dmx\_ts\_feed\_t* feed & Pointer to the TS feed API and instance data.\\
+ \_\_u16 pid & PID value to filter. Only the TS packets carrying the specified PID will
+ be passed to the API client.\\
+ size\_t callback\_length & Number of bytes to deliver with each
+ call to the dmx\_ts\_cb() callback
+ function. The value of this
+ parameter should be a multiple of 188.\\
+ size\_t circular\_buffer\_size & Size of the circular buffer for the filtered TS packets.\\
+ int descramble & If non-zero, descramble the filtered TS packets.\\
+ struct timespec timeout & Maximum time to wait before
+ delivering received TS packets to the client.
+ }{
+ 0 & The function was completed without errors.\\
+ -ENOMEM & Not enough memory for the requested buffer size.\\
+ -ENOSYS & No descrambling facility available for TS.\\
+ -EINVAL & Bad parameter.
+}
+
+
+\kifunction{start\_filtering()}{
+ int start\_filtering(dmx\_ts\_feed\_t* feed);
+ }{
+ Starts filtering TS packets on this TS feed, according to its settings.
+ The PID value to filter can be set by the API client.
+ All matching TS packets are delivered asynchronously to the client,
+ using the callback function registered with allocate\_ts\_feed().
+ }{
+ dmx\_ts\_feed\_t* feed & Pointer to the TS feed API and instance data.
+ }{
+ 0 & The function was completed without errors.\\
+ -EINVAL & Bad parameter.
+}
+
+\kifunction{stop\_filtering()}{
+ int stop\_filtering(dmx\_ts\_feed\_t* feed);
+ }{
+ Stops filtering TS packets on this TS feed.
+ }{
+ dmx\_ts\_feed\_t* feed & Pointer to the TS feed API and instance data.
+ }{
+ 0 & The function was completed without errors.\\
+ -EINVAL & Bad parameter.
+}
+
+\clearpage
+
+\devsubsec{Section Feed API}
+
+A section feed is a resource consisting of a PID filter and a set of section filters.
+Using this API, the client can set the properties of a section feed and to
+start/stop filtering.
+The API is defined as an abstract interface of the type dmx\_section\_feed\_t.
+The functions that implement the interface should be defined static or module
+private. The client can get the handle of a section feed API by calling the function
+allocate\_section\_feed() in the demux API.
+
+On demux platforms that provide section filtering in hardware, the Section Feed API
+implementation provides a software wrapper for the demux hardware. Other platforms
+may support only PID filtering in hardware, requiring that TS packets are converted to
+sections in software. In the latter case the Section Feed API implementation can be a
+client of the TS Feed API.
+
+
+\kifunction{set()}{
+ int set(dmx\_section\_feed\_t* feed, \_\_u16 pid, size\_t circular\_buffer\_size,
+ int descramble, int check\_crc);
+ }{
+ This function sets the parameters of a section feed. Any filtering in progress on the
+ section feed must be stopped before calling this function.
+ If descrambling is enabled, the payload\_scrambling\_control and
+ address\_scrambling\_control fields of received DVB datagram sections should be
+ observed. If either one is non-zero, the section should be descrambled either in
+ hardware or using the functions descramble\_mac\_address() and
+ descramble\_section\_payload() of the demux API. Note that according to the
+ MPEG-2 Systems specification, only the payloads of private sections can be
+ scrambled while the rest of the section data must be sent in the clear.
+ }{
+ dmx\_section\_feed\_t* feed & Pointer to the section feed API and instance data.\\
+ \_\_u16 pid & PID value to filter; only the TS packets
+ carrying the specified PID will be accepted.\\
+ size\_t circular\_buffer\_size & Size of the circular buffer for filtered sections.\\
+ int descramble & If non-zero, descramble any sections that are scrambled.\\
+ int check\_crc & If non-zero, check the CRC values of filtered sections.
+ }{
+ 0 & The function was completed without errors.\\
+ -ENOMEM & Not enough memory for the requested buffer size.\\
+ -ENOSYS & No descrambling facility available for sections.\\
+ -EINVAL & Bad parameters.
+}
+
+\kifunction{allocate\_filter()}{
+ int allocate\_filter(dmx\_section\_feed\_t* feed, dmx\_section\_filter\_t** filter);
+ }{
+ This function is used to allocate a section filter on the demux.
+ It should only be called when no filtering is in progress on this section feed.
+ If a filter cannot be allocated, the function fails with -ENOSPC.
+ See in section \ref{sectionfilter} for the format of the section filter. \\
+ The bitfields filter\_mask and filter\_value should only be modified when no
+ filtering is in progress on this section feed. filter\_mask controls which bits of
+ filter\_value are compared with the section headers/payload. On a binary value of 1
+ in filter\_mask, the corresponding bits are compared. The filter only accepts sections
+ that are equal to filter\_value in all the tested bit positions. Any changes to the
+ values of filter\_mask and filter\_value are guaranteed to take effect only when
+ the start\_filtering() function is called next time. The parent pointer in the struct
+ is initialized by the API implementation to the value of the feed parameter. The priv
+ pointer is not used by the API implementation, and can thus be freely utilized by the
+ caller of this function. Any data pointed to by the priv pointer is available to the
+ recipient of the dmx\_section\_cb() function call.\\
+ While the maximum section filter length (DMX\_MAX\_FILTER\_SIZE)
+ is currently set at 16 bytes, hardware filters of that size are not
+ available on all platforms. Therefore, section filtering will often
+ take place first in hardware, followed by filtering in software for the
+ header bytes that were not covered by a hardware filter.
+ The filter\_mask field can be checked to determine how many bytes of
+ the section filter are actually used, and if the
+ hardware filter will suffice. Additionally, software-only section filters
+ can optionally be
+ allocated to clients when all hardware section filters are in use.
+ Note that on most demux hardware it is not possible to filter on the
+ section\_length field
+ of the section header -- thus this field is ignored, even though it is included in
+ filter\_value and filter\_mask fields.
+ }{
+ dmx\_section\_feed\_t* feed & Pointer to the section feed API and instance data.\\
+ dmx\_section\_filter\_t** filter & Pointer to the allocated filter.
+ }{
+ 0 & The function was completed without errors.\\
+ -ENOSPC & No filters of given type and length available.\\
+ -EINVAL & Bad parameters.
+}
+
+\kifunction{release\_filter()}{
+ int release\_filter ( dmx\_section\_feed\_t* feed, dmx\_section\_filter\_t* filter);
+ }{
+ This function releases all the resources of a previously allocated section filter.
+ The function should not be called while filtering is in progress on this section feed.
+ After calling this function, the caller should not try to dereference the
+ filter pointer.
+ }{
+ dmx\_section\_feed\_t* feed & Pointer to the section feed API and instance data.\\
+ dmx\_section\_filter\_t* filter & I/O Pointer to the instance data of a section filter.
+ }{
+ 0 & The function was completed without errors.\\
+ -ENODEV & No such filter allocated.\\
+ -EINVAL & Bad parameter.
+}
+
+\kifunction{start\_filtering()}{
+ int start\_filtering ( dmx\_section\_feed\_t* feed );
+ }{
+ Starts filtering sections on this section feed, according to its settings.
+ Sections are first filtered based on their PID and then matched with the
+ section filters allocated for this feed.
+ If the section matches the PID filter and at least one section filter, it is delivered
+ to the API client. The section is delivered asynchronously using the callback function
+ registered with allocate\_section\_feed().
+ }{
+ dmx\_section\_feed\_t* feed & Pointer to the section feed API and instance data.\\
+ }{
+ 0 & The function was completed without errors.\\
+ -EINVAL & Bad parameter.
+}
+
+\kifunction{stop\_filtering()}{
+ int stop\_filtering ( dmx\_section\_feed\_t* feed );
+ }{
+ Stops filtering sections on this section feed. Note that any changes to the
+ filtering parameters (filter\_value, filter\_mask, etc.) should only be made
+ when filtering is stopped.
+ }{
+ dmx\_section\_feed\_t* feed & Pointer to the section feed API and instance data.
+ }{
+ 0 & The function was completed without errors.\\
+ -EINVAL & Bad parameter.
+}
+
+
+
+%%% Local Variables:
+%%% mode: latex
+%%% TeX-master: "dvbapi"
+%%% End:
diff --git a/dvb-spec/dvbapi/sec.tex b/dvb-spec/dvbapi/sec.tex
new file mode 100644
index 000000000..6ccd89481
--- /dev/null
+++ b/dvb-spec/dvbapi/sec.tex
@@ -0,0 +1,282 @@
+\devsec{DVB SEC API}
+
+The DVB SEC device controls the Satellite Equipment Control of
+the DVB hardware, i.e. DiSEqC and V-SEC.
+It is accessed through \texttt{/dev/ost/sec}.
+
+\devsubsec{SEC Data Types}
+
+\devsubsubsec{secDiseqcCmd}
+\label{secdiseqccmd}
+
+\begin{verbatim}
+struct secDiseqcCmd {
+ uint8_t addr;
+ uint8_t cmd;
+ uint8_t numParams;
+ uint8_t params[SEC_MAX_DISEQC_PARAMS];
+};
+\end{verbatim}
+
+
+\devsubsubsec{secVoltage}
+\label{secvoltage}
+
+\begin{verbatim}
+typedef uint32_t secVoltage;
+\end{verbatim}
+\begin{verbatim}
+enum {
+ SEC_VOLTAGE_OFF,
+ SEC_VOLTAGE_LT,
+ SEC_VOLTAGE_13,
+ SEC_VOLTAGE_13_5,
+ SEC_VOLTAGE_18,
+ SEC_VOLTAGE_18_5
+};
+\end{verbatim}
+
+
+\devsubsubsec{secToneMode}
+\label{sectonemode}
+
+\begin{verbatim}
+typedef uint32_t secToneMode;
+\end{verbatim}
+\begin{verbatim}
+typedef enum {
+ SEC_TONE_ON,
+ SEC_TONE_OFF
+} secToneMode_t;
+\end{verbatim}
+
+
+\devsubsubsec{secMiniCmd}
+\label{secminicmd}
+
+\begin{verbatim}
+typedef uint32_t secMiniCmd;
+\end{verbatim}
+\begin{verbatim}
+typedef enum {
+ SEC_MINI_NONE,
+ SEC_MINI_A,
+ SEC_MINI_B
+} secMiniCmd_t;
+\end{verbatim}
+\begin{verbatim}
+struct secStatus {
+ int32_t busMode;
+ secVoltage selVolt;
+ secToneMode contTone;
+};
+\end{verbatim}
+
+\begin{verbatim}
+enum {
+ SEC_BUS_IDLE,
+ SEC_BUS_BUSY,
+ SEC_BUS_OFF,
+ SEC_BUS_OVERLOAD
+};
+\end{verbatim}
+
+
+\devsubsubsec{secCommand}
+\label{seccommand}
+
+\begin{verbatim}
+struct secCommand {
+ int32_t type;
+ union {
+ struct secDiseqcCmd diseqc;
+ uint8_t vsec;
+ uint32_t pause;
+ } u;
+};
+\end{verbatim}
+
+
+\devsubsubsec{secCmdSequence}
+\label{seccmdsequence}
+
+\begin{verbatim}
+struct secCmdSequence {
+ secVoltage voltage;
+ secMiniCmd miniCommand;
+ secToneMode continuousTone;
+
+ uint32_t numCommands;
+ struct secCommand* commands;
+};
+\end{verbatim}
+
+\begin{verbatim}
+enum {
+ SEC_CMDTYPE_DISEQC,
+ SEC_CMDTYPE_VSEC,
+ SEC_CMDTYPE_PAUSE
+};
+\end{verbatim}
+
+\begin{verbatim}
+typedef enum {
+ SEC_DISEQC_SENT,
+ SEC_VSEC_SENT,
+ SEC_PAUSE_COMPLETE,
+ SEC_CALLBACK_ERROR
+} secCallback_t;
+\end{verbatim}
+
+\clearpage
+
+\devsubsec{SEC Function Calls}
+
+\function{open()}{
+ int open(const char *deviceName, int flags);}{
+ This system call opens a named SEC device for subsequent use.
+ If the device is opened in read-only mode, only status and statistics
+ monitoring is allowed. If the device is opened in read/write mode, all
+ types of operations can be performed.
+ Any number of applications can have simultaneous access to the device.
+ }{
+ const char *deviceName & Name of specific SEC device.\\
+ int flags & A bit-wise OR of the following flags:\\
+ & \hspace{1em} O\_RDONLY read-only access\\
+ & \hspace{1em} O\_RDWR read/write access\\
+ & The optional flag O\_NONBLOCK is not supported. If O\_NONBLOCK is set,
+ open() and most other subsequent calls to the device will return -1 and
+ set errno to EWOULDBLOCK.
+ The communication with the peripheral devices is sequential by nature,
+ so it is probably preferable to use the device in synchronous mode.
+ This is the motivation for not going through the extra effort of
+ implementing asynchronous operation of the device.
+ }{
+ ENODEV & Device driver not loaded/available.\\
+ EFAULT & deviceName does not refer to a valid memory area.\\
+ EBUSY & Device or resource busy.\\
+ EINVAL & Invalid argument.\\
+}
+
+\function{close()}{
+ int close(int fd);}{
+ This system call closes a previously opened SEC device.
+ }{
+ int fd & File descriptor returned by a previous call to open().\\
+ }{
+ EBADF & fd is not a valid open file descriptor.\\
+}
+
+\ifunction{SEC\_GET\_STATUS}{
+ int ioctl(int fd, int request = SEC\_GET\_STATUS, struct secStatus* status);}{
+ This call gets the status of the device.
+ }{
+ int fd & File descriptor returned by a previous call to open().\\
+ int request & Equals SEC\_GET\_STATUS for this command.\\
+ struct secStatus* status & The status of the device.\\
+ }{
+ ENODEV & Device driver not loaded/available.\\
+ EFAULT & status is an invalid pointer.\\
+ EBUSY & Device or resource busy.\\
+ EINVAL & Invalid argument.\\
+ EPERM & File not opened with read permissions.\\
+ EINTERNAL & Internal error in the device driver.\\
+}
+
+\ifunction{SEC\_RESET\_OVERLOAD}{
+ int ioctl(int fd, int request = SEC\_RESET\_OVERLOAD);}{
+ If the bus has been automatically powered off due to power overload, this
+ ioctl call restores the power to the bus. The call requires read/write
+ access to the device.
+ This call has no effect if the device is manually powered off.
+ }{
+ int fd & File descriptor returned by a previous call to open().\\
+ int request & Equals SEC\_RESET\_OVERLOAD for this command.\\
+ }{
+ EBADF & fd is not a valid file descriptor.\\
+ EPERM & Permission denied (needs read/write access).\\
+ EINTERNAL & Internal error in the device driver.\\
+}
+
+\ifunction{SEC\_RESET\_OVERLOAD}{
+int ioctl(int fd, int request = SEC\_SEND\_SEQUENCE, struct secCmdSequence *seq);
+}{
+This ioctl call is used to send a sequence of DiSEqCTM and/or V-SEC
+commands. The first version of the SEC device does not support V-SEC
+signaling and it aborts the operation with an error code if a V-SEC
+command is detected in the input data.\\
+\begin{itemize}
+\item[$\bullet$] The call will fail with errno set to EBUSOVERLOAD if the bus is
+overloaded. If the bus is overloaded, SEC\_RESET\_OVERLOAD can be
+called and the operation can be retried.
+\item[$\bullet$] If seq.numCommands equals 0 and seq.miniCommand equals SEC\_MINI\_NONE,
+the bus voltage will be switched and the continuous 22kHz tone
+generation enabled/disabled immediately.
+\end{itemize}\\
+This operation is atomic. If several processes calls this ioctl
+simultaneously, the operations will be serialized so a complete sequence
+is sent at a time.
+ }{
+ int fd & File descriptor returned by a previous call to open().\\
+ int request & Equals SEC\_SEND\_SEQUENCE for this command.\\
+ struct secCmdSequence *seq & Pointer to the command sequence to be transmitted.\\
+ }{
+ EBADF & fd is not a valid file descriptor.\\
+ EFAULT & Seq points to an invalid address.\\
+ EINVAL & The data structure referred to by seq is invalid in some way.\\
+ EPERM & Permission denied (needs read/write access).\\
+ EINTERNAL & Internal error in the device driver.\\
+ EBUSMODE & The device is not prepared for transmission
+ (e.g. it might be manually powered off).\\
+ EBUSOVERLOAD & Bus overload has occurred.\\
+}
+
+
+\ifunction{SEC\_SET\_TONE}{
+int ioctl(int fd, int request = SEC\_SET\_TONE, secToneMode tone);
+}{
+This call is used to set the generation of the continuous 22kHz tone.
+The possibility to just change the tone mode is already provided by
+ioctl SEC\_SEND\_SEQUENCE, but SEC\_SET\_TONE is an easier to use interface.
+To keep the transmission of a command sequence as
+an atomic operation, SEC\_SET\_TONE will block if a transmission is in
+progress. This call requires read/write permissions.
+}{
+int fd & File descriptor returned by a previous call to open().\\
+int request & Equals SEC\_SET\_TONE for this command.\\
+secToneMode tone & The requested tone generation mode (on/off).\\
+}{
+ENODEV & Device driver not loaded/available.\\
+EBUSY & Device or resource busy.\\
+EINVAL & Invalid argument.\\
+EPERM & File not opened with read permissions.\\
+EINTERNAL & Internal error in the device driver.\\
+}
+
+
+\ifunction{SEC\_SET\_VOLTAGE}{
+int ioctl(int fd, int request = SEC\_SET\_VOLTAGE, secVoltage voltage);
+}{
+This call is used to set the bus voltage. The possibility to just change
+the bus voltage is already provided by ioctl SEC\_SEND\_SEQUENCE, but
+SEC\_SET\_VOLTAGE is an easier to use interface.
+To keep the transmission of a command sequence as
+an atomic operation, SEC\_SET\_VOLTAGE will block if a transmission is in
+progress.
+This call requires read/write permissions.
+}{
+int fd & File descriptor returned by a previous call to open().\\
+int request & Equals SEC\_SET\_VOLTAGE for this command.\\
+secVoltage voltage & The requested bus voltage.\\
+}{
+ENODEV & Device driver not loaded/available.\\
+EBUSY & Device or resource busy.\\
+EINVAL & Invalid argument.\\
+EPERM & File not opened with read permissions.\\
+EINTERNAL & Internal error in the device driver.\\
+}
+
+%%% Local Variables:
+%%% mode: latex
+%%% TeX-master: "dvbapi"
+%%% End:
diff --git a/dvb-spec/dvbapi/title.tex b/dvb-spec/dvbapi/title.tex
new file mode 100644
index 000000000..ce8b584c1
--- /dev/null
+++ b/dvb-spec/dvbapi/title.tex
@@ -0,0 +1,24 @@
+\pagenumbering{arabic}
+\pagestyle{empty}
+\title{\huge\textbf{LINUX DVB API}}
+
+\author{
+\includegraphics{cimlogo.psi}\\
+ Convergence integrated media GmbH\\\\
+ Dr. Ralph J.K. Metzler\\
+ \texttt{<rjkm@convergence.de>}\\\\
+ Dr. Marcus O.C. Metzler\\
+ \texttt{<mocm@convergence.de>}
+% Rosenthalerstr. 51\\
+% 10178 Berlin\\Germany
+}
+\date{09/15/2001\\V 0.9.4}
+\maketitle
+
+\newpage
+
+%\end{titlepage}
+% Local Variables:
+% mode: latex
+% TeX-master: "dvbapi"
+% End: \ No newline at end of file
diff --git a/dvb-spec/dvbapi/video.tex b/dvb-spec/dvbapi/video.tex
new file mode 100644
index 000000000..67abb9586
--- /dev/null
+++ b/dvb-spec/dvbapi/video.tex
@@ -0,0 +1,684 @@
+\devsec{DVB Video Device}
+
+The DVB video device controls the MPEG2 video decoder of the DVB hardware.
+It can be accessed through \texttt{/dev/ost/video}.
+The include file \texttt{ost/video.h} defines the data types and lists all I/O calls.
+
+
+\devsubsec{Video Data Types}
+
+\devsubsubsec{videoFormat\_t}
+\label{videoformat}
+
+The \texttt{videoFormat\_t} data type defined by
+\begin{verbatim}
+typedef enum {
+ VIDEO_FORMAT_4_3,
+ VIDEO_FORMAT_16_9
+} videoFormat_t;
+\end{verbatim}
+is used in the VIDEO\_SET\_FORMAT function (\ref{videosetformat}) to
+tell the driver which aspect ratio the output hardware (e.g. TV) has.
+It is also used in the data structures videoStatus (\ref{videostatus})
+returned by VIDEO\_GET\_STATUS (\ref{videogetstatus}) and
+videoEvent (\ref{videoevent}) returned by VIDEO\_GET\_EVENT (\ref{videogetevent})
+which report about the display format of the current video stream.
+
+\devsubsubsec{videoDisplayFormat\_t}
+\label{videodispformat}
+
+In case the display format of the video stream and of the
+display hardware differ the application has to specify how to handle
+the cropping of the picture.
+This can be done using the VIDEO\_SET\_DISPLAY\_FORMAT call
+(\ref{videosetdisplayformat}) which accepts
+\begin{verbatim}
+typedef enum {
+ VIDEO_PAN_SCAN,
+ VIDEO_LETTER_BOX,
+ VIDEO_CENTER_CUT_OUT
+} videoDisplayFormat_t;
+\end{verbatim}
+as argument.
+
+
+\devsubsubsec{video stream source}
+\label{videostreamsource}
+The video stream source is set through the VIDEO\_SELECT\_SOURCE
+call and can take the following values, depending on whether we are
+replaying from an internal (demuxer) or external (user write) source.
+\begin{verbatim}
+typedef enum {
+ VIDEO_SOURCE_DEMUX,
+ VIDEO_SOURCE_MEMORY
+} videoStreamSource_t;
+\end{verbatim}
+VIDEO\_SOURCE\_DEMUX selects the demultiplexer (fed
+either by the frontend or the DVR device) as the source of
+the video stream.
+If VIDEO\_SOURCE\_MEMORY is selected the stream
+comes from the application through the \texttt{write()}
+system call.
+
+\devsubsubsec{video play state}
+\label{videoplaystate}
+The following values can be returned by the VIDEO\_GET\_STATUS call
+representing the state of video playback.
+\begin{verbatim}
+typedef enum {
+ VIDEO_STOPPED,
+ VIDEO_PLAYING,
+ VIDEO_FREEZED
+} videoPlayState_t;
+\end{verbatim}
+
+
+\devsubsubsec{video event}
+\label{videoevent}
+The following is the structure of a video event as it is returned by
+the VIDEO\_GET\_EVENT call.
+\begin{verbatim}
+struct videoEvent {
+ int32_t type;
+ time_t timestamp;
+ union {
+ videoFormat_t videoFormat;
+ } u;
+};
+\end{verbatim}
+
+\devsubsubsec{video status}
+\label{videostatus}
+The VIDEO\_GET\_STATUS call returns the following structure informing
+about various states of the playback operation.
+\begin{verbatim}
+struct videoStatus {
+ boolean videoBlank;
+ videoPlayState_t playState;
+ videoStreamSource_t streamSource;
+ videoFormat_t videoFormat;
+ videoDisplayFormat_t displayFormat;
+};
+\end{verbatim}
+If videoBlank is set video will be blanked out if the channel is changed or
+if playback is stopped. Otherwise, the last picture will be displayed.
+playState indicates if the video is currently frozen, stopped, or
+being played back. The streamSource corresponds to the seleted source
+for the video stream. It can come either from the demultiplexer or from memory.
+The videoFormat indicates the aspect ratio (one of 4:3 or 16:9)
+of the currently played video stream.
+Finally, displayFormat corresponds to the selected cropping mode in case the
+source video format is not the same as the format of the output device.
+
+
+\devsubsubsec{video display still picture}
+\label{videostill}
+An I-frame displayed via the VIDEO\_STILLPICTURE call is passed on
+within the following structure.
+\begin{verbatim}
+/* pointer to and size of a single iframe in memory */
+struct videoDisplayStillPicture {
+ char *iFrame;
+ int32_t size;
+};
+\end{verbatim}
+
+\devsubsubsec{video capabilities}
+\label{videocaps}
+A call to VIDEO\_GET\_CAPABILITIES returns an unsigned integer with
+the following bits set according to the hardwares capabilities.
+\begin{verbatim}
+/* bit definitions for capabilities: */
+/* can the hardware decode MPEG1 and/or MPEG2? */
+#define VIDEO_CAP_MPEG1 1
+#define VIDEO_CAP_MPEG2 2
+/* can you send a system and/or program stream to video device?
+ (you still have to open the video and the audio device but only
+ send the stream to the video device) */
+#define VIDEO_CAP_SYS 4
+#define VIDEO_CAP_PROG 8
+/* can the driver also handle SPU, NAVI and CSS encoded data?
+ (CSS API is not present yet) */
+#define VIDEO_CAP_SPU 16
+#define VIDEO_CAP_NAVI 32
+#define VIDEO_CAP_CSS 64
+\end{verbatim}
+
+
+\devsubsubsec{video system}
+\label{videosys}
+A call to VIDEO\_SET\_SYSTEM sets the desired video system for TV
+output. The following system types can be set:
+
+\begin{verbatim}
+typedef enum {
+ VIDEO_SYSTEM_PAL,
+ VIDEO_SYSTEM_NTSC,
+ VIDEO_SYSTEM_PALN,
+ VIDEO_SYSTEM_PALNc,
+ VIDEO_SYSTEM_PALM,
+ VIDEO_SYSTEM_NTSC60,
+ VIDEO_SYSTEM_PAL60,
+ VIDEO_SYSTEM_PALM60
+} videoSystem_t;
+\end{verbatim}
+
+
+
+\devsubsubsec{video highlights}
+\label{vhilite}
+Calling the ioctl VIDEO\_SET\_HIGHLIGHTS posts the SPU highlight
+information. The call expects the following format for that information:
+
+\begin{verbatim}
+typedef
+struct videoHighlight {
+ boolean active; /* 1=show highlight, 0=hide highlight */
+ uint8_t contrast1; /* 7- 4 Pattern pixel contrast */
+ /* 3- 0 Background pixel contrast */
+ uint8_t contrast2; /* 7- 4 Emphasis pixel-2 contrast */
+ /* 3- 0 Emphasis pixel-1 contrast */
+ uint8_t color1; /* 7- 4 Pattern pixel color */
+ /* 3- 0 Background pixel color */
+ uint8_t color2; /* 7- 4 Emphasis pixel-2 color */
+ /* 3- 0 Emphasis pixel-1 color */
+ uint32_t ypos; /* 23-22 auto action mode */
+ /* 21-12 start y */
+ /* 9- 0 end y */
+ uint32_t xpos; /* 23-22 button color number */
+ /* 21-12 start x */
+ /* 9- 0 end x */
+} videoHighlight_t;
+\end{verbatim}
+
+
+\devsubsubsec{video SPU}
+\label{videospu}
+Calling VIDEO\_SET\_SPU deactivates or activates SPU decoding,
+according to the following format:
+\begin{verbatim}
+typedef
+struct videoSPU {
+ boolean active;
+ int streamID;
+} videoSPU_t;
+\end{verbatim}
+
+
+\devsubsubsec{video SPU palette}
+\label{vspupal}
+The following structure is used to set the SPU palette by calling VIDEO\_SPU\_PALETTE:
+\begin{verbatim}
+typedef
+struct videoSPUPalette{ /* SPU Palette information */
+ int length;
+ uint8_t *palette;
+} videoSPUPalette_t;
+\end{verbatim}
+
+\devsubsubsec{video NAVI pack}
+\label{videonavi}
+In order to get the navigational data the following structure has to
+be passed to the ioctl VIDEO\_GET\_NAVI:
+\begin{verbatim}
+typedef
+struct videoNaviPack{
+ int length; /* 0 ... 1024 */
+ uint8_t data[1024];
+} videoNaviPack_t;
+\end{verbatim}
+
+
+\devsubsubsec{video attributes}
+\label{vattrib}
+The following attributes can be set by a call to VIDEO\_SET\_ATTRIBUTES:
+\begin{verbatim}
+typedef uint16_t videoAttributes_t;
+/* bits: descr. */
+/* 15-14 Video compression mode (0=MPEG-1, 1=MPEG-2) */
+/* 13-12 TV system (0=525/60, 1=625/50) */
+/* 11-10 Aspect ratio (0=4:3, 3=16:9) */
+/* 9- 8 permitted display mode on 4:3 monitor (0=both, 1=only pan-sca */
+/* 7 line 21-1 data present in GOP (1=yes, 0=no) */
+/* 6 line 21-2 data present in GOP (1=yes, 0=no) */
+/* 5- 3 source resolution (0=720x480/576, 1=704x480/576, 2=352x480/57 */
+/* 2 source letterboxed (1=yes, 0=no) */
+/* 0 film/camera mode (0=camera, 1=film (625/50 only)) */
+\end{verbatim}
+
+
+\clearpage
+
+\devsubsec{Video Function Calls}
+
+\function{open()}{
+ int open(const char *deviceName, int flags);}{
+ This system call opens a named video device (e.g. /dev/ost/video)
+ for subsequent use.
+
+ When an open() call has succeeded, the device will be ready for use.
+ The significance of blocking or non-blocking mode is described in
+ the documentation for functions where there is a difference.
+ It does not affect the semantics of the open() call itself.
+ A device opened in blocking mode can later be put into non-blocking mode
+ (and vice versa) using the F\_SETFL command of the fcntl system
+ call.
+ This is a standard system call, documented in the Linux manual
+ page for fcntl.
+ Only one user can open the Video Device in O\_RDWR mode. All other attempts to
+ open the device in this mode will fail, and an error-code will be returned.
+ If the Video Device is opened in O\_RDONLY mode, the only ioctl call that can
+ be used is VIDEO\_GET\_STATUS. All other call will return an error code.
+ }{
+ const char *deviceName & Name of specific video device.\\
+ int flags & A bit-wise OR of the following flags:\\
+ & \hspace{1em} O\_RDONLY read-only access\\
+ & \hspace{1em} O\_RDWR read/write access\\
+ & \hspace{1em} O\_NONBLOCK open in non-blocking mode \\
+ & \hspace{1em} (blocking mode is the default)\\
+ }{
+ ENODEV & Device driver not loaded/available.\\
+ EINTERNAL & Internal error.\\
+ EBUSY & Device or resource busy.\\
+ EINVAL & Invalid argument.\\
+}
+
+\function{close()}{
+ int close(int fd);}{
+ This system call closes a previously opened video device.
+ }{
+ int fd & File descriptor returned by a previous call to open().\\
+ }{
+ EBADF & fd is not a valid open file descriptor.\\
+}
+
+\function{write()}{
+ size\_t write(int fd, const void *buf, size\_t count);}{
+ This system call can only be used if VIDEO\_SOURCE\_MEMORY is selected in the
+ ioctl call VIDEO\_SELECT\_SOURCE. The data provided shall be in PES
+ format, unless the capability allows other formats.
+ If O\_NONBLOCK is not specified the function will block until buffer space is
+ available. The amount of data to be transferred is implied by count.
+ }{
+ int fd & File descriptor returned by a previous call to open().\\
+ void *buf & Pointer to the buffer containing the PES data.\\
+ size\_t count& Size of buf.\\
+ }{
+ EPERM& Mode VIDEO\_SOURCE\_MEMORY not selected.\\
+ ENOMEM& Attempted to write more data than the internal buffer can hold.\\
+ EBADF& fd is not a valid open file descriptor.\\
+}
+
+
+\ifunction{VIDEO\_STOP}{
+ int ioctl(fd, int request = VIDEO\_STOP, boolean mode);}{
+ This ioctl call asks the Video Device to stop playing the current stream.
+ Depending on the input parameter, the screen can be blanked out or
+ displaying the last decoded frame.
+}{
+int fd & File descriptor returned by a previous call to open(). \\
+int request & Equals VIDEO\_STOP for this command. \\
+Boolean mode & Indicates how the screen shall be handled. \\
+& TRUE: Blank screen when stop. \\
+& FALSE: Show last decoded frame.\\
+}{
+EBADF& fd is not a valid open file descriptor \\
+EINTERNAL & Internal error, possibly in the communication with
+ the DVB subsystem.\\
+}
+
+\ifunction{VIDEO\_PLAY}{
+ int ioctl(fd, int request = VIDEO\_PLAY);}{
+ This ioctl call asks the Video Device to start playing a video stream
+ from the selected source.
+}{
+int fd & File descriptor returned by a previous call to open(). \\
+int request & Equals VIDEO\_PLAY for this command. \\
+}{
+EBADF& fd is not a valid open file descriptor \\
+EINTERNAL & Internal error, possibly in the communication with
+ the DVB subsystem.\\
+}
+
+
+\ifunction{VIDEO\_FREEZE}{
+ int ioctl(fd, int request = VIDEO\_FREEZE);}{
+ This ioctl call suspends the live video stream being played.
+ Decoding and playing are frozen. It is then possible to restart
+ the decoding and playing process of the video stream using the
+ VIDEO\_CONTINUE command. If VIDEO\_SOURCE\_MEMORY is selected in the
+ ioctl call VIDEO\_SELECT\_SOURCE, the DVB subsystem will not decode
+ any more data until the ioctl call VIDEO\_CONTINUE or VIDEO\_PLAY is
+ performed.
+}{
+int fd & File descriptor returned by a previous call to open(). \\
+int request & Equals VIDEO\_FREEZE for this command. \\
+}{
+EBADF& fd is not a valid open file descriptor \\
+EINTERNAL & Internal error, possibly in the communication with
+ the DVB subsystem.\\
+}
+
+\ifunction{VIDEO\_CONTINUE}{
+ int ioctl(fd, int request = VIDEO\_CONTINUE);}{
+ This ioctl call restarts decoding and playing processes of the video
+ stream which was played before a call to VIDEO\_FREEZE was made.
+ }{
+ int fd & File descriptor returned by a previous call to open(). \\
+ int request & Equals VIDEO\_CONTINUE for this command. \\
+ }{
+ EBADF& fd is not a valid open file descriptor \\
+ EINTERNAL & Internal error, possibly in the communication with
+ the DVB subsystem.\\
+ }
+
+
+\ifunction{VIDEO\_SELECT\_SOURCE}{
+ int ioctl(fd, int request = VIDEO\_SELECT\_SOURCE, videoStreamSource\_t source);}{
+ This ioctl call informs the video device which source shall be used
+ for the input data. The possible sources are demux or memory. If
+ memory is selected, the data is fed to the video device through
+ the write command.
+ }{
+ int fd & File descriptor returned by a previous call to open().\\
+ int request& Equals VIDEO\_SELECT\_SOURCE for this command. \\
+ videoStreamSource\_t source&Indicates which source shall be used for the Video stream.\\
+ }{
+ EBADF& fd is not a valid open file descriptor \\
+ EINTERNAL & Internal error, possibly in the communication with the DVB subsystem.\\
+}
+
+\ifunction{VIDEO\_SET\_BLANK}{
+ int ioctl(fd, int request = VIDEO\_SET\_BLANK, boolean mode);}{
+ This ioctl call asks the Video Device to blank out the picture.
+}{
+int fd & File descriptor returned by a previous call to open().\\
+int request& Equals VIDEO\_SET\_BLANK for this command. \\
+boolean mode&TRUE: Blank screen when stop.\\
+ &FALSE: Show last decoded frame.\\
+}{
+EBADF& fd is not a valid open file descriptor \\
+EINTERNAL & Internal error, possibly in the communication with the DVB subsystem.\\
+EINVAL & Illegal input parameter\\
+}
+
+\ifunction{VIDEO\_GET\_STATUS}{
+\label{videogetstatus}
+ int ioctl(fd, int request = VIDEO\_GET\_STATUS, struct videoStatus *status);}{
+ This ioctl call asks the Video Device to return the current status of the device.
+ }{
+ int fd & File descriptor returned by a previous call to open().\\
+ int request& Equals VIDEO\_GET\_STATUS for this command.\\
+ struct videoStatus *status & Returns the current status of the Video Device.\\
+}{
+EBADF& fd is not a valid open file descriptor \\
+EINTERNAL & Internal error, possibly in the communication with the DVB subsystem.\\
+EFAULT & status points to invalid address\\
+}
+
+\ifunction{VIDEO\_GET\_EVENT}{
+\label{videogetevent}
+ int ioctl(fd, int request = VIDEO\_GET\_EVENT, struct videoEvent *ev);}{
+ This ioctl call returns an event of type videoEvent if available.
+ If an event is not available, the behavior depends on whether the device is in
+ blocking or non-blocking mode. In the latter case, the call fails immediately
+ with errno set to EWOULDBLOCK. In the former case, the call blocks until an
+ event becomes available.
+ The standard Linux poll() and/or select() system calls can be used with the
+ device file descriptor to watch for new events. For select(), the file
+ descriptor should be included in the exceptfds argument, and for poll(),
+ POLLPRI should be specified as the wake-up condition.
+ Read-only permissions are sufficient for this ioctl call.
+ }{
+ int fd & File descriptor returned by a previous call to open().\\
+ int request& Equals VIDEO\_GET\_EVENT for this command.\\
+ struct videoEvent *ev & Points to the location where the event, if any, is
+ to be stored.\\
+}{
+EBADF & fd is not a valid open file descriptor \\
+EFAULT & ev points to invalid address \\
+EWOULDBLOCK & There is no event pending, and the device is in non-blocking mode.\\
+EBUFFEROVERFLOW & \\
+&Overflow in event queue - one or more events were lost.\\
+}
+
+\ifunction{VIDEO\_SET\_DISPLAY\_FORMAT}{
+\label{videosetdisplayformat}
+ int ioctl(fd, int request = VIDEO\_SET\_DISPLAY\_FORMAT, videoDisplayFormat\_t format);}{
+ This ioctl call asks the Video Device to select the video format to be applied
+ by the MPEG chip on the video.
+ }{
+ int fd & File descriptor returned by a previous call to open().\\
+ int request & Equals VIDEO\_SET\_DISPLAY\_FORMAT for this command.\\
+ videoDisplayFormat\_t format & Selects the video format to be used.\\
+ }{
+ EBADF& fd is not a valid open file descriptor \\
+ EINTERNAL & Internal error.\\
+ EINVAL & Illegal parameter format.\\
+}
+
+\ifunction{VIDEO\_STILLPICTURE}{
+ int ioctl(fd, int request = VIDEO\_STILLPICTURE, struct videoDisplayStillPicture *sp);}{
+ This ioctl call asks the Video Device to display a still picture (I-frame).
+ The input data shall contain an I-frame. If the pointer is NULL, then the
+ current displayed still picture is blanked.
+ }{
+ int fd & File descriptor returned by a previous call to open().\\
+ int request & Equals VIDEO\_STILLPICTURE for this command.\\
+ struct videoDisplayStillPicture *sp&
+ Pointer to a location where an I-frame and size is stored.\\
+ }{
+ EBADF& fd is not a valid open file descriptor \\
+ EINTERNAL & Internal error.\\
+ EFAULT & sp points to an invalid iframe.\\
+}
+
+\ifunction{VIDEO\_FAST\_FORWARD}{
+ int ioctl(fd, int request = VIDEO\_FAST\_FORWARD, int nFrames);}{
+ This ioctl call asks the Video Device to skip decoding of N number of I-frames.
+ This call can only be used if VIDEO\_SOURCE\_MEMORY is selected.
+ }{
+ int fd & File descriptor returned by a previous call to open().\\
+ int request & Equals VIDEO\_FAST\_FORWARD for this command.\\
+ int nFrames & The number of frames to skip.\\
+ }{
+ EBADF& fd is not a valid open file descriptor \\
+ EINTERNAL & Internal error.\\
+ EPERM & Mode VIDEO\_SOURCE\_MEMORY not selected.\\
+ EINVAL & Illegal parameter format.\\
+}
+
+\ifunction{VIDEO\_SLOWMOTION}{
+ int ioctl(fd, int request = VIDEO\_SLOWMOTION, int nFrames);}{
+ This ioctl call asks the video device to repeat decoding frames N
+ number of times.
+ This call can only be used if VIDEO\_SOURCE\_MEMORY is selected.
+ }{
+ int fd & File descriptor returned by a previous call to open().\\
+ int request & Equals VIDEO\_SLOWMOTION for this command.\\
+ int nFrames & The number of times to repeat each frame.\\
+ }{
+ EBADF& fd is not a valid open file descriptor \\
+ EINTERNAL & Internal error.\\
+ EPERM & Mode VIDEO\_SOURCE\_MEMORY not selected.\\
+ EINVAL & Illegal parameter format.\\
+}
+
+\ifunction{VIDEO\_GET\_CAPABILITIES}{
+ int ioctl(fd, int request = VIDEO\_GET\_CAPABILITIES, unsigned int *cap);}{
+ This ioctl call asks the video device about its decoding capabilities.
+ On success it returns and integer which has bits set according to the
+ defines in section \ref{videocaps}.
+ }{
+ int fd & File descriptor returned by a previous call to open().\\
+ int request & Equals VIDEO\_GET\_CAPABILITIES for this command.\\
+ unsigned int *cap & Pointer to a location where to store the
+ capability information.\\
+ }{
+ EBADF& fd is not a valid open file descriptor \\
+ EFAULT & cap points to an invalid iframe.\\
+}
+
+\ifunction{VIDEO\_SET\_ID}{
+ int ioctl(int fd, int request = VIDEO\_SET\_ID, int id);}{
+ This ioctl selects which sub-stream is to be decoded if a program or
+ system stream is sent to the video device.
+ }{
+ int fd & File descriptor returned by a previous call to open().\\
+ int request & Equals VIDEO\_SET\_ID for this command.\\
+ int id& video sub-stream id
+ }{
+ EBADF& fd is not a valid open file descriptor.\\
+ EINTERNAL & Internal error.\\
+ EINVAL & Invalid sub-stream id.
+}
+
+\ifunction{VIDEO\_CLEAR\_BUFFER}{
+ int ioctl(fd, int request = VIDEO\_CLEAR\_BUFFER);}{
+ This ioctl call clears all video buffers in the driver and
+ in the decoder hardware.
+ }{
+ int fd & File descriptor returned by a previous call to open().\\
+ int request & Equals VIDEO\_CLEAR\_BUFFER for this command.\\
+ }{
+ EBADF& fd is not a valid open file descriptor \\
+}
+
+\ifunction{VIDEO\_SET\_STREAMTYPE}{
+ int ioctl(fd, int request = VIDEO\_SET\_STREAMTYPE, int type);}{
+ This ioctl tells the driver which kind of stream to expect
+ being written to it. If this call is not used the default of video PES
+ is used. Some drivers might not support this call and always expect PES.
+ }{
+ int fd & File descriptor returned by a previous call to open().\\
+ int request & Equals VIDEO\_SET\_STREAMTYPE for this command.\\
+ int type & stream type\\
+ }{
+ EBADF& fd is not a valid open file descriptor \\
+ EINVAL& type is not a valid or supported stream type.\\
+}
+
+\ifunction{VIDEO\_SET\_FORMAT}{
+\label{videosetformat}
+ int ioctl(fd, int request = VIDEO\_SET\_FORMAT, videoFormat\_t format);
+}{
+ This ioctl sets the screen format (aspect ratio) of the connected
+ output device (TV) so that the output of the decoder can
+ be adjusted accordingly.
+ }{
+ int fd & File descriptor returned by a previous call to open().\\
+ int request & Equals VIDEO\_SET\_FORMAT for this command.\\
+ videoFormat\_t format& video format of TV as defined in section \ref{videoformat}.\\
+ }{
+ EBADF& fd is not a valid open file descriptor \\
+ EINVAL& format is not a valid video format.\\
+}
+
+\ifunction{VIDEO\_SET\_SYSTEM}{
+\label{videosetsystem}
+ int ioctl(fd, int request = VIDEO\_SET\_SYSTEM , videoSystem\_t system);
+}{
+ This ioctl sets the television output format. The format (see section
+ \ref{videosys}) may vary from the color format of the displayed MPEG
+ stream. If the hardware is not able to display the requested format
+ the call will return an error.
+}{
+ int fd & File descriptor returned by a previous call to open().\\
+ int request & Equals VIDEO\_SET\_FORMAT for this command.\\
+ videoSystem\_t system& video system of TV output.\\
+}{
+ EBADF& fd is not a valid open file descriptor \\
+ EINVAL& system is not a valid or supported video system.\\
+}
+
+\ifunction{VIDEO\_SET\_HIGHLIGHT}{
+\label{videosethighlight}
+ int ioctl(fd, int request = VIDEO\_SET\_HIGHLIGHT ,videoHighlight\_t *vhilite)
+}{
+ This ioctl sets the SPU highlight information for the menu access of
+ a DVD.
+}{
+ int fd & File descriptor returned by a previous call to open().\\
+ int request & Equals VIDEO\_SET\_HIGHLIGHT for this command.\\
+ videoHighlight\_t *vhilite& SPU Highlight information according to
+ section \ref{vhilite}.\\
+}{
+ EBADF& fd is not a valid open file descriptor. \\
+ EINVAL& input is not a valid highlight setting.\\
+}
+
+
+\ifunction{VIDEO\_SET\_SPU}{
+\label{videosetspu}
+ int ioctl(fd, int request = VIDEO\_SET\_SPU , videoSPU\_t *spu)
+}{
+ This ioctl activates or deactivates SPU decoding in a DVD input
+ stream. It can only be used, if the driver is able to handle a DVD
+ stream.
+}{
+ int fd & File descriptor returned by a previous call to open().\\
+ int request & Equals VIDEO\_SET\_SPU for this command.\\
+ videoSPU\_t *spu& SPU decoding (de)activation and subid setting
+ according to section \ref{videospu}.\\
+}{
+ EBADF& fd is not a valid open file descriptor \\
+ EINVAL& input is not a valid spu setting or driver cannot handle SPU.\\
+}
+
+
+\ifunction{VIDEO\_SET\_SPU\_PALETTE}{
+\label{videosetspupalette}
+ int ioctl(fd, int request = VIDEO\_SET\_SPU\_PALETTE ,videoSPUPalette\_t *palette )
+}{
+ This ioctl sets the SPU color palette.
+}{
+ int fd & File descriptor returned by a previous call to open().\\
+ int request & Equals VIDEO\_SET\_SPU\_PALETTE for this command.\\
+ videoSPUPalette\_t *palette& SPU palette according to section \ref{vspupal}.\\
+}{
+ EBADF& fd is not a valid open file descriptor \\
+ EINVAL& input is not a valid palette or driver doesn't handle SPU.\\
+}
+
+
+
+\ifunction{VIDEO\_GET\_NAVI}{
+\label{videosetnavi}
+ int ioctl(fd, int request = VIDEO\_GET\_NAVI , videoNaviPack\_t *navipack)
+}{
+ This ioctl returns navigational information from the DVD stream. This is
+ especially needed if an encoded stream has to be decoded by the hardware.
+}{
+ int fd & File descriptor returned by a previous call to open().\\
+ int request & Equals VIDEO\_GET\_NAVI for this command.\\
+ videoNaviPack\_t *navipack& PCI or DSI pack (private stream 2)
+ according to section \ref{videonavi}.\\
+}{
+ EBADF& fd is not a valid open file descriptor \\
+ EFAULT& driver is not able to return navigational information\\
+}
+
+
+\ifunction{VIDEO\_SET\_ATTRIBUTES}{
+\label{videosetattributes}
+ int ioctl(fd, int request = VIDEO\_SET\_ATTRIBUTE ,videoAttributes\_t
+ vattr)
+}{
+ This ioctl is intended for DVD playback and allows you to set
+ certain information about the stream. Some hardware may not need
+ this information, but the call also tells the hardware to prepare
+ for DVD playback.
+}{
+ int fd & File descriptor returned by a previous call to open().\\
+ int request & Equals VIDEO\_SET\_ATTRIBUTE for this command.\\
+ videoAttributes\_t vattr& video attributes according to section \ref{vattrib}.\\
+}{
+ EBADF& fd is not a valid open file descriptor \\
+ EINVAL& input is not a valid attribute setting.\\
+}
+
+
+%%% Local Variables:
+%%% mode: latex
+%%% TeX-master: "dvbapi"
+%%% End: