<title>Kernel Demux API</title><para>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 forDVB device driver writers. The header file for this API is named <emphasis role="tt">demux.h</emphasis> and located in<emphasis role="tt">drivers/media/dvb/dvb-core</emphasis>.</para><para>Maintainer note: This section must be reviewed. It is probably out of date.</para> <section id="kernel_demux_data_types"><title>Kernel Demux Data Types</title> <section id="dmx_success_t"><title>dmx_success_t</title> <programlisting> 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;</programlisting> </section><section id="ts_filter_types"><title>TS filter types</title> <programlisting> /⋆--------------------------------------------------------------------------⋆/ /⋆ 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) ⋆/</programlisting> </section><section id="dmx_ts_pes_t"><title>dmx_ts_pes_t</title><para>The structure</para><programlisting> 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;</programlisting><para>describes the PES type for filters which write to a built-in decoder. The correspond (andshould be kept identical) to the types in the demux device.</para><programlisting> 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;</programlisting> <programlisting> /⋆--------------------------------------------------------------------------⋆/ /⋆ 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;</programlisting> <programlisting> 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;</programlisting> <programlisting> 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;</programlisting> <programlisting> 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</programlisting> </section><section id="demux_demux_t"><title>demux_demux_t</title> <programlisting> /⋆ ⋆ 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;</programlisting> </section><section id="demux_directory"><title>Demux directory</title> <programlisting> /⋆ ⋆ 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);</programlisting> </section></section><section id="demux_directory_api"><title>Demux Directory API</title><para>The demux directory is a Linux kernel-wide facility for registering and accessing theMPEG-2 TS demuxes in the system. Run-time registering and unregistering of demux driversis possible using this API.</para><para>All demux drivers in the directory implement the abstract interface dmx_demux_t.</para> <sectionrole="subsection"><title>dmx_register_demux()</title><para>DESCRIPTION</para><informaltable><tgroup cols="1"><tbody><row><entry align="char"><para>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(),</para></entry> </row></tbody></tgroup></informaltable><para>SYNOPSIS</para><informaltable><tgroup cols="1"><tbody><row><entry align="char"><para>int dmx_register_demux ( dmx_demux_t ⋆demux )</para></entry> </row></tbody></tgroup></informaltable><para>PARAMETERS</para><informaltable><tgroup cols="2"><tbody><row><entry align="char"><para>dmx_demux_t* demux</para></entry><entry align="char"><para>Pointer to the demux structure.</para></entry> </row></tbody></tgroup></informaltable><para>RETURNS</para><informaltable><tgroup cols="2"><tbody><row><entry align="char"><para>0</para></entry><entry align="char"><para>The function was completed without errors.</para></entry> </row><row><entry align="char"><para>-EEXIST</para></entry><entry align="char"><para>A demux with the same value of the id field already stored in the directory.</para></entry> </row><row><entry align="char"><para>-ENOSPC</para></entry><entry align="char"><para>No space left in the directory.</para></entry> </row></tbody></tgroup></informaltable> </section><sectionrole="subsection"><title>dmx_unregister_demux()</title><para>DESCRIPTION</para><informaltable><tgroup cols="1"><tbody><row><entry align="char"><para>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.</para></entry> </row></tbody></tgroup></informaltable><para>SYNOPSIS</para><informaltable><tgroup cols="1"><tbody><row><entry align="char"><para>int dmx_unregister_demux ( dmx_demux_t ⋆demux )</para></entry> </row></tbody></tgroup></informaltable><para>PARAMETERS</para><informaltable><tgroup cols="2"><tbody><row><entry align="char"><para>dmx_demux_t* demux</para></entry><entry align="char"><para>Pointer to the demux structure which is to be unregistered.</para></entry> </row></tbody></tgroup></informaltable><para>RETURNS</para><informaltable><tgroup cols="2"><tbody><row><entry align="char"><para>0</para></entry><entry align="char"><para>The function was completed without errors.</para></entry> </row><row><entry align="char"><para>ENODEV</para></entry><entry align="char"><para>The specified demux is not registered in the demux directory.</para></entry> </row><row><entry align="char"><para>EBUSY</para></entry><entry align="char"><para>The specified demux is currently in use.</para></entry> </row></tbody></tgroup></informaltable> </section><sectionrole="subsection"><title>dmx_get_demuxes()</title><para>DESCRIPTION</para><informaltable><tgroup cols="1"><tbody><row><entry align="char"><para>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.</para></entry> </row></tbody></tgroup></informaltable><para>SYNOPSIS</para><informaltable><tgroup cols="1"><tbody><row><entry align="char"><para>struct list_head ⋆dmx_get_demuxes ()</para></entry> </row></tbody></tgroup></informaltable><para>PARAMETERS</para><informaltable><tgroup cols="2"><tbody><row><entry align="char"><para>none</para></entry> </row></tbody></tgroup></informaltable><para>RETURNS</para><informaltable><tgroup cols="2"><tbody><row><entry align="char"><para>struct list_head *</para></entry><entry align="char"><para>A list of demux interfaces, or NULL in the case of an empty list.</para></entry> </row></tbody></tgroup></informaltable> </section></section><section id="demux_api"><title>Demux API</title><para>The demux API should be implemented for each demux in the system. It is used to selectthe TS source of a demux and to manage the demux resources. When the demuxclient allocates a resource via the demux API, it receives a pointer to the API of thatresource.</para><para>Each demux receives its TS input from a DVB front-end or from memory, as set via thedemux API. In a system with more than one front-end, the API can be used to select one ofthe DVB front-ends as a TS source for a demux, unless this is fixed in the HW platform. Thedemux API only controls front-ends regarding their connections with demuxes; the APIsused to set the other front-end parameters, such as tuning, are not defined in thisdocument.</para><para>The functions that implement the abstract interface demux should be defined static ormodule private and registered to the Demux Directory for external access. It is not necessaryto implement every function in the demux_t struct, however (for example, a demux interfacemight support Section filtering, but not TS or PES filtering). The API client is expected tocheck the value of any function pointer before calling the function: the value of NULL means“function not available”.</para><para>Whenever the functions of the demux API modify shared data, the possibilities of lostupdate and race condition problems should be addressed, e.g. by protecting parts of code withmutexes. This is especially important on multi-processor hosts.</para><para>Note that functions called from a bottom half context must not sleep, at least in the 2.2.xkernels. Even a simple memory allocation can result in a kernel thread being put to sleep ifswapping is needed. For example, the Linux kernel calls the functions of a network deviceinterface from a bottom half context. Thus, if a demux API function is called from networkdevice code, the function must not sleep.</para> <section id="kdapi_fopen"><title>open()</title><para>DESCRIPTION</para><informaltable><tgroup cols="1"><tbody><row><entry align="char"><para>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 theLines 1–500 of 2309. Load more
<title>Kernel Demux API</title> <para>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 <emphasis role="tt">demux.h</emphasis> and located in <emphasis role="tt">drivers/media/dvb/dvb-core</emphasis>. </para> <para>Maintainer note: This section must be reviewed. It is probably out of date. </para> <section id="kernel_demux_data_types"> <title>Kernel Demux Data Types</title> <section id="dmx_success_t"> <title>dmx_success_t</title> <programlisting> 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; </programlisting> </section> <section id="ts_filter_types"> <title>TS filter types</title> <programlisting> /⋆--------------------------------------------------------------------------⋆/ /⋆ 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) ⋆/ </programlisting> </section> <section id="dmx_ts_pes_t"> <title>dmx_ts_pes_t</title> <para>The structure </para> <programlisting> 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; </programlisting> <para>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. </para> <programlisting> 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; </programlisting> <programlisting> /⋆--------------------------------------------------------------------------⋆/ /⋆ 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; </programlisting> <programlisting> 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; </programlisting> <programlisting> 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; </programlisting> <programlisting> 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 </programlisting> </section> <section id="demux_demux_t"> <title>demux_demux_t</title> <programlisting> /⋆ ⋆ 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; </programlisting> </section> <section id="demux_directory"> <title>Demux directory</title> <programlisting> /⋆ ⋆ 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); </programlisting> </section></section> <section id="demux_directory_api"> <title>Demux Directory API</title> <para>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. </para> <para>All demux drivers in the directory implement the abstract interface dmx_demux_t. </para> <section role="subsection"><title>dmx_register_demux()</title> <para>DESCRIPTION </para> <informaltable><tgroup cols="1"><tbody><row><entry align="char"> <para>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(),</para> </entry> </row></tbody></tgroup></informaltable> <para>SYNOPSIS </para> <informaltable><tgroup cols="1"><tbody><row><entry align="char"> <para>int dmx_register_demux ( dmx_demux_t ⋆demux )</para> </entry> </row></tbody></tgroup></informaltable> <para>PARAMETERS </para> <informaltable><tgroup cols="2"><tbody><row><entry align="char"> <para>dmx_demux_t* demux</para> </entry><entry align="char"> <para>Pointer to the demux structure.</para> </entry> </row></tbody></tgroup></informaltable> <para>RETURNS </para> <informaltable><tgroup cols="2"><tbody><row><entry align="char"> <para>0</para> </entry><entry align="char"> <para>The function was completed without errors.</para> </entry> </row><row><entry align="char"> <para>-EEXIST</para> </entry><entry align="char"> <para>A demux with the same value of the id field already stored in the directory.</para> </entry> </row><row><entry align="char"> <para>-ENOSPC</para> </entry><entry align="char"> <para>No space left in the directory.</para> </entry> </row></tbody></tgroup></informaltable> </section><section role="subsection"><title>dmx_unregister_demux()</title> <para>DESCRIPTION </para> <informaltable><tgroup cols="1"><tbody><row><entry align="char"> <para>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.</para> </entry> </row></tbody></tgroup></informaltable> <para>SYNOPSIS </para> <informaltable><tgroup cols="1"><tbody><row><entry align="char"> <para>int dmx_unregister_demux ( dmx_demux_t ⋆demux )</para> </entry> </row></tbody></tgroup></informaltable> <para>PARAMETERS </para> <informaltable><tgroup cols="2"><tbody><row><entry align="char"> <para>dmx_demux_t* demux</para> </entry><entry align="char"> <para>Pointer to the demux structure which is to be unregistered.</para> </entry> </row></tbody></tgroup></informaltable> <para>RETURNS </para> <informaltable><tgroup cols="2"><tbody><row><entry align="char"> <para>0</para> </entry><entry align="char"> <para>The function was completed without errors.</para> </entry> </row><row><entry align="char"> <para>ENODEV</para> </entry><entry align="char"> <para>The specified demux is not registered in the demux directory.</para> </entry> </row><row><entry align="char"> <para>EBUSY</para> </entry><entry align="char"> <para>The specified demux is currently in use.</para> </entry> </row></tbody></tgroup></informaltable> </section><section role="subsection"><title>dmx_get_demuxes()</title> <para>DESCRIPTION </para> <informaltable><tgroup cols="1"><tbody><row><entry align="char"> <para>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.</para> </entry> </row></tbody></tgroup></informaltable> <para>SYNOPSIS </para> <informaltable><tgroup cols="1"><tbody><row><entry align="char"> <para>struct list_head ⋆dmx_get_demuxes ()</para> </entry> </row></tbody></tgroup></informaltable> <para>PARAMETERS </para> <informaltable><tgroup cols="2"><tbody><row><entry align="char"> <para>none</para> </entry> </row></tbody></tgroup></informaltable> <para>RETURNS </para> <informaltable><tgroup cols="2"><tbody><row><entry align="char"> <para>struct list_head *</para> </entry><entry align="char"> <para>A list of demux interfaces, or NULL in the case of an empty list.</para> </entry> </row></tbody></tgroup></informaltable> </section></section> <section id="demux_api"> <title>Demux API</title> <para>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. </para> <para>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. </para> <para>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”. </para> <para>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. </para> <para>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. </para> <section id="kdapi_fopen"> <title>open()</title> <para>DESCRIPTION </para> <informaltable><tgroup cols="1"><tbody><row><entry align="char"> <para>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