From 9034551a3bbc76b79a152806c781b1b8e8ea3a9a Mon Sep 17 00:00:00 2001
From: rjkm <devnull@localhost>
Date: Sun, 16 Sep 2001 22:27:03 -0300
Subject: new API docs

---
 dvb-spec/dvbapi/kdapi.tex | 1007 +++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 1007 insertions(+)
 create mode 100644 dvb-spec/dvbapi/kdapi.tex

(limited to 'dvb-spec/dvbapi/kdapi.tex')

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: 
-- 
cgit v1.2.3


From f1e2fc77631891bd568baff424cbe535a2795d65 Mon Sep 17 00:00:00 2001
From: rjkm <devnull@localhost>
Date: Wed, 19 Sep 2001 18:48:28 -0300
Subject: removed some typos

---
 dvb-spec/dvbapi/kdapi.tex | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

(limited to 'dvb-spec/dvbapi/kdapi.tex')

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]; 
-- 
cgit v1.2.3


From ab85b007da42f42856a775d8cff97332093f5b34 Mon Sep 17 00:00:00 2001
From: holger <devnull@localhost>
Date: Thu, 10 Oct 2002 15:59:05 -0300
Subject: make room for the new HEAD trunk

---
 dvb-spec/dvbapi/kdapi.tex | 1007 ---------------------------------------------
 1 file changed, 1007 deletions(-)
 delete mode 100644 dvb-spec/dvbapi/kdapi.tex

(limited to 'dvb-spec/dvbapi/kdapi.tex')

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: 
-- 
cgit v1.2.3


From 5a523e605b9b6d1ae50d0707c1874c5b7f0959cc Mon Sep 17 00:00:00 2001
From: holger <devnull@localhost>
Date: Thu, 10 Oct 2002 16:22:27 -0300
Subject: the new HEAD

---
 dvb-spec/dvbapi/kdapi.tex | 1007 +++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 1007 insertions(+)
 create mode 100644 dvb-spec/dvbapi/kdapi.tex

(limited to 'dvb-spec/dvbapi/kdapi.tex')

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: 
-- 
cgit v1.2.3


From 622f6e3335a0dd1a97cdaee9913c1f105f3e36fa Mon Sep 17 00:00:00 2001
From: js <devnull@localhost>
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/kdapi.tex | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

(limited to 'dvb-spec/dvbapi/kdapi.tex')

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}
 
-- 
cgit v1.2.3

