8.3. 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.

8.3.1. open()

DESCRIPTION

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.

SYNOPSIS

int open ( demux_t⋆ demux );

PARAMETERS

demux_t* demux

Pointer to the demux API and instance data.

RETURNS

0

The function was completed without errors.

-EUSERS

Maximum usage count reached.

-EINVAL

Bad parameter.

8.3.2. close()

DESCRIPTION

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.

SYNOPSIS

int close(demux_t⋆ demux);

PARAMETERS

demux_t* demux

Pointer to the demux API and instance data.

RETURNS

0

The function was completed without errors.

-ENODEV

The demux was not in use.

-EINVAL

Bad parameter.

8.3.3. write()

DESCRIPTION

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.

SYNOPSIS

int write(demux_t⋆ demux, const char⋆ buf, size_t count);

PARAMETERS

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.

RETURNS

0

The function was completed without errors.

-ENOSYS

The command is not implemented.

-EINVAL

Bad parameter.

8.3.4. allocate_ts_feed()

DESCRIPTION

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.

SYNOPSIS

int allocate_ts_feed(dmx_demux_t⋆ demux, dmx_ts_feed_t⋆⋆ feed, dmx_ts_cb callback);

PARAMETERS

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

RETURNS

0

The function was completed without errors.

-EBUSY

No more TS feeds available.

-ENOSYS

The command is not implemented.

-EINVAL

Bad parameter.

8.3.5. release_ts_feed()

DESCRIPTION

Releases the resources allocated with allocate_ts_feed(). Any filtering in progress on the TS feed should be stopped before calling this function.

SYNOPSIS

int release_ts_feed(dmx_demux_t⋆ demux, dmx_ts_feed_t⋆ feed);

PARAMETERS

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.

RETURNS

0

The function was completed without errors.

-EINVAL

Bad parameter.

8.3.6. allocate_section_feed()

DESCRIPTION

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.

SYNOPSIS

int allocate_section_feed(dmx_demux_t⋆ demux, dmx_section_feed_t ⋆⋆feed, dmx_section_cb callback);

PARAMETERS

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.

RETURNS

0

The function was completed without errors.

-EBUSY

No more section feeds available.

-ENOSYS

The command is not implemented.

-EINVAL

Bad parameter.

8.3.7. release_section_feed()

DESCRIPTION

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.

SYNOPSIS

int release_section_feed(dmx_demux_t⋆ demux, dmx_section_feed_t ⋆feed);

PARAMETERS

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.

RETURNS

0

The function was completed without errors.

-EINVAL

Bad parameter.

8.3.8. descramble_mac_address()

DESCRIPTION

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.

SYNOPSIS

int descramble_mac_address(dmx_demux_t⋆ demux, __u8 ⋆buffer1, size_t buffer1_length, __u8 ⋆buffer2, size_t buffer2_length, __u16 pid);

PARAMETERS

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.

RETURNS

0

The function was completed without errors.

-ENOSYS

No descrambling facility available.

-EINVAL

Bad parameter.

8.3.9. descramble_section_payload()

DESCRIPTION

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.

SYNOPSIS

int descramble_section_payload(dmx_demux_t⋆ demux, __u8 ⋆buffer1, size_t buffer1_length, __u8 ⋆buffer2, size_t buffer2_length, __u16 pid);

PARAMETERS

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.

RETURNS

0

The function was completed without errors.

-ENOSYS

No descrambling facility available.

-EINVAL

Bad parameter.

8.3.10. add_frontend()

DESCRIPTION

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().

SYNOPSIS

int add_frontend(dmx_demux_t ⋆demux, dmx_frontend_t ⋆frontend);

PARAMETERS

dmx_demux_t* demux

Pointer to the demux API and instance data.

dmx_frontend_t* frontend

Pointer to the front-end instance data.

RETURNS

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.

8.3.11. remove_frontend()

DESCRIPTION

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.

SYNOPSIS

int remove_frontend(dmx_demux_t⋆ demux, dmx_frontend_t⋆ frontend);

PARAMETERS

dmx_demux_t* demux

Pointer to the demux API and instance data.

dmx_frontend_t* frontend

Pointer to the front-end instance data.

RETURNS

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().

8.3.12. get_frontends()

DESCRIPTION

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.

SYNOPSIS

struct list_head⋆ get_frontends(dmx_demux_t⋆ demux);

PARAMETERS

dmx_demux_t* demux

Pointer to the demux API and instance data.

RETURNS

dmx_demux_t*

A list of front-end interfaces, or NULL in the case of an empty list.

8.3.13. connect_frontend()

DESCRIPTION

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().

SYNOPSIS

int connect_frontend(dmx_demux_t⋆ demux, dmx_frontend_t⋆ frontend);

PARAMETERS

dmx_demux_t* demux

Pointer to the demux API and instance data.

dmx_frontend_t* frontend

Pointer to the front-end instance data.

RETURNS

0

The function was completed without errors.

-EINVAL

Bad parameter.

-EBUSY

The front-end is in use.

8.3.14. disconnect_frontend()

DESCRIPTION

Disconnects the demux and a front-end previously connected by a connect_frontend() call.

SYNOPSIS

int disconnect_frontend(dmx_demux_t⋆ demux);

PARAMETERS

dmx_demux_t* demux

Pointer to the demux API and instance data.

RETURNS

0

The function was completed without errors.

-EINVAL

Bad parameter.