From 9034551a3bbc76b79a152806c781b1b8e8ea3a9a Mon Sep 17 00:00:00 2001 From: rjkm Date: Sun, 16 Sep 2001 22:27:03 -0300 Subject: new API docs --- dvb-spec/dvbapi/Makefile | 30 ++ dvb-spec/dvbapi/audio.tex | 436 +++++++++++++++++ dvb-spec/dvbapi/bibsection.sty | 29 ++ dvb-spec/dvbapi/ca.tex | 127 +++++ dvb-spec/dvbapi/cimlogo.psi | 122 +++++ dvb-spec/dvbapi/demux.tex | 392 ++++++++++++++++ dvb-spec/dvbapi/devices.tex | 12 + dvb-spec/dvbapi/dvbapi.tex | 166 +++++++ dvb-spec/dvbapi/dvbstb.fig | 59 +++ dvb-spec/dvbapi/examples.tex | 365 +++++++++++++++ dvb-spec/dvbapi/fig2pstex | 6 + dvb-spec/dvbapi/getbb | 12 + dvb-spec/dvbapi/intro.tex | 192 ++++++++ dvb-spec/dvbapi/kdapi.tex | 1007 ++++++++++++++++++++++++++++++++++++++++ dvb-spec/dvbapi/sec.tex | 282 +++++++++++ dvb-spec/dvbapi/title.tex | 24 + dvb-spec/dvbapi/video.tex | 684 +++++++++++++++++++++++++++ 17 files changed, 3945 insertions(+) create mode 100644 dvb-spec/dvbapi/Makefile create mode 100644 dvb-spec/dvbapi/audio.tex create mode 100644 dvb-spec/dvbapi/bibsection.sty create mode 100644 dvb-spec/dvbapi/ca.tex create mode 100644 dvb-spec/dvbapi/cimlogo.psi create mode 100644 dvb-spec/dvbapi/demux.tex create mode 100644 dvb-spec/dvbapi/devices.tex create mode 100644 dvb-spec/dvbapi/dvbapi.tex create mode 100644 dvb-spec/dvbapi/dvbstb.fig create mode 100644 dvb-spec/dvbapi/examples.tex create mode 100755 dvb-spec/dvbapi/fig2pstex create mode 100755 dvb-spec/dvbapi/getbb create mode 100644 dvb-spec/dvbapi/intro.tex create mode 100644 dvb-spec/dvbapi/kdapi.tex create mode 100644 dvb-spec/dvbapi/sec.tex create mode 100644 dvb-spec/dvbapi/title.tex create mode 100644 dvb-spec/dvbapi/video.tex (limited to 'dvb-spec/dvbapi') 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 +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#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 +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#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{}\\\\ + Dr. Marcus O.C. Metzler\\ + \texttt{} +% 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: -- cgit v1.2.3 From 7577c23439dfbc1d67e490d9dfa4cbd8e3b548ed Mon Sep 17 00:00:00 2001 From: rjkm Date: Sun, 16 Sep 2001 22:27:38 -0300 Subject: added new API docs --- dvb-spec/dvbapi/frontend.tex | 612 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 612 insertions(+) create mode 100644 dvb-spec/dvbapi/frontend.tex (limited to 'dvb-spec/dvbapi') diff --git a/dvb-spec/dvbapi/frontend.tex b/dvb-spec/dvbapi/frontend.tex new file mode 100644 index 000000000..74f21225d --- /dev/null +++ b/dvb-spec/dvbapi/frontend.tex @@ -0,0 +1,612 @@ +\devsec{DVB Frontend API} + +The DVB frontend device controls the tuner and DVB demodulator hardware. +It can be accessed through \texttt{/dev/ost/frontend}. +If you are using \texttt{devfs} you can use \texttt{/dev/dvb/card0/frontend}. +The frontend device will only be made visible through \texttt{devfs} +if the corresponding card actually has a frontend. Cards which support +the DVB API but, e.g., only can play back recordings, will not offer the +frontend device. + +\devsubsec{Frontend Data Types} + +\devsubsubsec{frontend status} +\label{frontendstatus} + +Several functions of the frontend device use the feStatus data +type defined by +\begin{verbatim} +typedef uint32_t feStatus; +\end{verbatim} +to indicate the current state and/or state changes of +the frontend hardware. + +\noindent +It can take on the values +\begin{verbatim} +#define FE_HAS_POWER 1 +#define FE_HAS_SIGNAL 2 +#define FE_SPECTRUM_INV 4 +#define FE_HAS_LOCK 8 +#define TUNER_HAS_LOCK 128 +\end{verbatim} +which can be ORed together and have the following meaning: + +\medskip + +\begin{tabular}{lp{11cm}} +FE\_HAS\_POWER & the frontend is powered up and is ready to be used\\ +FE\_HAS\_SIGNAL & the frontend detects a signal above the normal noise level\\ +FE\_SPECTRUM\_INV & spectrum inversion is enabled/was necessary for lock\\ +FE\_HAS\_LOCK & frontend successfully locked to a DVB signal \\ +TUNER\_HAS\_LOCK & the tuner has a frequency lock +\end{tabular} + + +\devsubsubsec{frontend parameters} +\label{frontendparameters} + +The kind of parameters passed to the frontend device for tuning +depend on the kind of hardware you are using. +All kinds of parameters are combined as a union in the +FrontendParameters structure: +\begin{verbatim} +typedef struct { + __u32 Frequency; /* (absolute) frequency in Hz for QAM/OFDM */ + /* intermediate frequency in kHz for QPSK */ + union { + QPSKParameters qpsk; + QAMParameters qam; + OFDMParameters ofdm; + } u; +} FrontendParameters; +\end{verbatim} + +For satellite QPSK frontends you have to use QPSKParameters defined by +\begin{verbatim} +typedef struct { + __u32 SymbolRate; /* symbol rate in Symbols per second */ + CodeRate FEC_inner; /* forward error correction (see above) */ +} QPSKParameters; +\end{verbatim} +for cable QAM frontend you use the QAMParameters structure +\begin{verbatim} +typedef struct { + __u32 SymbolRate; /* symbol rate in Symbols per second */ + CodeRate FEC_inner; /* forward error correction (see above) */ + CodeRate FEC_outer; /* forward error correction (see above) */ + Modulation QAM; /* modulation type (see above) */ +} QAMParameters; +\end{verbatim} +DVB-T frontends are supported by the OFDMParamters structure +\begin{verbatim} +typedef struct { + BandWidth bandWidth; + CodeRate HP_CodeRate; /* high priority stream code rate */ + CodeRate LP_CodeRate; /* low priority stream code rate */ + Modulation Constellation; /* modulation type (see above) */ + TransmitMode TransmissionMode; + GuardInterval guardInterval; + Hierarchy HierarchyInformation; +} OFDMParameters; +\end{verbatim} + +In the case of QPSK frontends the Frequency field specifies the intermediate +frequency, i.e. the offset which is effectively added to the local oscillator +frequency (LOF) of the LNB. +The intermediate frequency has to be specified in units of kHz. +For QAM and OFDM frontends the Frequency specifies the absolute frequency +and is given in Hz. + +\noindent +The possible values for the FEC\_inner field are +\begin{verbatim} +enum { + FEC_AUTO, + FEC_1_2, + FEC_2_3, + FEC_3_4, + FEC_5_6, + FEC_7_8, + FEC_NONE +}; +\end{verbatim} +which correspond to error correction rates of $1\over 2$, $2\over 3$, etc., +no error correction or auto detection. + +\noindent +For cable and terrestrial frontends (QAM and OFDM) one also has to +specify the quadrature modulation mode which can be one of the following: +\begin{verbatim} +typedef enum +{ QPSK, + QAM_16, + QAM_32, + QAM_64, + QAM_128, + QAM_256 +} QAM_TYPE; +\end{verbatim} + +Finally, there are several more parameters for OFDM: +\begin{verbatim} +typedef enum { + TRANSMISSION_MODE_2K, + TRANSMISSION_MODE_8K +} TransmitMode; +\end{verbatim} + +\begin{verbatim} +typedef enum { + BANDWIDTH_8_MHZ, + BANDWIDTH_7_MHZ, + BANDWIDTH_6_MHZ +} BandWidth; +\end{verbatim} + +\begin{verbatim} +typedef enum { + GUARD_INTERVAL_1_32, + GUARD_INTERVAL_1_16, + GUARD_INTERVAL_1_8, + GUARD_INTERVAL_1_4 +} GuardInterval; +\end{verbatim} + +\begin{verbatim} +typedef enum { + HIERARCHY_NONE, + HIERARCHY_1, + HIERARCHY_2, + HIERARCHY_4 +} Hierarchy; +\end{verbatim} + + +\devsubsubsec{frontend events} +\label{frontendevents} + +\begin{verbatim} +enum { + FE_UNEXPECTED_EV, + FE_COMPLETION_EV, + FE_FAILURE_EV +}; +\end{verbatim} + +\begin{verbatim} +typedef struct { + EventType type; /* type of event, FE_UNEXPECTED_EV, ... */ + long timestamp; /* time in seconds since 1970-01-01 */ + + union { + struct { + FrontendStatus previousStatus; /* status before event */ + FrontendStatus currentStatus; /* status during event */ + } unexpectedEvent; + FrontendParameters completionEvent; /* parameters for which the + tuning succeeded */ + FrontendStatus failureEvent; /* status at failure (e.g. no lock) */ + } u; +} FrontendEvent; +\end{verbatim} + +\begin{verbatim} +struct qpskRegister { + uint8_t chipId; + uint8_t address; + uint8_t value; +}; +\end{verbatim} + +\begin{verbatim} +struct qamRegister { + uint8_t chipId; + uint8_t address; + uint8_t value; +}; +\end{verbatim} + +\begin{verbatim} +struct qpskFrontendInfo { + uint32_t minFrequency; + uint32_t maxFrequency; + uint32_t maxSymbolRate; + uint32_t minSymbolRate; + uint32_t hwType; + uint32_t hwVersion; +}; +\end{verbatim} + +\begin{verbatim} +struct qamFrontendInfo { + uint32_t minFrequency; + uint32_t maxFrequency; + uint32_t maxSymbolRate; + uint32_t minSymbolRate; + uint32_t hwType; + uint32_t hwVersion; +}; +\end{verbatim} + +\begin{verbatim} +typedef enum { + FE_POWER_ON, + FE_POWER_STANDBY, + FE_POWER_SUSPEND, + FE_POWER_OFF +} powerState_t; +\end{verbatim} + + +\clearpage + + +\devsubsec{Frontend Function Calls} + +\function{open()}{ + int open(const char *deviceName, int flags);}{ + This system call opens a named frontend device (e.g. /dev/ost/qpskfe + for a satellite frontend or /dev/ost/qamfe for a cable frontend) + for subsequent use. + + The device can be opened in read-only mode, which only allows + monitoring of device status and statistics, or read/write mode, which allows + any kind of use (e.g. performing tuning operations.) + + In a system with multiple front-ends, it is usually the case that multiple + devices cannot be open in read/write mode simultaneously. As long as a + front-end device is opened in read/write mode, other open() calls in + read/write mode will either fail or block, depending on whether + non-blocking or blocking mode was specified. + A front-end 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. + When an open() call has succeeded, the device will be ready for use in the + specified mode. This implies that the corresponding hardware is powered up, + and that other front-ends may have been powered down to make that possible. + + }{ + 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 front-end device. + After closing a front-end device, its corresponding hardware might be + powered down automatically, but only when this is needed to open + another front-end device. + To affect an unconditional power down, it should be done explicitly using + the OST\_SET\_POWER\_STATE ioctl. + 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.\\ +} + +\ifunction{OST\_SELFTEST}{ + int ioctl(int fd, int request = OST\_SELFTEST);}{ + This ioctl call initiates an automatic self-test of the front-end hardware. + This call requires read/write access to the device. + }{ + int fd & File descriptor returned by a previous call to open().\\ + int request & Equals OST\_SELFTEST for this command.\\ + }{ + -1& Self test failure.\\ +} + +\ifunction{OST\_SET\_POWER\_STATE}{ + int ioctl(int fd, int request = OST\_SET\_POWER\_STATE, uint32\_t state);}{ + This ioctl call, implemented in many OST device drivers, enables direct + control over the power state of the hardware device, which may be on, off, + standby, or suspend. The latter two are low-power modes, which disable all + functionality of the device until turned on again. In contrast to the off + state, however, the standby and suspend states resume operation in the same + state as when the device was active. The only difference between the standby + and suspend states is a different tradeoff between resume time and power + consumption. Power consumption may be lower in the suspend state at the + cost of a longer resume time.\\ + A device that implements this call does not necessarily support two low-power + modes. If it only supports one low-power state, or none at all, the + OST\_SET\_POWER\_STATE operation for the missing states will + still succeed, but + it will be mapped to an existing state as per this table: \\ + \begin{center} + \begin{tabular}[h]{cll} + number of low-power & requested state & resulting state\\ + states supported &&\\ + \\ + 1 & standby & suspend \\ + 1 & suspend & suspend \\ + 0 & standby & on \\ + 0 & suspend & on + \end{tabular} + \end{center}\\ + For other cases where a required state is missing, an error code will be + returned. This can happen if a device does not support the power-off state, + but nevertheless implements this ioctl operation for control of low-power + states. + When opening a device in read/write mode, the driver ensures that the + corresponding hardware device is turned on initially. If the device is + later turned off or put in suspend mode, it has to be explicitly turned on + again.\\ + This call requires read/write access to the device. (Note that the power + management driver can affect the power state of devices without using this + ioctl operation, so having exclusive read/write access to a device does not + imply total control over the power state.) + }{ + int fd & File descriptor returned by a previous call to open().\\ + int request & Equals OST\_SET\_POWER\_STATE for this command.\\ + uint32\_t state & Requested power state. One of: \\ + & + \begin{tabular}[h]{ll} + OST\_POWER\_ON& turn power on\\ + OST\_POWER\_STANDBY& set device in standby mode\\ + OST\_POWER\_SUSPEND& set device in suspend mode\\ + OST\_POWER\_OFF& turn power off\\ + \end{tabular} + }{ + EBADF& fd is not a valid open file descriptor.\\ + EINVAL& Illegal state, or not available on this device.\\ + EPERM & Permission denied (needs read/write access).\\ + ENOSYS& Function not available for this device. +} + +\ifunction{FE\_GET\_POWER\_STATE}{ + int ioctl(int fd, int request = OST\_GET\_POWER\_STATE, uint32\_t *state);}{ + This ioctl call, implemented in many OST device drivers, obtains the power + state of the hardware device, which may be on, off, standby, or suspend. + A device that implements this call does not necessarily support all four states. + If there is only one low-power state, the suspend state will be returned for + that state. If there is no low-power state, the on state will be reported + standby and suspend states will be equivalent to the on state. + For this command, read-only access to the device is sufficient. + }{ + int fd & File descriptor returned by a previous call to open().\\ + int request & Equals OST\_GET\_POWER\_STATE for this command.\\ + uint32\_t *state & Requested power state. One of: \\ + & + \begin{tabular}[h]{ll} + OST\_POWER\_ON& power is on\\ + OST\_POWER\_STANDBY& device in standby mode\\ + OST\_POWER\_SUSPEND& device in suspend mode\\ + OST\_POWER\_OFF& power is off\\ + \end{tabular} + }{ + EBADF& fd is not a valid open file descriptor.\\ + EINVAL& Illegal state, or not available on this device.\\ + EFAULT& state points to invalid address.\\ + ENOSYS& Function not available for this device. +} + +\ifunction{FE\_READ\_STATUS}{ + int ioctl(int fd, int request = FE\_READ\_STATUS, feStatus *status);}{ + This ioctl call returns status information about the front-end. + This call only requires read-only access to the device. + }{ + int fd & File descriptor returned by a previous call to open().\\ + int request & Equals FE\_READ\_STATUS for this command.\\ + struct feStatus *status&Points to the location where the front-end + status word is to be stored. + }{ + EBADF& fd is not a valid open file descriptor.\\ + EFAULT& status points to invalid address.\\ +} + +\ifunction{FE\_READ\_BER}{ + int ioctl(int fd, int request = FE\_READ\_BER, uint32\_t *ber);}{ + This ioctl call returns the bit error rate for the signal currently + received/demodulated by the front-end. For this command, read-only access + to the device is sufficient. + }{ + int fd & File descriptor returned by a previous call to open().\\ + int request & Equals FE\_READ\_BER for this command.\\ + uint32\_t *ber & The bit error rate, as a multiple of $10^{-9}$, + is stored into *ber.\\ + & Example: a value of 2500 corresponds to a bit error + rate of $2.5\cdot 10^{-6}$, or 1 error in 400000 bits. + }{ + EBADF& fd is not a valid open file descriptor.\\ + EFAULT& ber points to invalid address.\\ + ENOSIGNAL& There is no signal, thus no meaningful bit error + rate. Also returned if the front-end is not turned on.\\ + ENOSYS& Function not available for this device. +} + +\ifunction{FE\_READ\_SNR}{ + int ioctl(int fd, int request = FE\_READ\_SNR, int32\_t *snr);}{ + This ioctl call returns the signal-to-noise ratio for the signal currently + received by the front-end. For this command, read-only access to the device + is sufficient. + }{ + int fd & File descriptor returned by a previous call to open().\\ + int request & Equals FE\_READ\_SNR for this command.\\ + int32\_t *snr& The signal-to-noise ratio, as a multiple of + $10^{-6}$ dB, is stored into *snr.\\ + & Example: a value of 12,300,000 corresponds + to a signal-to-noise ratio of 12.3 dB. +}{ + EBADF& fd is not a valid open file descriptor.\\ + EFAULT& snr points to invalid address.\\ + ENOSIGNAL& There is no signal, thus no meaningful signal + strength value. Also returned if front-end is not turned on.\\ + ENOSYS& Function not available for this device. +} + +\ifunction{FE\_READ\_SIGNAL\_STRENGTH}{ + int ioctl( int fd, int request = FE\_READ\_SIGNAL\_STRENGTH, int32\_t *strength); +}{ +This ioctl call returns the signal strength value for the signal currently +received by the front-end. For this command, read-only access to the device +is sufficient. +}{ +int fd & File descriptor returned by a previous call to open().\\ +int request & Equals FE\_READ\_SIGNAL\_STRENGTH for this command.\\ +int32\_t *strength & The signal strength value, as a multiple of + $10^{-6 }$ dBm, + is stored into *strength. \\ + &Example: a value of -12,500,000 corresponds to a signal + strength value of -12.5 dBm. +}{ + EBADF& fd is not a valid open file descriptor.\\ + EFAULT& status points to invalid address.\\ + ENOSIGNAL& There is no signal, thus no meaningful signal + strength value. Also returned if front-end is not turned on.\\ + ENOSYS& Function not available for this device. +} + +\ifunction{FE\_READ\_UNCORRECTED\_BLOCKS}{ + int ioctl( int fd, int request = FE\_READ\_UNCORRECTED\_BLOCKS, uint32\_t *ublocks); }{ + This ioctl call returns the number of uncorrected blocks detected by + the device driver during its lifetime. + For meaningful measurements, the increment in + block count during a specific time interval should be calculated. + For this command, read-only access to the device is sufficient.\\ + Note that the counter will wrap to zero after its maximum count has + been reached. +}{ +int fd & File descriptor returned by a previous call to open().\\ +int request & Equals FE\_READ\_UNCORRECTED\_BLOCKS for this command.\\ +uint32\_t *ublocks & The total number of uncorrected blocks seen +by the driver so far. +}{ + EBADF& fd is not a valid open file descriptor.\\ + EFAULT& ublocks points to invalid address.\\ + ENOSYS& Function not available for this device. +} + + +\ifunction{FE\_GET\_NEXT\_FREQUENCY}{ + int ioctl( int fd, int request = FE\_GET\_NEXT\_FREQUENCY, uint32\_t *freq);}{ + When scanning a frequency range, it is desirable to use a scanning step size + that is as large as possible, yet small enough to be able to lock to any signal + within the range. + This ioctl operation does just that - it increments a given frequency by a + step size suitable for efficient scanning. + The step size used by this function may be a quite complex function of the given + frequency, hardware capabilities, and parameter settings of the device. Thus, a + returned result is only valid for the current state of the device. + For this command, read-only access to the device is sufficient.\\ + Note that scanning may still be excruciatingly slow on some hardware, for + other reasons than a non-optimal scanning step size. + }{ + int fd & File descriptor returned by a previous call to open().\\ + int request & Equals FE\_GET\_NEXT\_FREQUENCY for this command.\\ + uint32\_t *freq& Input: a given frequency \\ + & Output: the frequency corresponding to + the next higher frequency setting.\\ + }{ + EBADF& fd is not a valid open file descriptor.\\ + EFAULT& freq points to invalid address.\\ + EINVAL& Maximum supported frequency reached.\\ + ENOSYS& Function not available for this device. +} + +\ifunction{FE\_GET\_NEXT\_SYMBOL\_RATE}{ + int ioctl( int fd, int request = FE\_GET\_NEXT\_SYMBOL\_RATE, uint32\_t *symbolRate); + }{ + When scanning a range of symbol rates (e.g. for "blind acquisition") it is + desirable to use a scanning step size that is as large as possible, yet + small enough to detect any valid signal within the range. This ioctl + operation does just that - it increments a given symbol rate by a step size + suitable for efficient scanning. + The step size used by this function may be a quite complex function of the given + symbol rate, hardware capabilities, and parameter settings of the device. + Thus, a returned result is only valid for the current state of the device. + For this command, read-only access to the device is sufficient. + }{ + int fd & File descriptor returned by a previous call to open().\\ + int request & Equals FE\_GET\_NEXT\_SYMBOL\_RATE for this command.\\ + uint32\_t *symbolRate& Input: a given symbol rate \\ + & Output: the symbol rate corresponding to + the next higher symbol rate.\\ + }{ + EBADF& fd is not a valid open file descriptor.\\ + EFAULT& symbolRate points to invalid address.\\ + EINVAL& Maximum supported symbol rate reached.\\ + ENOSYS& Function not available for this device. +} + +\ifunction{FE\_SET\_FRONTEND}{ + int ioctl(int fd, int request = FE\_SET\_FRONTEND, struct FrontendParameters *p);}{ + This ioctl call starts a tuning operation using specified parameters. + The result of this call will be successful if the parameters were valid and + the tuning could be initiated. + The result of the tuning operation in itself, however, will arrive + asynchronously as an event (see documentation for FE\_GET\_EVENT + and FrontendEvent.) + If a new FE\_SET\_FRONTEND operation is initiated before the previous + one was completed, + the previous operation will be aborted in favor of the new one. + This command requires read/write access to the device. + }{ + int fd & File descriptor returned by a previous call to open().\\ + int request & Equals FE\_SET\_FRONTEND for this command.\\ + struct FrontendParameters *p& Points to parameters for tuning operation.\\ + }{ + EBADF& fd is not a valid open file descriptor.\\ + EFAULT& p points to invalid address.\\ + EINVAL& Maximum supported symbol rate reached.\\ +} + +\ifunction{FE\_GET\_EVENT}{ + int ioctl(int fd, int request = QPSK\_GET\_EVENT, struct qpskEvent *ev);}{ + This ioctl call returns an event of type qpskEvent 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. + Since the event queue allocated is rather small (room for 8 events), the queue + must be serviced regularly to avoid overflow. If an overflow happens, the + oldest event is discarded from the queue, and an error (EBUFFEROVERFLOW) occurs + the next time the queue is read. After reporting the error condition in this + fashion, subsequent QPSK\_GET\_EVENT calls will return events from the queue as + usual.\\ + For the sake of implementation simplicity, this command requires read/write + access to the device. + }{ + int fd & File descriptor returned by a previous call to open().\\ + int request & Equals QPSK\_GET\_EVENT for this command.\\ + struct qpskEvent *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{FE\_GET\_INFO}{ + int ioctl(int fd, int request = FE\_GET\_INFO, struct FrontendInfo *info);}{ + This ioctl call returns information about the front-end. + This call only requires read-only access to the device. + }{ + int fd & File descriptor returned by a previous call to open().\\ + int request & Equals FE\_GET\_INFO for this command.\\ + struct qpskFrontendInfo *info & Points to the location where the front-end + information is to be stored. + }{ + EBADF& fd is not a valid open file descriptor.\\ + EFAULT& info points to invalid address.\\ +} + +%%% Local Variables: +%%% mode: latex +%%% TeX-master: "dvbapi" +%%% End: -- cgit v1.2.3 From f1e2fc77631891bd568baff424cbe535a2795d65 Mon Sep 17 00:00:00 2001 From: rjkm Date: Wed, 19 Sep 2001 18:48:28 -0300 Subject: removed some typos --- dvb-spec/dvbapi/frontend.tex | 1 - dvb-spec/dvbapi/kdapi.tex | 4 ++-- dvb-spec/dvbapi/sec.tex | 2 +- 3 files changed, 3 insertions(+), 4 deletions(-) (limited to 'dvb-spec/dvbapi') diff --git a/dvb-spec/dvbapi/frontend.tex b/dvb-spec/dvbapi/frontend.tex index 74f21225d..5b496c688 100644 --- a/dvb-spec/dvbapi/frontend.tex +++ b/dvb-spec/dvbapi/frontend.tex @@ -288,7 +288,6 @@ typedef enum { another front-end device. To affect an unconditional power down, it should be done explicitly using the OST\_SET\_POWER\_STATE ioctl. - This system call closes a previously opened audio device. }{ int fd & File descriptor returned by a previous call to open().\\ }{ diff --git a/dvb-spec/dvbapi/kdapi.tex b/dvb-spec/dvbapi/kdapi.tex index 6cee25c85..59490299b 100644 --- a/dvb-spec/dvbapi/kdapi.tex +++ b/dvb-spec/dvbapi/kdapi.tex @@ -41,7 +41,7 @@ typedef enum { \label{dmxtspest} The structure -/\begin{verbatim} +\begin{verbatim} typedef enum { DMX_TS_PES_AUDIO, /* also send packets to audio decoder (if it exists) */ @@ -109,8 +109,8 @@ typedef struct dmx_pes_feed_s { \end{verbatim} -\begin{verbatim} \label{sectionfilter} +\begin{verbatim} typedef struct { __u8 filter_value [DMX_MAX_FILTER_SIZE]; __u8 filter_mask [DMX_MAX_FILTER_SIZE]; diff --git a/dvb-spec/dvbapi/sec.tex b/dvb-spec/dvbapi/sec.tex index 6ccd89481..88342c3a6 100644 --- a/dvb-spec/dvbapi/sec.tex +++ b/dvb-spec/dvbapi/sec.tex @@ -198,7 +198,7 @@ typedef enum { EINTERNAL & Internal error in the device driver.\\ } -\ifunction{SEC\_RESET\_OVERLOAD}{ +\ifunction{SEC\_SEND\_SEQUENCE}{ 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 -- cgit v1.2.3 From 4b03c3f1a363c428d5bf45e040073345d336ec1c Mon Sep 17 00:00:00 2001 From: rjkm Date: Fri, 21 Sep 2001 09:47:12 -0300 Subject: added inversion field --- dvb-spec/dvbapi/frontend.tex | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) (limited to 'dvb-spec/dvbapi') diff --git a/dvb-spec/dvbapi/frontend.tex b/dvb-spec/dvbapi/frontend.tex index 5b496c688..23b9d3e22 100644 --- a/dvb-spec/dvbapi/frontend.tex +++ b/dvb-spec/dvbapi/frontend.tex @@ -26,8 +26,11 @@ It can take on the values \begin{verbatim} #define FE_HAS_POWER 1 #define FE_HAS_SIGNAL 2 -#define FE_SPECTRUM_INV 4 +#define FE_SPECTRUM_INV 4 #define FE_HAS_LOCK 8 +#define FE_HAS_CARRIER 16 +#define FE_HAS_VITERBI 32 +#define FE_HAS_SYNC 64 #define TUNER_HAS_LOCK 128 \end{verbatim} which can be ORed together and have the following meaning: @@ -39,6 +42,9 @@ FE\_HAS\_POWER & the frontend is powered up and is ready to be used\\ FE\_HAS\_SIGNAL & the frontend detects a signal above the normal noise level\\ FE\_SPECTRUM\_INV & spectrum inversion is enabled/was necessary for lock\\ FE\_HAS\_LOCK & frontend successfully locked to a DVB signal \\ +FE\_HAS\_CARRIER & carrier detected in signal\\ +FE\_HAS\_VITERBI & lock at viterbi decoder stage\\ +FE\_HAS\_SYNC & TS sync bytes detected \\ TUNER\_HAS\_LOCK & the tuner has a frequency lock \end{tabular} @@ -54,6 +60,7 @@ FrontendParameters structure: typedef struct { __u32 Frequency; /* (absolute) frequency in Hz for QAM/OFDM */ /* intermediate frequency in kHz for QPSK */ + SpectralInversion Inversion; /* spectral inversion */ union { QPSKParameters qpsk; QAMParameters qam; @@ -73,8 +80,8 @@ for cable QAM frontend you use the QAMParameters structure \begin{verbatim} typedef struct { __u32 SymbolRate; /* symbol rate in Symbols per second */ - CodeRate FEC_inner; /* forward error correction (see above) */ CodeRate FEC_outer; /* forward error correction (see above) */ + CodeRate FEC_inner; /* forward error correction (see above) */ Modulation QAM; /* modulation type (see above) */ } QAMParameters; \end{verbatim} @@ -98,6 +105,18 @@ The intermediate frequency has to be specified in units of kHz. For QAM and OFDM frontends the Frequency specifies the absolute frequency and is given in Hz. +The Inversion field can take one of these values: +\begin{verbatim} +typedef enum { + INVERSION_OFF, + INVERSION_ON, + INVERSION_AUTO +} SpectralInversion; +\end{verbatim} +It indicates if spectral inversion should be presumed or not. +In the automatic setting (INVERSION_AUTO) the hardware will +try to figure out the correct setting by itself. + \noindent The possible values for the FEC\_inner field are \begin{verbatim} -- cgit v1.2.3 From bb5ef2e954dffbdc1ec75b20ead76b202365862a Mon Sep 17 00:00:00 2001 From: mocm Date: Mon, 15 Oct 2001 11:17:02 -0200 Subject: added ignore --- dvb-spec/dvbapi/.cvsignore | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 dvb-spec/dvbapi/.cvsignore (limited to 'dvb-spec/dvbapi') diff --git a/dvb-spec/dvbapi/.cvsignore b/dvb-spec/dvbapi/.cvsignore new file mode 100644 index 000000000..fb6974f6b --- /dev/null +++ b/dvb-spec/dvbapi/.cvsignore @@ -0,0 +1,11 @@ +dvbapi.ps +dvbstb.ps +dvbstb.pst +dvbapi.bbl +dvbapi.aux +dvbapi.blg +dvbapi.dvi +dvbapi.log +dvbapi.pdf +dvbapi.out +dvbapi.toc -- cgit v1.2.3 From 231baf9444ac6726bec99d892d2cff2c4af32f5a Mon Sep 17 00:00:00 2001 From: mocm Date: Tue, 12 Feb 2002 14:29:24 -0200 Subject: updateupdatedd --- dvb-spec/dvbapi/frontend.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'dvb-spec/dvbapi') diff --git a/dvb-spec/dvbapi/frontend.tex b/dvb-spec/dvbapi/frontend.tex index 23b9d3e22..ceb2f93db 100644 --- a/dvb-spec/dvbapi/frontend.tex +++ b/dvb-spec/dvbapi/frontend.tex @@ -114,7 +114,7 @@ typedef enum { } SpectralInversion; \end{verbatim} It indicates if spectral inversion should be presumed or not. -In the automatic setting (INVERSION_AUTO) the hardware will +In the automatic setting (\verb INVERSION_AUTO) the hardware will try to figure out the correct setting by itself. \noindent -- cgit v1.2.3 From d50611422c6fb579b75a45b4d36613147abb69e4 Mon Sep 17 00:00:00 2001 From: mocm Date: Thu, 14 Feb 2002 08:51:00 -0200 Subject: some updates and correctionsome updates and correctionss --- dvb-spec/dvbapi/examples.tex | 115 ++++++++++++++++++++++--------------------- dvb-spec/dvbapi/intro.tex | 9 ++-- dvb-spec/dvbapi/title.tex | 4 +- 3 files changed, 64 insertions(+), 64 deletions(-) (limited to 'dvb-spec/dvbapi') diff --git a/dvb-spec/dvbapi/examples.tex b/dvb-spec/dvbapi/examples.tex index d2786a6f6..114579b80 100644 --- a/dvb-spec/dvbapi/examples.tex +++ b/dvb-spec/dvbapi/examples.tex @@ -23,30 +23,32 @@ tuners, but can easily be adjusted for QAM. #include #define DMX "/dev/ost/demux" -#define QPSK "/dev/ost/qpskfe" +#define FRONT "/dev/ost/frontend" #define SEC "/dev/ost/sec" -/* routine for checking if we have a signal */ -int has_signal(int front) +/* routine for checking if we have a signal and other status information*/ +int FEReadStatus(int fd, FrontendStatus *stat) { - feStatus stat; - - if ( front < 0 ){ - if((front = open(QPSK,O_RDWR)) < 0){ - perror("FRONTEND DEVICE: "); - return -1; - } - } + int ans; - FEReadStatus(front, &stat); - if (stat & FE_HAS_SIGNAL) - return 0; - else { - printf("Tuning failed\n"); + if ( (ans = ioctl(fd,FE_READ_STATUS,stat) < 0)){ + perror("FE READ STATUS: "); return -1; } + + if (*stat & FE_HAS_POWER) + printf("FE HAS POWER\n"); + + if (*stat & FE_HAS_SIGNAL) + printf("FE HAS SIGNAL\n"); + + if (*stat & FE_SPECTRUM_INV) + printf("SPEKTRUM INV\n"); + + return 0; } + /* tune qpsk */ /* freq: frequency of transponder */ /* vpid, apid, tpid: PIDs of video, audio and teletext TS packets */ @@ -65,14 +67,15 @@ int set_qpsk_channel(int freq, int vpid, int apid, int tpid, struct secCommand scmd; struct secCmdSequence scmds; struct dmxPesFilterParams pesFilterParams; - struct qpskParameters qpsk; + FrontendParameters frp; struct pollfd pfd[1]; - struct qpskEvent event; - int front, sec, demux1, demux2, demux3; + FrontendEvent event; + int demux1, dmeux2, demux3, front, - /* Open all the necessary the devices */ + frequency = (uint32_t) freq; + symbolrate = (uint32_t) srate; - if((front = open(QPSK,O_RDWR)) < 0){ + if((front = open(FRONT,O_RDWR)) < 0){ perror("FRONTEND DEVICE: "); return -1; } @@ -82,40 +85,41 @@ int set_qpsk_channel(int freq, int vpid, int apid, int tpid, return -1; } - if ((demux1 = open(DMX, O_RDWR|O_NONBLOCK)) < 0){ - perror("DEMUX DEVICE: "); - return -1; + if (demux1 < 0){ + 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 (demux2 < 0){ + 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; + if (demux3 < 0){ + 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); + frp.Frequency = (freq - lnb_lof1); scmds.continuousTone = SEC_TONE_OFF; } else { - qpsk.iFrequency = (freq - lnb_lof2); + frp.Frequency = (freq - lnb_lof2); scmds.continuousTone = SEC_TONE_ON; } - - /* Set the polarity of the transponder by setting the correct - voltage on the universal LNB */ - + frp.Inversion = INVERSION_AUTO; 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; @@ -127,32 +131,31 @@ int set_qpsk_channel(int freq, int vpid, int apid, int tpid, 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 */ + if (ioctl(sec, SEC_SEND_SEQUENCE, &scmds) < 0){ + perror("SEC SEND: "); + return -1; + } - qpsk.SymbolRate = srate; - qpsk.FEC_inner = fec; + frp.u.qpsk.SymbolRate = srate; + frp.u.qpsk.FEC_inner = fec; - /* Now send it all to the frontend device */ - if (ioctl(front, QPSK_TUNE, &qpsk) < 0){ + if (ioctl(front, FE_SET_FRONTEND, &frp) < 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) + if ( ioctl(front, FE_GET_EVENT, &event) == -EBUFFEROVERFLOW){ perror("qpsk get event"); @@ -166,15 +169,14 @@ int set_qpsk_channel(int freq, int vpid, int apid, int tpid, case FE_FAILURE_EV: printf("failure event\n"); return -1; - case FE_COMPLETION_EV: + + 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; @@ -205,8 +207,7 @@ int set_qpsk_channel(int freq, int vpid, int apid, int tpid, return -1; } - /* check if we have a signal */ - return has_signal(front); + return has_signal(fds); } \end{verbatim} @@ -262,7 +263,7 @@ int switch_to_record(int demux1, int demux2, uint16_t vpid, uint16_t apid) } if (demux2 < 0){ - if ((demux2=open(DMXdemuxs, O_RDWR|O_NONBLOCK)) + if ((demux2=open(DMX, O_RDWR|O_NONBLOCK)) < 0){ perror("DEMUX DEVICE: "); return -1; diff --git a/dvb-spec/dvbapi/intro.tex b/dvb-spec/dvbapi/intro.tex index acb6b4b85..e026a86e1 100644 --- a/dvb-spec/dvbapi/intro.tex +++ b/dvb-spec/dvbapi/intro.tex @@ -110,8 +110,7 @@ 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/frontend}, \item \texttt{/dev/ost/sec}, \item \texttt{/dev/ost/demux}, \item \texttt{/dev/ost/ca}, @@ -151,7 +150,7 @@ 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 +and a frontend which do not belong to the same card but have the same number. With \textsl{devfs} we propose a different scheme for the device names. @@ -169,14 +168,14 @@ 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 +/dev/dvb/card0/frontend0 demux0 /dev/dvb/card1/video0 audio0 demux0 demux1 - qpskfe0 + frontend0 sec0 \end{verbatim} diff --git a/dvb-spec/dvbapi/title.tex b/dvb-spec/dvbapi/title.tex index ce8b584c1..574464d23 100644 --- a/dvb-spec/dvbapi/title.tex +++ b/dvb-spec/dvbapi/title.tex @@ -12,7 +12,7 @@ % Rosenthalerstr. 51\\ % 10178 Berlin\\Germany } -\date{09/15/2001\\V 0.9.4} +\date{02/14/2002\\V 0.9.4} \maketitle \newpage @@ -21,4 +21,4 @@ % Local Variables: % mode: latex % TeX-master: "dvbapi" -% End: \ No newline at end of file +% End: -- cgit v1.2.3 From 7dddc78f51709f911af1106541603949765e3c9f Mon Sep 17 00:00:00 2001 From: mocm Date: Fri, 15 Feb 2002 08:17:18 -0200 Subject: corrections to audio_set_id documentation --- dvb-spec/dvbapi/audio.tex | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) (limited to 'dvb-spec/dvbapi') diff --git a/dvb-spec/dvbapi/audio.tex b/dvb-spec/dvbapi/audio.tex index 8c5b4fe82..e81dd2f89 100644 --- a/dvb-spec/dvbapi/audio.tex +++ b/dvb-spec/dvbapi/audio.tex @@ -354,7 +354,12 @@ typedef uint16_t audioAttributes_t; \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. + system stream is sent to the video device. If no audio stream type is set + the id has to be in [0xC0,0xDF] for MPEG sound, in [0x80,0x87] for + AC3 and in [0xA0,0xA7] for LPCM. More specifications may follow + for other stream types. If the stream type is set the id just + specifies the substream id of the audio stream and only the first 5 + bits are recognized. }{ int fd & File descriptor returned by a previous call to open().\\ int request & Equals AUDIO\_SET\_ID for this command.\\ @@ -382,7 +387,7 @@ typedef uint16_t audioAttributes_t; 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. + like LPCM and AC3. }{ int fd & File descriptor returned by a previous call to open().\\ int request & Equals AUDIO\_SET\_STREAMTYPE for this command.\\ @@ -395,7 +400,8 @@ typedef uint16_t audioAttributes_t; \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 + This ioctl can be used to set the extension id for MPEG streams in + DVD playback. Only the first 3 bits are recognized. }{ int fd & File descriptor returned by a previous call to open().\\ int request & Equals AUDIO\_SET\_EXT\_ID for this command.\\ -- cgit v1.2.3 From aed2950af0b53026e245705b265059ee9a439e1f Mon Sep 17 00:00:00 2001 From: mocm Date: Mon, 4 Mar 2002 09:27:48 -0300 Subject: some error corrections --- dvb-spec/dvbapi/dvbapi.tex | 2 +- dvb-spec/dvbapi/intro.tex | 10 +--------- dvb-spec/dvbapi/video.tex | 6 ++++-- 3 files changed, 6 insertions(+), 12 deletions(-) (limited to 'dvb-spec/dvbapi') diff --git a/dvb-spec/dvbapi/dvbapi.tex b/dvb-spec/dvbapi/dvbapi.tex index f9fcb841c..ad0251c01 100644 --- a/dvb-spec/dvbapi/dvbapi.tex +++ b/dvb-spec/dvbapi/dvbapi.tex @@ -131,7 +131,7 @@ \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} +\cfoot{\copyright 2002 convergence GmbH} \input{intro.tex} diff --git a/dvb-spec/dvbapi/intro.tex b/dvb-spec/dvbapi/intro.tex index e026a86e1..1d859fadb 100644 --- a/dvb-spec/dvbapi/intro.tex +++ b/dvb-spec/dvbapi/intro.tex @@ -68,7 +68,7 @@ time and re-inserted into the TS. 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 +contains data streams with information about the programs offered in this or other streams of the same provider. \item MPEG2 audio and video decoder @@ -118,14 +118,6 @@ The individual devices are called 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 diff --git a/dvb-spec/dvbapi/video.tex b/dvb-spec/dvbapi/video.tex index 67abb9586..2659db238 100644 --- a/dvb-spec/dvbapi/video.tex +++ b/dvb-spec/dvbapi/video.tex @@ -2,8 +2,10 @@ 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. - +The include file \texttt{ost/video.h} defines the data types and lists +all I/O calls. Please note that some DVB cards don't have their own +MPEG decoder, which results in the omission of the audio and video +device as well as the video4linux device. \devsubsec{Video Data Types} -- cgit v1.2.3 From ab85b007da42f42856a775d8cff97332093f5b34 Mon Sep 17 00:00:00 2001 From: holger Date: Thu, 10 Oct 2002 15:59:05 -0300 Subject: make room for the new HEAD trunk --- dvb-spec/dvbapi/.cvsignore | 11 - dvb-spec/dvbapi/Makefile | 30 -- dvb-spec/dvbapi/audio.tex | 442 ------------------ dvb-spec/dvbapi/bibsection.sty | 29 -- dvb-spec/dvbapi/ca.tex | 127 ----- dvb-spec/dvbapi/cimlogo.psi | 122 ----- dvb-spec/dvbapi/demux.tex | 392 ---------------- dvb-spec/dvbapi/devices.tex | 12 - dvb-spec/dvbapi/dvbapi.tex | 166 ------- dvb-spec/dvbapi/dvbstb.fig | 59 --- dvb-spec/dvbapi/examples.tex | 366 --------------- dvb-spec/dvbapi/fig2pstex | 6 - dvb-spec/dvbapi/frontend.tex | 630 ------------------------- dvb-spec/dvbapi/getbb | 12 - dvb-spec/dvbapi/intro.tex | 183 -------- dvb-spec/dvbapi/kdapi.tex | 1007 ---------------------------------------- dvb-spec/dvbapi/sec.tex | 282 ----------- dvb-spec/dvbapi/title.tex | 24 - dvb-spec/dvbapi/video.tex | 686 --------------------------- 19 files changed, 4586 deletions(-) delete mode 100644 dvb-spec/dvbapi/.cvsignore delete mode 100644 dvb-spec/dvbapi/Makefile delete mode 100644 dvb-spec/dvbapi/audio.tex delete mode 100644 dvb-spec/dvbapi/bibsection.sty delete mode 100644 dvb-spec/dvbapi/ca.tex delete mode 100644 dvb-spec/dvbapi/cimlogo.psi delete mode 100644 dvb-spec/dvbapi/demux.tex delete mode 100644 dvb-spec/dvbapi/devices.tex delete mode 100644 dvb-spec/dvbapi/dvbapi.tex delete mode 100644 dvb-spec/dvbapi/dvbstb.fig delete mode 100644 dvb-spec/dvbapi/examples.tex delete mode 100755 dvb-spec/dvbapi/fig2pstex delete mode 100644 dvb-spec/dvbapi/frontend.tex delete mode 100755 dvb-spec/dvbapi/getbb delete mode 100644 dvb-spec/dvbapi/intro.tex delete mode 100644 dvb-spec/dvbapi/kdapi.tex delete mode 100644 dvb-spec/dvbapi/sec.tex delete mode 100644 dvb-spec/dvbapi/title.tex delete mode 100644 dvb-spec/dvbapi/video.tex (limited to 'dvb-spec/dvbapi') diff --git a/dvb-spec/dvbapi/.cvsignore b/dvb-spec/dvbapi/.cvsignore deleted file mode 100644 index fb6974f6b..000000000 --- a/dvb-spec/dvbapi/.cvsignore +++ /dev/null @@ -1,11 +0,0 @@ -dvbapi.ps -dvbstb.ps -dvbstb.pst -dvbapi.bbl -dvbapi.aux -dvbapi.blg -dvbapi.dvi -dvbapi.log -dvbapi.pdf -dvbapi.out -dvbapi.toc diff --git a/dvb-spec/dvbapi/Makefile b/dvb-spec/dvbapi/Makefile deleted file mode 100644 index fe9827cff..000000000 --- a/dvb-spec/dvbapi/Makefile +++ /dev/null @@ -1,30 +0,0 @@ -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 deleted file mode 100644 index e81dd2f89..000000000 --- a/dvb-spec/dvbapi/audio.tex +++ /dev/null @@ -1,442 +0,0 @@ -\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. If no audio stream type is set - the id has to be in [0xC0,0xDF] for MPEG sound, in [0x80,0x87] for - AC3 and in [0xA0,0xA7] for LPCM. More specifications may follow - for other stream types. If the stream type is set the id just - specifies the substream id of the audio stream and only the first 5 - bits are recognized. - }{ - 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 LPCM 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 extension id for MPEG streams in - DVD playback. Only the first 3 bits are recognized. - }{ - 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 deleted file mode 100644 index 7f9eedc6a..000000000 --- a/dvb-spec/dvbapi/bibsection.sty +++ /dev/null @@ -1,29 +0,0 @@ -\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 deleted file mode 100644 index eba512b1b..000000000 --- a/dvb-spec/dvbapi/ca.tex +++ /dev/null @@ -1,127 +0,0 @@ -\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 deleted file mode 100644 index b7b089a49..000000000 --- a/dvb-spec/dvbapi/cimlogo.psi +++ /dev/null @@ -1,122 +0,0 @@ -%!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 deleted file mode 100644 index 541ee633a..000000000 --- a/dvb-spec/dvbapi/demux.tex +++ /dev/null @@ -1,392 +0,0 @@ -\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 deleted file mode 100644 index 9c561e853..000000000 --- a/dvb-spec/dvbapi/devices.tex +++ /dev/null @@ -1,12 +0,0 @@ -\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 deleted file mode 100644 index ad0251c01..000000000 --- a/dvb-spec/dvbapi/dvbapi.tex +++ /dev/null @@ -1,166 +0,0 @@ -\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 2002 convergence 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 deleted file mode 100644 index 0a6bbadc3..000000000 --- a/dvb-spec/dvbapi/dvbstb.fig +++ /dev/null @@ -1,59 +0,0 @@ -#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 deleted file mode 100644 index 114579b80..000000000 --- a/dvb-spec/dvbapi/examples.tex +++ /dev/null @@ -1,366 +0,0 @@ -\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 -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#define DMX "/dev/ost/demux" -#define FRONT "/dev/ost/frontend" -#define SEC "/dev/ost/sec" - -/* routine for checking if we have a signal and other status information*/ -int FEReadStatus(int fd, FrontendStatus *stat) -{ - int ans; - - if ( (ans = ioctl(fd,FE_READ_STATUS,stat) < 0)){ - perror("FE READ STATUS: "); - return -1; - } - - if (*stat & FE_HAS_POWER) - printf("FE HAS POWER\n"); - - if (*stat & FE_HAS_SIGNAL) - printf("FE HAS SIGNAL\n"); - - if (*stat & FE_SPECTRUM_INV) - printf("SPEKTRUM INV\n"); - - return 0; -} - - -/* 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; - FrontendParameters frp; - struct pollfd pfd[1]; - FrontendEvent event; - int demux1, dmeux2, demux3, front, - - frequency = (uint32_t) freq; - symbolrate = (uint32_t) srate; - - if((front = open(FRONT,O_RDWR)) < 0){ - perror("FRONTEND DEVICE: "); - return -1; - } - - if((sec = open(SEC,O_RDWR)) < 0){ - perror("SEC DEVICE: "); - return -1; - } - - if (demux1 < 0){ - if ((demux1=open(DMX, O_RDWR|O_NONBLOCK)) - < 0){ - perror("DEMUX DEVICE: "); - return -1; - } - } - - if (demux2 < 0){ - if ((demux2=open(DMX, O_RDWR|O_NONBLOCK)) - < 0){ - perror("DEMUX DEVICE: "); - return -1; - } - } - - if (demux3 < 0){ - if ((demux3=open(DMX, O_RDWR|O_NONBLOCK)) - < 0){ - perror("DEMUX DEVICE: "); - return -1; - } - } - - if (freq < lnb_slof) { - frp.Frequency = (freq - lnb_lof1); - scmds.continuousTone = SEC_TONE_OFF; - } else { - frp.Frequency = (freq - lnb_lof2); - scmds.continuousTone = SEC_TONE_ON; - } - frp.Inversion = INVERSION_AUTO; - if (pol) scmds.voltage = SEC_VOLTAGE_18; - else scmds.voltage = SEC_VOLTAGE_13; - - 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; - if (ioctl(sec, SEC_SEND_SEQUENCE, &scmds) < 0){ - perror("SEC SEND: "); - return -1; - } - - if (ioctl(sec, SEC_SEND_SEQUENCE, &scmds) < 0){ - perror("SEC SEND: "); - return -1; - } - - frp.u.qpsk.SymbolRate = srate; - frp.u.qpsk.FEC_inner = fec; - - if (ioctl(front, FE_SET_FRONTEND, &frp) < 0){ - perror("QPSK TUNE: "); - return -1; - } - - 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, FE_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"); - } - } - } - - - 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; - } - - return has_signal(fds); -} - -\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 -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#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(DMX, 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 deleted file mode 100755 index bf62eb7ec..000000000 --- a/dvb-spec/dvbapi/fig2pstex +++ /dev/null @@ -1,6 +0,0 @@ -#!/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/frontend.tex b/dvb-spec/dvbapi/frontend.tex deleted file mode 100644 index ceb2f93db..000000000 --- a/dvb-spec/dvbapi/frontend.tex +++ /dev/null @@ -1,630 +0,0 @@ -\devsec{DVB Frontend API} - -The DVB frontend device controls the tuner and DVB demodulator hardware. -It can be accessed through \texttt{/dev/ost/frontend}. -If you are using \texttt{devfs} you can use \texttt{/dev/dvb/card0/frontend}. -The frontend device will only be made visible through \texttt{devfs} -if the corresponding card actually has a frontend. Cards which support -the DVB API but, e.g., only can play back recordings, will not offer the -frontend device. - -\devsubsec{Frontend Data Types} - -\devsubsubsec{frontend status} -\label{frontendstatus} - -Several functions of the frontend device use the feStatus data -type defined by -\begin{verbatim} -typedef uint32_t feStatus; -\end{verbatim} -to indicate the current state and/or state changes of -the frontend hardware. - -\noindent -It can take on the values -\begin{verbatim} -#define FE_HAS_POWER 1 -#define FE_HAS_SIGNAL 2 -#define FE_SPECTRUM_INV 4 -#define FE_HAS_LOCK 8 -#define FE_HAS_CARRIER 16 -#define FE_HAS_VITERBI 32 -#define FE_HAS_SYNC 64 -#define TUNER_HAS_LOCK 128 -\end{verbatim} -which can be ORed together and have the following meaning: - -\medskip - -\begin{tabular}{lp{11cm}} -FE\_HAS\_POWER & the frontend is powered up and is ready to be used\\ -FE\_HAS\_SIGNAL & the frontend detects a signal above the normal noise level\\ -FE\_SPECTRUM\_INV & spectrum inversion is enabled/was necessary for lock\\ -FE\_HAS\_LOCK & frontend successfully locked to a DVB signal \\ -FE\_HAS\_CARRIER & carrier detected in signal\\ -FE\_HAS\_VITERBI & lock at viterbi decoder stage\\ -FE\_HAS\_SYNC & TS sync bytes detected \\ -TUNER\_HAS\_LOCK & the tuner has a frequency lock -\end{tabular} - - -\devsubsubsec{frontend parameters} -\label{frontendparameters} - -The kind of parameters passed to the frontend device for tuning -depend on the kind of hardware you are using. -All kinds of parameters are combined as a union in the -FrontendParameters structure: -\begin{verbatim} -typedef struct { - __u32 Frequency; /* (absolute) frequency in Hz for QAM/OFDM */ - /* intermediate frequency in kHz for QPSK */ - SpectralInversion Inversion; /* spectral inversion */ - union { - QPSKParameters qpsk; - QAMParameters qam; - OFDMParameters ofdm; - } u; -} FrontendParameters; -\end{verbatim} - -For satellite QPSK frontends you have to use QPSKParameters defined by -\begin{verbatim} -typedef struct { - __u32 SymbolRate; /* symbol rate in Symbols per second */ - CodeRate FEC_inner; /* forward error correction (see above) */ -} QPSKParameters; -\end{verbatim} -for cable QAM frontend you use the QAMParameters structure -\begin{verbatim} -typedef struct { - __u32 SymbolRate; /* symbol rate in Symbols per second */ - CodeRate FEC_outer; /* forward error correction (see above) */ - CodeRate FEC_inner; /* forward error correction (see above) */ - Modulation QAM; /* modulation type (see above) */ -} QAMParameters; -\end{verbatim} -DVB-T frontends are supported by the OFDMParamters structure -\begin{verbatim} -typedef struct { - BandWidth bandWidth; - CodeRate HP_CodeRate; /* high priority stream code rate */ - CodeRate LP_CodeRate; /* low priority stream code rate */ - Modulation Constellation; /* modulation type (see above) */ - TransmitMode TransmissionMode; - GuardInterval guardInterval; - Hierarchy HierarchyInformation; -} OFDMParameters; -\end{verbatim} - -In the case of QPSK frontends the Frequency field specifies the intermediate -frequency, i.e. the offset which is effectively added to the local oscillator -frequency (LOF) of the LNB. -The intermediate frequency has to be specified in units of kHz. -For QAM and OFDM frontends the Frequency specifies the absolute frequency -and is given in Hz. - -The Inversion field can take one of these values: -\begin{verbatim} -typedef enum { - INVERSION_OFF, - INVERSION_ON, - INVERSION_AUTO -} SpectralInversion; -\end{verbatim} -It indicates if spectral inversion should be presumed or not. -In the automatic setting (\verb INVERSION_AUTO) the hardware will -try to figure out the correct setting by itself. - -\noindent -The possible values for the FEC\_inner field are -\begin{verbatim} -enum { - FEC_AUTO, - FEC_1_2, - FEC_2_3, - FEC_3_4, - FEC_5_6, - FEC_7_8, - FEC_NONE -}; -\end{verbatim} -which correspond to error correction rates of $1\over 2$, $2\over 3$, etc., -no error correction or auto detection. - -\noindent -For cable and terrestrial frontends (QAM and OFDM) one also has to -specify the quadrature modulation mode which can be one of the following: -\begin{verbatim} -typedef enum -{ QPSK, - QAM_16, - QAM_32, - QAM_64, - QAM_128, - QAM_256 -} QAM_TYPE; -\end{verbatim} - -Finally, there are several more parameters for OFDM: -\begin{verbatim} -typedef enum { - TRANSMISSION_MODE_2K, - TRANSMISSION_MODE_8K -} TransmitMode; -\end{verbatim} - -\begin{verbatim} -typedef enum { - BANDWIDTH_8_MHZ, - BANDWIDTH_7_MHZ, - BANDWIDTH_6_MHZ -} BandWidth; -\end{verbatim} - -\begin{verbatim} -typedef enum { - GUARD_INTERVAL_1_32, - GUARD_INTERVAL_1_16, - GUARD_INTERVAL_1_8, - GUARD_INTERVAL_1_4 -} GuardInterval; -\end{verbatim} - -\begin{verbatim} -typedef enum { - HIERARCHY_NONE, - HIERARCHY_1, - HIERARCHY_2, - HIERARCHY_4 -} Hierarchy; -\end{verbatim} - - -\devsubsubsec{frontend events} -\label{frontendevents} - -\begin{verbatim} -enum { - FE_UNEXPECTED_EV, - FE_COMPLETION_EV, - FE_FAILURE_EV -}; -\end{verbatim} - -\begin{verbatim} -typedef struct { - EventType type; /* type of event, FE_UNEXPECTED_EV, ... */ - long timestamp; /* time in seconds since 1970-01-01 */ - - union { - struct { - FrontendStatus previousStatus; /* status before event */ - FrontendStatus currentStatus; /* status during event */ - } unexpectedEvent; - FrontendParameters completionEvent; /* parameters for which the - tuning succeeded */ - FrontendStatus failureEvent; /* status at failure (e.g. no lock) */ - } u; -} FrontendEvent; -\end{verbatim} - -\begin{verbatim} -struct qpskRegister { - uint8_t chipId; - uint8_t address; - uint8_t value; -}; -\end{verbatim} - -\begin{verbatim} -struct qamRegister { - uint8_t chipId; - uint8_t address; - uint8_t value; -}; -\end{verbatim} - -\begin{verbatim} -struct qpskFrontendInfo { - uint32_t minFrequency; - uint32_t maxFrequency; - uint32_t maxSymbolRate; - uint32_t minSymbolRate; - uint32_t hwType; - uint32_t hwVersion; -}; -\end{verbatim} - -\begin{verbatim} -struct qamFrontendInfo { - uint32_t minFrequency; - uint32_t maxFrequency; - uint32_t maxSymbolRate; - uint32_t minSymbolRate; - uint32_t hwType; - uint32_t hwVersion; -}; -\end{verbatim} - -\begin{verbatim} -typedef enum { - FE_POWER_ON, - FE_POWER_STANDBY, - FE_POWER_SUSPEND, - FE_POWER_OFF -} powerState_t; -\end{verbatim} - - -\clearpage - - -\devsubsec{Frontend Function Calls} - -\function{open()}{ - int open(const char *deviceName, int flags);}{ - This system call opens a named frontend device (e.g. /dev/ost/qpskfe - for a satellite frontend or /dev/ost/qamfe for a cable frontend) - for subsequent use. - - The device can be opened in read-only mode, which only allows - monitoring of device status and statistics, or read/write mode, which allows - any kind of use (e.g. performing tuning operations.) - - In a system with multiple front-ends, it is usually the case that multiple - devices cannot be open in read/write mode simultaneously. As long as a - front-end device is opened in read/write mode, other open() calls in - read/write mode will either fail or block, depending on whether - non-blocking or blocking mode was specified. - A front-end 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. - When an open() call has succeeded, the device will be ready for use in the - specified mode. This implies that the corresponding hardware is powered up, - and that other front-ends may have been powered down to make that possible. - - }{ - 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 front-end device. - After closing a front-end device, its corresponding hardware might be - powered down automatically, but only when this is needed to open - another front-end device. - To affect an unconditional power down, it should be done explicitly using - the OST\_SET\_POWER\_STATE ioctl. - }{ - int fd & File descriptor returned by a previous call to open().\\ - }{ - EBADF & fd is not a valid open file descriptor.\\ -} - -\ifunction{OST\_SELFTEST}{ - int ioctl(int fd, int request = OST\_SELFTEST);}{ - This ioctl call initiates an automatic self-test of the front-end hardware. - This call requires read/write access to the device. - }{ - int fd & File descriptor returned by a previous call to open().\\ - int request & Equals OST\_SELFTEST for this command.\\ - }{ - -1& Self test failure.\\ -} - -\ifunction{OST\_SET\_POWER\_STATE}{ - int ioctl(int fd, int request = OST\_SET\_POWER\_STATE, uint32\_t state);}{ - This ioctl call, implemented in many OST device drivers, enables direct - control over the power state of the hardware device, which may be on, off, - standby, or suspend. The latter two are low-power modes, which disable all - functionality of the device until turned on again. In contrast to the off - state, however, the standby and suspend states resume operation in the same - state as when the device was active. The only difference between the standby - and suspend states is a different tradeoff between resume time and power - consumption. Power consumption may be lower in the suspend state at the - cost of a longer resume time.\\ - A device that implements this call does not necessarily support two low-power - modes. If it only supports one low-power state, or none at all, the - OST\_SET\_POWER\_STATE operation for the missing states will - still succeed, but - it will be mapped to an existing state as per this table: \\ - \begin{center} - \begin{tabular}[h]{cll} - number of low-power & requested state & resulting state\\ - states supported &&\\ - \\ - 1 & standby & suspend \\ - 1 & suspend & suspend \\ - 0 & standby & on \\ - 0 & suspend & on - \end{tabular} - \end{center}\\ - For other cases where a required state is missing, an error code will be - returned. This can happen if a device does not support the power-off state, - but nevertheless implements this ioctl operation for control of low-power - states. - When opening a device in read/write mode, the driver ensures that the - corresponding hardware device is turned on initially. If the device is - later turned off or put in suspend mode, it has to be explicitly turned on - again.\\ - This call requires read/write access to the device. (Note that the power - management driver can affect the power state of devices without using this - ioctl operation, so having exclusive read/write access to a device does not - imply total control over the power state.) - }{ - int fd & File descriptor returned by a previous call to open().\\ - int request & Equals OST\_SET\_POWER\_STATE for this command.\\ - uint32\_t state & Requested power state. One of: \\ - & - \begin{tabular}[h]{ll} - OST\_POWER\_ON& turn power on\\ - OST\_POWER\_STANDBY& set device in standby mode\\ - OST\_POWER\_SUSPEND& set device in suspend mode\\ - OST\_POWER\_OFF& turn power off\\ - \end{tabular} - }{ - EBADF& fd is not a valid open file descriptor.\\ - EINVAL& Illegal state, or not available on this device.\\ - EPERM & Permission denied (needs read/write access).\\ - ENOSYS& Function not available for this device. -} - -\ifunction{FE\_GET\_POWER\_STATE}{ - int ioctl(int fd, int request = OST\_GET\_POWER\_STATE, uint32\_t *state);}{ - This ioctl call, implemented in many OST device drivers, obtains the power - state of the hardware device, which may be on, off, standby, or suspend. - A device that implements this call does not necessarily support all four states. - If there is only one low-power state, the suspend state will be returned for - that state. If there is no low-power state, the on state will be reported - standby and suspend states will be equivalent to the on state. - For this command, read-only access to the device is sufficient. - }{ - int fd & File descriptor returned by a previous call to open().\\ - int request & Equals OST\_GET\_POWER\_STATE for this command.\\ - uint32\_t *state & Requested power state. One of: \\ - & - \begin{tabular}[h]{ll} - OST\_POWER\_ON& power is on\\ - OST\_POWER\_STANDBY& device in standby mode\\ - OST\_POWER\_SUSPEND& device in suspend mode\\ - OST\_POWER\_OFF& power is off\\ - \end{tabular} - }{ - EBADF& fd is not a valid open file descriptor.\\ - EINVAL& Illegal state, or not available on this device.\\ - EFAULT& state points to invalid address.\\ - ENOSYS& Function not available for this device. -} - -\ifunction{FE\_READ\_STATUS}{ - int ioctl(int fd, int request = FE\_READ\_STATUS, feStatus *status);}{ - This ioctl call returns status information about the front-end. - This call only requires read-only access to the device. - }{ - int fd & File descriptor returned by a previous call to open().\\ - int request & Equals FE\_READ\_STATUS for this command.\\ - struct feStatus *status&Points to the location where the front-end - status word is to be stored. - }{ - EBADF& fd is not a valid open file descriptor.\\ - EFAULT& status points to invalid address.\\ -} - -\ifunction{FE\_READ\_BER}{ - int ioctl(int fd, int request = FE\_READ\_BER, uint32\_t *ber);}{ - This ioctl call returns the bit error rate for the signal currently - received/demodulated by the front-end. For this command, read-only access - to the device is sufficient. - }{ - int fd & File descriptor returned by a previous call to open().\\ - int request & Equals FE\_READ\_BER for this command.\\ - uint32\_t *ber & The bit error rate, as a multiple of $10^{-9}$, - is stored into *ber.\\ - & Example: a value of 2500 corresponds to a bit error - rate of $2.5\cdot 10^{-6}$, or 1 error in 400000 bits. - }{ - EBADF& fd is not a valid open file descriptor.\\ - EFAULT& ber points to invalid address.\\ - ENOSIGNAL& There is no signal, thus no meaningful bit error - rate. Also returned if the front-end is not turned on.\\ - ENOSYS& Function not available for this device. -} - -\ifunction{FE\_READ\_SNR}{ - int ioctl(int fd, int request = FE\_READ\_SNR, int32\_t *snr);}{ - This ioctl call returns the signal-to-noise ratio for the signal currently - received by the front-end. For this command, read-only access to the device - is sufficient. - }{ - int fd & File descriptor returned by a previous call to open().\\ - int request & Equals FE\_READ\_SNR for this command.\\ - int32\_t *snr& The signal-to-noise ratio, as a multiple of - $10^{-6}$ dB, is stored into *snr.\\ - & Example: a value of 12,300,000 corresponds - to a signal-to-noise ratio of 12.3 dB. -}{ - EBADF& fd is not a valid open file descriptor.\\ - EFAULT& snr points to invalid address.\\ - ENOSIGNAL& There is no signal, thus no meaningful signal - strength value. Also returned if front-end is not turned on.\\ - ENOSYS& Function not available for this device. -} - -\ifunction{FE\_READ\_SIGNAL\_STRENGTH}{ - int ioctl( int fd, int request = FE\_READ\_SIGNAL\_STRENGTH, int32\_t *strength); -}{ -This ioctl call returns the signal strength value for the signal currently -received by the front-end. For this command, read-only access to the device -is sufficient. -}{ -int fd & File descriptor returned by a previous call to open().\\ -int request & Equals FE\_READ\_SIGNAL\_STRENGTH for this command.\\ -int32\_t *strength & The signal strength value, as a multiple of - $10^{-6 }$ dBm, - is stored into *strength. \\ - &Example: a value of -12,500,000 corresponds to a signal - strength value of -12.5 dBm. -}{ - EBADF& fd is not a valid open file descriptor.\\ - EFAULT& status points to invalid address.\\ - ENOSIGNAL& There is no signal, thus no meaningful signal - strength value. Also returned if front-end is not turned on.\\ - ENOSYS& Function not available for this device. -} - -\ifunction{FE\_READ\_UNCORRECTED\_BLOCKS}{ - int ioctl( int fd, int request = FE\_READ\_UNCORRECTED\_BLOCKS, uint32\_t *ublocks); }{ - This ioctl call returns the number of uncorrected blocks detected by - the device driver during its lifetime. - For meaningful measurements, the increment in - block count during a specific time interval should be calculated. - For this command, read-only access to the device is sufficient.\\ - Note that the counter will wrap to zero after its maximum count has - been reached. -}{ -int fd & File descriptor returned by a previous call to open().\\ -int request & Equals FE\_READ\_UNCORRECTED\_BLOCKS for this command.\\ -uint32\_t *ublocks & The total number of uncorrected blocks seen -by the driver so far. -}{ - EBADF& fd is not a valid open file descriptor.\\ - EFAULT& ublocks points to invalid address.\\ - ENOSYS& Function not available for this device. -} - - -\ifunction{FE\_GET\_NEXT\_FREQUENCY}{ - int ioctl( int fd, int request = FE\_GET\_NEXT\_FREQUENCY, uint32\_t *freq);}{ - When scanning a frequency range, it is desirable to use a scanning step size - that is as large as possible, yet small enough to be able to lock to any signal - within the range. - This ioctl operation does just that - it increments a given frequency by a - step size suitable for efficient scanning. - The step size used by this function may be a quite complex function of the given - frequency, hardware capabilities, and parameter settings of the device. Thus, a - returned result is only valid for the current state of the device. - For this command, read-only access to the device is sufficient.\\ - Note that scanning may still be excruciatingly slow on some hardware, for - other reasons than a non-optimal scanning step size. - }{ - int fd & File descriptor returned by a previous call to open().\\ - int request & Equals FE\_GET\_NEXT\_FREQUENCY for this command.\\ - uint32\_t *freq& Input: a given frequency \\ - & Output: the frequency corresponding to - the next higher frequency setting.\\ - }{ - EBADF& fd is not a valid open file descriptor.\\ - EFAULT& freq points to invalid address.\\ - EINVAL& Maximum supported frequency reached.\\ - ENOSYS& Function not available for this device. -} - -\ifunction{FE\_GET\_NEXT\_SYMBOL\_RATE}{ - int ioctl( int fd, int request = FE\_GET\_NEXT\_SYMBOL\_RATE, uint32\_t *symbolRate); - }{ - When scanning a range of symbol rates (e.g. for "blind acquisition") it is - desirable to use a scanning step size that is as large as possible, yet - small enough to detect any valid signal within the range. This ioctl - operation does just that - it increments a given symbol rate by a step size - suitable for efficient scanning. - The step size used by this function may be a quite complex function of the given - symbol rate, hardware capabilities, and parameter settings of the device. - Thus, a returned result is only valid for the current state of the device. - For this command, read-only access to the device is sufficient. - }{ - int fd & File descriptor returned by a previous call to open().\\ - int request & Equals FE\_GET\_NEXT\_SYMBOL\_RATE for this command.\\ - uint32\_t *symbolRate& Input: a given symbol rate \\ - & Output: the symbol rate corresponding to - the next higher symbol rate.\\ - }{ - EBADF& fd is not a valid open file descriptor.\\ - EFAULT& symbolRate points to invalid address.\\ - EINVAL& Maximum supported symbol rate reached.\\ - ENOSYS& Function not available for this device. -} - -\ifunction{FE\_SET\_FRONTEND}{ - int ioctl(int fd, int request = FE\_SET\_FRONTEND, struct FrontendParameters *p);}{ - This ioctl call starts a tuning operation using specified parameters. - The result of this call will be successful if the parameters were valid and - the tuning could be initiated. - The result of the tuning operation in itself, however, will arrive - asynchronously as an event (see documentation for FE\_GET\_EVENT - and FrontendEvent.) - If a new FE\_SET\_FRONTEND operation is initiated before the previous - one was completed, - the previous operation will be aborted in favor of the new one. - This command requires read/write access to the device. - }{ - int fd & File descriptor returned by a previous call to open().\\ - int request & Equals FE\_SET\_FRONTEND for this command.\\ - struct FrontendParameters *p& Points to parameters for tuning operation.\\ - }{ - EBADF& fd is not a valid open file descriptor.\\ - EFAULT& p points to invalid address.\\ - EINVAL& Maximum supported symbol rate reached.\\ -} - -\ifunction{FE\_GET\_EVENT}{ - int ioctl(int fd, int request = QPSK\_GET\_EVENT, struct qpskEvent *ev);}{ - This ioctl call returns an event of type qpskEvent 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. - Since the event queue allocated is rather small (room for 8 events), the queue - must be serviced regularly to avoid overflow. If an overflow happens, the - oldest event is discarded from the queue, and an error (EBUFFEROVERFLOW) occurs - the next time the queue is read. After reporting the error condition in this - fashion, subsequent QPSK\_GET\_EVENT calls will return events from the queue as - usual.\\ - For the sake of implementation simplicity, this command requires read/write - access to the device. - }{ - int fd & File descriptor returned by a previous call to open().\\ - int request & Equals QPSK\_GET\_EVENT for this command.\\ - struct qpskEvent *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{FE\_GET\_INFO}{ - int ioctl(int fd, int request = FE\_GET\_INFO, struct FrontendInfo *info);}{ - This ioctl call returns information about the front-end. - This call only requires read-only access to the device. - }{ - int fd & File descriptor returned by a previous call to open().\\ - int request & Equals FE\_GET\_INFO for this command.\\ - struct qpskFrontendInfo *info & Points to the location where the front-end - information is to be stored. - }{ - EBADF& fd is not a valid open file descriptor.\\ - EFAULT& info points to invalid address.\\ -} - -%%% Local Variables: -%%% mode: latex -%%% TeX-master: "dvbapi" -%%% End: diff --git a/dvb-spec/dvbapi/getbb b/dvb-spec/dvbapi/getbb deleted file mode 100755 index 004714d3a..000000000 --- a/dvb-spec/dvbapi/getbb +++ /dev/null @@ -1,12 +0,0 @@ -#!/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 deleted file mode 100644 index 1d859fadb..000000000 --- a/dvb-spec/dvbapi/intro.tex +++ /dev/null @@ -1,183 +0,0 @@ -\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 streams 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/frontend}, -\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. - -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 not belong 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/frontend0 - demux0 - -/dev/dvb/card1/video0 - audio0 - demux0 - demux1 - frontend0 - 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 deleted file mode 100644 index 59490299b..000000000 --- a/dvb-spec/dvbapi/kdapi.tex +++ /dev/null @@ -1,1007 +0,0 @@ -\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} - - -\label{sectionfilter} -\begin{verbatim} -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 deleted file mode 100644 index 88342c3a6..000000000 --- a/dvb-spec/dvbapi/sec.tex +++ /dev/null @@ -1,282 +0,0 @@ -\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\_SEND\_SEQUENCE}{ -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 deleted file mode 100644 index 574464d23..000000000 --- a/dvb-spec/dvbapi/title.tex +++ /dev/null @@ -1,24 +0,0 @@ -\pagenumbering{arabic} -\pagestyle{empty} -\title{\huge\textbf{LINUX DVB API}} - -\author{ -\includegraphics{cimlogo.psi}\\ - Convergence integrated media GmbH\\\\ - Dr. Ralph J.K. Metzler\\ - \texttt{}\\\\ - Dr. Marcus O.C. Metzler\\ - \texttt{} -% Rosenthalerstr. 51\\ -% 10178 Berlin\\Germany -} -\date{02/14/2002\\V 0.9.4} -\maketitle - -\newpage - -%\end{titlepage} -% Local Variables: -% mode: latex -% TeX-master: "dvbapi" -% End: diff --git a/dvb-spec/dvbapi/video.tex b/dvb-spec/dvbapi/video.tex deleted file mode 100644 index 2659db238..000000000 --- a/dvb-spec/dvbapi/video.tex +++ /dev/null @@ -1,686 +0,0 @@ -\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. Please note that some DVB cards don't have their own -MPEG decoder, which results in the omission of the audio and video -device as well as the video4linux device. - -\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: -- cgit v1.2.3 From 5a523e605b9b6d1ae50d0707c1874c5b7f0959cc Mon Sep 17 00:00:00 2001 From: holger Date: Thu, 10 Oct 2002 16:22:27 -0300 Subject: the new HEAD --- dvb-spec/dvbapi/.cvsignore | 11 + dvb-spec/dvbapi/Makefile | 30 ++ dvb-spec/dvbapi/audio.tex | 442 ++++++++++++++++++ dvb-spec/dvbapi/bibsection.sty | 29 ++ dvb-spec/dvbapi/ca.tex | 127 +++++ dvb-spec/dvbapi/cimlogo.psi | 122 +++++ dvb-spec/dvbapi/demux.tex | 392 ++++++++++++++++ dvb-spec/dvbapi/devices.tex | 12 + dvb-spec/dvbapi/dvbapi.tex | 166 +++++++ dvb-spec/dvbapi/dvbstb.fig | 59 +++ dvb-spec/dvbapi/examples.tex | 366 +++++++++++++++ dvb-spec/dvbapi/fig2pstex | 6 + dvb-spec/dvbapi/frontend.tex | 630 +++++++++++++++++++++++++ dvb-spec/dvbapi/getbb | 12 + dvb-spec/dvbapi/intro.tex | 183 ++++++++ dvb-spec/dvbapi/kdapi.tex | 1007 ++++++++++++++++++++++++++++++++++++++++ dvb-spec/dvbapi/sec.tex | 282 +++++++++++ dvb-spec/dvbapi/title.tex | 24 + dvb-spec/dvbapi/video.tex | 686 +++++++++++++++++++++++++++ 19 files changed, 4586 insertions(+) create mode 100644 dvb-spec/dvbapi/.cvsignore create mode 100644 dvb-spec/dvbapi/Makefile create mode 100644 dvb-spec/dvbapi/audio.tex create mode 100644 dvb-spec/dvbapi/bibsection.sty create mode 100644 dvb-spec/dvbapi/ca.tex create mode 100644 dvb-spec/dvbapi/cimlogo.psi create mode 100644 dvb-spec/dvbapi/demux.tex create mode 100644 dvb-spec/dvbapi/devices.tex create mode 100644 dvb-spec/dvbapi/dvbapi.tex create mode 100644 dvb-spec/dvbapi/dvbstb.fig create mode 100644 dvb-spec/dvbapi/examples.tex create mode 100755 dvb-spec/dvbapi/fig2pstex create mode 100644 dvb-spec/dvbapi/frontend.tex create mode 100755 dvb-spec/dvbapi/getbb create mode 100644 dvb-spec/dvbapi/intro.tex create mode 100644 dvb-spec/dvbapi/kdapi.tex create mode 100644 dvb-spec/dvbapi/sec.tex create mode 100644 dvb-spec/dvbapi/title.tex create mode 100644 dvb-spec/dvbapi/video.tex (limited to 'dvb-spec/dvbapi') diff --git a/dvb-spec/dvbapi/.cvsignore b/dvb-spec/dvbapi/.cvsignore new file mode 100644 index 000000000..fb6974f6b --- /dev/null +++ b/dvb-spec/dvbapi/.cvsignore @@ -0,0 +1,11 @@ +dvbapi.ps +dvbstb.ps +dvbstb.pst +dvbapi.bbl +dvbapi.aux +dvbapi.blg +dvbapi.dvi +dvbapi.log +dvbapi.pdf +dvbapi.out +dvbapi.toc diff --git a/dvb-spec/dvbapi/Makefile b/dvb-spec/dvbapi/Makefile new file mode 100644 index 000000000..aae688f33 --- /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 -o $@ $< + +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..7b6427094 --- /dev/null +++ b/dvb-spec/dvbapi/audio.tex @@ -0,0 +1,442 @@ +\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 +} audio_stream_source_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 +} audio_play_state_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, +} audio_channel_select_t; +\end{verbatim} + +\devsubsubsec{audio_status\_t} +\label{audiostatus} +The AUDIO\_GET\_STATUS call returns the following structure informing +about various states of the playback operation. +\begin{verbatim} +typedef struct audio_status { + boolean AV_sync_state; + boolean mute_state; + audio_play_state_t play_state; + audio_stream_source_t stream_source; + audio_channel_select_t channel_select; + boolean bypass_mode; +} audio_status_t; +\end{verbatim} + +\devsubsubsec{audio_mixer\_t} +\label{audiomixer} +The following structure is used by the AUDIO\_SET\_MIXER call to set +the audio volume. +\begin{verbatim} +typedef struct audio_mixer { + unsigned int volume_left; + unsigned int volume_right; +} audio_mixer_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 audio_karaoke{ /* 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 */ +} audio_karaoke_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 audio_attributes_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 audio_status *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 audio_status *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. If no audio stream type is set + the id has to be in [0xC0,0xDF] for MPEG sound, in [0x80,0x87] for + AC3 and in [0xA0,0xA7] for LPCM. More specifications may follow + for other stream types. If the stream type is set the id just + specifies the substream id of the audio stream and only the first 5 + bits are recognized. + }{ + 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, audio_mixer\_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.\\ + audio_mixer\_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 LPCM 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 extension id for MPEG streams in + DVD playback. Only the first 3 bits are recognized. + }{ + 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, audio_karaoke\_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.\\ + audio_karaoke\_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..3607bbffc --- /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 +} dmx_output_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. */ +} dmx_input_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 +} dmx_pes_type_t; +\end{verbatim} + + +\devsubsubsec{dmx_event\_t} +\label{dmxeventt} + +\begin{verbatim} +typedef enum +{ + DMX_SCRAMBLING_EV, + DMX_FRONTEND_EV +} dmx_event_t; +\end{verbatim} + + +\devsubsubsec{dmxScramblingStatus\_t} +\label{dmxscramblingstatus} + +\begin{verbatim} +typedef enum +{ + DMX_SCRAMBLING_OFF, + DMX_SCRAMBLING_ON +} dmx_scrambling_status_t; +\end{verbatim} + + +\devsubsubsec{dmx_filter\_t} +\label{dmxfilter} + +\begin{verbatim} +typedef struct dmx_filter +{ + uint8_t filter[DMX_FILTER_SIZE]; + uint8_t mask[DMX_FILTER_SIZE]; +} dmx_filter_t; +\end{verbatim} + + +\devsubsubsec{dmx_sct_filter_params} +\label{dmxsctfilterparams} + +\begin{verbatim} +struct dmx_sct_filter_params +{ + dvb_pid_t pid; + dmx_filter_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{dmx_pes_filter_params} +\label{dmxpesfilterparams} + +\begin{verbatim} +struct dmx_pes_filter_params +{ + dvb_pid_t pid; + dmx_input_t input; + dmx_output_t output; + dmx_pes_type_t pesType; + uint32_t flags; +}; +\end{verbatim} + + +\devsubsubsec{dmx_event} +\label{dmxevent} + +\begin{verbatim} +struct dmx_event +{ + dmx_event_t event; + time_t timeStamp; + union + { + dmx_scrambling_status_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 dmx_sct_filter_params *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 dmx_sct_filter_params *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 dmx_pes_filter_params *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 dmx_pes_filter_params *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 dmx_event *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 dmx_event *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..ad0251c01 --- /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 2002 convergence 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..ea2797481 --- /dev/null +++ b/dvb-spec/dvbapi/examples.tex @@ -0,0 +1,366 @@ +\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 +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#define DMX "/dev/ost/demux" +#define FRONT "/dev/ost/frontend" +#define SEC "/dev/ost/sec" + +/* routine for checking if we have a signal and other status information*/ +int FEReadStatus(int fd, fe_status_t *stat) +{ + int ans; + + if ( (ans = ioctl(fd,FE_READ_STATUS,stat) < 0)){ + perror("FE READ STATUS: "); + return -1; + } + + if (*stat & FE_HAS_POWER) + printf("FE HAS POWER\n"); + + if (*stat & FE_HAS_SIGNAL) + printf("FE HAS SIGNAL\n"); + + if (*stat & FE_SPECTRUM_INV) + printf("SPEKTRUM INV\n"); + + return 0; +} + + +/* 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 dmx_pes_filter_params pesFilterParams; + FrontendParameters frp; + struct pollfd pfd[1]; + FrontendEvent event; + int demux1, dmeux2, demux3, front, + + frequency = (uint32_t) freq; + symbolrate = (uint32_t) srate; + + if((front = open(FRONT,O_RDWR)) < 0){ + perror("FRONTEND DEVICE: "); + return -1; + } + + if((sec = open(SEC,O_RDWR)) < 0){ + perror("SEC DEVICE: "); + return -1; + } + + if (demux1 < 0){ + if ((demux1=open(DMX, O_RDWR|O_NONBLOCK)) + < 0){ + perror("DEMUX DEVICE: "); + return -1; + } + } + + if (demux2 < 0){ + if ((demux2=open(DMX, O_RDWR|O_NONBLOCK)) + < 0){ + perror("DEMUX DEVICE: "); + return -1; + } + } + + if (demux3 < 0){ + if ((demux3=open(DMX, O_RDWR|O_NONBLOCK)) + < 0){ + perror("DEMUX DEVICE: "); + return -1; + } + } + + if (freq < lnb_slof) { + frp.Frequency = (freq - lnb_lof1); + scmds.continuousTone = SEC_TONE_OFF; + } else { + frp.Frequency = (freq - lnb_lof2); + scmds.continuousTone = SEC_TONE_ON; + } + frp.Inversion = INVERSION_AUTO; + if (pol) scmds.voltage = SEC_VOLTAGE_18; + else scmds.voltage = SEC_VOLTAGE_13; + + 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; + if (ioctl(sec, SEC_SEND_SEQUENCE, &scmds) < 0){ + perror("SEC SEND: "); + return -1; + } + + if (ioctl(sec, SEC_SEND_SEQUENCE, &scmds) < 0){ + perror("SEC SEND: "); + return -1; + } + + frp.u.qpsk.SymbolRate = srate; + frp.u.qpsk.FEC_inner = fec; + + if (ioctl(front, FE_SET_FRONTEND, &frp) < 0){ + perror("QPSK TUNE: "); + return -1; + } + + 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, FE_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"); + } + } + } + + + 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; + } + + return has_signal(fds); +} + +\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 +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#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 dmx_pes_filter_params pesFilterParams; + + if (demux1 < 0){ + if ((demux1=open(DMX, O_RDWR|O_NONBLOCK)) + < 0){ + perror("DEMUX DEVICE: "); + return -1; + } + } + + if (demux2 < 0){ + if ((demux2=open(DMX, 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/frontend.tex b/dvb-spec/dvbapi/frontend.tex new file mode 100644 index 000000000..cb3285d06 --- /dev/null +++ b/dvb-spec/dvbapi/frontend.tex @@ -0,0 +1,630 @@ +\devsec{DVB Frontend API} + +The DVB frontend device controls the tuner and DVB demodulator hardware. +It can be accessed through \texttt{/dev/ost/frontend}. +If you are using \texttt{devfs} you can use \texttt{/dev/dvb/card0/frontend}. +The frontend device will only be made visible through \texttt{devfs} +if the corresponding card actually has a frontend. Cards which support +the DVB API but, e.g., only can play back recordings, will not offer the +frontend device. + +\devsubsec{Frontend Data Types} + +\devsubsubsec{frontend status} +\label{frontendstatus} + +Several functions of the frontend device use the feStatus data +type defined by +\begin{verbatim} +typedef uint32_t feStatus; +\end{verbatim} +to indicate the current state and/or state changes of +the frontend hardware. + +\noindent +It can take on the values +\begin{verbatim} +#define FE_HAS_POWER 1 +#define FE_HAS_SIGNAL 2 +#define FE_SPECTRUM_INV 4 +#define FE_HAS_LOCK 8 +#define FE_HAS_CARRIER 16 +#define FE_HAS_VITERBI 32 +#define FE_HAS_SYNC 64 +#define TUNER_HAS_LOCK 128 +\end{verbatim} +which can be ORed together and have the following meaning: + +\medskip + +\begin{tabular}{lp{11cm}} +FE\_HAS\_POWER & the frontend is powered up and is ready to be used\\ +FE\_HAS\_SIGNAL & the frontend detects a signal above the normal noise level\\ +FE\_SPECTRUM\_INV & spectrum inversion is enabled/was necessary for lock\\ +FE\_HAS\_LOCK & frontend successfully locked to a DVB signal \\ +FE\_HAS\_CARRIER & carrier detected in signal\\ +FE\_HAS\_VITERBI & lock at viterbi decoder stage\\ +FE\_HAS\_SYNC & TS sync bytes detected \\ +TUNER\_HAS\_LOCK & the tuner has a frequency lock +\end{tabular} + + +\devsubsubsec{frontend parameters} +\label{frontendparameters} + +The kind of parameters passed to the frontend device for tuning +depend on the kind of hardware you are using. +All kinds of parameters are combined as a union in the +FrontendParameters structure: +\begin{verbatim} +typedef struct { + __u32 Frequency; /* (absolute) frequency in Hz for QAM/OFDM */ + /* intermediate frequency in kHz for QPSK */ + fe_spectral_inversion_t Inversion; /* spectral inversion */ + union { + QPSKParameters qpsk; + QAMParameters qam; + OFDMParameters ofdm; + } u; +} FrontendParameters; +\end{verbatim} + +For satellite QPSK frontends you have to use QPSKParameters defined by +\begin{verbatim} +typedef struct { + __u32 SymbolRate; /* symbol rate in Symbols per second */ + fe_code_rate_t FEC_inner; /* forward error correction (see above) */ +} QPSKParameters; +\end{verbatim} +for cable QAM frontend you use the QAMParameters structure +\begin{verbatim} +typedef struct { + __u32 SymbolRate; /* symbol rate in Symbols per second */ + fe_code_rate_t FEC_outer; /* forward error correction (see above) */ + fe_code_rate_t FEC_inner; /* forward error correction (see above) */ + fe_modulation_t QAM; /* modulation type (see above) */ +} QAMParameters; +\end{verbatim} +DVB-T frontends are supported by the OFDMParamters structure +\begin{verbatim} +typedef struct { + fe_bandwidth_t bandWidth; + fe_code_rate_t HP_fe_code_rate_t; /* high priority stream code rate */ + fe_code_rate_t LP_fe_code_rate_t; /* low priority stream code rate */ + fe_modulation_t Constellation; /* modulation type (see above) */ + fe_transmit_mode_t TransmissionMode; + fe_guard_interval_t guardInterval; + fe_hierarchy_t fe_hierarchy_tInformation; +} OFDMParameters; +\end{verbatim} + +In the case of QPSK frontends the Frequency field specifies the intermediate +frequency, i.e. the offset which is effectively added to the local oscillator +frequency (LOF) of the LNB. +The intermediate frequency has to be specified in units of kHz. +For QAM and OFDM frontends the Frequency specifies the absolute frequency +and is given in Hz. + +The Inversion field can take one of these values: +\begin{verbatim} +typedef enum { + INVERSION_OFF, + INVERSION_ON, + INVERSION_AUTO +} fe_spectral_inversion_t; +\end{verbatim} +It indicates if spectral inversion should be presumed or not. +In the automatic setting (\verb INVERSION\_AUTO) the hardware will +try to figure out the correct setting by itself. + +\noindent +The possible values for the FEC\_inner field are +\begin{verbatim} +enum { + FEC_AUTO, + FEC_1_2, + FEC_2_3, + FEC_3_4, + FEC_5_6, + FEC_7_8, + FEC_NONE +}; +\end{verbatim} +which correspond to error correction rates of $1\over 2$, $2\over 3$, etc., +no error correction or auto detection. + +\noindent +For cable and terrestrial frontends (QAM and OFDM) one also has to +specify the quadrature modulation mode which can be one of the following: +\begin{verbatim} +typedef enum +{ QPSK, + QAM_16, + QAM_32, + QAM_64, + QAM_128, + QAM_256 +} QAM_TYPE; +\end{verbatim} + +Finally, there are several more parameters for OFDM: +\begin{verbatim} +typedef enum { + TRANSMISSION_MODE_2K, + TRANSMISSION_MODE_8K +} fe_transmit_mode_t; +\end{verbatim} + +\begin{verbatim} +typedef enum { + BANDWIDTH_8_MHZ, + BANDWIDTH_7_MHZ, + BANDWIDTH_6_MHZ +} fe_bandwidth_t; +\end{verbatim} + +\begin{verbatim} +typedef enum { + GUARD_INTERVAL_1_32, + GUARD_INTERVAL_1_16, + GUARD_INTERVAL_1_8, + GUARD_INTERVAL_1_4 +} fe_guard_interval_t; +\end{verbatim} + +\begin{verbatim} +typedef enum { + HIERARCHY_NONE, + HIERARCHY_1, + HIERARCHY_2, + HIERARCHY_4 +} fe_hierarchy_t; +\end{verbatim} + + +\devsubsubsec{frontend events} +\label{frontendevents} + +\begin{verbatim} +enum { + FE_UNEXPECTED_EV, + FE_COMPLETION_EV, + FE_FAILURE_EV +}; +\end{verbatim} + +\begin{verbatim} +typedef struct { + EventType type; /* type of event, FE_UNEXPECTED_EV, ... */ + long timestamp; /* time in seconds since 1970-01-01 */ + + union { + struct { + fe_status_t previousStatus; /* status before event */ + fe_status_t currentStatus; /* status during event */ + } unexpectedEvent; + FrontendParameters completionEvent; /* parameters for which the + tuning succeeded */ + fe_status_t failureEvent; /* status at failure (e.g. no lock) */ + } u; +} FrontendEvent; +\end{verbatim} + +\begin{verbatim} +struct qpskRegister { + uint8_t chipId; + uint8_t address; + uint8_t value; +}; +\end{verbatim} + +\begin{verbatim} +struct qamRegister { + uint8_t chipId; + uint8_t address; + uint8_t value; +}; +\end{verbatim} + +\begin{verbatim} +struct qpskFrontendInfo { + uint32_t minFrequency; + uint32_t maxFrequency; + uint32_t maxSymbolRate; + uint32_t minSymbolRate; + uint32_t hwType; + uint32_t hwVersion; +}; +\end{verbatim} + +\begin{verbatim} +struct qamFrontendInfo { + uint32_t minFrequency; + uint32_t maxFrequency; + uint32_t maxSymbolRate; + uint32_t minSymbolRate; + uint32_t hwType; + uint32_t hwVersion; +}; +\end{verbatim} + +\begin{verbatim} +typedef enum { + FE_POWER_ON, + FE_POWER_STANDBY, + FE_POWER_SUSPEND, + FE_POWER_OFF +} powerState_t; +\end{verbatim} + + +\clearpage + + +\devsubsec{Frontend Function Calls} + +\function{open()}{ + int open(const char *deviceName, int flags);}{ + This system call opens a named frontend device (e.g. /dev/ost/qpskfe + for a satellite frontend or /dev/ost/qamfe for a cable frontend) + for subsequent use. + + The device can be opened in read-only mode, which only allows + monitoring of device status and statistics, or read/write mode, which allows + any kind of use (e.g. performing tuning operations.) + + In a system with multiple front-ends, it is usually the case that multiple + devices cannot be open in read/write mode simultaneously. As long as a + front-end device is opened in read/write mode, other open() calls in + read/write mode will either fail or block, depending on whether + non-blocking or blocking mode was specified. + A front-end 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. + When an open() call has succeeded, the device will be ready for use in the + specified mode. This implies that the corresponding hardware is powered up, + and that other front-ends may have been powered down to make that possible. + + }{ + 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 front-end device. + After closing a front-end device, its corresponding hardware might be + powered down automatically, but only when this is needed to open + another front-end device. + To affect an unconditional power down, it should be done explicitly using + the OST\_SET\_POWER\_STATE ioctl. + }{ + int fd & File descriptor returned by a previous call to open().\\ + }{ + EBADF & fd is not a valid open file descriptor.\\ +} + +\ifunction{OST\_SELFTEST}{ + int ioctl(int fd, int request = OST\_SELFTEST);}{ + This ioctl call initiates an automatic self-test of the front-end hardware. + This call requires read/write access to the device. + }{ + int fd & File descriptor returned by a previous call to open().\\ + int request & Equals OST\_SELFTEST for this command.\\ + }{ + -1& Self test failure.\\ +} + +\ifunction{OST\_SET\_POWER\_STATE}{ + int ioctl(int fd, int request = OST\_SET\_POWER\_STATE, uint32\_t state);}{ + This ioctl call, implemented in many OST device drivers, enables direct + control over the power state of the hardware device, which may be on, off, + standby, or suspend. The latter two are low-power modes, which disable all + functionality of the device until turned on again. In contrast to the off + state, however, the standby and suspend states resume operation in the same + state as when the device was active. The only difference between the standby + and suspend states is a different tradeoff between resume time and power + consumption. Power consumption may be lower in the suspend state at the + cost of a longer resume time.\\ + A device that implements this call does not necessarily support two low-power + modes. If it only supports one low-power state, or none at all, the + OST\_SET\_POWER\_STATE operation for the missing states will + still succeed, but + it will be mapped to an existing state as per this table: \\ + \begin{center} + \begin{tabular}[h]{cll} + number of low-power & requested state & resulting state\\ + states supported &&\\ + \\ + 1 & standby & suspend \\ + 1 & suspend & suspend \\ + 0 & standby & on \\ + 0 & suspend & on + \end{tabular} + \end{center}\\ + For other cases where a required state is missing, an error code will be + returned. This can happen if a device does not support the power-off state, + but nevertheless implements this ioctl operation for control of low-power + states. + When opening a device in read/write mode, the driver ensures that the + corresponding hardware device is turned on initially. If the device is + later turned off or put in suspend mode, it has to be explicitly turned on + again.\\ + This call requires read/write access to the device. (Note that the power + management driver can affect the power state of devices without using this + ioctl operation, so having exclusive read/write access to a device does not + imply total control over the power state.) + }{ + int fd & File descriptor returned by a previous call to open().\\ + int request & Equals OST\_SET\_POWER\_STATE for this command.\\ + uint32\_t state & Requested power state. One of: \\ + & + \begin{tabular}[h]{ll} + OST\_POWER\_ON& turn power on\\ + OST\_POWER\_STANDBY& set device in standby mode\\ + OST\_POWER\_SUSPEND& set device in suspend mode\\ + OST\_POWER\_OFF& turn power off\\ + \end{tabular} + }{ + EBADF& fd is not a valid open file descriptor.\\ + EINVAL& Illegal state, or not available on this device.\\ + EPERM & Permission denied (needs read/write access).\\ + ENOSYS& Function not available for this device. +} + +\ifunction{FE\_GET\_POWER\_STATE}{ + int ioctl(int fd, int request = OST\_GET\_POWER\_STATE, uint32\_t *state);}{ + This ioctl call, implemented in many OST device drivers, obtains the power + state of the hardware device, which may be on, off, standby, or suspend. + A device that implements this call does not necessarily support all four states. + If there is only one low-power state, the suspend state will be returned for + that state. If there is no low-power state, the on state will be reported + standby and suspend states will be equivalent to the on state. + For this command, read-only access to the device is sufficient. + }{ + int fd & File descriptor returned by a previous call to open().\\ + int request & Equals OST\_GET\_POWER\_STATE for this command.\\ + uint32\_t *state & Requested power state. One of: \\ + & + \begin{tabular}[h]{ll} + OST\_POWER\_ON& power is on\\ + OST\_POWER\_STANDBY& device in standby mode\\ + OST\_POWER\_SUSPEND& device in suspend mode\\ + OST\_POWER\_OFF& power is off\\ + \end{tabular} + }{ + EBADF& fd is not a valid open file descriptor.\\ + EINVAL& Illegal state, or not available on this device.\\ + EFAULT& state points to invalid address.\\ + ENOSYS& Function not available for this device. +} + +\ifunction{FE\_READ\_STATUS}{ + int ioctl(int fd, int request = FE\_READ\_STATUS, feStatus *status);}{ + This ioctl call returns status information about the front-end. + This call only requires read-only access to the device. + }{ + int fd & File descriptor returned by a previous call to open().\\ + int request & Equals FE\_READ\_STATUS for this command.\\ + struct feStatus *status&Points to the location where the front-end + status word is to be stored. + }{ + EBADF& fd is not a valid open file descriptor.\\ + EFAULT& status points to invalid address.\\ +} + +\ifunction{FE\_READ\_BER}{ + int ioctl(int fd, int request = FE\_READ\_BER, uint32\_t *ber);}{ + This ioctl call returns the bit error rate for the signal currently + received/demodulated by the front-end. For this command, read-only access + to the device is sufficient. + }{ + int fd & File descriptor returned by a previous call to open().\\ + int request & Equals FE\_READ\_BER for this command.\\ + uint32\_t *ber & The bit error rate, as a multiple of $10^{-9}$, + is stored into *ber.\\ + & Example: a value of 2500 corresponds to a bit error + rate of $2.5\cdot 10^{-6}$, or 1 error in 400000 bits. + }{ + EBADF& fd is not a valid open file descriptor.\\ + EFAULT& ber points to invalid address.\\ + ENOSIGNAL& There is no signal, thus no meaningful bit error + rate. Also returned if the front-end is not turned on.\\ + ENOSYS& Function not available for this device. +} + +\ifunction{FE\_READ\_SNR}{ + int ioctl(int fd, int request = FE\_READ\_SNR, int32\_t *snr);}{ + This ioctl call returns the signal-to-noise ratio for the signal currently + received by the front-end. For this command, read-only access to the device + is sufficient. + }{ + int fd & File descriptor returned by a previous call to open().\\ + int request & Equals FE\_READ\_SNR for this command.\\ + int32\_t *snr& The signal-to-noise ratio, as a multiple of + $10^{-6}$ dB, is stored into *snr.\\ + & Example: a value of 12,300,000 corresponds + to a signal-to-noise ratio of 12.3 dB. +}{ + EBADF& fd is not a valid open file descriptor.\\ + EFAULT& snr points to invalid address.\\ + ENOSIGNAL& There is no signal, thus no meaningful signal + strength value. Also returned if front-end is not turned on.\\ + ENOSYS& Function not available for this device. +} + +\ifunction{FE\_READ\_SIGNAL\_STRENGTH}{ + int ioctl( int fd, int request = FE\_READ\_SIGNAL\_STRENGTH, int32\_t *strength); +}{ +This ioctl call returns the signal strength value for the signal currently +received by the front-end. For this command, read-only access to the device +is sufficient. +}{ +int fd & File descriptor returned by a previous call to open().\\ +int request & Equals FE\_READ\_SIGNAL\_STRENGTH for this command.\\ +int32\_t *strength & The signal strength value, as a multiple of + $10^{-6 }$ dBm, + is stored into *strength. \\ + &Example: a value of -12,500,000 corresponds to a signal + strength value of -12.5 dBm. +}{ + EBADF& fd is not a valid open file descriptor.\\ + EFAULT& status points to invalid address.\\ + ENOSIGNAL& There is no signal, thus no meaningful signal + strength value. Also returned if front-end is not turned on.\\ + ENOSYS& Function not available for this device. +} + +\ifunction{FE\_READ\_UNCORRECTED\_BLOCKS}{ + int ioctl( int fd, int request = FE\_READ\_UNCORRECTED\_BLOCKS, uint32\_t *ublocks); }{ + This ioctl call returns the number of uncorrected blocks detected by + the device driver during its lifetime. + For meaningful measurements, the increment in + block count during a specific time interval should be calculated. + For this command, read-only access to the device is sufficient.\\ + Note that the counter will wrap to zero after its maximum count has + been reached. +}{ +int fd & File descriptor returned by a previous call to open().\\ +int request & Equals FE\_READ\_UNCORRECTED\_BLOCKS for this command.\\ +uint32\_t *ublocks & The total number of uncorrected blocks seen +by the driver so far. +}{ + EBADF& fd is not a valid open file descriptor.\\ + EFAULT& ublocks points to invalid address.\\ + ENOSYS& Function not available for this device. +} + + +\ifunction{FE\_GET\_NEXT\_FREQUENCY}{ + int ioctl( int fd, int request = FE\_GET\_NEXT\_FREQUENCY, uint32\_t *freq);}{ + When scanning a frequency range, it is desirable to use a scanning step size + that is as large as possible, yet small enough to be able to lock to any signal + within the range. + This ioctl operation does just that - it increments a given frequency by a + step size suitable for efficient scanning. + The step size used by this function may be a quite complex function of the given + frequency, hardware capabilities, and parameter settings of the device. Thus, a + returned result is only valid for the current state of the device. + For this command, read-only access to the device is sufficient.\\ + Note that scanning may still be excruciatingly slow on some hardware, for + other reasons than a non-optimal scanning step size. + }{ + int fd & File descriptor returned by a previous call to open().\\ + int request & Equals FE\_GET\_NEXT\_FREQUENCY for this command.\\ + uint32\_t *freq& Input: a given frequency \\ + & Output: the frequency corresponding to + the next higher frequency setting.\\ + }{ + EBADF& fd is not a valid open file descriptor.\\ + EFAULT& freq points to invalid address.\\ + EINVAL& Maximum supported frequency reached.\\ + ENOSYS& Function not available for this device. +} + +\ifunction{FE\_GET\_NEXT\_SYMBOL\_RATE}{ + int ioctl( int fd, int request = FE\_GET\_NEXT\_SYMBOL\_RATE, uint32\_t *symbolRate); + }{ + When scanning a range of symbol rates (e.g. for "blind acquisition") it is + desirable to use a scanning step size that is as large as possible, yet + small enough to detect any valid signal within the range. This ioctl + operation does just that - it increments a given symbol rate by a step size + suitable for efficient scanning. + The step size used by this function may be a quite complex function of the given + symbol rate, hardware capabilities, and parameter settings of the device. + Thus, a returned result is only valid for the current state of the device. + For this command, read-only access to the device is sufficient. + }{ + int fd & File descriptor returned by a previous call to open().\\ + int request & Equals FE\_GET\_NEXT\_SYMBOL\_RATE for this command.\\ + uint32\_t *symbolRate& Input: a given symbol rate \\ + & Output: the symbol rate corresponding to + the next higher symbol rate.\\ + }{ + EBADF& fd is not a valid open file descriptor.\\ + EFAULT& symbolRate points to invalid address.\\ + EINVAL& Maximum supported symbol rate reached.\\ + ENOSYS& Function not available for this device. +} + +\ifunction{FE\_SET\_FRONTEND}{ + int ioctl(int fd, int request = FE\_SET\_FRONTEND, struct FrontendParameters *p);}{ + This ioctl call starts a tuning operation using specified parameters. + The result of this call will be successful if the parameters were valid and + the tuning could be initiated. + The result of the tuning operation in itself, however, will arrive + asynchronously as an event (see documentation for FE\_GET\_EVENT + and FrontendEvent.) + If a new FE\_SET\_FRONTEND operation is initiated before the previous + one was completed, + the previous operation will be aborted in favor of the new one. + This command requires read/write access to the device. + }{ + int fd & File descriptor returned by a previous call to open().\\ + int request & Equals FE\_SET\_FRONTEND for this command.\\ + struct FrontendParameters *p& Points to parameters for tuning operation.\\ + }{ + EBADF& fd is not a valid open file descriptor.\\ + EFAULT& p points to invalid address.\\ + EINVAL& Maximum supported symbol rate reached.\\ +} + +\ifunction{FE\_GET\_EVENT}{ + int ioctl(int fd, int request = QPSK\_GET\_EVENT, struct qpskEvent *ev);}{ + This ioctl call returns an event of type qpskEvent 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. + Since the event queue allocated is rather small (room for 8 events), the queue + must be serviced regularly to avoid overflow. If an overflow happens, the + oldest event is discarded from the queue, and an error (EBUFFEROVERFLOW) occurs + the next time the queue is read. After reporting the error condition in this + fashion, subsequent QPSK\_GET\_EVENT calls will return events from the queue as + usual.\\ + For the sake of implementation simplicity, this command requires read/write + access to the device. + }{ + int fd & File descriptor returned by a previous call to open().\\ + int request & Equals QPSK\_GET\_EVENT for this command.\\ + struct qpskEvent *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{FE\_GET\_INFO}{ + int ioctl(int fd, int request = FE\_GET\_INFO, struct FrontendInfo *info);}{ + This ioctl call returns information about the front-end. + This call only requires read-only access to the device. + }{ + int fd & File descriptor returned by a previous call to open().\\ + int request & Equals FE\_GET\_INFO for this command.\\ + struct qpskFrontendInfo *info & Points to the location where the front-end + information is to be stored. + }{ + EBADF& fd is not a valid open file descriptor.\\ + EFAULT& info points to invalid address.\\ +} + +%%% Local Variables: +%%% mode: latex +%%% TeX-master: "dvbapi" +%%% End: 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..1d859fadb --- /dev/null +++ b/dvb-spec/dvbapi/intro.tex @@ -0,0 +1,183 @@ +\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 streams 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/frontend}, +\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. + +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 not belong 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/frontend0 + demux0 + +/dev/dvb/card1/video0 + audio0 + demux0 + demux1 + frontend0 + 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..59490299b --- /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} + + +\label{sectionfilter} +\begin{verbatim} +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..88342c3a6 --- /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\_SEND\_SEQUENCE}{ +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..574464d23 --- /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{}\\\\ + Dr. Marcus O.C. Metzler\\ + \texttt{} +% Rosenthalerstr. 51\\ +% 10178 Berlin\\Germany +} +\date{02/14/2002\\V 0.9.4} +\maketitle + +\newpage + +%\end{titlepage} +% Local Variables: +% mode: latex +% TeX-master: "dvbapi" +% End: diff --git a/dvb-spec/dvbapi/video.tex b/dvb-spec/dvbapi/video.tex new file mode 100644 index 000000000..ee61ad78b --- /dev/null +++ b/dvb-spec/dvbapi/video.tex @@ -0,0 +1,686 @@ +\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. Please note that some DVB cards don't have their own +MPEG decoder, which results in the omission of the audio and video +device as well as the video4linux device. + +\devsubsec{Video Data Types} + +\devsubsubsec{video_format\_t} +\label{videoformat} + +The \texttt{video_format\_t} data type defined by +\begin{verbatim} +typedef enum { + VIDEO_FORMAT_4_3, + VIDEO_FORMAT_16_9 +} video_format_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 video_status (\ref{videostatus}) +returned by VIDEO\_GET\_STATUS (\ref{videogetstatus}) and +video_event (\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 +} video_displayformat_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 +} video_stream_source_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 +} video_play_state_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 video_event { + int32_t type; + time_t timestamp; + union { + video_format_t video_format; + } 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 video_status { + boolean video_blank; + video_play_state_t play_state; + video_stream_source_t stream_source; + video_format_t video_format; + video_displayformat_t display_format; +}; +\end{verbatim} +If video_blank is set video will be blanked out if the channel is changed or +if playback is stopped. Otherwise, the last picture will be displayed. +play_state indicates if the video is currently frozen, stopped, or +being played back. The stream_source corresponds to the seleted source +for the video stream. It can come either from the demultiplexer or from memory. +The video_format indicates the aspect ratio (one of 4:3 or 16:9) +of the currently played video stream. +Finally, display_format 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 video_still_picture { + 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 +} video_system_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 video_highlight { + 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 */ +} video_highlight_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 video_spu { + boolean active; + int stream_id; +} video_spu_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 video_spu_palette{ /* SPU Palette information */ + int length; + uint8_t *palette; +} video_spu_palette_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 video_navi_pack{ + int length; /* 0 ... 1024 */ + uint8_t data[1024]; +} video_navi_pack_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 video_attributes_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 video_status *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 video_status *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 video_event *ev);}{ + This ioctl call returns an event of type video_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. + 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 video_event *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 video_still_picture *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 video_still_picture *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, video_format\_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.\\ + video_format\_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 ,video_highlight\_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.\\ + video_highlight\_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 , video_spu\_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.\\ + video_spu\_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 ,video_spu_palette\_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.\\ + video_spu_palette\_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 , video_navi_pack\_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.\\ + video_navi_pack\_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: -- cgit v1.2.3 From a801585585baeadfc1a94c685ebd83304640ff54 Mon Sep 17 00:00:00 2001 From: holger Date: Thu, 10 Oct 2002 16:46:21 -0300 Subject: more CodingStyle racism --- dvb-spec/dvbapi/demux.tex | 12 ++++++------ dvb-spec/dvbapi/examples.tex | 12 ++++++------ dvb-spec/dvbapi/frontend.tex | 4 ++-- dvb-spec/dvbapi/video.tex | 2 +- 4 files changed, 15 insertions(+), 15 deletions(-) (limited to 'dvb-spec/dvbapi') diff --git a/dvb-spec/dvbapi/demux.tex b/dvb-spec/dvbapi/demux.tex index 3607bbffc..5a8cc1e9a 100644 --- a/dvb-spec/dvbapi/demux.tex +++ b/dvb-spec/dvbapi/demux.tex @@ -6,7 +6,7 @@ It can be accessed through \texttt{/dev/ost/demux}. \devsubsec{Demux Data Types} \begin{verbatim} -typedef uint16_t dvb_pid_t; +typedef uint16_t uint16_t; \end{verbatim} @@ -96,7 +96,7 @@ typedef struct dmx_filter \begin{verbatim} struct dmx_sct_filter_params { - dvb_pid_t pid; + uint16_t pid; dmx_filter_t filter; uint32_t timeout; uint32_t flags; @@ -113,10 +113,10 @@ struct dmx_sct_filter_params \begin{verbatim} struct dmx_pes_filter_params { - dvb_pid_t pid; + uint16_t pid; dmx_input_t input; dmx_output_t output; - dmx_pes_type_t pesType; + dmx_pes_type_t pes_type; uint32_t flags; }; \end{verbatim} @@ -200,7 +200,7 @@ struct dmx_event 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, + in a buffer overflow error. In this case EOVERFLOW 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 @@ -222,7 +222,7 @@ struct dmx_event EBADF & fd is not a valid open file descriptor.\\ ECRC & Last section had a CRC error - no data returned. The buffer is flushed.\\ - EBUFFEROVERFLOW & \\ + EOVERFLOW & \\ & The filtered data was not read from the buffer in due time, resulting in non-read data being lost. The buffer is flushed.\\ diff --git a/dvb-spec/dvbapi/examples.tex b/dvb-spec/dvbapi/examples.tex index ea2797481..fa5c24b48 100644 --- a/dvb-spec/dvbapi/examples.tex +++ b/dvb-spec/dvbapi/examples.tex @@ -157,7 +157,7 @@ int set_qpsk_channel(int freq, int vpid, int apid, int tpid, printf("Getting QPSK event\n"); if ( ioctl(front, FE_GET_EVENT, &event) - == -EBUFFEROVERFLOW){ + == -EOVERFLOW){ perror("qpsk get event"); return -1; } @@ -180,7 +180,7 @@ int set_qpsk_channel(int freq, int vpid, int apid, int tpid, pesFilterParams.pid = vpid; pesFilterParams.input = DMX_IN_FRONTEND; pesFilterParams.output = DMX_OUT_DECODER; - pesFilterParams.pesType = DMX_PES_VIDEO; + pesFilterParams.pes_type = DMX_PES_VIDEO; pesFilterParams.flags = DMX_IMMEDIATE_START; if (ioctl(demux1, DMX_SET_PES_FILTER, &pesFilterParams) < 0){ perror("set_vpid"); @@ -190,7 +190,7 @@ int set_qpsk_channel(int freq, int vpid, int apid, int tpid, pesFilterParams.pid = apid; pesFilterParams.input = DMX_IN_FRONTEND; pesFilterParams.output = DMX_OUT_DECODER; - pesFilterParams.pesType = DMX_PES_AUDIO; + pesFilterParams.pes_type = DMX_PES_AUDIO; pesFilterParams.flags = DMX_IMMEDIATE_START; if (ioctl(demux2, DMX_SET_PES_FILTER, &pesFilterParams) < 0){ perror("set_apid"); @@ -200,7 +200,7 @@ int set_qpsk_channel(int freq, int vpid, int apid, int tpid, pesFilterParams.pid = tpid; pesFilterParams.input = DMX_IN_FRONTEND; pesFilterParams.output = DMX_OUT_DECODER; - pesFilterParams.pesType = DMX_PES_TELETEXT; + pesFilterParams.pes_type = DMX_PES_TELETEXT; pesFilterParams.flags = DMX_IMMEDIATE_START; if (ioctl(demux3, DMX_SET_PES_FILTER, &pesFilterParams) < 0){ perror("set_tpid"); @@ -273,7 +273,7 @@ int switch_to_record(int demux1, int demux2, uint16_t vpid, uint16_t apid) pesFilterParams.pid = vpid; pesFilterParams.input = DMX_IN_FRONTEND; pesFilterParams.output = DMX_OUT_TS_TAP; - pesFilterParams.pesType = DMX_PES_VIDEO; + pesFilterParams.pes_type = DMX_PES_VIDEO; pesFilterParams.flags = DMX_IMMEDIATE_START; if (ioctl(demux1, DMX_SET_PES_FILTER, &pesFilterParams) < 0){ perror("DEMUX DEVICE"); @@ -282,7 +282,7 @@ int switch_to_record(int demux1, int demux2, uint16_t vpid, uint16_t apid) pesFilterParams.pid = apid; pesFilterParams.input = DMX_IN_FRONTEND; pesFilterParams.output = DMX_OUT_TS_TAP; - pesFilterParams.pesType = DMX_PES_AUDIO; + pesFilterParams.pes_type = DMX_PES_AUDIO; pesFilterParams.flags = DMX_IMMEDIATE_START; if (ioctl(demux2, DMX_SET_PES_FILTER, &pesFilterParams) < 0){ perror("DEMUX DEVICE"); diff --git a/dvb-spec/dvbapi/frontend.tex b/dvb-spec/dvbapi/frontend.tex index cb3285d06..e41ef3d54 100644 --- a/dvb-spec/dvbapi/frontend.tex +++ b/dvb-spec/dvbapi/frontend.tex @@ -591,7 +591,7 @@ by the driver so far. POLLPRI should be specified as the wake-up condition. Since the event queue allocated is rather small (room for 8 events), the queue must be serviced regularly to avoid overflow. If an overflow happens, the - oldest event is discarded from the queue, and an error (EBUFFEROVERFLOW) occurs + oldest event is discarded from the queue, and an error (EOVERFLOW) occurs the next time the queue is read. After reporting the error condition in this fashion, subsequent QPSK\_GET\_EVENT calls will return events from the queue as usual.\\ @@ -606,7 +606,7 @@ by the driver so far. EFAULT& ev points to invalid address.\\ EWOULDBLOCK & There is no event pending, and the device is in non-blocking mode.\\ - EBUFFEROVERFLOW &\\ + EOVERFLOW &\\ & Overflow in event queue - one or more events were lost.\\ } diff --git a/dvb-spec/dvbapi/video.tex b/dvb-spec/dvbapi/video.tex index ee61ad78b..d33f03c83 100644 --- a/dvb-spec/dvbapi/video.tex +++ b/dvb-spec/dvbapi/video.tex @@ -440,7 +440,7 @@ EFAULT & status points to invalid address\\ 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 & \\ +EOVERFLOW & \\ &Overflow in event queue - one or more events were lost.\\ } -- cgit v1.2.3 From d6e1cc571bad041ab402ef377b6ae86bb7599c05 Mon Sep 17 00:00:00 2001 From: holger Date: Thu, 5 Dec 2002 09:37:23 -0200 Subject: Syntax fixes by Joerg Friedrich --- dvb-spec/dvbapi/Makefile | 2 +- dvb-spec/dvbapi/audio.tex | 42 +++++++++---------- dvb-spec/dvbapi/demux.tex | 54 ++++++++++++------------- dvb-spec/dvbapi/video.tex | 100 +++++++++++++++++++++++----------------------- 4 files changed, 99 insertions(+), 99 deletions(-) (limited to 'dvb-spec/dvbapi') diff --git a/dvb-spec/dvbapi/Makefile b/dvb-spec/dvbapi/Makefile index aae688f33..fe9827cff 100644 --- a/dvb-spec/dvbapi/Makefile +++ b/dvb-spec/dvbapi/Makefile @@ -4,7 +4,7 @@ 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 -o $@ $< + dvipdf $< $@ dvbapi.ps: dvbapi.dvi dvips -o $@ $< diff --git a/dvb-spec/dvbapi/audio.tex b/dvb-spec/dvbapi/audio.tex index 7b6427094..540248463 100644 --- a/dvb-spec/dvbapi/audio.tex +++ b/dvb-spec/dvbapi/audio.tex @@ -18,7 +18,7 @@ replaying from an internal (demuxer) or external (user write) source. typedef enum { AUDIO_SOURCE_DEMUX, AUDIO_SOURCE_MEMORY -} audio_stream_source_t; +} audio\_stream_source_t; \end{verbatim} AUDIO\_SOURCE\_DEMUX selects the demultiplexer (fed either by the frontend or the DVR device) as the source of @@ -36,7 +36,7 @@ typedef enum { AUDIO_STOPPED, AUDIO_PLAYING, AUDIO_PAUSED -} audio_play_state_t; +} audio\_play_state_t; \end{verbatim} \devsubsubsec{audioChannelSelect\_t} @@ -48,33 +48,33 @@ typedef enum { AUDIO_STEREO, AUDIO_MONO_LEFT, AUDIO_MONO_RIGHT, -} audio_channel_select_t; +} audio\_channel_select_t; \end{verbatim} -\devsubsubsec{audio_status\_t} +\devsubsubsec{audio\_status\_t} \label{audiostatus} The AUDIO\_GET\_STATUS call returns the following structure informing about various states of the playback operation. \begin{verbatim} -typedef struct audio_status { +typedef struct audio\_status { boolean AV_sync_state; boolean mute_state; - audio_play_state_t play_state; - audio_stream_source_t stream_source; - audio_channel_select_t channel_select; + audio\_play_state_t play_state; + audio\_stream_source_t stream_source; + audio\_channel_select_t channel_select; boolean bypass_mode; -} audio_status_t; +} audio\_status_t; \end{verbatim} -\devsubsubsec{audio_mixer\_t} +\devsubsubsec{audio\_mixer\_t} \label{audiomixer} The following structure is used by the AUDIO\_SET\_MIXER call to set the audio volume. \begin{verbatim} -typedef struct audio_mixer { +typedef struct audio\_mixer { unsigned int volume_left; unsigned int volume_right; -} audio_mixer_t; +} audio\_mixer_t; \end{verbatim} \devsubsubsec{audio encodings} @@ -99,20 +99,20 @@ the following bits set according to the hardwares capabilities. The ioctl AUDIO\_SET\_KARAOKE uses the following format: \begin{verbatim} typedef -struct audio_karaoke{ /* if Vocal1 or Vocal2 are non-zero, they get mixed */ +struct audio\_karaoke{ /* 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 */ -} audio_karaoke_t; +} audio\_karaoke_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 audio_attributes_t; +typedef uint16_t audio\_attributes_t; /* bits: descr. */ /* 15-13 audio coding mode (0=ac3, 2=mpeg1, 3=mpeg2ext, 4=LPCM, 6=DTS, */ /* 12 multichannel extension */ @@ -311,13 +311,13 @@ typedef uint16_t audio_attributes_t; \ifunction{AUDIO\_GET\_STATUS}{ int ioctl(int fd, int request = AUDIO\_GET\_STATUS, - struct audio_status *status);}{ + struct audio\_status *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 audio_status *status & Returns the current state of Audio Device. + struct audio\_status *status & Returns the current state of Audio Device. }{ EBADF& fd is not a valid open file descriptor.\\ EINTERNAL & Internal error.\\ @@ -371,12 +371,12 @@ typedef uint16_t audio_attributes_t; } \ifunction{AUDIO\_SET\_MIXER}{ - int ioctl(int fd, int request = AUDIO\_SET\_MIXER, audio_mixer\_t *mix);}{ + int ioctl(int fd, int request = AUDIO\_SET\_MIXER, audio\_mixer\_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.\\ - audio_mixer\_t *mix& mixer settings. + audio\_mixer\_t *mix& mixer settings. }{ EBADF& fd is not a valid open file descriptor.\\ EINTERNAL & Internal error.\\ @@ -425,12 +425,12 @@ typedef uint16_t audio_attributes_t; } \ifunction{AUDIO\_SET\_KARAOKE}{ - int ioctl(fd, int request = AUDIO\_SET\_STREAMTYPE, audio_karaoke\_t *karaoke);}{ + int ioctl(fd, int request = AUDIO\_SET\_STREAMTYPE, audio\_karaoke\_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.\\ - audio_karaoke\_t *karaoke & karaoke settings according to section \ref{audiokaraoke}.\\ + audio\_karaoke\_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.\\ diff --git a/dvb-spec/dvbapi/demux.tex b/dvb-spec/dvbapi/demux.tex index 5a8cc1e9a..c74b133ec 100644 --- a/dvb-spec/dvbapi/demux.tex +++ b/dvb-spec/dvbapi/demux.tex @@ -19,7 +19,7 @@ typedef enum DMX_OUT_DECODER, DMX_OUT_TAP, DMX_OUT_TS_TAP -} dmx_output_t; +} dmx\_output_t; \end{verbatim} /* Output multiplexed into a new TS */ /* (to be retrieved by reading from the */ @@ -34,7 +34,7 @@ typedef enum { DMX_IN_FRONTEND, /* Input from a front-end device. */ DMX_IN_DVR /* Input from the logical DVR device. */ -} dmx_input_t; +} dmx\_input_t; \end{verbatim} @@ -50,11 +50,11 @@ typedef enum DMX_PES_SUBTITLE, DMX_PES_PCR, DMX_PES_OTHER -} dmx_pes_type_t; +} dmx\_pes\_type_t; \end{verbatim} -\devsubsubsec{dmx_event\_t} +\devsubsubsec{dmx\_event\_t} \label{dmxeventt} \begin{verbatim} @@ -62,7 +62,7 @@ typedef enum { DMX_SCRAMBLING_EV, DMX_FRONTEND_EV -} dmx_event_t; +} dmx\_event_t; \end{verbatim} @@ -74,30 +74,30 @@ typedef enum { DMX_SCRAMBLING_OFF, DMX_SCRAMBLING_ON -} dmx_scrambling_status_t; +} dmx\_scrambling_status_t; \end{verbatim} -\devsubsubsec{dmx_filter\_t} +\devsubsubsec{dmx\_filter\_t} \label{dmxfilter} \begin{verbatim} -typedef struct dmx_filter +typedef struct dmx\_filter { uint8_t filter[DMX_FILTER_SIZE]; uint8_t mask[DMX_FILTER_SIZE]; -} dmx_filter_t; +} dmx\_filter\_t; \end{verbatim} -\devsubsubsec{dmx_sct_filter_params} +\devsubsubsec{dmx\_sct\_filter\_params} \label{dmxsctfilterparams} \begin{verbatim} -struct dmx_sct_filter_params +struct dmx\_sct\_filter\_params { uint16_t pid; - dmx_filter_t filter; + dmx\_filter\_t filter; uint32_t timeout; uint32_t flags; #define DMX_CHECK_CRC 1 @@ -107,32 +107,32 @@ struct dmx_sct_filter_params \end{verbatim} -\devsubsubsec{dmx_pes_filter_params} +\devsubsubsec{dmx\_pes\_filter\_params} \label{dmxpesfilterparams} \begin{verbatim} -struct dmx_pes_filter_params +struct dmx\_pes\_filter\_params { uint16_t pid; - dmx_input_t input; - dmx_output_t output; - dmx_pes_type_t pes_type; + dmx\_input_t input; + dmx\_output_t output; + dmx\_pes\_type_t pes\_type; uint32_t flags; }; \end{verbatim} -\devsubsubsec{dmx_event} +\devsubsubsec{dmx\_event} \label{dmxevent} \begin{verbatim} -struct dmx_event +struct dmx\_event { - dmx_event_t event; + dmx\_event_t event; time_t timeStamp; union { - dmx_scrambling_status_t scrambling; + dmx\_scrambling_status_t scrambling; } u; }; \end{verbatim} @@ -295,7 +295,7 @@ struct dmx_event } \ifunction{DMX\_SET\_FILTER}{ - int ioctl( int fd, int request = DMX\_SET\_FILTER, struct dmx_sct_filter_params *params); + int ioctl( int fd, int request = DMX\_SET\_FILTER, struct dmx\_sct\_filter\_params *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 @@ -310,7 +310,7 @@ struct dmx_event }{ int fd & File descriptor returned by a previous call to open().\\ int request & Equals DMX\_SET\_FILTER for this command.\\ - struct dmx_sct_filter_params *params + struct dmx\_sct\_filter\_params *params & Pointer to structure containing filter parameters.\\ }{ EBADF & fd is not a valid file descriptor.\\ @@ -319,7 +319,7 @@ struct dmx_event \ifunction{DMX\_SET\_PES\_FILTER}{ int ioctl( int fd, int request = DMX\_SET\_PES\_FILTER, - struct dmx_pes_filter_params *params); + struct dmx\_pes\_filter\_params *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 @@ -335,7 +335,7 @@ struct dmx_event }{ int fd & File descriptor returned by a previous call to open().\\ int request & Equals DMX\_SET\_PES\_FILTER for this command.\\ - struct dmx_pes_filter_params *params + struct dmx\_pes\_filter\_params *params & Pointer to structure containing filter parameters.\\ }{ EBADF & fd is not a valid file descriptor.\\ @@ -364,7 +364,7 @@ struct dmx_event } \ifunction{DMX\_GET\_EVENT}{ - int ioctl( int fd, int request = DMX\_GET\_EVENT, struct dmx_event *ev); + int ioctl( int fd, int request = DMX\_GET\_EVENT, struct dmx\_event *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 @@ -379,7 +379,7 @@ struct dmx_event }{ int fd & File descriptor returned by a previous call to open().\\ int request & Equals DMX\_GET\_EVENT for this command.\\ - struct dmx_event *ev & Pointer to the location where the event is to be stored.\\ + struct dmx\_event *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.\\ diff --git a/dvb-spec/dvbapi/video.tex b/dvb-spec/dvbapi/video.tex index d33f03c83..7300c95c0 100644 --- a/dvb-spec/dvbapi/video.tex +++ b/dvb-spec/dvbapi/video.tex @@ -9,21 +9,21 @@ device as well as the video4linux device. \devsubsec{Video Data Types} -\devsubsubsec{video_format\_t} +\devsubsubsec{video\_format\_t} \label{videoformat} -The \texttt{video_format\_t} data type defined by +The \texttt{video\_format\_t} data type defined by \begin{verbatim} typedef enum { VIDEO_FORMAT_4_3, VIDEO_FORMAT_16_9 -} video_format_t; +} video\_format_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 video_status (\ref{videostatus}) +It is also used in the data structures video\_status (\ref{videostatus}) returned by VIDEO\_GET\_STATUS (\ref{videogetstatus}) and -video_event (\ref{videoevent}) returned by VIDEO\_GET\_EVENT (\ref{videogetevent}) +video\_event (\ref{videoevent}) returned by VIDEO\_GET\_EVENT (\ref{videogetevent}) which report about the display format of the current video stream. \devsubsubsec{videoDisplayFormat\_t} @@ -39,7 +39,7 @@ typedef enum { VIDEO_PAN_SCAN, VIDEO_LETTER_BOX, VIDEO_CENTER_CUT_OUT -} video_displayformat_t; +} video\_displayformat_t; \end{verbatim} as argument. @@ -53,7 +53,7 @@ replaying from an internal (demuxer) or external (user write) source. typedef enum { VIDEO_SOURCE_DEMUX, VIDEO_SOURCE_MEMORY -} video_stream_source_t; +} video\_stream\_source_t; \end{verbatim} VIDEO\_SOURCE\_DEMUX selects the demultiplexer (fed either by the frontend or the DVR device) as the source of @@ -71,7 +71,7 @@ typedef enum { VIDEO_STOPPED, VIDEO_PLAYING, VIDEO_FREEZED -} video_play_state_t; +} video\_play\_state_t; \end{verbatim} @@ -80,11 +80,11 @@ typedef enum { The following is the structure of a video event as it is returned by the VIDEO\_GET\_EVENT call. \begin{verbatim} -struct video_event { +struct video\_event { int32_t type; time_t timestamp; union { - video_format_t video_format; + video\_format_t video\_format; } u; }; \end{verbatim} @@ -94,22 +94,22 @@ struct video_event { The VIDEO\_GET\_STATUS call returns the following structure informing about various states of the playback operation. \begin{verbatim} -struct video_status { - boolean video_blank; - video_play_state_t play_state; - video_stream_source_t stream_source; - video_format_t video_format; - video_displayformat_t display_format; +struct video\_status { + boolean video\_blank; + video\_play\_state_t play\_state; + video\_stream\_source_t stream\_source; + video\_format_t video\_format; + video\_displayformat_t display\_format; }; \end{verbatim} -If video_blank is set video will be blanked out if the channel is changed or +If video\_blank is set video will be blanked out if the channel is changed or if playback is stopped. Otherwise, the last picture will be displayed. -play_state indicates if the video is currently frozen, stopped, or -being played back. The stream_source corresponds to the seleted source +play\_state indicates if the video is currently frozen, stopped, or +being played back. The stream\_source corresponds to the seleted source for the video stream. It can come either from the demultiplexer or from memory. -The video_format indicates the aspect ratio (one of 4:3 or 16:9) +The video\_format indicates the aspect ratio (one of 4:3 or 16:9) of the currently played video stream. -Finally, display_format corresponds to the selected cropping mode in case the +Finally, display\_format corresponds to the selected cropping mode in case the source video format is not the same as the format of the output device. @@ -119,7 +119,7 @@ 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 video_still_picture { +struct video\_still\_picture { char *iFrame; int32_t size; }; @@ -162,7 +162,7 @@ typedef enum { VIDEO_SYSTEM_NTSC60, VIDEO_SYSTEM_PAL60, VIDEO_SYSTEM_PALM60 -} video_system_t; +} video\_system_t; \end{verbatim} @@ -174,7 +174,7 @@ information. The call expects the following format for that information: \begin{verbatim} typedef -struct video_highlight { +struct video\_highlight { boolean active; /* 1=show highlight, 0=hide highlight */ uint8_t contrast1; /* 7- 4 Pattern pixel contrast */ /* 3- 0 Background pixel contrast */ @@ -190,7 +190,7 @@ struct video_highlight { uint32_t xpos; /* 23-22 button color number */ /* 21-12 start x */ /* 9- 0 end x */ -} video_highlight_t; +} video\_highlight_t; \end{verbatim} @@ -200,10 +200,10 @@ Calling VIDEO\_SET\_SPU deactivates or activates SPU decoding, according to the following format: \begin{verbatim} typedef -struct video_spu { +struct video\_spu { boolean active; - int stream_id; -} video_spu_t; + int stream\_id; +} video\_spu\_t; \end{verbatim} @@ -212,10 +212,10 @@ struct video_spu { The following structure is used to set the SPU palette by calling VIDEO\_SPU\_PALETTE: \begin{verbatim} typedef -struct video_spu_palette{ /* SPU Palette information */ +struct video\_spu\_palette{ /* SPU Palette information */ int length; uint8_t *palette; -} video_spu_palette_t; +} video\_spu\_palette_t; \end{verbatim} \devsubsubsec{video NAVI pack} @@ -224,10 +224,10 @@ In order to get the navigational data the following structure has to be passed to the ioctl VIDEO\_GET\_NAVI: \begin{verbatim} typedef -struct video_navi_pack{ +struct video\_navi\_pack{ int length; /* 0 ... 1024 */ uint8_t data[1024]; -} video_navi_pack_t; +} video\_navi\_pack_t; \end{verbatim} @@ -235,7 +235,7 @@ struct video_navi_pack{ \label{vattrib} The following attributes can be set by a call to VIDEO\_SET\_ATTRIBUTES: \begin{verbatim} -typedef uint16_t video_attributes_t; +typedef uint16_t video\_attributes_t; /* bits: descr. */ /* 15-14 Video compression mode (0=MPEG-1, 1=MPEG-2) */ /* 13-12 TV system (0=525/60, 1=625/50) */ @@ -406,12 +406,12 @@ EINVAL & Illegal input parameter\\ \ifunction{VIDEO\_GET\_STATUS}{ \label{videogetstatus} - int ioctl(fd, int request = VIDEO\_GET\_STATUS, struct video_status *status);}{ + int ioctl(fd, int request = VIDEO\_GET\_STATUS, struct video\_status *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 video_status *status & Returns the current status of the Video Device.\\ + struct video\_status *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.\\ @@ -420,8 +420,8 @@ EFAULT & status points to invalid address\\ \ifunction{VIDEO\_GET\_EVENT}{ \label{videogetevent} - int ioctl(fd, int request = VIDEO\_GET\_EVENT, struct video_event *ev);}{ - This ioctl call returns an event of type video_event if available. + int ioctl(fd, int request = VIDEO\_GET\_EVENT, struct video\_event *ev);}{ + This ioctl call returns an event of type video\_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 @@ -434,7 +434,7 @@ EFAULT & status points to invalid address\\ }{ int fd & File descriptor returned by a previous call to open().\\ int request& Equals VIDEO\_GET\_EVENT for this command.\\ - struct video_event *ev & Points to the location where the event, if any, is + struct video\_event *ev & Points to the location where the event, if any, is to be stored.\\ }{ EBADF & fd is not a valid open file descriptor \\ @@ -460,14 +460,14 @@ EOVERFLOW & \\ } \ifunction{VIDEO\_STILLPICTURE}{ - int ioctl(fd, int request = VIDEO\_STILLPICTURE, struct video_still_picture *sp);}{ + int ioctl(fd, int request = VIDEO\_STILLPICTURE, struct video\_still\_picture *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 video_still_picture *sp& + struct video\_still\_picture *sp& Pointer to a location where an I-frame and size is stored.\\ }{ EBADF& fd is not a valid open file descriptor \\ @@ -562,7 +562,7 @@ EOVERFLOW & \\ \ifunction{VIDEO\_SET\_FORMAT}{ \label{videosetformat} - int ioctl(fd, int request = VIDEO\_SET\_FORMAT, video_format\_t format); + int ioctl(fd, int request = VIDEO\_SET\_FORMAT, video\_format\_t format); }{ This ioctl sets the screen format (aspect ratio) of the connected output device (TV) so that the output of the decoder can @@ -570,7 +570,7 @@ EOVERFLOW & \\ }{ int fd & File descriptor returned by a previous call to open().\\ int request & Equals VIDEO\_SET\_FORMAT for this command.\\ - video_format\_t format& video format of TV as defined in section \ref{videoformat}.\\ + video\_format\_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.\\ @@ -595,14 +595,14 @@ EOVERFLOW & \\ \ifunction{VIDEO\_SET\_HIGHLIGHT}{ \label{videosethighlight} - int ioctl(fd, int request = VIDEO\_SET\_HIGHLIGHT ,video_highlight\_t *vhilite) + int ioctl(fd, int request = VIDEO\_SET\_HIGHLIGHT ,video\_highlight\_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.\\ - video_highlight\_t *vhilite& SPU Highlight information according to + video\_highlight\_t *vhilite& SPU Highlight information according to section \ref{vhilite}.\\ }{ EBADF& fd is not a valid open file descriptor. \\ @@ -612,7 +612,7 @@ EOVERFLOW & \\ \ifunction{VIDEO\_SET\_SPU}{ \label{videosetspu} - int ioctl(fd, int request = VIDEO\_SET\_SPU , video_spu\_t *spu) + int ioctl(fd, int request = VIDEO\_SET\_SPU , video\_spu\_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 @@ -620,7 +620,7 @@ EOVERFLOW & \\ }{ int fd & File descriptor returned by a previous call to open().\\ int request & Equals VIDEO\_SET\_SPU for this command.\\ - video_spu\_t *spu& SPU decoding (de)activation and subid setting + video\_spu\_t *spu& SPU decoding (de)activation and subid setting according to section \ref{videospu}.\\ }{ EBADF& fd is not a valid open file descriptor \\ @@ -630,13 +630,13 @@ EOVERFLOW & \\ \ifunction{VIDEO\_SET\_SPU\_PALETTE}{ \label{videosetspupalette} - int ioctl(fd, int request = VIDEO\_SET\_SPU\_PALETTE ,video_spu_palette\_t *palette ) + int ioctl(fd, int request = VIDEO\_SET\_SPU\_PALETTE ,video\_spu\_palette\_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.\\ - video_spu_palette\_t *palette& SPU palette according to section \ref{vspupal}.\\ + video\_spu\_palette\_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.\\ @@ -646,14 +646,14 @@ EOVERFLOW & \\ \ifunction{VIDEO\_GET\_NAVI}{ \label{videosetnavi} - int ioctl(fd, int request = VIDEO\_GET\_NAVI , video_navi_pack\_t *navipack) + int ioctl(fd, int request = VIDEO\_GET\_NAVI , video\_navi\_pack\_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.\\ - video_navi_pack\_t *navipack& PCI or DSI pack (private stream 2) + video\_navi\_pack\_t *navipack& PCI or DSI pack (private stream 2) according to section \ref{videonavi}.\\ }{ EBADF& fd is not a valid open file descriptor \\ -- cgit v1.2.3 From 76715ed624559f5d635cc50f74df12a8ac2ad977 Mon Sep 17 00:00:00 2001 From: js Date: Wed, 5 Feb 2003 16:32:21 -0200 Subject: fix syntax error in example program --- dvb-spec/dvbapi/examples.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'dvb-spec/dvbapi') diff --git a/dvb-spec/dvbapi/examples.tex b/dvb-spec/dvbapi/examples.tex index fa5c24b48..126268c5d 100644 --- a/dvb-spec/dvbapi/examples.tex +++ b/dvb-spec/dvbapi/examples.tex @@ -70,7 +70,7 @@ int set_qpsk_channel(int freq, int vpid, int apid, int tpid, FrontendParameters frp; struct pollfd pfd[1]; FrontendEvent event; - int demux1, dmeux2, demux3, front, + int demux1, demux2, demux3, front; frequency = (uint32_t) freq; symbolrate = (uint32_t) srate; -- cgit v1.2.3 From 622f6e3335a0dd1a97cdaee9913c1f105f3e36fa Mon Sep 17 00:00:00 2001 From: js Date: Mon, 10 Feb 2003 10:18:16 -0200 Subject: - merged GNU FDL lincense from NEWSTRUCT branch - updated from DVB_API_VERSION 3 - various minor fixes/additions - bumped version number to 1.0.0-pre1 to match wth upcoming linuxtv-dvb driver release --- dvb-spec/dvbapi/LICENSE | 355 ++++++++++++++++++++++ dvb-spec/dvbapi/Makefile | 8 +- dvb-spec/dvbapi/audio.tex | 80 ++--- dvb-spec/dvbapi/ca.tex | 4 +- dvb-spec/dvbapi/demux.tex | 101 +++---- dvb-spec/dvbapi/devices.tex | 6 +- dvb-spec/dvbapi/dvbapi.tex | 8 +- dvb-spec/dvbapi/examples.tex | 26 +- dvb-spec/dvbapi/fdl.tex | 367 +++++++++++++++++++++++ dvb-spec/dvbapi/frontend.tex | 689 +++++++++++++++++++++++-------------------- dvb-spec/dvbapi/intro.tex | 117 +++----- dvb-spec/dvbapi/kdapi.tex | 9 +- dvb-spec/dvbapi/net.tex | 19 ++ dvb-spec/dvbapi/sec.tex | 282 ------------------ dvb-spec/dvbapi/title.tex | 24 +- dvb-spec/dvbapi/video.tex | 101 ++++--- 16 files changed, 1350 insertions(+), 846 deletions(-) create mode 100644 dvb-spec/dvbapi/LICENSE create mode 100644 dvb-spec/dvbapi/fdl.tex create mode 100644 dvb-spec/dvbapi/net.tex delete mode 100644 dvb-spec/dvbapi/sec.tex (limited to 'dvb-spec/dvbapi') diff --git a/dvb-spec/dvbapi/LICENSE b/dvb-spec/dvbapi/LICENSE new file mode 100644 index 000000000..b42936beb --- /dev/null +++ b/dvb-spec/dvbapi/LICENSE @@ -0,0 +1,355 @@ + GNU Free Documentation License + Version 1.1, March 2000 + + Copyright (C) 2000 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + +0. PREAMBLE + +The purpose of this License is to make a manual, textbook, or other +written document "free" in the sense of freedom: to assure everyone +the effective freedom to copy and redistribute it, with or without +modifying it, either commercially or noncommercially. Secondarily, +this License preserves for the author and publisher a way to get +credit for their work, while not being considered responsible for +modifications made by others. + +This License is a kind of "copyleft", which means that derivative +works of the document must themselves be free in the same sense. It +complements the GNU General Public License, which is a copyleft +license designed for free software. + +We have designed this License in order to use it for manuals for free +software, because free software needs free documentation: a free +program should come with manuals providing the same freedoms that the +software does. But this License is not limited to software manuals; +it can be used for any textual work, regardless of subject matter or +whether it is published as a printed book. We recommend this License +principally for works whose purpose is instruction or reference. + + +1. APPLICABILITY AND DEFINITIONS + +This License applies to any manual or other work that contains a +notice placed by the copyright holder saying it can be distributed +under the terms of this License. The "Document", below, refers to any +such manual or work. Any member of the public is a licensee, and is +addressed as "you". + +A "Modified Version" of the Document means any work containing the +Document or a portion of it, either copied verbatim, or with +modifications and/or translated into another language. + +A "Secondary Section" is a named appendix or a front-matter section of +the Document that deals exclusively with the relationship of the +publishers or authors of the Document to the Document's overall subject +(or to related matters) and contains nothing that could fall directly +within that overall subject. (For example, if the Document is in part a +textbook of mathematics, a Secondary Section may not explain any +mathematics.) The relationship could be a matter of historical +connection with the subject or with related matters, or of legal, +commercial, philosophical, ethical or political position regarding +them. + +The "Invariant Sections" are certain Secondary Sections whose titles +are designated, as being those of Invariant Sections, in the notice +that says that the Document is released under this License. + +The "Cover Texts" are certain short passages of text that are listed, +as Front-Cover Texts or Back-Cover Texts, in the notice that says that +the Document is released under this License. + +A "Transparent" copy of the Document means a machine-readable copy, +represented in a format whose specification is available to the +general public, whose contents can be viewed and edited directly and +straightforwardly with generic text editors or (for images composed of +pixels) generic paint programs or (for drawings) some widely available +drawing editor, and that is suitable for input to text formatters or +for automatic translation to a variety of formats suitable for input +to text formatters. A copy made in an otherwise Transparent file +format whose markup has been designed to thwart or discourage +subsequent modification by readers is not Transparent. A copy that is +not "Transparent" is called "Opaque". + +Examples of suitable formats for Transparent copies include plain +ASCII without markup, Texinfo input format, LaTeX input format, SGML +or XML using a publicly available DTD, and standard-conforming simple +HTML designed for human modification. Opaque formats include +PostScript, PDF, proprietary formats that can be read and edited only +by proprietary word processors, SGML or XML for which the DTD and/or +processing tools are not generally available, and the +machine-generated HTML produced by some word processors for output +purposes only. + +The "Title Page" means, for a printed book, the title page itself, +plus such following pages as are needed to hold, legibly, the material +this License requires to appear in the title page. For works in +formats which do not have any title page as such, "Title Page" means +the text near the most prominent appearance of the work's title, +preceding the beginning of the body of the text. + + +2. VERBATIM COPYING + +You may copy and distribute the Document in any medium, either +commercially or noncommercially, provided that this License, the +copyright notices, and the license notice saying this License applies +to the Document are reproduced in all copies, and that you add no other +conditions whatsoever to those of this License. You may not use +technical measures to obstruct or control the reading or further +copying of the copies you make or distribute. However, you may accept +compensation in exchange for copies. If you distribute a large enough +number of copies you must also follow the conditions in section 3. + +You may also lend copies, under the same conditions stated above, and +you may publicly display copies. + + +3. COPYING IN QUANTITY + +If you publish printed copies of the Document numbering more than 100, +and the Document's license notice requires Cover Texts, you must enclose +the copies in covers that carry, clearly and legibly, all these Cover +Texts: Front-Cover Texts on the front cover, and Back-Cover Texts on +the back cover. Both covers must also clearly and legibly identify +you as the publisher of these copies. The front cover must present +the full title with all words of the title equally prominent and +visible. You may add other material on the covers in addition. +Copying with changes limited to the covers, as long as they preserve +the title of the Document and satisfy these conditions, can be treated +as verbatim copying in other respects. + +If the required texts for either cover are too voluminous to fit +legibly, you should put the first ones listed (as many as fit +reasonably) on the actual cover, and continue the rest onto adjacent +pages. + +If you publish or distribute Opaque copies of the Document numbering +more than 100, you must either include a machine-readable Transparent +copy along with each Opaque copy, or state in or with each Opaque copy +a publicly-accessible computer-network location containing a complete +Transparent copy of the Document, free of added material, which the +general network-using public has access to download anonymously at no +charge using public-standard network protocols. If you use the latter +option, you must take reasonably prudent steps, when you begin +distribution of Opaque copies in quantity, to ensure that this +Transparent copy will remain thus accessible at the stated location +until at least one year after the last time you distribute an Opaque +copy (directly or through your agents or retailers) of that edition to +the public. + +It is requested, but not required, that you contact the authors of the +Document well before redistributing any large number of copies, to give +them a chance to provide you with an updated version of the Document. + + +4. MODIFICATIONS + +You may copy and distribute a Modified Version of the Document under +the conditions of sections 2 and 3 above, provided that you release +the Modified Version under precisely this License, with the Modified +Version filling the role of the Document, thus licensing distribution +and modification of the Modified Version to whoever possesses a copy +of it. In addition, you must do these things in the Modified Version: + +A. Use in the Title Page (and on the covers, if any) a title distinct + from that of the Document, and from those of previous versions + (which should, if there were any, be listed in the History section + of the Document). You may use the same title as a previous version + if the original publisher of that version gives permission. +B. List on the Title Page, as authors, one or more persons or entities + responsible for authorship of the modifications in the Modified + Version, together with at least five of the principal authors of the + Document (all of its principal authors, if it has less than five). +C. State on the Title page the name of the publisher of the + Modified Version, as the publisher. +D. Preserve all the copyright notices of the Document. +E. Add an appropriate copyright notice for your modifications + adjacent to the other copyright notices. +F. Include, immediately after the copyright notices, a license notice + giving the public permission to use the Modified Version under the + terms of this License, in the form shown in the Addendum below. +G. Preserve in that license notice the full lists of Invariant Sections + and required Cover Texts given in the Document's license notice. +H. Include an unaltered copy of this License. +I. Preserve the section entitled "History", and its title, and add to + it an item stating at least the title, year, new authors, and + publisher of the Modified Version as given on the Title Page. If + there is no section entitled "History" in the Document, create one + stating the title, year, authors, and publisher of the Document as + given on its Title Page, then add an item describing the Modified + Version as stated in the previous sentence. +J. Preserve the network location, if any, given in the Document for + public access to a Transparent copy of the Document, and likewise + the network locations given in the Document for previous versions + it was based on. These may be placed in the "History" section. + You may omit a network location for a work that was published at + least four years before the Document itself, or if the original + publisher of the version it refers to gives permission. +K. In any section entitled "Acknowledgements" or "Dedications", + preserve the section's title, and preserve in the section all the + substance and tone of each of the contributor acknowledgements + and/or dedications given therein. +L. Preserve all the Invariant Sections of the Document, + unaltered in their text and in their titles. Section numbers + or the equivalent are not considered part of the section titles. +M. Delete any section entitled "Endorsements". Such a section + may not be included in the Modified Version. +N. Do not retitle any existing section as "Endorsements" + or to conflict in title with any Invariant Section. + +If the Modified Version includes new front-matter sections or +appendices that qualify as Secondary Sections and contain no material +copied from the Document, you may at your option designate some or all +of these sections as invariant. To do this, add their titles to the +list of Invariant Sections in the Modified Version's license notice. +These titles must be distinct from any other section titles. + +You may add a section entitled "Endorsements", provided it contains +nothing but endorsements of your Modified Version by various +parties--for example, statements of peer review or that the text has +been approved by an organization as the authoritative definition of a +standard. + +You may add a passage of up to five words as a Front-Cover Text, and a +passage of up to 25 words as a Back-Cover Text, to the end of the list +of Cover Texts in the Modified Version. Only one passage of +Front-Cover Text and one of Back-Cover Text may be added by (or +through arrangements made by) any one entity. If the Document already +includes a cover text for the same cover, previously added by you or +by arrangement made by the same entity you are acting on behalf of, +you may not add another; but you may replace the old one, on explicit +permission from the previous publisher that added the old one. + +The author(s) and publisher(s) of the Document do not by this License +give permission to use their names for publicity for or to assert or +imply endorsement of any Modified Version. + + +5. COMBINING DOCUMENTS + +You may combine the Document with other documents released under this +License, under the terms defined in section 4 above for modified +versions, provided that you include in the combination all of the +Invariant Sections of all of the original documents, unmodified, and +list them all as Invariant Sections of your combined work in its +license notice. + +The combined work need only contain one copy of this License, and +multiple identical Invariant Sections may be replaced with a single +copy. If there are multiple Invariant Sections with the same name but +different contents, make the title of each such section unique by +adding at the end of it, in parentheses, the name of the original +author or publisher of that section if known, or else a unique number. +Make the same adjustment to the section titles in the list of +Invariant Sections in the license notice of the combined work. + +In the combination, you must combine any sections entitled "History" +in the various original documents, forming one section entitled +"History"; likewise combine any sections entitled "Acknowledgements", +and any sections entitled "Dedications". You must delete all sections +entitled "Endorsements." + + +6. COLLECTIONS OF DOCUMENTS + +You may make a collection consisting of the Document and other documents +released under this License, and replace the individual copies of this +License in the various documents with a single copy that is included in +the collection, provided that you follow the rules of this License for +verbatim copying of each of the documents in all other respects. + +You may extract a single document from such a collection, and distribute +it individually under this License, provided you insert a copy of this +License into the extracted document, and follow this License in all +other respects regarding verbatim copying of that document. + + +7. AGGREGATION WITH INDEPENDENT WORKS + +A compilation of the Document or its derivatives with other separate +and independent documents or works, in or on a volume of a storage or +distribution medium, does not as a whole count as a Modified Version +of the Document, provided no compilation copyright is claimed for the +compilation. Such a compilation is called an "aggregate", and this +License does not apply to the other self-contained works thus compiled +with the Document, on account of their being thus compiled, if they +are not themselves derivative works of the Document. + +If the Cover Text requirement of section 3 is applicable to these +copies of the Document, then if the Document is less than one quarter +of the entire aggregate, the Document's Cover Texts may be placed on +covers that surround only the Document within the aggregate. +Otherwise they must appear on covers around the whole aggregate. + + +8. TRANSLATION + +Translation is considered a kind of modification, so you may +distribute translations of the Document under the terms of section 4. +Replacing Invariant Sections with translations requires special +permission from their copyright holders, but you may include +translations of some or all Invariant Sections in addition to the +original versions of these Invariant Sections. You may include a +translation of this License provided that you also include the +original English version of this License. In case of a disagreement +between the translation and the original English version of this +License, the original English version will prevail. + + +9. TERMINATION + +You may not copy, modify, sublicense, or distribute the Document except +as expressly provided for under this License. Any other attempt to +copy, modify, sublicense or distribute the Document is void, and will +automatically terminate your rights under this License. However, +parties who have received copies, or rights, from you under this +License will not have their licenses terminated so long as such +parties remain in full compliance. + + +10. FUTURE REVISIONS OF THIS LICENSE + +The Free Software Foundation may publish new, revised versions +of the GNU Free Documentation License from time to time. Such new +versions will be similar in spirit to the present version, but may +differ in detail to address new problems or concerns. See +http://www.gnu.org/copyleft/. + +Each version of the License is given a distinguishing version number. +If the Document specifies that a particular numbered version of this +License "or any later version" applies to it, you have the option of +following the terms and conditions either of that specified version or +of any later version that has been published (not as a draft) by the +Free Software Foundation. If the Document does not specify a version +number of this License, you may choose any version ever published (not +as a draft) by the Free Software Foundation. + + +ADDENDUM: How to use this License for your documents + +To use this License in a document you have written, include a copy of +the License in the document and put the following copyright and +license notices just after the title page: + + Copyright (c) YEAR YOUR NAME. + Permission is granted to copy, distribute and/or modify this document + under the terms of the GNU Free Documentation License, Version 1.1 + or any later version published by the Free Software Foundation; + with the Invariant Sections being LIST THEIR TITLES, with the + Front-Cover Texts being LIST, and with the Back-Cover Texts being LIST. + A copy of the license is included in the section entitled "GNU + Free Documentation License". + +If you have no Invariant Sections, write "with no Invariant Sections" +instead of saying which ones are invariant. If you have no +Front-Cover Texts, write "no Front-Cover Texts" instead of +"Front-Cover Texts being LIST"; likewise for Back-Cover Texts. + +If your document contains nontrivial examples of program code, we +recommend releasing these examples in parallel under your choice of +free software license, such as the GNU General Public License, +to permit their use in free software. diff --git a/dvb-spec/dvbapi/Makefile b/dvb-spec/dvbapi/Makefile index fe9827cff..83a5e5f7a 100644 --- a/dvb-spec/dvbapi/Makefile +++ b/dvb-spec/dvbapi/Makefile @@ -1,13 +1,13 @@ 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 +TEXS= dvbapi.tex devices.tex video.tex audio.tex ca.tex net.tex frontend.tex \ + demux.tex kdapi.tex examples.tex intro.tex title.tex dvbstb.ps dvbapi.pdf: dvbapi.dvi - dvipdf $< $@ + dvipdf $< dvbapi.ps: dvbapi.dvi - dvips -o $@ $< + dvips $< dvbapi.dvi: dvbapi.bbl $(TEXS) -latex dvbapi diff --git a/dvb-spec/dvbapi/audio.tex b/dvb-spec/dvbapi/audio.tex index 540248463..05c23e56f 100644 --- a/dvb-spec/dvbapi/audio.tex +++ b/dvb-spec/dvbapi/audio.tex @@ -1,7 +1,13 @@ \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}. +It can be accessed through \texttt{/dev/dvb/adapter0/audio0}. +Data types and and ioctl definitions can be accessed by including +\texttt{linux/dvb/video.h} in your application. + +Please note that some DVB cards don't have their own +MPEG decoder, which results in the omission of the audio and video +device. \devsubsec{Audio Data Types} @@ -9,16 +15,16 @@ It can be accessed through \texttt{/dev/ost/audio}. This section describes the structures, data types and defines used when talking to the audio device. -\devsubsubsec{audioStreamSource\_t} +\devsubsubsec{audio\_stream\_source\_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. +replaying from an internal (demux) or external (user write) source. \begin{verbatim} typedef enum { AUDIO_SOURCE_DEMUX, AUDIO_SOURCE_MEMORY -} audio\_stream_source_t; +} audio_stream_source_t; \end{verbatim} AUDIO\_SOURCE\_DEMUX selects the demultiplexer (fed either by the frontend or the DVR device) as the source of @@ -27,7 +33,7 @@ If AUDIO\_SOURCE\_MEMORY is selected the stream comes from the application through the \texttt{write()} system call. -\devsubsubsec{audioPlayState\_t} +\devsubsubsec{audio\_play\_state\_t} The following values can be returned by the AUDIO\_GET\_STATUS call representing the state of audio playback. \label{audioplaystate} @@ -36,45 +42,45 @@ typedef enum { AUDIO_STOPPED, AUDIO_PLAYING, AUDIO_PAUSED -} audio\_play_state_t; +} audio_play_state_t; \end{verbatim} -\devsubsubsec{audioChannelSelect\_t} +\devsubsubsec{audio\_channel\_select\_t} \label{audiochannelselect} The audio channel selected via AUDIO\_CHANNEL\_SELECT is determined by -the following values. +the following values. \begin{verbatim} typedef enum { AUDIO_STEREO, AUDIO_MONO_LEFT, AUDIO_MONO_RIGHT, -} audio\_channel_select_t; +} audio_channel_select_t; \end{verbatim} -\devsubsubsec{audio\_status\_t} +\devsubsubsec{struct audio\_status} \label{audiostatus} The AUDIO\_GET\_STATUS call returns the following structure informing about various states of the playback operation. \begin{verbatim} -typedef struct audio\_status { +typedef struct audio_status { boolean AV_sync_state; boolean mute_state; - audio\_play_state_t play_state; - audio\_stream_source_t stream_source; - audio\_channel_select_t channel_select; + audio_play_state_t play_state; + audio_stream_source_t stream_source; + audio_channel_select_t channel_select; boolean bypass_mode; -} audio\_status_t; +} audio_status_t; \end{verbatim} -\devsubsubsec{audio\_mixer\_t} +\devsubsubsec{struct audio\_mixer} \label{audiomixer} The following structure is used by the AUDIO\_SET\_MIXER call to set the audio volume. \begin{verbatim} -typedef struct audio\_mixer { +typedef struct audio_mixer { unsigned int volume_left; unsigned int volume_right; -} audio\_mixer_t; +} audio_mixer_t; \end{verbatim} \devsubsubsec{audio encodings} @@ -94,25 +100,31 @@ the following bits set according to the hardwares capabilities. \end{verbatim} -\devsubsubsec{audio karaoke} +\devsubsubsec{struct audio\_karaoke} \label{audiokaraoke} The ioctl AUDIO\_SET\_KARAOKE uses the following format: \begin{verbatim} typedef -struct audio\_karaoke{ /* 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 */ -} audio\_karaoke_t; +struct audio_karaoke{ + int vocal1; + int vocal2; + int melody; +} audio_karaoke_t; \end{verbatim} +If Vocal1 or Vocal2 are non-zero, they get mixed +into left and right t at 70\% each. +If both, Vocal1 and Vocal2 are non-zero, Vocal1 gets +mixed into the left channel and +Vocal2 into the right channel at 100\% each. +Ff Melody is non-zero, the melody channel gets mixed +into left and right. + \devsubsubsec{audio attributes} \label{aattrib} The following attributes can be set by a call to AUDIO\_SET\_ATTRIBUTES: \begin{verbatim} -typedef uint16_t audio\_attributes_t; +typedef uint16_t audio_attributes_t; /* bits: descr. */ /* 15-13 audio coding mode (0=ac3, 2=mpeg1, 3=mpeg2ext, 4=LPCM, 6=DTS, */ /* 12 multichannel extension */ @@ -130,7 +142,7 @@ typedef uint16_t audio\_attributes_t; \function{open()}{ int open(const char *deviceName, int flags);}{ - This system call opens a named audio device (e.g. /dev/ost/audio) for subsequent + This system call opens a named audio device (e.g. /dev/dvb/adapter0/audio0) 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 @@ -225,7 +237,7 @@ typedef uint16_t audio\_attributes_t; \ifunction{AUDIO\_SELECT\_SOURCE}{ int ioctl(int fd, int request = AUDIO\_SELECT\_SOURCE, - audioStreamSource\_t source);}{ + audio\_stream\_source\_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 @@ -233,7 +245,7 @@ typedef uint16_t audio\_attributes_t; }{ 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\_source\_t source& Indicates the source that shall be used for the Audio stream. }{ EBADF& fd is not a valid open file descriptor.\\ @@ -295,13 +307,13 @@ typedef uint16_t audio\_attributes_t; \ifunction{AUDIO\_CHANNEL\_SELECT}{ int ioctl(int fd, int request = AUDIO\_CHANNEL\_SELECT, - audioChannelSelect\_t);}{ + audio\_channel\_select\_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 & + audio\_channel\_select\_t ch & Select the output format of the audio (mono left/right, stereo). }{ EBADF& fd is not a valid open file descriptor.\\ @@ -412,13 +424,13 @@ typedef uint16_t audio\_attributes_t; } \ifunction{AUDIO\_SET\_ATTRIBUTES}{ - int ioctl(fd, int request = AUDIO\_SET\_ATTRIBUTES, audioAttributes\_t attr );}{ + int ioctl(fd, int request = AUDIO\_SET\_ATTRIBUTES, audio\_attributes\_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}\\ + audio\_attributes\_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.\\ diff --git a/dvb-spec/dvbapi/ca.tex b/dvb-spec/dvbapi/ca.tex index eba512b1b..fe76da454 100644 --- a/dvb-spec/dvbapi/ca.tex +++ b/dvb-spec/dvbapi/ca.tex @@ -1,7 +1,9 @@ \devsec{DVB CA Device} The DVB CA device controls the conditional access hardware. -It can be accessed through \texttt{/dev/ost/ca}. +It can be accessed through \texttt{/dev/dvb/adapter0/ca0}. +Data types and and ioctl definitions can be accessed by including +\texttt{linux/dvb/ca.h} in your application. \devsubsec{CA Data Types} diff --git a/dvb-spec/dvbapi/demux.tex b/dvb-spec/dvbapi/demux.tex index c74b133ec..dd032f58d 100644 --- a/dvb-spec/dvbapi/demux.tex +++ b/dvb-spec/dvbapi/demux.tex @@ -1,16 +1,14 @@ \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}. +It can be accessed through \texttt{/dev/adapter0/demux0}. +Data types and and ioctl definitions can be accessed by including +\texttt{linux/dvb/dmx.h} in your application. \devsubsec{Demux Data Types} -\begin{verbatim} -typedef uint16_t uint16_t; -\end{verbatim} - -\devsubsubsec{dmxOutput\_t} +\devsubsubsec{dmx\_output\_t} \label{dmxoutput} \begin{verbatim} @@ -19,26 +17,30 @@ typedef enum DMX_OUT_DECODER, DMX_OUT_TAP, DMX_OUT_TS_TAP -} dmx\_output_t; +} dmx_output_t; \end{verbatim} -/* Output multiplexed into a new TS */ -/* (to be retrieved by reading from the */ -/* logical DVR device). */ + +\noindent\texttt{DMX\_OUT\_TAP} delivers the stream output to the demux device +on which the ioctl is called. + +\noindent\texttt{DMX\_OUT\_TS\_TAP} routes output to the logical DVR device +\texttt{/dev/dvb/adapter0/dvr0}, which delivers a TS multiplexed from +all filters for which \texttt{DMX\_OUT\_TS\_TAP} was specified. -\devsubsubsec{dmxInput\_t} +\devsubsubsec{dmx\_input\_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. */ -} dmx\_input_t; + DMX_IN_FRONTEND, + DMX_IN_DVR +} dmx_input_t; \end{verbatim} -\devsubsubsec{dmxPesType\_t} +\devsubsubsec{dmx\_pes\_type\_t} \label{dmxpestype} \begin{verbatim} @@ -50,7 +52,7 @@ typedef enum DMX_PES_SUBTITLE, DMX_PES_PCR, DMX_PES_OTHER -} dmx\_pes\_type_t; +} dmx_pes_type_t; \end{verbatim} @@ -62,11 +64,11 @@ typedef enum { DMX_SCRAMBLING_EV, DMX_FRONTEND_EV -} dmx\_event_t; +} dmx_event_t; \end{verbatim} -\devsubsubsec{dmxScramblingStatus\_t} +\devsubsubsec{dmx\_scrambling\_status\_t} \label{dmxscramblingstatus} \begin{verbatim} @@ -74,32 +76,32 @@ typedef enum { DMX_SCRAMBLING_OFF, DMX_SCRAMBLING_ON -} dmx\_scrambling_status_t; +} dmx_scrambling_status_t; \end{verbatim} -\devsubsubsec{dmx\_filter\_t} +\devsubsubsec{struct dmx\_filter} \label{dmxfilter} \begin{verbatim} -typedef struct dmx\_filter +typedef struct dmx_filter { uint8_t filter[DMX_FILTER_SIZE]; uint8_t mask[DMX_FILTER_SIZE]; -} dmx\_filter\_t; +} dmx_filter_t; \end{verbatim} -\devsubsubsec{dmx\_sct\_filter\_params} +\devsubsubsec{struct dmx\_sct\_filter\_params} \label{dmxsctfilterparams} \begin{verbatim} -struct dmx\_sct\_filter\_params +struct dmx_sct_filter_params { - uint16_t pid; - dmx\_filter\_t filter; - uint32_t timeout; - uint32_t flags; + uint16_t pid; + dmx_filter_t filter; + uint32_t timeout; + uint32_t flags; #define DMX_CHECK_CRC 1 #define DMX_ONESHOT 2 #define DMX_IMMEDIATE_START 4 @@ -107,32 +109,32 @@ struct dmx\_sct\_filter\_params \end{verbatim} -\devsubsubsec{dmx\_pes\_filter\_params} +\devsubsubsec{struct dmx\_pes\_filter\_params} \label{dmxpesfilterparams} \begin{verbatim} -struct dmx\_pes\_filter\_params +struct dmx_pes_filter_params { - uint16_t pid; - dmx\_input_t input; - dmx\_output_t output; - dmx\_pes\_type_t pes\_type; - uint32_t flags; + uint16_t pid; + dmx_input_t input; + dmx_output_t output; + dmx_pes_type_t pes_type; + uint32_t flags; }; \end{verbatim} -\devsubsubsec{dmx\_event} +\devsubsubsec{struct dmx\_event} \label{dmxevent} \begin{verbatim} -struct dmx\_event +struct dmx_event { - dmx\_event_t event; - time_t timeStamp; + dmx_event_t event; + time_t timeStamp; union { - dmx\_scrambling_status_t scrambling; + dmx_scrambling_status_t scrambling; } u; }; \end{verbatim} @@ -142,16 +144,15 @@ struct dmx\_event \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 + This system call, used with a device name of /dev/dvb/adapter0/demux0, + 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 + /dev/dvb/adapter0/dvr0 is a logical device to be used for retrieving Transport + Streams for digital video recording. When reading from this device a transport stream containing the packets from all PES - filters set in the corresponding demux device (/dev/ost/demuxn) + filters set in the corresponding demux device (/dev/dvb/adapter0/demux0) 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. @@ -211,7 +212,7 @@ struct dmx\_event 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 + in the corresponding demux device /dev/dvb/adapter0/demux0 having the output set to DMX\_OUT\_TS\_TAP. }{ int fd & File descriptor returned by a previous call to open().\\ @@ -236,11 +237,11 @@ struct dmx\_event \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 + This system call is only provided by the logical device /dev/dvb/adapter0/dvr0, + associated with 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. + corresponding physical demux device, /dev/dvb/adapter0/demux0. The amount of data to be transferred is implied by count. }{ int fd & File descriptor returned by a previous call to open().\\ diff --git a/dvb-spec/dvbapi/devices.tex b/dvb-spec/dvbapi/devices.tex index 9c561e853..11eccd897 100644 --- a/dvb-spec/dvbapi/devices.tex +++ b/dvb-spec/dvbapi/devices.tex @@ -1,9 +1,9 @@ -\input{video.tex} -\input{audio.tex} \input{frontend.tex} -\input{sec.tex} \input{demux.tex} +\input{video.tex} +\input{audio.tex} \input{ca.tex} +\input{net.tex} \input{kdapi.tex} %%% Local Variables: diff --git a/dvb-spec/dvbapi/dvbapi.tex b/dvb-spec/dvbapi/dvbapi.tex index ad0251c01..d75c2417f 100644 --- a/dvb-spec/dvbapi/dvbapi.tex +++ b/dvb-spec/dvbapi/dvbapi.tex @@ -1,4 +1,4 @@ -\documentclass[10pt]{book} +\documentclass[a4paper,10pt]{book} \usepackage[dvips,colorlinks=true]{hyperref} \usepackage{times} @@ -131,7 +131,7 @@ \renewcommand{\sectionmark}[1]{\markright{\thesection.\ #1}{}} \lhead[\fancyplain{}{\bfseries \thepage}]{\bfseries \rightmark} \rhead[\fancyplain{}{\bfseries \leftmark}]{\bfseries \thepage} -\cfoot{\copyright 2002 convergence GmbH} +%\cfoot{\copyright\ 2002, 2003 Convergence GmbH} \input{intro.tex} @@ -145,6 +145,10 @@ \cleardoublepage +\input{fdl.tex} + +\cleardoublepage + \thispagestyle{plain}\chaptermark{Bibliography} \addcontentsline{toc}{chapter}{Bibliography} \bibliographystyle{bibsec} diff --git a/dvb-spec/dvbapi/examples.tex b/dvb-spec/dvbapi/examples.tex index 126268c5d..c9a19ba29 100644 --- a/dvb-spec/dvbapi/examples.tex +++ b/dvb-spec/dvbapi/examples.tex @@ -1,6 +1,10 @@ \chapter{Examples} In this section we would like to present some examples for using the DVB API. +Maintainer note: This section is out of date. Please refer to the sample +programs packaged with the driver distribution from +\texttt{http://linuxtv.org/}. + \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 @@ -17,14 +21,14 @@ tuners, but can easily be adjusted for QAM. #include #include -#include -#include -#include +#include +#include +#include #include -#define DMX "/dev/ost/demux" -#define FRONT "/dev/ost/frontend" -#define SEC "/dev/ost/sec" +#define DMX "/dev/dvb/adapter0/demux1" +#define FRONT "/dev/dvb/adapter0/frontend1" +#define SEC "/dev/dvb/adapter0/sec1" /* routine for checking if we have a signal and other status information*/ int FEReadStatus(int fd, fe_status_t *stat) @@ -234,12 +238,12 @@ recording. #include #include -#include -#include +#include +#include #include -#define DVR "/dev/ost/dvr" -#define AUDIO "/dev/ost/audio" -#define VIDEO "/dev/ost/video" +#define DVR "/dev/dvb/adapter0/dvr1" +#define AUDIO "/dev/dvb/adapter0/audio1" +#define VIDEO "/dev/dvb/adapter0/video1" #define BUFFY (188*20) #define MAX_LENGTH (1024*1024*5) /* record 5MB */ diff --git a/dvb-spec/dvbapi/fdl.tex b/dvb-spec/dvbapi/fdl.tex new file mode 100644 index 000000000..c0fcbe3f3 --- /dev/null +++ b/dvb-spec/dvbapi/fdl.tex @@ -0,0 +1,367 @@ +% fdl.tex +% This file is a chapter. It must be included in a larger document to work +% properly. + +\chapter{GNU Free Documentation License} + +Version 1.1, March 2000\\ + + Copyright \copyright\ 2000 Free Software Foundation, Inc.\\ + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\\ + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +\section*{Preamble} + +The purpose of this License is to make a manual, textbook, or other +written document ``free'' in the sense of freedom: to assure everyone +the effective freedom to copy and redistribute it, with or without +modifying it, either commercially or noncommercially. Secondarily, +this License preserves for the author and publisher a way to get +credit for their work, while not being considered responsible for +modifications made by others. + +This License is a kind of ``copyleft'', which means that derivative +works of the document must themselves be free in the same sense. It +complements the GNU General Public License, which is a copyleft +license designed for free software. + +We have designed this License in order to use it for manuals for free +software, because free software needs free documentation: a free +program should come with manuals providing the same freedoms that the +software does. But this License is not limited to software manuals; +it can be used for any textual work, regardless of subject matter or +whether it is published as a printed book. We recommend this License +principally for works whose purpose is instruction or reference. + +\section{Applicability and Definitions} + +This License applies to any manual or other work that contains a +notice placed by the copyright holder saying it can be distributed +under the terms of this License. The ``Document'', below, refers to any +such manual or work. Any member of the public is a licensee, and is +addressed as ``you''. + +A ``Modified Version'' of the Document means any work containing the +Document or a portion of it, either copied verbatim, or with +modifications and/or translated into another language. + +A ``Secondary Section'' is a named appendix or a front-matter section of +the Document that deals exclusively with the relationship of the +publishers or authors of the Document to the Document's overall subject +(or to related matters) and contains nothing that could fall directly +within that overall subject. (For example, if the Document is in part a +textbook of mathematics, a Secondary Section may not explain any +mathematics.) The relationship could be a matter of historical +connection with the subject or with related matters, or of legal, +commercial, philosophical, ethical or political position regarding +them. + +The ``Invariant Sections'' are certain Secondary Sections whose titles +are designated, as being those of Invariant Sections, in the notice +that says that the Document is released under this License. + +The ``Cover Texts'' are certain short passages of text that are listed, +as Front-Cover Texts or Back-Cover Texts, in the notice that says that +the Document is released under this License. + +A ``Transparent'' copy of the Document means a machine-readable copy, +represented in a format whose specification is available to the +general public, whose contents can be viewed and edited directly and +straightforwardly with generic text editors or (for images composed of +pixels) generic paint programs or (for drawings) some widely available +drawing editor, and that is suitable for input to text formatters or +for automatic translation to a variety of formats suitable for input +to text formatters. A copy made in an otherwise Transparent file +format whose markup has been designed to thwart or discourage +subsequent modification by readers is not Transparent. A copy that is +not ``Transparent'' is called ``Opaque''. + +Examples of suitable formats for Transparent copies include plain +ASCII without markup, Texinfo input format, \LaTeX~input format, SGML +or XML using a publicly available DTD, and standard-conforming simple +HTML designed for human modification. Opaque formats include +PostScript, PDF, proprietary formats that can be read and edited only +by proprietary word processors, SGML or XML for which the DTD and/or +processing tools are not generally available, and the +machine-generated HTML produced by some word processors for output +purposes only. + +The ``Title Page'' means, for a printed book, the title page itself, +plus such following pages as are needed to hold, legibly, the material +this License requires to appear in the title page. For works in +formats which do not have any title page as such, ``Title Page'' means +the text near the most prominent appearance of the work's title, +preceding the beginning of the body of the text. + + +\section{Verbatim Copying} + +You may copy and distribute the Document in any medium, either +commercially or noncommercially, provided that this License, the +copyright notices, and the license notice saying this License applies +to the Document are reproduced in all copies, and that you add no other +conditions whatsoever to those of this License. You may not use +technical measures to obstruct or control the reading or further +copying of the copies you make or distribute. However, you may accept +compensation in exchange for copies. If you distribute a large enough +number of copies you must also follow the conditions in section 3. + +You may also lend copies, under the same conditions stated above, and +you may publicly display copies. + + +\section{Copying in Quantity} + +If you publish printed copies of the Document numbering more than 100, +and the Document's license notice requires Cover Texts, you must enclose +the copies in covers that carry, clearly and legibly, all these Cover +Texts: Front-Cover Texts on the front cover, and Back-Cover Texts on +the back cover. Both covers must also clearly and legibly identify +you as the publisher of these copies. The front cover must present +the full title with all words of the title equally prominent and +visible. You may add other material on the covers in addition. +Copying with changes limited to the covers, as long as they preserve +the title of the Document and satisfy these conditions, can be treated +as verbatim copying in other respects. + +If the required texts for either cover are too voluminous to fit +legibly, you should put the first ones listed (as many as fit +reasonably) on the actual cover, and continue the rest onto adjacent +pages. + +If you publish or distribute Opaque copies of the Document numbering +more than 100, you must either include a machine-readable Transparent +copy along with each Opaque copy, or state in or with each Opaque copy +a publicly-accessible computer-network location containing a complete +Transparent copy of the Document, free of added material, which the +general network-using public has access to download anonymously at no +charge using public-standard network protocols. If you use the latter +option, you must take reasonably prudent steps, when you begin +distribution of Opaque copies in quantity, to ensure that this +Transparent copy will remain thus accessible at the stated location +until at least one year after the last time you distribute an Opaque +copy (directly or through your agents or retailers) of that edition to +the public. + +It is requested, but not required, that you contact the authors of the +Document well before redistributing any large number of copies, to give +them a chance to provide you with an updated version of the Document. + + +\section{Modifications} + +You may copy and distribute a Modified Version of the Document under +the conditions of sections 2 and 3 above, provided that you release +the Modified Version under precisely this License, with the Modified +Version filling the role of the Document, thus licensing distribution +and modification of the Modified Version to whoever possesses a copy +of it. In addition, you must do these things in the Modified Version: + +\begin{itemize} + +\item Use in the Title Page (and on the covers, if any) a title distinct + from that of the Document, and from those of previous versions + (which should, if there were any, be listed in the History section + of the Document). You may use the same title as a previous version + if the original publisher of that version gives permission. +\item List on the Title Page, as authors, one or more persons or entities + responsible for authorship of the modifications in the Modified + Version, together with at least five of the principal authors of the + Document (all of its principal authors, if it has less than five). +\item State on the Title page the name of the publisher of the + Modified Version, as the publisher. +\item Preserve all the copyright notices of the Document. +\item Add an appropriate copyright notice for your modifications + adjacent to the other copyright notices. +\item Include, immediately after the copyright notices, a license notice + giving the public permission to use the Modified Version under the + terms of this License, in the form shown in the Addendum below. +\item Preserve in that license notice the full lists of Invariant Sections + and required Cover Texts given in the Document's license notice. +\item Include an unaltered copy of this License. +\item Preserve the section entitled ``History'', and its title, and add to + it an item stating at least the title, year, new authors, and + publisher of the Modified Version as given on the Title Page. If + there is no section entitled ``History'' in the Document, create one + stating the title, year, authors, and publisher of the Document as + given on its Title Page, then add an item describing the Modified + Version as stated in the previous sentence. +\item Preserve the network location, if any, given in the Document for + public access to a Transparent copy of the Document, and likewise + the network locations given in the Document for previous versions + it was based on. These may be placed in the ``History'' section. + You may omit a network location for a work that was published at + least four years before the Document itself, or if the original + publisher of the version it refers to gives permission. +\item In any section entitled ``Acknowledgements'' or ``Dedications'', + preserve the section's title, and preserve in the section all the + substance and tone of each of the contributor acknowledgements + and/or dedications given therein. +\item Preserve all the Invariant Sections of the Document, + unaltered in their text and in their titles. Section numbers + or the equivalent are not considered part of the section titles. +\item Delete any section entitled ``Endorsements''. Such a section + may not be included in the Modified Version. +\item Do not retitle any existing section as ``Endorsements'' + or to conflict in title with any Invariant Section. + +\end{itemize} + +If the Modified Version includes new front-matter sections or +appendices that qualify as Secondary Sections and contain no material +copied from the Document, you may at your option designate some or all +of these sections as invariant. To do this, add their titles to the +list of Invariant Sections in the Modified Version's license notice. +These titles must be distinct from any other section titles. + +You may add a section entitled ``Endorsements'', provided it contains +nothing but endorsements of your Modified Version by various +parties -- for example, statements of peer review or that the text has +been approved by an organization as the authoritative definition of a +standard. + +You may add a passage of up to five words as a Front-Cover Text, and a +passage of up to 25 words as a Back-Cover Text, to the end of the list +of Cover Texts in the Modified Version. Only one passage of +Front-Cover Text and one of Back-Cover Text may be added by (or +through arrangements made by) any one entity. If the Document already +includes a cover text for the same cover, previously added by you or +by arrangement made by the same entity you are acting on behalf of, +you may not add another; but you may replace the old one, on explicit +permission from the previous publisher that added the old one. + +The author(s) and publisher(s) of the Document do not by this License +give permission to use their names for publicity for or to assert or +imply endorsement of any Modified Version. + + +\section{Combining Documents} + +You may combine the Document with other documents released under this +License, under the terms defined in section 4 above for modified +versions, provided that you include in the combination all of the +Invariant Sections of all of the original documents, unmodified, and +list them all as Invariant Sections of your combined work in its +license notice. + +The combined work need only contain one copy of this License, and +multiple identical Invariant Sections may be replaced with a single +copy. If there are multiple Invariant Sections with the same name but +different contents, make the title of each such section unique by +adding at the end of it, in parentheses, the name of the original +author or publisher of that section if known, or else a unique number. +Make the same adjustment to the section titles in the list of +Invariant Sections in the license notice of the combined work. + +In the combination, you must combine any sections entitled ``History'' +in the various original documents, forming one section entitled +``History''; likewise combine any sections entitled ``Acknowledgements'', +and any sections entitled ``Dedications''. You must delete all sections +entitled ``Endorsements.'' + + +\section{Collections of Documents} + +You may make a collection consisting of the Document and other documents +released under this License, and replace the individual copies of this +License in the various documents with a single copy that is included in +the collection, provided that you follow the rules of this License for +verbatim copying of each of the documents in all other respects. + +You may extract a single document from such a collection, and distribute +it individually under this License, provided you insert a copy of this +License into the extracted document, and follow this License in all +other respects regarding verbatim copying of that document. + + + +\section{Aggregation With Independent Works} + +A compilation of the Document or its derivatives with other separate +and independent documents or works, in or on a volume of a storage or +distribution medium, does not as a whole count as a Modified Version +of the Document, provided no compilation copyright is claimed for the +compilation. Such a compilation is called an ``aggregate'', and this +License does not apply to the other self-contained works thus compiled +with the Document, on account of their being thus compiled, if they +are not themselves derivative works of the Document. + +If the Cover Text requirement of section 3 is applicable to these +copies of the Document, then if the Document is less than one quarter +of the entire aggregate, the Document's Cover Texts may be placed on +covers that surround only the Document within the aggregate. +Otherwise they must appear on covers around the whole aggregate. + + +\section{Translation} + +Translation is considered a kind of modification, so you may +distribute translations of the Document under the terms of section 4. +Replacing Invariant Sections with translations requires special +permission from their copyright holders, but you may include +translations of some or all Invariant Sections in addition to the +original versions of these Invariant Sections. You may include a +translation of this License provided that you also include the +original English version of this License. In case of a disagreement +between the translation and the original English version of this +License, the original English version will prevail. + + +\section{Termination} + +You may not copy, modify, sublicense, or distribute the Document except +as expressly provided for under this License. Any other attempt to +copy, modify, sublicense or distribute the Document is void, and will +automatically terminate your rights under this License. However, +parties who have received copies, or rights, from you under this +License will not have their licenses terminated so long as such +parties remain in full compliance. + + +\section{Future Revisions of This License} + +The Free Software Foundation may publish new, revised versions +of the GNU Free Documentation License from time to time. Such new +versions will be similar in spirit to the present version, but may +differ in detail to address new problems or concerns. See +http://www.gnu.org/copyleft/. + +Each version of the License is given a distinguishing version number. +If the Document specifies that a particular numbered version of this +License "or any later version" applies to it, you have the option of +following the terms and conditions either of that specified version or +of any later version that has been published (not as a draft) by the +Free Software Foundation. If the Document does not specify a version +number of this License, you may choose any version ever published (not +as a draft) by the Free Software Foundation. + +\section*{ADDENDUM: How to use this License for your documents} + +To use this License in a document you have written, include a copy of +the License in the document and put the following copyright and +license notices just after the title page: + +\begin{quote} + + Copyright \copyright\ YEAR YOUR NAME. + Permission is granted to copy, distribute and/or modify this document + under the terms of the GNU Free Documentation License, Version 1.1 + or any later version published by the Free Software Foundation; + with the Invariant Sections being LIST THEIR TITLES, with the + Front-Cover Texts being LIST, and with the Back-Cover Texts being LIST. + A copy of the license is included in the section entitled ``GNU + Free Documentation License''. + +\end{quote} + +If you have no Invariant Sections, write ``with no Invariant Sections'' +instead of saying which ones are invariant. If you have no +Front-Cover Texts, write ``no Front-Cover Texts'' instead of +``Front-Cover Texts being LIST''; likewise for Back-Cover Texts. + +If your document contains nontrivial examples of program code, we +recommend releasing these examples in parallel under your choice of +free software license, such as the GNU General Public License, +to permit their use in free software. + diff --git a/dvb-spec/dvbapi/frontend.tex b/dvb-spec/dvbapi/frontend.tex index e41ef3d54..bb177df1b 100644 --- a/dvb-spec/dvbapi/frontend.tex +++ b/dvb-spec/dvbapi/frontend.tex @@ -1,52 +1,176 @@ \devsec{DVB Frontend API} The DVB frontend device controls the tuner and DVB demodulator hardware. -It can be accessed through \texttt{/dev/ost/frontend}. -If you are using \texttt{devfs} you can use \texttt{/dev/dvb/card0/frontend}. -The frontend device will only be made visible through \texttt{devfs} -if the corresponding card actually has a frontend. Cards which support -the DVB API but, e.g., only can play back recordings, will not offer the -frontend device. +It can be accessed through \texttt{/dev/dvb/adapter0/frontend0}. +Data types and and ioctl definitions can be accessed by including +\texttt{linux/dvb/frontend.h} in your application. + +DVB frontends come in three varieties: DVB-S (satellite), DVB-C (cable) +and DVB-T (terrestrial). Transmission via the internet (DVB-IP) is +not handled by this API. +For DVB-S the frontend device also supports satellite equipment control +(SEC) via DiSEqC and V-SEC protocols. The DiSEqC (digital SEC) specification +is available from Eutelsat \texttt{http://www.eutelsat.org/}. + +Note that the DVB API may also be used for MPEG decoder-only PCI cards, +in which case there exists no frontend device. \devsubsec{Frontend Data Types} -\devsubsubsec{frontend status} -\label{frontendstatus} +\devsubsubsec{frontend type} +\label{frontendtype} + +For historic reasons frontend types are named after the +type of modulation used in transmission. -Several functions of the frontend device use the feStatus data -type defined by \begin{verbatim} -typedef uint32_t feStatus; +typedef enum fe_type { + FE_QPSK, /* DVB-S */ + FE_QAM, /* DVB-C */ + FE_OFDM /* DVB-T */ +} fe_type_t; \end{verbatim} -to indicate the current state and/or state changes of -the frontend hardware. -\noindent -It can take on the values +\devsubsubsec{frontend capabilities} +\label{frontendcaps} + +Capabilities describe what a frontend can do. Some capabilities +can only be supported for a specific frontend type. + +\begin{verbatim} +typedef enum fe_caps { + FE_IS_STUPID = 0, + FE_CAN_INVERSION_AUTO = 0x1, + FE_CAN_FEC_1_2 = 0x2, + FE_CAN_FEC_2_3 = 0x4, + FE_CAN_FEC_3_4 = 0x8, + FE_CAN_FEC_4_5 = 0x10, + FE_CAN_FEC_5_6 = 0x20, + FE_CAN_FEC_6_7 = 0x40, + FE_CAN_FEC_7_8 = 0x80, + FE_CAN_FEC_8_9 = 0x100, + FE_CAN_FEC_AUTO = 0x200, + FE_CAN_QPSK = 0x400, + FE_CAN_QAM_16 = 0x800, + FE_CAN_QAM_32 = 0x1000, + FE_CAN_QAM_64 = 0x2000, + FE_CAN_QAM_128 = 0x4000, + FE_CAN_QAM_256 = 0x8000, + FE_CAN_QAM_AUTO = 0x10000, + FE_CAN_TRANSMISSION_MODE_AUTO = 0x20000, + FE_CAN_BANDWIDTH_AUTO = 0x40000, + FE_CAN_GUARD_INTERVAL_AUTO = 0x80000, + FE_CAN_HIERARCHY_AUTO = 0x100000, + FE_CAN_MUTE_TS = 0x80000000, + FE_CAN_CLEAN_SETUP = 0x40000000 +} fe_caps_t; +\end{verbatim} + +\devsubsubsec{frontend information} +\label{frontendinfo} + +Information about the frontend ca be queried with +FE\_GET\_INFO (\ref{fegetinfo}). + +\begin{verbatim} +struct dvb_frontend_info { + char name[128]; + fe_type_t type; + uint32_t frequency_min; + uint32_t frequency_max; + uint32_t frequency_stepsize; + uint32_t frequency_tolerance; + uint32_t symbol_rate_min; + uint32_t symbol_rate_max; + uint32_t symbol_rate_tolerance; /* ppm */ + uint32_t notifier_delay; /* ms */ + fe_caps_t caps; +}; +\end{verbatim} + +\devsubsubsec{diseqc master command} +\label{diseqcmastercmd} + +A message sent from the frontend to DiSEqC capable equipment. + +\begin{verbatim} +struct dvb_diseqc_master_cmd { + uint8_t msg [6]; /* { framing, address, command, data[3] } */ + uint8_t msg_len; /* valid values are 3...6 */ +}; +\end{verbatim} + +\devsubsubsec{diseqc slave reply} +\label{diseqcslavereply} + +A reply to the frontend from DiSEqC 2.0 capable equipment. + +\begin{verbatim} +struct dvb_diseqc_slave_reply { + uint8_t msg [4]; /* { framing, data [3] } */ + uint8_t msg_len; /* valid values are 0...4, 0 means no msg */ + int timeout; /* return from ioctl after timeout ms with */ +}; /* errorcode when no message was received */ +\end{verbatim} + +\devsubsubsec{SEC voltage} +\label{secvoltage} + +The voltage is usually used with non-DiSEqC capable LNBs to +switch the polarzation (horizontal/vertical). + +\begin{verbatim} +typedef enum fe_sec_voltage { + SEC_VOLTAGE_13, + SEC_VOLTAGE_18 +} fe_sec_voltage_t; +\end{verbatim} + +\devsubsubsec{SEC continuous tone} +\label{sectone} + +The continous 22KHz tone is usually used with non-DiSEqC capable LNBs to +switch the high/low band of a dual-band LNB. + +\begin{verbatim} +typedef enum fe_sec_tone_mode { + SEC_TONE_ON, + SEC_TONE_OFF +} fe_sec_tone_mode_t; +\end{verbatim} + +\devsubsubsec{SEC tone burst} +\label{sectoneburst} + +The 22KHz tone burst is usually used with non-DiSEqC capable +switches to select between two connected LNBs/satellites. + \begin{verbatim} -#define FE_HAS_POWER 1 -#define FE_HAS_SIGNAL 2 -#define FE_SPECTRUM_INV 4 -#define FE_HAS_LOCK 8 -#define FE_HAS_CARRIER 16 -#define FE_HAS_VITERBI 32 -#define FE_HAS_SYNC 64 -#define TUNER_HAS_LOCK 128 +typedef enum fe_sec_mini_cmd { + SEC_MINI_A, + SEC_MINI_B +} fe_sec_mini_cmd_t; \end{verbatim} -which can be ORed together and have the following meaning: -\medskip -\begin{tabular}{lp{11cm}} -FE\_HAS\_POWER & the frontend is powered up and is ready to be used\\ -FE\_HAS\_SIGNAL & the frontend detects a signal above the normal noise level\\ -FE\_SPECTRUM\_INV & spectrum inversion is enabled/was necessary for lock\\ -FE\_HAS\_LOCK & frontend successfully locked to a DVB signal \\ -FE\_HAS\_CARRIER & carrier detected in signal\\ -FE\_HAS\_VITERBI & lock at viterbi decoder stage\\ -FE\_HAS\_SYNC & TS sync bytes detected \\ -TUNER\_HAS\_LOCK & the tuner has a frequency lock -\end{tabular} +\devsubsubsec{frontend status} +\label{frontendstatus} + +Several functions of the frontend device use the fe\_status data +type defined by +\begin{verbatim} +typedef enum fe_status { + FE_HAS_SIGNAL = 0x01, /* found something above the noise level */ + FE_HAS_CARRIER = 0x02, /* found a DVB signal */ + FE_HAS_VITERBI = 0x04, /* FEC is stable */ + FE_HAS_SYNC = 0x08, /* found sync bytes */ + FE_HAS_LOCK = 0x10, /* everything's working... */ + FE_TIMEDOUT = 0x20, /* no lock within the last ~2 seconds */ + FE_REINIT = 0x40 /* frontend was reinitialized, */ +} fe_status_t; /* application is recommned to reset */ +\end{verbatim} +to indicate the current state and/or state changes of +the frontend hardware. \devsubsubsec{frontend parameters} @@ -57,45 +181,44 @@ depend on the kind of hardware you are using. All kinds of parameters are combined as a union in the FrontendParameters structure: \begin{verbatim} -typedef struct { - __u32 Frequency; /* (absolute) frequency in Hz for QAM/OFDM */ - /* intermediate frequency in kHz for QPSK */ - fe_spectral_inversion_t Inversion; /* spectral inversion */ +struct dvb_frontend_parameters { + uint32_t frequency; /* (absolute) frequency in Hz for QAM/OFDM */ + /* intermediate frequency in kHz for QPSK */ + fe_spectral_inversion_t inversion; union { - QPSKParameters qpsk; - QAMParameters qam; - OFDMParameters ofdm; + struct dvb_qpsk_parameters qpsk; + struct dvb_qam_parameters qam; + struct dvb_ofdm_parameters ofdm; } u; -} FrontendParameters; +}; \end{verbatim} For satellite QPSK frontends you have to use QPSKParameters defined by \begin{verbatim} -typedef struct { - __u32 SymbolRate; /* symbol rate in Symbols per second */ - fe_code_rate_t FEC_inner; /* forward error correction (see above) */ -} QPSKParameters; +struct dvb_qpsk_parameters { + uint32_t symbol_rate; /* symbol rate in Symbols per second */ + fe_code_rate_t fec_inner; /* forward error correction (see above) */ +}; \end{verbatim} for cable QAM frontend you use the QAMParameters structure \begin{verbatim} -typedef struct { - __u32 SymbolRate; /* symbol rate in Symbols per second */ - fe_code_rate_t FEC_outer; /* forward error correction (see above) */ - fe_code_rate_t FEC_inner; /* forward error correction (see above) */ - fe_modulation_t QAM; /* modulation type (see above) */ -} QAMParameters; +struct dvb_qam_parameters { + uint32_t symbol_rate; /* symbol rate in Symbols per second */ + fe_code_rate_t fec_inner; /* forward error correction (see above) */ + fe_modulation_t modulation; /* modulation type (see above) */ +}; \end{verbatim} DVB-T frontends are supported by the OFDMParamters structure \begin{verbatim} -typedef struct { - fe_bandwidth_t bandWidth; - fe_code_rate_t HP_fe_code_rate_t; /* high priority stream code rate */ - fe_code_rate_t LP_fe_code_rate_t; /* low priority stream code rate */ - fe_modulation_t Constellation; /* modulation type (see above) */ - fe_transmit_mode_t TransmissionMode; - fe_guard_interval_t guardInterval; - fe_hierarchy_t fe_hierarchy_tInformation; -} OFDMParameters; +struct dvb_ofdm_parameters { + fe_bandwidth_t bandwidth; + fe_code_rate_t code_rate_HP; /* high priority stream code rate */ + fe_code_rate_t code_rate_LP; /* low priority stream code rate */ + fe_modulation_t constellation; /* modulation type (see above) */ + fe_transmit_mode_t transmission_mode; + fe_guard_interval_t guard_interval; + fe_hierarchy_t hierarchy_information; +}; \end{verbatim} In the case of QPSK frontends the Frequency field specifies the intermediate @@ -107,7 +230,7 @@ and is given in Hz. The Inversion field can take one of these values: \begin{verbatim} -typedef enum { +typedef enum fe_spectral_inversion { INVERSION_OFF, INVERSION_ON, INVERSION_AUTO @@ -120,15 +243,18 @@ try to figure out the correct setting by itself. \noindent The possible values for the FEC\_inner field are \begin{verbatim} -enum { - FEC_AUTO, +typedef enum fe_code_rate { + FEC_NONE = 0, FEC_1_2, FEC_2_3, FEC_3_4, + FEC_4_5, FEC_5_6, + FEC_6_7, FEC_7_8, - FEC_NONE -}; + FEC_8_9, + FEC_AUTO +} fe_code_rate_t; \end{verbatim} which correspond to error correction rates of $1\over 2$, $2\over 3$, etc., no error correction or auto detection. @@ -137,47 +263,52 @@ no error correction or auto detection. For cable and terrestrial frontends (QAM and OFDM) one also has to specify the quadrature modulation mode which can be one of the following: \begin{verbatim} -typedef enum -{ QPSK, +typedef enum fe_modulation { + QPSK, QAM_16, QAM_32, QAM_64, QAM_128, - QAM_256 -} QAM_TYPE; + QAM_256, + QAM_AUTO +} fe_modulation_t; \end{verbatim} Finally, there are several more parameters for OFDM: \begin{verbatim} -typedef enum { +typedef enum fe_transmit_mode { TRANSMISSION_MODE_2K, - TRANSMISSION_MODE_8K + TRANSMISSION_MODE_8K, + TRANSMISSION_MODE_AUTO } fe_transmit_mode_t; \end{verbatim} \begin{verbatim} -typedef enum { +typedef enum fe_bandwidth { BANDWIDTH_8_MHZ, BANDWIDTH_7_MHZ, - BANDWIDTH_6_MHZ + BANDWIDTH_6_MHZ, + BANDWIDTH_AUTO } fe_bandwidth_t; \end{verbatim} \begin{verbatim} -typedef enum { +typedef enum fe_guard_interval { GUARD_INTERVAL_1_32, GUARD_INTERVAL_1_16, GUARD_INTERVAL_1_8, - GUARD_INTERVAL_1_4 + GUARD_INTERVAL_1_4, + GUARD_INTERVAL_AUTO } fe_guard_interval_t; \end{verbatim} \begin{verbatim} -typedef enum { +typedef enum fe_hierarchy { HIERARCHY_NONE, HIERARCHY_1, HIERARCHY_2, - HIERARCHY_4 + HIERARCHY_4, + HIERARCHY_AUTO } fe_hierarchy_t; \end{verbatim} @@ -186,78 +317,12 @@ typedef enum { \label{frontendevents} \begin{verbatim} -enum { - FE_UNEXPECTED_EV, - FE_COMPLETION_EV, - FE_FAILURE_EV +struct dvb_frontend_event { + fe_status_t status; + struct dvb_frontend_parameters parameters; }; \end{verbatim} -\begin{verbatim} -typedef struct { - EventType type; /* type of event, FE_UNEXPECTED_EV, ... */ - long timestamp; /* time in seconds since 1970-01-01 */ - - union { - struct { - fe_status_t previousStatus; /* status before event */ - fe_status_t currentStatus; /* status during event */ - } unexpectedEvent; - FrontendParameters completionEvent; /* parameters for which the - tuning succeeded */ - fe_status_t failureEvent; /* status at failure (e.g. no lock) */ - } u; -} FrontendEvent; -\end{verbatim} - -\begin{verbatim} -struct qpskRegister { - uint8_t chipId; - uint8_t address; - uint8_t value; -}; -\end{verbatim} - -\begin{verbatim} -struct qamRegister { - uint8_t chipId; - uint8_t address; - uint8_t value; -}; -\end{verbatim} - -\begin{verbatim} -struct qpskFrontendInfo { - uint32_t minFrequency; - uint32_t maxFrequency; - uint32_t maxSymbolRate; - uint32_t minSymbolRate; - uint32_t hwType; - uint32_t hwVersion; -}; -\end{verbatim} - -\begin{verbatim} -struct qamFrontendInfo { - uint32_t minFrequency; - uint32_t maxFrequency; - uint32_t maxSymbolRate; - uint32_t minSymbolRate; - uint32_t hwType; - uint32_t hwVersion; -}; -\end{verbatim} - -\begin{verbatim} -typedef enum { - FE_POWER_ON, - FE_POWER_STANDBY, - FE_POWER_SUSPEND, - FE_POWER_OFF -} powerState_t; -\end{verbatim} - - \clearpage @@ -265,9 +330,9 @@ typedef enum { \function{open()}{ int open(const char *deviceName, int flags);}{ - This system call opens a named frontend device (e.g. /dev/ost/qpskfe - for a satellite frontend or /dev/ost/qamfe for a cable frontend) - for subsequent use. + This system call opens a named frontend device (/dev/dvb/adapter0/frontend0) + for subsequent use. Usually the first thing to do after a successful open + is to find out the frontend type with FE\_GET\_INFO. The device can be opened in read-only mode, which only allows monitoring of device status and statistics, or read/write mode, which allows @@ -303,119 +368,21 @@ typedef enum { int close(int fd);}{ This system call closes a previously opened front-end device. After closing a front-end device, its corresponding hardware might be - powered down automatically, but only when this is needed to open - another front-end device. - To affect an unconditional power down, it should be done explicitly using - the OST\_SET\_POWER\_STATE ioctl. + powered down automatically. }{ int fd & File descriptor returned by a previous call to open().\\ }{ EBADF & fd is not a valid open file descriptor.\\ } -\ifunction{OST\_SELFTEST}{ - int ioctl(int fd, int request = OST\_SELFTEST);}{ - This ioctl call initiates an automatic self-test of the front-end hardware. - This call requires read/write access to the device. - }{ - int fd & File descriptor returned by a previous call to open().\\ - int request & Equals OST\_SELFTEST for this command.\\ - }{ - -1& Self test failure.\\ -} - -\ifunction{OST\_SET\_POWER\_STATE}{ - int ioctl(int fd, int request = OST\_SET\_POWER\_STATE, uint32\_t state);}{ - This ioctl call, implemented in many OST device drivers, enables direct - control over the power state of the hardware device, which may be on, off, - standby, or suspend. The latter two are low-power modes, which disable all - functionality of the device until turned on again. In contrast to the off - state, however, the standby and suspend states resume operation in the same - state as when the device was active. The only difference between the standby - and suspend states is a different tradeoff between resume time and power - consumption. Power consumption may be lower in the suspend state at the - cost of a longer resume time.\\ - A device that implements this call does not necessarily support two low-power - modes. If it only supports one low-power state, or none at all, the - OST\_SET\_POWER\_STATE operation for the missing states will - still succeed, but - it will be mapped to an existing state as per this table: \\ - \begin{center} - \begin{tabular}[h]{cll} - number of low-power & requested state & resulting state\\ - states supported &&\\ - \\ - 1 & standby & suspend \\ - 1 & suspend & suspend \\ - 0 & standby & on \\ - 0 & suspend & on - \end{tabular} - \end{center}\\ - For other cases where a required state is missing, an error code will be - returned. This can happen if a device does not support the power-off state, - but nevertheless implements this ioctl operation for control of low-power - states. - When opening a device in read/write mode, the driver ensures that the - corresponding hardware device is turned on initially. If the device is - later turned off or put in suspend mode, it has to be explicitly turned on - again.\\ - This call requires read/write access to the device. (Note that the power - management driver can affect the power state of devices without using this - ioctl operation, so having exclusive read/write access to a device does not - imply total control over the power state.) - }{ - int fd & File descriptor returned by a previous call to open().\\ - int request & Equals OST\_SET\_POWER\_STATE for this command.\\ - uint32\_t state & Requested power state. One of: \\ - & - \begin{tabular}[h]{ll} - OST\_POWER\_ON& turn power on\\ - OST\_POWER\_STANDBY& set device in standby mode\\ - OST\_POWER\_SUSPEND& set device in suspend mode\\ - OST\_POWER\_OFF& turn power off\\ - \end{tabular} - }{ - EBADF& fd is not a valid open file descriptor.\\ - EINVAL& Illegal state, or not available on this device.\\ - EPERM & Permission denied (needs read/write access).\\ - ENOSYS& Function not available for this device. -} - -\ifunction{FE\_GET\_POWER\_STATE}{ - int ioctl(int fd, int request = OST\_GET\_POWER\_STATE, uint32\_t *state);}{ - This ioctl call, implemented in many OST device drivers, obtains the power - state of the hardware device, which may be on, off, standby, or suspend. - A device that implements this call does not necessarily support all four states. - If there is only one low-power state, the suspend state will be returned for - that state. If there is no low-power state, the on state will be reported - standby and suspend states will be equivalent to the on state. - For this command, read-only access to the device is sufficient. - }{ - int fd & File descriptor returned by a previous call to open().\\ - int request & Equals OST\_GET\_POWER\_STATE for this command.\\ - uint32\_t *state & Requested power state. One of: \\ - & - \begin{tabular}[h]{ll} - OST\_POWER\_ON& power is on\\ - OST\_POWER\_STANDBY& device in standby mode\\ - OST\_POWER\_SUSPEND& device in suspend mode\\ - OST\_POWER\_OFF& power is off\\ - \end{tabular} - }{ - EBADF& fd is not a valid open file descriptor.\\ - EINVAL& Illegal state, or not available on this device.\\ - EFAULT& state points to invalid address.\\ - ENOSYS& Function not available for this device. -} - \ifunction{FE\_READ\_STATUS}{ - int ioctl(int fd, int request = FE\_READ\_STATUS, feStatus *status);}{ + int ioctl(int fd, int request = FE\_READ\_STATUS, fe\_status\_t *status);}{ This ioctl call returns status information about the front-end. This call only requires read-only access to the device. }{ int fd & File descriptor returned by a previous call to open().\\ int request & Equals FE\_READ\_STATUS for this command.\\ - struct feStatus *status&Points to the location where the front-end + struct fe\_status\_t *status & Points to the location where the front-end status word is to be stored. }{ EBADF& fd is not a valid open file descriptor.\\ @@ -430,10 +397,7 @@ typedef enum { }{ int fd & File descriptor returned by a previous call to open().\\ int request & Equals FE\_READ\_BER for this command.\\ - uint32\_t *ber & The bit error rate, as a multiple of $10^{-9}$, - is stored into *ber.\\ - & Example: a value of 2500 corresponds to a bit error - rate of $2.5\cdot 10^{-6}$, or 1 error in 400000 bits. + uint32\_t *ber & The bit error rate is stored into *ber.\\ }{ EBADF& fd is not a valid open file descriptor.\\ EFAULT& ber points to invalid address.\\ @@ -443,17 +407,14 @@ typedef enum { } \ifunction{FE\_READ\_SNR}{ - int ioctl(int fd, int request = FE\_READ\_SNR, int32\_t *snr);}{ + int ioctl(int fd, int request = FE\_READ\_SNR, int16\_t *snr);}{ This ioctl call returns the signal-to-noise ratio for the signal currently received by the front-end. For this command, read-only access to the device is sufficient. }{ int fd & File descriptor returned by a previous call to open().\\ int request & Equals FE\_READ\_SNR for this command.\\ - int32\_t *snr& The signal-to-noise ratio, as a multiple of - $10^{-6}$ dB, is stored into *snr.\\ - & Example: a value of 12,300,000 corresponds - to a signal-to-noise ratio of 12.3 dB. + int16\_t *snr& The signal-to-noise ratio is stored into *snr.\\ }{ EBADF& fd is not a valid open file descriptor.\\ EFAULT& snr points to invalid address.\\ @@ -463,7 +424,7 @@ typedef enum { } \ifunction{FE\_READ\_SIGNAL\_STRENGTH}{ - int ioctl( int fd, int request = FE\_READ\_SIGNAL\_STRENGTH, int32\_t *strength); + int ioctl( int fd, int request = FE\_READ\_SIGNAL\_STRENGTH, int16\_t *strength); }{ This ioctl call returns the signal strength value for the signal currently received by the front-end. For this command, read-only access to the device @@ -471,11 +432,7 @@ is sufficient. }{ int fd & File descriptor returned by a previous call to open().\\ int request & Equals FE\_READ\_SIGNAL\_STRENGTH for this command.\\ -int32\_t *strength & The signal strength value, as a multiple of - $10^{-6 }$ dBm, - is stored into *strength. \\ - &Example: a value of -12,500,000 corresponds to a signal - strength value of -12.5 dBm. +int16\_t *strength & The signal strength value is stored into *strength.\\ }{ EBADF& fd is not a valid open file descriptor.\\ EFAULT& status points to invalid address.\\ @@ -505,59 +462,8 @@ by the driver so far. } -\ifunction{FE\_GET\_NEXT\_FREQUENCY}{ - int ioctl( int fd, int request = FE\_GET\_NEXT\_FREQUENCY, uint32\_t *freq);}{ - When scanning a frequency range, it is desirable to use a scanning step size - that is as large as possible, yet small enough to be able to lock to any signal - within the range. - This ioctl operation does just that - it increments a given frequency by a - step size suitable for efficient scanning. - The step size used by this function may be a quite complex function of the given - frequency, hardware capabilities, and parameter settings of the device. Thus, a - returned result is only valid for the current state of the device. - For this command, read-only access to the device is sufficient.\\ - Note that scanning may still be excruciatingly slow on some hardware, for - other reasons than a non-optimal scanning step size. - }{ - int fd & File descriptor returned by a previous call to open().\\ - int request & Equals FE\_GET\_NEXT\_FREQUENCY for this command.\\ - uint32\_t *freq& Input: a given frequency \\ - & Output: the frequency corresponding to - the next higher frequency setting.\\ - }{ - EBADF& fd is not a valid open file descriptor.\\ - EFAULT& freq points to invalid address.\\ - EINVAL& Maximum supported frequency reached.\\ - ENOSYS& Function not available for this device. -} - -\ifunction{FE\_GET\_NEXT\_SYMBOL\_RATE}{ - int ioctl( int fd, int request = FE\_GET\_NEXT\_SYMBOL\_RATE, uint32\_t *symbolRate); - }{ - When scanning a range of symbol rates (e.g. for "blind acquisition") it is - desirable to use a scanning step size that is as large as possible, yet - small enough to detect any valid signal within the range. This ioctl - operation does just that - it increments a given symbol rate by a step size - suitable for efficient scanning. - The step size used by this function may be a quite complex function of the given - symbol rate, hardware capabilities, and parameter settings of the device. - Thus, a returned result is only valid for the current state of the device. - For this command, read-only access to the device is sufficient. - }{ - int fd & File descriptor returned by a previous call to open().\\ - int request & Equals FE\_GET\_NEXT\_SYMBOL\_RATE for this command.\\ - uint32\_t *symbolRate& Input: a given symbol rate \\ - & Output: the symbol rate corresponding to - the next higher symbol rate.\\ - }{ - EBADF& fd is not a valid open file descriptor.\\ - EFAULT& symbolRate points to invalid address.\\ - EINVAL& Maximum supported symbol rate reached.\\ - ENOSYS& Function not available for this device. -} - \ifunction{FE\_SET\_FRONTEND}{ - int ioctl(int fd, int request = FE\_SET\_FRONTEND, struct FrontendParameters *p);}{ + int ioctl(int fd, int request = FE\_SET\_FRONTEND, struct dvb\_frontend\_parameters *p);}{ This ioctl call starts a tuning operation using specified parameters. The result of this call will be successful if the parameters were valid and the tuning could be initiated. @@ -571,7 +477,21 @@ by the driver so far. }{ int fd & File descriptor returned by a previous call to open().\\ int request & Equals FE\_SET\_FRONTEND for this command.\\ - struct FrontendParameters *p& Points to parameters for tuning operation.\\ + struct dvb\_frontend\_parameters *p& Points to parameters for tuning operation.\\ + }{ + EBADF& fd is not a valid open file descriptor.\\ + EFAULT& p points to invalid address.\\ + EINVAL& Maximum supported symbol rate reached.\\ +} + +\ifunction{FE\_GET\_FRONTEND}{ + int ioctl(int fd, int request = FE\_GET\_FRONTEND, struct dvb\_frontend\_parameters *p);}{ + This ioctl call queries the currently effective frontend parameters. + For this command, read-only access to the device is sufficient. + }{ + int fd & File descriptor returned by a previous call to open().\\ + int request & Equals FE\_SET\_FRONTEND for this command.\\ + struct dvb\_frontend\_parameters *p& Points to parameters for tuning operation.\\ }{ EBADF& fd is not a valid open file descriptor.\\ EFAULT& p points to invalid address.\\ @@ -579,8 +499,8 @@ by the driver so far. } \ifunction{FE\_GET\_EVENT}{ - int ioctl(int fd, int request = QPSK\_GET\_EVENT, struct qpskEvent *ev);}{ - This ioctl call returns an event of type qpskEvent if available. If an event + int ioctl(int fd, int request = QPSK\_GET\_EVENT, struct dvb\_frontend\_event *ev);}{ + This ioctl call returns a frontend 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 @@ -593,14 +513,15 @@ by the driver so far. must be serviced regularly to avoid overflow. If an overflow happens, the oldest event is discarded from the queue, and an error (EOVERFLOW) occurs the next time the queue is read. After reporting the error condition in this - fashion, subsequent QPSK\_GET\_EVENT calls will return events from the queue as + fashion, subsequent FE\_GET\_EVENT calls will return events from the queue as usual.\\ For the sake of implementation simplicity, this command requires read/write access to the device. }{ int fd & File descriptor returned by a previous call to open().\\ - int request & Equals QPSK\_GET\_EVENT for this command.\\ - struct qpskEvent *ev&Points to the location where the event, if any, is to be stored. + int request & Equals FE\_GET\_EVENT for this command.\\ + struct dvb\_frontend\_event *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.\\ @@ -611,19 +532,133 @@ by the driver so far. } \ifunction{FE\_GET\_INFO}{ - int ioctl(int fd, int request = FE\_GET\_INFO, struct FrontendInfo *info);}{ +\label{fegetinfo} + int ioctl(int fd, int request = FE\_GET\_INFO, struct dvb\_frontend\_info *info);}{ This ioctl call returns information about the front-end. This call only requires read-only access to the device. }{ int fd & File descriptor returned by a previous call to open().\\ int request & Equals FE\_GET\_INFO for this command.\\ - struct qpskFrontendInfo *info & Points to the location where the front-end + struct dvb\_frontend\_info *info & Points to the location where the front-end information is to be stored. }{ EBADF& fd is not a valid open file descriptor.\\ EFAULT& info points to invalid address.\\ } +\ifunction{FE\_DISEC\_RESET\_OVERLOAD}{ + int ioctl(int fd, int request = FE\_DISEC\_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 FE\_DISEC\_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{FE\_DISEC\_SEND\_MASTER\_CMD}{ +int ioctl(int fd, int request = FE\_DISEC\_SEND\_MASTER\_CMD, struct dvb\_diseqc\_master\_cmd *cmd);}{ + This ioctl call is used to send a a DiSEqC command.\\ + }{ + int fd & File descriptor returned by a previous call to open().\\ + int request & Equals FE\_DISEC\_SEND\_MASTER\_CMD for this command.\\ + struct dvb\_diseqc\_master\_cmd *cmd & Pointer to the command 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.\\ +} + +\ifunction{FE\_DISEC\_RECV\_SLAVE\_REPLY}{ +int ioctl(int fd, int request = FE\_DISEC\_RECV\_SLAVE\_REPLY, struct dvb\_diseqc\_slave\_reply *reply);}{ +This ioctl call is used to receive reply to a DiSEqC 2.0 command.\\ + }{ + int fd & File descriptor returned by a previous call to open().\\ + int request & Equals FE\_DISEC\_RECV\_SLAVE\_REPLY for this command.\\ + struct dvb\_diseqc\_slave\_reply *reply & Pointer to the command to be received.\\ + }{ + 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.\\ +} + +\ifunction{FE\_DISEC\_SEND\_BURST}{ +int ioctl(int fd, int request = FE\_DISEC\_SEND\_BURST, fe\_sec\_mini\_cmd\_t burst);}{ +This ioctl call is used to send a 22KHz tone burst.\\ + }{ + int fd & File descriptor returned by a previous call to open().\\ + int request & Equals FE\_DISEC\_SEND\_BURST for this command.\\ + fe\_sec\_mini\_cmd\_t burst & burst A or B.\\ + }{ + 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.\\ +} + + +\ifunction{FE\_SET\_TONE}{ +int ioctl(int fd, int request = FE\_SET\_TONE, fe\_sec\_tone\_mode\_t tone);}{ +This call is used to set the generation of the continuous 22kHz tone. +This call requires read/write permissions. +}{ +int fd & File descriptor returned by a previous call to open().\\ +int request & Equals FE\_SET\_TONE for this command.\\ +fe\_sec\_tone\_mode\_t 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{FE\_SET\_VOLTAGE}{ +int ioctl(int fd, int request = FE\_SET\_VOLTAGE, fe\_sec\_voltage\_t voltage);}{ +This call is used to set the bus voltage. +This call requires read/write permissions. +}{ +int fd & File descriptor returned by a previous call to open().\\ +int request & Equals FE\_SET\_VOLTAGE for this command.\\ +fe\_sec\_voltage\_t 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.\\ +} + +\ifunction{FE\_ENABLE\_HIGH\_LNB\_VOLTAGE}{ +int ioctl(int fd, int request = FE\_ENABLE\_HIGH\_LNB\_VOLTAGE, int high);}{ +If high != 0 enables slightly higher voltages instead of 13/18V +(to compensate for long cables). +This call requires read/write permissions. +}{ +int fd & File descriptor returned by a previous call to open().\\ +int request & Equals FE\_SET\_VOLTAGE for this command.\\ +int high & 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" diff --git a/dvb-spec/dvbapi/intro.tex b/dvb-spec/dvbapi/intro.tex index 1d859fadb..613bcd6c8 100644 --- a/dvb-spec/dvbapi/intro.tex +++ b/dvb-spec/dvbapi/intro.tex @@ -1,15 +1,21 @@ \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. +part I of the MPEG2 specification ISO/IEC 13818 (aka ITU-T H.222), +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. + +Various DVB standards documents are available from +\texttt{http://www.dvb.org/} and/or \texttt{http://www.etsi.org/}. 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 @@ -26,11 +32,12 @@ 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. +the Linux DVB API will be constantly reviewed and improved. With the Linux driver for the Siemens/Hauppauge DVB PCI card Convergence provides a first implementation of the Linux DVB API. +\newpage \section{Overview} \begin{figure}[htbp] @@ -49,14 +56,10 @@ main hardware components: 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. - +this signal into an MPEG transport stream (TS). In case of a satellite +frontend, this includes a facility for satellite equipment control (SEC), +which allows control of LNB polarization, multi feed switches or +dish rotors. \item Conditional Access (CA) hardware like CI adapters and smartcard slots @@ -74,10 +77,11 @@ 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 +decoders. After decoding they 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. @@ -91,11 +95,9 @@ Also not every card or STB provides conditional access hardware. 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. +video, audio, frontend, demux, CA and IP-over-DVB networking. 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. @@ -104,78 +106,41 @@ 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. +\smallskip 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 +\texttt{/dev/dvb}. The individual devices are called \begin{itemize} -\item \texttt{/dev/ost/audio}, -\item \texttt{/dev/ost/video}, -\item \texttt{/dev/ost/frontend}, -\item \texttt{/dev/ost/sec}, -\item \texttt{/dev/ost/demux}, -\item \texttt{/dev/ost/ca}, +\item \texttt{/dev/dvb/adapterN/audioM}, +\item \texttt{/dev/dvb/adapterN/videoM}, +\item \texttt{/dev/dvb/adapterN/frontendM}, +\item \texttt{/dev/dvb/adapterN/netM}, +\item \texttt{/dev/dvb/adapterN/demuxM}, +\item \texttt{/dev/dvb/adapterN/caM}, \end{itemize} -but we will omit the ``\texttt{/dev/ost/}'' in the further dicussion of -these devices. - -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. +where N enumerates the DVB PCI cards in a system starting from~0, +and M enumerates the devices of each type within each adapter, starting +from~0, too. +We will omit the ``\texttt{/dev/dvb/adapterN/}'' in the further dicussion of +these devices. The naming scheme for the devices is the same wheter devfs +is used or not. More details about the data structures and function calls of all the devices are described in the following chapters. +\section{API include files} -\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 not belong 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: +For each of the DVB devices a corresponding include file +exists. The DVB API include files should be included +in application sources with a partial path like: \begin{verbatim} -/dev/dvb/card0/frontend0 - demux0 - -/dev/dvb/card1/video0 - audio0 - demux0 - demux1 - frontend0 - sec0 +#include \end{verbatim} - -\section{Using the Devices} - -\dots - +To enable applications to support different API version, an additional +include file \texttt{linux/dvb/version.h} exists, which defines the +constant \texttt{DVB\_API\_VERSION}. This document describes +\texttt{DVB\_API\_VERSION~3}. %%% Local Variables: %%% mode: latex diff --git a/dvb-spec/dvbapi/kdapi.tex b/dvb-spec/dvbapi/kdapi.tex index 59490299b..f7fc69353 100644 --- a/dvb-spec/dvbapi/kdapi.tex +++ b/dvb-spec/dvbapi/kdapi.tex @@ -1,6 +1,13 @@ \devsec{Kernel Demux API} -The kernel demux API +The kernel demux API defines a driver-internal interface +for registering low-level, hardware specific driver to a +hardware independent demux layer. It is only of interest +for DVB device driver writers. The header file for this +API is named \texttt{demux.h} and located in +\texttt{drivers/media/dvb/dvb-core}. + +Maintainer note: This section must be reviewed. It is probably out of date. \devsubsec{Kernel Demux Data Types} diff --git a/dvb-spec/dvbapi/net.tex b/dvb-spec/dvbapi/net.tex new file mode 100644 index 000000000..dc6566633 --- /dev/null +++ b/dvb-spec/dvbapi/net.tex @@ -0,0 +1,19 @@ +\devsec{DVB Network API} + +The DVB net device enables feeding of MPE (multi protocol +encapsulation) packets received via DVB into the Linux network +protocol stack, e.g. for internet via satellite applications. +It can be accessed through \texttt{/dev/dvb/adapter0/net0}. +Data types and and ioctl definitions can be accessed by including +\texttt{linux/dvb/net.h} in your application. + + +\devsubsec{DVB Net Data Types} + +To be written\dots + + +%%% Local Variables: +%%% mode: latex +%%% TeX-master: "dvbapi" +%%% End: diff --git a/dvb-spec/dvbapi/sec.tex b/dvb-spec/dvbapi/sec.tex deleted file mode 100644 index 88342c3a6..000000000 --- a/dvb-spec/dvbapi/sec.tex +++ /dev/null @@ -1,282 +0,0 @@ -\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\_SEND\_SEQUENCE}{ -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 index 574464d23..29aca30d6 100644 --- a/dvb-spec/dvbapi/title.tex +++ b/dvb-spec/dvbapi/title.tex @@ -1,23 +1,27 @@ \pagenumbering{arabic} \pagestyle{empty} -\title{\huge\textbf{LINUX DVB API}} +\title{\huge\textbf{LINUX DVB API Version 3}} \author{ \includegraphics{cimlogo.psi}\\ - Convergence integrated media GmbH\\\\ - Dr. Ralph J.K. Metzler\\ - \texttt{}\\\\ - Dr. Marcus O.C. Metzler\\ - \texttt{} -% Rosenthalerstr. 51\\ -% 10178 Berlin\\Germany + Copyright 2002, 2003 Convergence GmbH\\\\ + Written by Dr. Ralph J.K. Metzler\\ + \texttt{}\\\\ + and Dr. Marcus O.C. Metzler\\ + \texttt{}\\ } -\date{02/14/2002\\V 0.9.4} +\date{02/10/2003\\V 1.0.0-pre1} + \maketitle +Permission is granted to copy, distribute and/or modify this document +under the terms of the GNU Free Documentation License, Version 1.1 +or any later version published by the Free Software Foundation. +A copy of the license is included in the chapter entitled "GNU +Free Documentation License". + \newpage -%\end{titlepage} % Local Variables: % mode: latex % TeX-master: "dvbapi" diff --git a/dvb-spec/dvbapi/video.tex b/dvb-spec/dvbapi/video.tex index 7300c95c0..3fa066b87 100644 --- a/dvb-spec/dvbapi/video.tex +++ b/dvb-spec/dvbapi/video.tex @@ -1,11 +1,22 @@ \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. Please note that some DVB cards don't have their own -MPEG decoder, which results in the omission of the audio and video -device as well as the video4linux device. +It can be accessed through \texttt{/dev/dvb/adapter0/video0}. +Data types and and ioctl definitions can be accessed by including +\texttt{linux/dvb/video.h} in your application. + + +Note that the DVB video device only controls decoding of the MPEG +video stream, not its presentation on the TV or computer screen. +On PCs this is typically handled by an associated video4linux device, e.g. +\texttt{/dev/video}, which allows scaling and defining output windows. + +Some DVB cards don't have their own MPEG decoder, which results in the omission +of the audio and video device as well as the video4linux device. + +The ioctls that deal with SPUs (sub picture units) and navigation +packets are only supported on some MPEG decoders made for DVD playback. + \devsubsec{Video Data Types} @@ -17,7 +28,7 @@ The \texttt{video\_format\_t} data type defined by typedef enum { VIDEO_FORMAT_4_3, VIDEO_FORMAT_16_9 -} video\_format_t; +} video_format_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. @@ -26,7 +37,7 @@ returned by VIDEO\_GET\_STATUS (\ref{videogetstatus}) and video\_event (\ref{videoevent}) returned by VIDEO\_GET\_EVENT (\ref{videogetevent}) which report about the display format of the current video stream. -\devsubsubsec{videoDisplayFormat\_t} +\devsubsubsec{video\_display\_format\_t} \label{videodispformat} In case the display format of the video stream and of the @@ -39,7 +50,7 @@ typedef enum { VIDEO_PAN_SCAN, VIDEO_LETTER_BOX, VIDEO_CENTER_CUT_OUT -} video\_displayformat_t; +} video_display_format_t; \end{verbatim} as argument. @@ -53,7 +64,7 @@ replaying from an internal (demuxer) or external (user write) source. typedef enum { VIDEO_SOURCE_DEMUX, VIDEO_SOURCE_MEMORY -} video\_stream\_source_t; +} video_stream_source_t; \end{verbatim} VIDEO\_SOURCE\_DEMUX selects the demultiplexer (fed either by the frontend or the DVR device) as the source of @@ -71,35 +82,35 @@ typedef enum { VIDEO_STOPPED, VIDEO_PLAYING, VIDEO_FREEZED -} video\_play\_state_t; +} video_play_state_t; \end{verbatim} -\devsubsubsec{video event} +\devsubsubsec{struct 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 video\_event { +struct video_event { int32_t type; time_t timestamp; union { - video\_format_t video\_format; + video_format_t video_format; } u; }; \end{verbatim} -\devsubsubsec{video status} +\devsubsubsec{struct video\_status} \label{videostatus} The VIDEO\_GET\_STATUS call returns the following structure informing about various states of the playback operation. \begin{verbatim} -struct video\_status { - boolean video\_blank; - video\_play\_state_t play\_state; - video\_stream\_source_t stream\_source; - video\_format_t video\_format; - video\_displayformat_t display\_format; +struct video_status { + boolean video_blank; + video_play_state_t play_state; + video_stream_source_t stream_source; + video_format_t video_format; + video_displayformat_t display_format; }; \end{verbatim} If video\_blank is set video will be blanked out if the channel is changed or @@ -113,13 +124,13 @@ Finally, display\_format 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} +\devsubsubsec{struct video\_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 video\_still\_picture { +struct video_still_picture { char *iFrame; int32_t size; }; @@ -162,19 +173,19 @@ typedef enum { VIDEO_SYSTEM_NTSC60, VIDEO_SYSTEM_PAL60, VIDEO_SYSTEM_PALM60 -} video\_system_t; +} video_system_t; \end{verbatim} -\devsubsubsec{video highlights} +\devsubsubsec{struct video\_highlight} \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 video\_highlight { +struct video_highlight { boolean active; /* 1=show highlight, 0=hide highlight */ uint8_t contrast1; /* 7- 4 Pattern pixel contrast */ /* 3- 0 Background pixel contrast */ @@ -190,7 +201,7 @@ struct video\_highlight { uint32_t xpos; /* 23-22 button color number */ /* 21-12 start x */ /* 9- 0 end x */ -} video\_highlight_t; +} video_highlight_t; \end{verbatim} @@ -200,10 +211,10 @@ Calling VIDEO\_SET\_SPU deactivates or activates SPU decoding, according to the following format: \begin{verbatim} typedef -struct video\_spu { +struct video_spu { boolean active; - int stream\_id; -} video\_spu\_t; + int stream_id; +} video_spu_t; \end{verbatim} @@ -212,10 +223,10 @@ struct video\_spu { The following structure is used to set the SPU palette by calling VIDEO\_SPU\_PALETTE: \begin{verbatim} typedef -struct video\_spu\_palette{ /* SPU Palette information */ +struct video_spu_palette{ int length; uint8_t *palette; -} video\_spu\_palette_t; +} video_spu_palette_t; \end{verbatim} \devsubsubsec{video NAVI pack} @@ -224,10 +235,10 @@ In order to get the navigational data the following structure has to be passed to the ioctl VIDEO\_GET\_NAVI: \begin{verbatim} typedef -struct video\_navi\_pack{ - int length; /* 0 ... 1024 */ +struct video_navi_pack{ + int length; /* 0 ... 1024 */ uint8_t data[1024]; -} video\_navi\_pack_t; +} video_navi_pack_t; \end{verbatim} @@ -235,7 +246,7 @@ struct video\_navi\_pack{ \label{vattrib} The following attributes can be set by a call to VIDEO\_SET\_ATTRIBUTES: \begin{verbatim} -typedef uint16_t video\_attributes_t; +typedef uint16_t video_attributes_t; /* bits: descr. */ /* 15-14 Video compression mode (0=MPEG-1, 1=MPEG-2) */ /* 13-12 TV system (0=525/60, 1=625/50) */ @@ -255,7 +266,7 @@ typedef uint16_t video\_attributes_t; \function{open()}{ int open(const char *deviceName, int flags);}{ - This system call opens a named video device (e.g. /dev/ost/video) + This system call opens a named video device (e.g. /dev/dvb/adapter0/video0) for subsequent use. When an open() call has succeeded, the device will be ready for use. @@ -376,7 +387,7 @@ EINTERNAL & Internal error, possibly in the communication with \ifunction{VIDEO\_SELECT\_SOURCE}{ - int ioctl(fd, int request = VIDEO\_SELECT\_SOURCE, videoStreamSource\_t source);}{ + int ioctl(fd, int request = VIDEO\_SELECT\_SOURCE, video\_stream\_source\_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 @@ -384,7 +395,7 @@ EINTERNAL & Internal error, possibly in the communication with }{ 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.\\ + video\_stream\_source\_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.\\ @@ -446,13 +457,13 @@ EOVERFLOW & \\ \ifunction{VIDEO\_SET\_DISPLAY\_FORMAT}{ \label{videosetdisplayformat} - int ioctl(fd, int request = VIDEO\_SET\_DISPLAY\_FORMAT, videoDisplayFormat\_t format);}{ + int ioctl(fd, int request = VIDEO\_SET\_DISPLAY\_FORMAT, video\_display\_format\_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.\\ + video\_display\_format\_t format & Selects the video format to be used.\\ }{ EBADF& fd is not a valid open file descriptor \\ EINTERNAL & Internal error.\\ @@ -578,7 +589,7 @@ EOVERFLOW & \\ \ifunction{VIDEO\_SET\_SYSTEM}{ \label{videosetsystem} - int ioctl(fd, int request = VIDEO\_SET\_SYSTEM , videoSystem\_t system); + int ioctl(fd, int request = VIDEO\_SET\_SYSTEM , video\_system\_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 @@ -587,7 +598,7 @@ EOVERFLOW & \\ }{ 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.\\ + video\_system\_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.\\ @@ -663,7 +674,7 @@ EOVERFLOW & \\ \ifunction{VIDEO\_SET\_ATTRIBUTES}{ \label{videosetattributes} - int ioctl(fd, int request = VIDEO\_SET\_ATTRIBUTE ,videoAttributes\_t + int ioctl(fd, int request = VIDEO\_SET\_ATTRIBUTE ,video\_attributes\_t vattr) }{ This ioctl is intended for DVD playback and allows you to set @@ -673,7 +684,7 @@ EOVERFLOW & \\ }{ 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}.\\ + video\_attributes\_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.\\ -- cgit v1.2.3 From e2d96061a03942dabe4a4248f41c7aea300f6680 Mon Sep 17 00:00:00 2001 From: holger Date: Mon, 10 Feb 2003 11:06:51 -0200 Subject: fix some minor typos --- dvb-spec/dvbapi/frontend.tex | 57 +++++++++++++++++++++++++------------------- 1 file changed, 33 insertions(+), 24 deletions(-) (limited to 'dvb-spec/dvbapi') diff --git a/dvb-spec/dvbapi/frontend.tex b/dvb-spec/dvbapi/frontend.tex index bb177df1b..cbd646b93 100644 --- a/dvb-spec/dvbapi/frontend.tex +++ b/dvb-spec/dvbapi/frontend.tex @@ -7,7 +7,7 @@ Data types and and ioctl definitions can be accessed by including DVB frontends come in three varieties: DVB-S (satellite), DVB-C (cable) and DVB-T (terrestrial). Transmission via the internet (DVB-IP) is -not handled by this API. +not yet handled by this API but a future extension is possible. For DVB-S the frontend device also supports satellite equipment control (SEC) via DiSEqC and V-SEC protocols. The DiSEqC (digital SEC) specification is available from Eutelsat \texttt{http://www.eutelsat.org/}. @@ -20,7 +20,7 @@ in which case there exists no frontend device. \devsubsubsec{frontend type} \label{frontendtype} -For historic reasons frontend types are named after the +For historical reasons frontend types are named after the type of modulation used in transmission. \begin{verbatim} @@ -117,7 +117,9 @@ struct dvb_diseqc_slave_reply { \label{secvoltage} The voltage is usually used with non-DiSEqC capable LNBs to -switch the polarzation (horizontal/vertical). +switch the polarzation (horizontal/vertical). +When using DiSEqC epuipment this voltage has to be switched consistently +to the DiSEqC commands as described in the DiSEqC spec. \begin{verbatim} typedef enum fe_sec_voltage { @@ -131,6 +133,8 @@ typedef enum fe_sec_voltage { The continous 22KHz tone is usually used with non-DiSEqC capable LNBs to switch the high/low band of a dual-band LNB. +When using DiSEqC epuipment this voltage has to be switched consistently +to the DiSEqC commands as described in the DiSEqC spec. \begin{verbatim} typedef enum fe_sec_tone_mode { @@ -144,6 +148,8 @@ typedef enum fe_sec_tone_mode { The 22KHz tone burst is usually used with non-DiSEqC capable switches to select between two connected LNBs/satellites. +When using DiSEqC epuipment this voltage has to be switched consistently +to the DiSEqC commands as described in the DiSEqC spec. \begin{verbatim} typedef enum fe_sec_mini_cmd { @@ -193,14 +199,15 @@ struct dvb_frontend_parameters { }; \end{verbatim} -For satellite QPSK frontends you have to use QPSKParameters defined by +For satellite QPSK frontends you have to use the \verb|QPSKParameters| member +defined by \begin{verbatim} struct dvb_qpsk_parameters { uint32_t symbol_rate; /* symbol rate in Symbols per second */ fe_code_rate_t fec_inner; /* forward error correction (see above) */ }; \end{verbatim} -for cable QAM frontend you use the QAMParameters structure +for cable QAM frontend you use the \verb|QAMParameters| structure \begin{verbatim} struct dvb_qam_parameters { uint32_t symbol_rate; /* symbol rate in Symbols per second */ @@ -208,7 +215,7 @@ struct dvb_qam_parameters { fe_modulation_t modulation; /* modulation type (see above) */ }; \end{verbatim} -DVB-T frontends are supported by the OFDMParamters structure +DVB-T frontends are supported by the \verb|OFDMParamters| structure \begin{verbatim} struct dvb_ofdm_parameters { fe_bandwidth_t bandwidth; @@ -221,9 +228,9 @@ struct dvb_ofdm_parameters { }; \end{verbatim} -In the case of QPSK frontends the Frequency field specifies the intermediate -frequency, i.e. the offset which is effectively added to the local oscillator -frequency (LOF) of the LNB. +In the case of QPSK frontends the \verb|Frequency| field specifies the +intermediate frequency, i.e. the offset which is effectively added to the +local oscillator frequency (LOF) of the LNB. The intermediate frequency has to be specified in units of kHz. For QAM and OFDM frontends the Frequency specifies the absolute frequency and is given in Hz. @@ -237,11 +244,11 @@ typedef enum fe_spectral_inversion { } fe_spectral_inversion_t; \end{verbatim} It indicates if spectral inversion should be presumed or not. -In the automatic setting (\verb INVERSION\_AUTO) the hardware will +In the automatic setting (\verb|INVERSION_AUTO|) the hardware will try to figure out the correct setting by itself. \noindent -The possible values for the FEC\_inner field are +The possible values for the \verb|FEC_inner| field are \begin{verbatim} typedef enum fe_code_rate { FEC_NONE = 0, @@ -256,7 +263,7 @@ typedef enum fe_code_rate { FEC_AUTO } fe_code_rate_t; \end{verbatim} -which correspond to error correction rates of $1\over 2$, $2\over 3$, etc., +which correspond to error correction rates of $1/2$, $2/3$, etc., no error correction or auto detection. \noindent @@ -546,15 +553,16 @@ by the driver so far. EFAULT& info points to invalid address.\\ } -\ifunction{FE\_DISEC\_RESET\_OVERLOAD}{ - int ioctl(int fd, int request = FE\_DISEC\_RESET\_OVERLOAD);}{ +\ifunction{FE\_DISEQC\_RESET\_OVERLOAD}{ + int ioctl(int fd, int request = FE\_DISEQC\_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. + Not all DVB adapters support this ioctl. }{ int fd & File descriptor returned by a previous call to open().\\ - int request & Equals FE\_DISEC\_RESET\_OVERLOAD for this command.\\ + int request & Equals FE\_DISEQC\_RESET\_OVERLOAD for this command.\\ }{ EBADF & fd is not a valid file descriptor.\\ EPERM & Permission denied (needs read/write access).\\ @@ -562,12 +570,12 @@ by the driver so far. } -\ifunction{FE\_DISEC\_SEND\_MASTER\_CMD}{ -int ioctl(int fd, int request = FE\_DISEC\_SEND\_MASTER\_CMD, struct dvb\_diseqc\_master\_cmd *cmd);}{ +\ifunction{FE\_DISEQC\_SEND\_MASTER\_CMD}{ +int ioctl(int fd, int request = FE\_DISEQC\_SEND\_MASTER\_CMD, struct dvb\_diseqc\_master\_cmd *cmd);}{ This ioctl call is used to send a a DiSEqC command.\\ }{ int fd & File descriptor returned by a previous call to open().\\ - int request & Equals FE\_DISEC\_SEND\_MASTER\_CMD for this command.\\ + int request & Equals FE\_DISEQC\_SEND\_MASTER\_CMD for this command.\\ struct dvb\_diseqc\_master\_cmd *cmd & Pointer to the command to be transmitted.\\ }{ EBADF & fd is not a valid file descriptor.\\ @@ -577,12 +585,12 @@ int ioctl(int fd, int request = FE\_DISEC\_SEND\_MASTER\_CMD, struct dvb\_diseqc EINTERNAL & Internal error in the device driver.\\ } -\ifunction{FE\_DISEC\_RECV\_SLAVE\_REPLY}{ -int ioctl(int fd, int request = FE\_DISEC\_RECV\_SLAVE\_REPLY, struct dvb\_diseqc\_slave\_reply *reply);}{ +\ifunction{FE\_DISEQC\_RECV\_SLAVE\_REPLY}{ +int ioctl(int fd, int request = FE\_DISEQC\_RECV\_SLAVE\_REPLY, struct dvb\_diseqc\_slave\_reply *reply);}{ This ioctl call is used to receive reply to a DiSEqC 2.0 command.\\ }{ int fd & File descriptor returned by a previous call to open().\\ - int request & Equals FE\_DISEC\_RECV\_SLAVE\_REPLY for this command.\\ + int request & Equals FE\_DISEQC\_RECV\_SLAVE\_REPLY for this command.\\ struct dvb\_diseqc\_slave\_reply *reply & Pointer to the command to be received.\\ }{ EBADF & fd is not a valid file descriptor.\\ @@ -592,12 +600,12 @@ This ioctl call is used to receive reply to a DiSEqC 2.0 command.\\ EINTERNAL & Internal error in the device driver.\\ } -\ifunction{FE\_DISEC\_SEND\_BURST}{ -int ioctl(int fd, int request = FE\_DISEC\_SEND\_BURST, fe\_sec\_mini\_cmd\_t burst);}{ +\ifunction{FE\_DISEQC\_SEND\_BURST}{ +int ioctl(int fd, int request = FE\_DISEQC\_SEND\_BURST, fe\_sec\_mini\_cmd\_t burst);}{ This ioctl call is used to send a 22KHz tone burst.\\ }{ int fd & File descriptor returned by a previous call to open().\\ - int request & Equals FE\_DISEC\_SEND\_BURST for this command.\\ + int request & Equals FE\_DISEQC\_SEND\_BURST for this command.\\ fe\_sec\_mini\_cmd\_t burst & burst A or B.\\ }{ EBADF & fd is not a valid file descriptor.\\ @@ -646,6 +654,7 @@ int ioctl(int fd, int request = FE\_ENABLE\_HIGH\_LNB\_VOLTAGE, int high);}{ If high != 0 enables slightly higher voltages instead of 13/18V (to compensate for long cables). This call requires read/write permissions. +Not all DVB adapters support this ioctl. }{ int fd & File descriptor returned by a previous call to open().\\ int request & Equals FE\_SET\_VOLTAGE for this command.\\ -- cgit v1.2.3 From b51e4627e2053a7434d1f308123a6a9b07e4e78f Mon Sep 17 00:00:00 2001 From: js Date: Thu, 24 Jul 2003 14:08:21 -0300 Subject: - document DMX_GET_STC - bump version to 1.0.0 --- dvb-spec/dvbapi/demux.tex | 32 +++++++++++++++++++++++++++++++- dvb-spec/dvbapi/title.tex | 2 +- 2 files changed, 32 insertions(+), 2 deletions(-) (limited to 'dvb-spec/dvbapi') diff --git a/dvb-spec/dvbapi/demux.tex b/dvb-spec/dvbapi/demux.tex index dd032f58d..882463090 100644 --- a/dvb-spec/dvbapi/demux.tex +++ b/dvb-spec/dvbapi/demux.tex @@ -139,6 +139,17 @@ struct dmx_event }; \end{verbatim} +\devsubsubsec{struct dmx\_stc} +\label{dmxstc} + +\begin{verbatim} +struct dmx_stc { + unsigned int num; /* input : which STC? 0..N */ + unsigned int base; /* output: divisor for stc to get 90 kHz clock */ + uint64_t stc; /* output: stc in 'base'*90 kHz units */ +}; +\end{verbatim} + \clearpage \devsubsec{Demux Function Calls} @@ -367,7 +378,7 @@ struct dmx_event \ifunction{DMX\_GET\_EVENT}{ int ioctl( int fd, int request = DMX\_GET\_EVENT, struct dmx\_event *ev); }{ - This ioctl call returns an event if available. If an event is not + 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 @@ -387,6 +398,25 @@ struct dmx_event EWOULDBLOCK & There is no event pending, and the device is in non-blocking mode.\\ } +\ifunction{DMX\_GET\_STC}{ + int ioctl( int fd, int request = DMX\_GET\_STC, struct dmx\_stc *stc); + }{ + This ioctl call returns the current value of the system time counter + (which is driven by a PES filter of type DMX\_PES\_PCR). Some hardware + supports more than one STC, so you must specify which one by setting + the num field of stc before the ioctl (range 0...n). The result is returned in form + of a ratio with a 64 bit numerator and a 32 bit denominator, so the + real 90kHz STC value is \begin{ttfamily}stc->stc / stc->base\end{ttfamily}. + }{ + int fd & File descriptor returned by a previous call to open().\\ + int request & Equals DMX\_GET\_STC for this command.\\ + struct dmx\_stc *stc & Pointer to the location where the stc is to be stored.\\ + }{ + EBADF & fd is not a valid file descriptor.\\ + EFAULT & stc points to an invalid address.\\ + EINVAL & Invalid stc number.\\ +} + %%% Local Variables: %%% mode: latex %%% TeX-master: "dvbapi" diff --git a/dvb-spec/dvbapi/title.tex b/dvb-spec/dvbapi/title.tex index 29aca30d6..857492b7e 100644 --- a/dvb-spec/dvbapi/title.tex +++ b/dvb-spec/dvbapi/title.tex @@ -10,7 +10,7 @@ and Dr. Marcus O.C. Metzler\\ \texttt{}\\ } -\date{02/10/2003\\V 1.0.0-pre1} +\date{24/07/2003\\V 1.0.0} \maketitle -- cgit v1.2.3 From 56a4ef5b2748552e9f28020a1dad9dec2119542c Mon Sep 17 00:00:00 2001 From: js Date: Fri, 25 Jul 2003 16:07:49 -0300 Subject: added HTML target --- dvb-spec/dvbapi/.cvsignore | 2 ++ dvb-spec/dvbapi/Makefile | 7 ++++--- dvb-spec/dvbapi/frontend.tex | 2 +- 3 files changed, 7 insertions(+), 4 deletions(-) (limited to 'dvb-spec/dvbapi') diff --git a/dvb-spec/dvbapi/.cvsignore b/dvb-spec/dvbapi/.cvsignore index fb6974f6b..71db27b0a 100644 --- a/dvb-spec/dvbapi/.cvsignore +++ b/dvb-spec/dvbapi/.cvsignore @@ -9,3 +9,5 @@ dvbapi.log dvbapi.pdf dvbapi.out dvbapi.toc +dvbapi.ind +dvbapi.ilg diff --git a/dvb-spec/dvbapi/Makefile b/dvb-spec/dvbapi/Makefile index 83a5e5f7a..1158360e2 100644 --- a/dvb-spec/dvbapi/Makefile +++ b/dvb-spec/dvbapi/Makefile @@ -10,9 +10,6 @@ dvbapi.ps: dvbapi.dvi dvips $< dvbapi.dvi: dvbapi.bbl $(TEXS) - -latex dvbapi - -bibtex dvbapi - -makeindex dvbapi -latex dvbapi -latex dvbapi @@ -21,6 +18,9 @@ dvbapi.bbl: $(TEXS) -bibtex dvbapi -makeindex dvbapi +html: dvbapi.dvi + latex2html -address "LinuxTV DVB API" -long_titles 4 -split 3 dvbapi.tex + %.ps: %.fig ./fig2pstex $< @@ -28,3 +28,4 @@ clean: rm -f dvbapi.dvi rm -f *.aux *.bbl *.blg *.idx *.ilg *.ind *.log *.out *.toc rm -f *.pdf *.pst *.ps + rm -rf dvbapi diff --git a/dvb-spec/dvbapi/frontend.tex b/dvb-spec/dvbapi/frontend.tex index cbd646b93..9ae8a343e 100644 --- a/dvb-spec/dvbapi/frontend.tex +++ b/dvb-spec/dvbapi/frontend.tex @@ -263,7 +263,7 @@ typedef enum fe_code_rate { FEC_AUTO } fe_code_rate_t; \end{verbatim} -which correspond to error correction rates of $1/2$, $2/3$, etc., +which correspond to error correction rates of 1/2, 2/3, etc., no error correction or auto detection. \noindent -- cgit v1.2.3 From e09b3f6768a32a3ac714c8a44fa5ec64f986a41f Mon Sep 17 00:00:00 2001 From: js Date: Tue, 29 Jul 2003 14:05:03 -0300 Subject: ignore html output dir --- dvb-spec/dvbapi/.cvsignore | 1 + 1 file changed, 1 insertion(+) (limited to 'dvb-spec/dvbapi') diff --git a/dvb-spec/dvbapi/.cvsignore b/dvb-spec/dvbapi/.cvsignore index 71db27b0a..89f9afcb7 100644 --- a/dvb-spec/dvbapi/.cvsignore +++ b/dvb-spec/dvbapi/.cvsignore @@ -11,3 +11,4 @@ dvbapi.out dvbapi.toc dvbapi.ind dvbapi.ilg +dvbapi -- cgit v1.2.3 From 8d72af7c80177c51843d0b0326d0a4a01099cb04 Mon Sep 17 00:00:00 2001 From: hunold Date: Fri, 23 Apr 2004 03:38:10 -0300 Subject: - standard dvips sends output to the default printer! use "-o $@" to send it to the destination file instead. (ever wondered who prints out the dvb api regularly on your laser printer? ;-) --- dvb-spec/dvbapi/Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'dvb-spec/dvbapi') diff --git a/dvb-spec/dvbapi/Makefile b/dvb-spec/dvbapi/Makefile index 1158360e2..6d349c80d 100644 --- a/dvb-spec/dvbapi/Makefile +++ b/dvb-spec/dvbapi/Makefile @@ -4,10 +4,10 @@ TEXS= dvbapi.tex devices.tex video.tex audio.tex ca.tex net.tex frontend.tex \ demux.tex kdapi.tex examples.tex intro.tex title.tex dvbstb.ps dvbapi.pdf: dvbapi.dvi - dvipdf $< + dvipdf -f $< -o $@ dvbapi.ps: dvbapi.dvi - dvips $< + dvips -f $< -o $@ dvbapi.dvi: dvbapi.bbl $(TEXS) -latex dvbapi -- cgit v1.2.3 From 6236b63ea391dfb73f0ade028a1ea7889eb5319c Mon Sep 17 00:00:00 2001 From: hunold Date: Fri, 23 Apr 2004 08:55:10 -0300 Subject: - fix dvipdf --- dvb-spec/dvbapi/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'dvb-spec/dvbapi') diff --git a/dvb-spec/dvbapi/Makefile b/dvb-spec/dvbapi/Makefile index 6d349c80d..e741df6da 100644 --- a/dvb-spec/dvbapi/Makefile +++ b/dvb-spec/dvbapi/Makefile @@ -4,7 +4,7 @@ TEXS= dvbapi.tex devices.tex video.tex audio.tex ca.tex net.tex frontend.tex \ demux.tex kdapi.tex examples.tex intro.tex title.tex dvbstb.ps dvbapi.pdf: dvbapi.dvi - dvipdf -f $< -o $@ + dvipdf $< $@ dvbapi.ps: dvbapi.dvi dvips -f $< -o $@ -- cgit v1.2.3 From e24be1d8a703d1ebcc4b2027be8071d82446b2b3 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 19 Feb 2009 18:19:36 +0000 Subject: spec: Use fancyhdr instead of obsolete fancyheadings From: Nicola Soranzo LaTeX package fancyheadings is obsolete and superseded by fancyhdr. Priority: normal Signed-off-by: Nicola Soranzo Signed-off-by: Mauro Carvalho Chehab --- dvb-spec/dvbapi/dvbapi.tex | 56 +++++++++++++++++++++++----------------------- 1 file changed, 28 insertions(+), 28 deletions(-) (limited to 'dvb-spec/dvbapi') diff --git a/dvb-spec/dvbapi/dvbapi.tex b/dvb-spec/dvbapi/dvbapi.tex index d75c2417f..74fc6510e 100644 --- a/dvb-spec/dvbapi/dvbapi.tex +++ b/dvb-spec/dvbapi/dvbapi.tex @@ -4,7 +4,7 @@ \usepackage{times} %\usepackage[hang]{caption} -\usepackage{fancyheadings} +\usepackage{fancyhdr} %\usepackage{lucidabr} %\usepackage{fancybox} \usepackage{array} @@ -24,82 +24,82 @@ \newcommand{\function}[5]{ \subsection{#1} - \noindent DESCRIPTION + \noindent DESCRIPTION \medskip - + \begin{tabular}[h]{p{11cm}} #3 \end{tabular} - + \medskip - \noindent SYNOPSIS + \noindent SYNOPSIS \medskip \begin{tabular}[h]{p{11cm}} {\tt #2} \end{tabular} - - %\item[] + + %\item[] \medskip -\noindent PARAMETERS +\noindent PARAMETERS \medskip - + \begin{tabular}[h]{p{3cm}p{8cm}} #4 \end{tabular} - - %\item[] + + %\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 + \noindent DESCRIPTION \medskip \begin{tabular}[h]{p{11cm}} #3 \end{tabular} - + \medskip - \noindent SYNOPSIS + \noindent SYNOPSIS \medskip \begin{tabular}[h]{p{11cm}} {\tt #2} \end{tabular} - - %\item[] + + %\item[] \medskip -\noindent PARAMETERS +\noindent PARAMETERS \medskip - + \begin{tabular}[h]{p{3cm}p{8cm}} #4 \end{tabular} - - %\item[] + + %\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}} @@ -164,7 +164,7 @@ \end{document} -%%% Local Variables: +%%% Local Variables: %%% mode: latex %%% TeX-master: t -%%% End: +%%% End: -- cgit v1.2.3