3.3. 数字电视解复用器 kABI

3.3.1. 数字电视解复用器

内核数字电视解复用器 kABI 定义了一个驱动程序内部接口,用于将底层、硬件特定的驱动程序注册到硬件独立的解复用层。它只对数字电视设备驱动程序编写者感兴趣。此 kABI 的头文件名为 demux.h,位于 include/media 中。

应为系统中的每个解复用器实现解复用器 kABI。它用于选择解复用器的 TS 源并管理解复用器资源。当解复用器客户端通过解复用器 kABI 分配资源时,它会收到指向该资源 kABI 的指针。

每个解复用器都从 DVB 前端或内存接收其 TS 输入,这是通过此解复用器 kABI 设置的。在具有多个前端的系统中,kABI 可用于选择其中一个 DVB 前端作为解复用器的 TS 源,除非这在 HW 平台中是固定的。

解复用器 kABI 仅控制与解复用器的连接有关的前端;用于设置其他前端参数(如调谐)的 kABI 通过数字电视前端 kABI 定义。

实现抽象接口解复用器的函数应定义为静态或模块私有,并注册到解复用器核心以进行外部访问。不必实现 dmx_demux 结构中的每个函数。例如,解复用器接口可能支持 Section 过滤,但不支持 PES 过滤。kABI 客户端应在调用函数之前检查任何函数指针的值:NULL 值表示该函数不可用。

每当解复用器 API 的函数修改共享数据时,应解决丢失更新和竞争条件问题的可能性,例如,通过使用互斥锁保护部分代码。

请注意,从下半部上下文调用的函数不得睡眠。即使不使用 GFP_ATOMIC 的简单内存分配也可能导致内核线程进入睡眠状态(如果需要交换)。例如,Linux 内核从下半部上下文调用网络设备接口的函数。因此,如果从网络设备代码调用解复用器 kABI 函数,则该函数不得睡眠。

3.3.2. 解复用器回调 API

此内核空间 API 包括将过滤后的数据传递到解复用器客户端的回调函数。与其他 DVB kABI 不同,这些函数由客户端提供并从解复用器代码中调用。

此抽象接口的函数指针未像其他解复用器 API 中那样打包到结构中,因为回调函数是彼此独立注册和使用的。例如,API 客户端可以提供多个用于接收 TS 数据包的回调函数,而没有用于 PES 数据包或 Section 的回调。

实现回调 API 的函数不需要是可重入的:当解复用器驱动程序调用这些函数之一时,驱动程序在原始调用返回之前不允许再次调用该函数。如果回调由硬件中断触发,建议使用 Linux 下半部机制或启动任务小程序,而不是直接从硬件中断进行回调函数调用。

此机制由 dmx_ts_cb()dmx_section_cb() 回调实现。

3.3.3. 数字电视解复用器设备注册函数和数据结构

enum dmxdev_type

解复用器筛选器类型的类型。

常量

DMXDEV_TYPE_NONE

未设置筛选器。

DMXDEV_TYPE_SEC

Section 筛选器。

DMXDEV_TYPE_PES

节目基本流 (PES) 筛选器。

enum dmxdev_state

dmxdev 的状态机。

常量

DMXDEV_STATE_FREE

指示筛选器已释放。

DMXDEV_STATE_ALLOCATED

指示已分配筛选器以供使用。

DMXDEV_STATE_SET

指示已设置筛选器参数。

DMXDEV_STATE_GO

指示筛选器正在运行。

DMXDEV_STATE_DONE

指示已筛选数据包并且筛选器现已禁用。仅在 DMX_ONESHOT 设置。请参阅 dmx_sct_filter_params

DMXDEV_STATE_TIMEDOUT

指示超时情况。

struct dmxdev_feed

数字电视 dmxdev 馈送

定义:

struct dmxdev_feed {
    u16 pid;
    struct dmx_ts_feed *ts;
    struct list_head next;
};

成员

pid

要筛选的节目 ID

ts

指向 struct dmx_ts_feed 的指针

next

struct list_head 指向下一个馈送。

struct dmxdev_filter

数字电视 dmxdev 筛选器

定义:

struct dmxdev_filter {
    union {
        struct dmx_section_filter *sec;
    } filter;
    union {
        struct list_head ts;
        struct dmx_section_feed *sec;
    } feed;
    union {
        struct dmx_sct_filter_params sec;
        struct dmx_pes_filter_params pes;
    } params;
    enum dmxdev_type type;
    enum dmxdev_state state;
    struct dmxdev *dev;
    struct dvb_ringbuffer buffer;
    struct dvb_vb2_ctx vb2_ctx;
    struct mutex mutex;
    struct timer_list timer;
    int todo;
    u8 secheader[3];
};

成员

筛选器

描述 dmxdev 筛选器的联合。当前仅用于 Section 筛选器。

filter.sec

a struct dmx_section_filter 指针。仅用于 Section 筛选器。

feed

描述 dmxdev 馈送的联合。根据筛选器类型,它可以是 feed.tsfeed.sec

feed.ts

a struct list_head 列表。用于 TS 和 PES 馈送。

feed.sec

a struct dmx_section_feed 指针。仅用于 Section 馈送。

params

描述 dmxdev 筛选器参数的联合。根据筛选器类型,它可以是 params.secparams.pes

params.sec

a struct dmx_sct_filter_params 嵌入式结构。仅用于 Section 筛选器。

params.pes

a struct dmx_pes_filter_params 嵌入式结构。仅用于 PES 筛选器。

type

dmxdev 筛选器的类型,由 enum dmxdev_type 定义。

state

dmxdev 筛选器的状态,由 enum dmxdev_state 定义。

dev

指向 struct dmxdev 的指针。

buffer

一个嵌入式 struct dvb_ringbuffer 缓冲区。

vb2_ctx

VB2 处理程序的控制结构

mutex

保护对 struct dmxdev_filter 的访问。

timer

struct timer_list 嵌入式计时器,用于检查馈送超时。仅用于 Section 筛选器。

todo

secheader 的索引。仅用于 Section 筛选器。

secheader

用于分析 Section 标头的缓冲区缓存。仅用于 Section 筛选器。

struct dmxdev

描述数字电视解复用器设备。

定义:

struct dmxdev {
    struct dvb_device *dvbdev;
    struct dvb_device *dvr_dvbdev;
    struct dmxdev_filter *filter;
    struct dmx_demux *demux;
    int filternum;
    int capabilities;
    unsigned int may_do_mmap:1;
    unsigned int exit:1;
#define DMXDEV_CAP_DUPLEX 1;
    struct dmx_frontend *dvr_orig_fe;
    struct dvb_ringbuffer dvr_buffer;
#define DVR_BUFFER_SIZE (10*188*1024);
    struct dvb_vb2_ctx dvr_vb2_ctx;
    struct mutex mutex;
    spinlock_t lock;
};

成员

dvbdev

指向与解复用器设备节点关联的 struct dvb_device 的指针。

dvr_dvbdev

指向与 dvr 设备节点关联的 struct dvb_device 的指针。

筛选器

指向 struct dmxdev_filter 的指针。

demux

指向 struct dmx_demux 的指针。

filternum

筛选器的数量。

capabilities

解复用器功能,由 enum dmx_demux_caps 定义。

may_do_mmap

用于指示设备是否可以进行 mmap 的标志。

exit

指示正在释放解复用器的标志。

dvr_orig_fe

指向 struct dmx_frontend 的指针。

dvr_buffer

用于 DVB 输出的嵌入式 struct dvb_ringbuffer

dvr_vb2_ctx

VB2 处理程序的控制结构

mutex

保护此结构的使用。

lock

保护对 dmxdev->filter->data 的访问。

int dvb_dmxdev_init(struct dmxdev *dmxdev, struct dvb_adapter *adap)

初始化数字电视解复用器并注册解复用器和 DVR 设备。

参数

struct dmxdev *dmxdev

指向 struct dmxdev 的指针。

struct dvb_adapter *adap

指向 struct dvb_adapter 的指针。

void dvb_dmxdev_release(struct dmxdev *dmxdev)

释放数字电视解复用器并取消注册。

参数

struct dmxdev *dmxdev

指向 struct dmxdev 的指针。

3.3.4. 高级数字电视解复用器接口

enum dvb_dmx_filter_type

解复用器馈送的类型。

常量

DMX_TYPE_TS

馈送处于 TS 模式。

DMX_TYPE_SEC

馈送处于 Section 模式。

enum dvb_dmx_state

解复用器筛选器的状态机。

常量

DMX_STATE_FREE

指示筛选器已释放。

DMX_STATE_ALLOCATED

指示已分配筛选器以供使用。

DMX_STATE_READY

指示筛选器已准备好使用。

DMX_STATE_GO

指示筛选器正在运行。

struct dvb_demux_filter

描述 DVB 解复用器 Section 筛选器。

定义:

struct dvb_demux_filter {
    struct dmx_section_filter filter;
    u8 maskandmode[DMX_MAX_FILTER_SIZE];
    u8 maskandnotmode[DMX_MAX_FILTER_SIZE];
    bool doneq;
    struct dvb_demux_filter *next;
    struct dvb_demux_feed *feed;
    int index;
    enum dvb_dmx_state state;
    enum dvb_dmx_filter_type type;
};

成员

筛选器

Section 筛选器,由 struct dmx_section_filter 定义。

maskandmode

逻辑 and 位掩码。

maskandnotmode

逻辑 and not 位掩码。

doneq

指示筛选器何时准备就绪的标志。

next

指向下一个 Section 筛选器的指针。

feed

struct dvb_demux_feed 指针。

index

使用的解复用器筛选器的索引。

state

筛选器的状态,由 enum dvb_dmx_state 描述。

type

筛选器的类型,由 enum dvb_dmx_filter_type 描述。

struct dvb_demux_feed

描述 DVB 字段

定义:

struct dvb_demux_feed {
    union {
        struct dmx_ts_feed ts;
        struct dmx_section_feed sec;
    } feed;
    union {
        dmx_ts_cb ts;
        dmx_section_cb sec;
    } cb;
    struct dvb_demux *demux;
    void *priv;
    enum dvb_dmx_filter_type type;
    enum dvb_dmx_state state;
    u16 pid;
    ktime_t timeout;
    struct dvb_demux_filter *filter;
    u32 buffer_flags;
    enum ts_filter_type ts_type;
    enum dmx_ts_pes pes_type;
    int cc;
    bool pusi_seen;
    u16 peslen;
    struct list_head list_head;
    unsigned int index;
};

成员

feed

描述数字电视馈送的联合。根据馈送类型,它可以是 feed.tsfeed.sec

feed.ts

a struct dmx_ts_feed 指针。仅用于 TS 馈送。

feed.sec

a struct dmx_section_feed 指针。仅用于 Section 馈送。

cb

描述数字电视回调的联合。根据馈送类型,它可以是 cb.tscb.sec

cb.ts

a dmx_ts_cb() 回调函数指针。仅用于 TS 馈送。

cb.sec

a dmx_section_cb() 回调函数指针。仅用于 Section 馈送。

demux

指向 struct dvb_demux 的指针。

priv

DVB 驱动程序可以选择使用的私有数据。

type

筛选器的类型,由 enum dvb_dmx_filter_type 定义。

state

筛选器的状态,由 enum dvb_dmx_state 定义。

pid

要筛选的 PID。

timeout

馈送超时。

筛选器

指向 struct dvb_demux_filter 的指针。

buffer_flags

用于通过 DVB 内存映射 API 报告不连续性用户的缓冲区标志,由 enum dmx_buffer_flags 定义。

ts_type

TS 的类型,由 enum ts_filter_type 定义。

pes_type

PES 的类型,由 enum dmx_ts_pes 定义。

cc

MPEG-TS 数据包连续性计数器

pusi_seen

如果为 true,则指示检测到不连续性。它用于防止馈送先前 Section 中的垃圾。

peslen

PES(数据包基本流)的长度。

list_head

数字电视解复用器馈送列表的头部。

index

每个馈送的唯一索引。可以用作硬件 pid 筛选器索引。

struct dvb_demux

表示数字电视解复用器

定义:

struct dvb_demux {
    struct dmx_demux dmx;
    void *priv;
    int filternum;
    int feednum;
    int (*start_feed)(struct dvb_demux_feed *feed);
    int (*stop_feed)(struct dvb_demux_feed *feed);
    int (*write_to_decoder)(struct dvb_demux_feed *feed, const u8 *buf, size_t len);
    u32 (*check_crc32)(struct dvb_demux_feed *feed, const u8 *buf, size_t len);
    void (*memcopy)(struct dvb_demux_feed *feed, u8 *dst, const u8 *src, size_t len);
    int users;
#define MAX_DVB_DEMUX_USERS 10;
    struct dvb_demux_filter *filter;
    struct dvb_demux_feed *feed;
    struct list_head frontend_list;
    struct dvb_demux_feed *pesfilter[DMX_PES_OTHER];
    u16 pids[DMX_PES_OTHER];
#define DMX_MAX_PID 0x2000;
    struct list_head feed_list;
    u8 tsbuf[204];
    int tsbufp;
    struct mutex mutex;
    spinlock_t lock;
    uint8_t *cnt_storage;
    ktime_t speed_last_time;
    uint32_t speed_pkts_cnt;
};

成员

dmx

嵌入式 struct dmx_demux,具有解复用器功能和回调。

priv

DVB 驱动程序可以选择使用的私有数据。

filternum

dvbfilternum

DVB 筛选器的最大数量。

feednum

DVB 馈送的最大数量。

start_feed

为了启动 DVB 馈送而要调用的回调例程。

stop_feed

为了停止 DVB 馈送而要调用的回调例程。

write_to_decoder

如果馈送是 TS 且路由到 A/V 解码器,则在收到新的 TS 数据包时要调用的回调例程。仅在 av7110-av.c 上使用。

check_crc32

用于检查 CRC 的回调例程。如果未初始化,dvb_demux 将使用内部例程。

memcopy

用于存储收到的数据的回调例程。如果未初始化,dvb_demux 将默认为 memcpy()

users

筛选器

指向 struct dvb_demux_filter 的指针。

feed

用于存储已打开的文件描述符数量的计数器。当前,它限制为 10 个用户。

filter

指向 struct dvb_demux_feed 的指针。

frontend_list

具有解复用器使用的前端的 struct list_head

pesfilter

具有要筛选的 PES 类型的 struct dvb_demux_feed 数组。

pids

筛选的节目 ID 列表。

feed_list

具有馈送的 struct list_head

tsbuf

用于在内部存储 TS 数据包的临时缓冲区。

mutex

tsbufp

lock

在内部使用的临时缓冲区索引。

mutex

指向 struct mutex 的指针,用于保护馈送设置逻辑。

lock

指向 spinlock_t 的指针,用于保护缓冲区处理。

cnt_storage

用于 TS/TEI 连续性检查的缓冲区。

speed_last_time

用于 TS 速度检查的 ktime_t

参数

speed_pkts_cnt

用于 TS 速度检查的数据包计数。

int dvb_dmx_init(struct dvb_demux *demux)

初始化数字电视解复用器结构。

struct dvb_demux *demux

dvb->demux.dmx.capabilities =
        DMX_TS_FILTERING | DMX_SECTION_FILTERING |
        DMX_MEMORY_BASED_FILTERING;
dvb->demux.priv       = dvb;
dvb->demux.filternum  = 256;
dvb->demux.feednum    = 256;
dvb->demux.start_feed = driver_start_feed;
dvb->demux.stop_feed  = driver_stop_feed;
ret = dvb_dmx_init(&dvb->demux);
if (ret < 0)
        return ret;
要初始化的 struct dvb_demux

描述

参数

speed_pkts_cnt

在能够注册数字电视解复用器结构之前,驱动程序应调用此例程。在其典型用法中,应在驱动程序中初始化一些字段,然后再调用它。

int dvb_dmx_init(struct dvb_demux *demux)

一个典型的用例是

void dvb_dmx_release(struct dvb_demux *demux)

释放数字电视解复用器内部缓冲区。

参数

speed_pkts_cnt

struct dvb_demux 要释放的结构。

DVB 核心在内部在 demux 处分配数据。此例程释放这些数据。请注意,结构本身不会释放,因为它可能会嵌入在其他结构中。

void dvb_dmx_swfilter_packets(struct dvb_demux *demux, const u8 *buf, size_t count)

将 dvb 软件筛选器用于缓冲区,该缓冲区具有多个 MPEG-TS 数据包,每个数据包 188 个字节。

指针指向 struct dvb_demux

int dvb_dmx_init(struct dvb_demux *demux)

const u8 *buf

要筛选的数据的缓冲区

size_t count

大小为 188 的 MPEG-TS 数据包的数量。

例程将丢弃不以 0x47 开头的 DVB 数据包。

释放数字电视解复用器内部缓冲区。

参数

speed_pkts_cnt

struct dvb_demux 要释放的结构。

DVB 核心在内部在 demux 处分配数据。此例程释放这些数据。请注意,结构本身不会释放,因为它可能会嵌入在其他结构中。

void dvb_dmx_swfilter_packets(struct dvb_demux *demux, const u8 *buf, size_t count)

将 dvb 软件筛选器用于缓冲区,该缓冲区具有多个 MPEG-TS 数据包,每个数据包 188 个字节。

指针指向 struct dvb_demux

int dvb_dmx_init(struct dvb_demux *demux)

如果 DVB 解复用器填充已对齐的 MPEG-TS 缓冲区,请使用此例程。

注意

size_t count

大小为 188 的 MPEG-TS 数据包的数量。

void dvb_dmx_swfilter_204(struct dvb_demux *demux, const u8 *buf, size_t count)

对具有多个每个 204 字节 MPEG-TS 数据包的缓冲区使用 dvb 软件过滤器。

参数

speed_pkts_cnt

struct dvb_demux 要释放的结构。

DVB 核心在内部在 demux 处分配数据。此例程释放这些数据。请注意,结构本身不会释放,因为它可能会嵌入在其他结构中。

void dvb_dmx_swfilter_packets(struct dvb_demux *demux, const u8 *buf, size_t count)

将 dvb 软件筛选器用于缓冲区,该缓冲区具有多个 MPEG-TS 数据包,每个数据包 188 个字节。

大小为 204 的 MPEG-TS 数据包的数量。

int dvb_dmx_init(struct dvb_demux *demux)

如果 DVB 解复用器填充已对齐的 MPEG-TS 缓冲区,请使用此例程。

注意

size_t count

buf 的大小应等于 count * 204

void dvb_dmx_swfilter_raw(struct dvb_demux *demux, const u8 *buf, size_t count)

将原始数据提供给用户空间,无需过滤

参数

speed_pkts_cnt

struct dvb_demux 要释放的结构。

DVB 核心在内部在 demux 处分配数据。此例程释放这些数据。请注意,结构本身不会释放,因为它可能会嵌入在其他结构中。

包含数据的缓冲区

将 dvb 软件筛选器用于缓冲区,该缓冲区具有多个 MPEG-TS 数据包,每个数据包 188 个字节。

要传递的数据包数量。每个数据包的实际大小取决于 dvb_demux->feed->cb.ts 逻辑。

int dvb_dmx_init(struct dvb_demux *demux)

如果驱动程序需要将原始有效负载传递到用户空间,而无需通过内核解复用器,请使用此选项。这意味着支持一些不是基于 MPEG-TS 的传输系统。

此函数依赖于 dvb_demux->feed->cb.ts 来实际处理缓冲区。

3.3.5. 驱动程序内部低级硬件特定驱动程序解复用器接口

enum ts_filter_type

dmx_ts_feed.set() 的过滤器类型位图

常量

TS_PACKET

将 TS 数据包(188 字节)发送到回调(默认)。

TS_PAYLOAD_ONLY

如果设置了 TS_PACKET,则仅将 TS 有效负载(每个数据包 <=184 字节)发送到回调

TS_DECODER

将流发送到内置解码器(如果存在)。

TS_DEMUX

如果设置了 TS_PACKET,则将 TS 发送到解复用设备,而不是 dvr 设备

struct dmx_ts_feed

包含 TS 馈送过滤器的结构

定义:

struct dmx_ts_feed {
    int is_filtering;
    struct dmx_demux *parent;
    void *priv;
    int (*set)(struct dmx_ts_feed *feed,u16 pid,int type,enum dmx_ts_pes pes_type, ktime_t timeout);
    int (*start_filtering)(struct dmx_ts_feed *feed);
    int (*stop_filtering)(struct dmx_ts_feed *feed);
};

成员

is_filtering

当正在进行过滤时,设置为非零值

parent

指向 struct dmx_demux 的指针

priv

指向 API 客户端的私有数据的指针

set

设置 TS 过滤器

start_filtering

启动 TS 过滤

stop_filtering

停止 TS 过滤

int dvb_dmx_init(struct dvb_demux *demux)

TS 馈送通常映射到解复用器芯片上的硬件 PID 过滤器。使用此 API,客户端可以设置过滤属性以启动/停止特定 TS 馈送上的 TS 数据包过滤。

struct dmx_section_filter

描述节过滤器的结构

定义:

struct dmx_section_filter {
    u8 filter_value[DMX_MAX_FILTER_SIZE];
    u8 filter_mask[DMX_MAX_FILTER_SIZE];
    u8 filter_mode[DMX_MAX_FILTER_SIZE];
    struct dmx_section_feed *parent;
    void *priv;
};

成员

filter_value

包含 TS 节标头的最多 16 个字节(128 位),节过滤器将匹配这些字节

filter_mask

包含 16 个字节(128 位)的过滤器掩码,其中 filter_value 指定的位将用于过滤器匹配逻辑。

filter_mode

包含 16 个字节(128 位)的过滤器模式。

parent

指向 struct dmx_section_feed 的反向指针。

priv

指向 API 客户端的私有数据的指针。

int dvb_dmx_init(struct dvb_demux *demux)

filter_mask 控制将 filter_value 的哪些位与节标头/有效负载进行比较。在 filter_mask 中的二进制值 1 上,将比较相应的位。过滤器仅接受所有经过测试的位位置上等于 filter_value 的节。

struct dmx_section_feed

包含节馈送过滤器的结构

定义:

struct dmx_section_feed {
    int is_filtering;
    struct dmx_demux *parent;
    void *priv;
    int check_crc;
    int (*set)(struct dmx_section_feed *feed,u16 pid, int check_crc);
    int (*allocate_filter)(struct dmx_section_feed *feed, struct dmx_section_filter **filter);
    int (*release_filter)(struct dmx_section_feed *feed, struct dmx_section_filter *filter);
    int (*start_filtering)(struct dmx_section_feed *feed);
    int (*stop_filtering)(struct dmx_section_feed *feed);
};

成员

is_filtering

当正在进行过滤时,设置为非零值

parent

指向 struct dmx_demux 的指针

priv

指向 API 客户端的私有数据的指针

check_crc

如果非零,则检查已过滤节的 CRC 值。

set

设置节过滤器

allocate_filter

此函数用于在解复用器上分配节过滤器。仅当在此节馈送上未进行过滤时才应调用它。如果无法分配过滤器,则函数将失败并返回 -ENOSPC。

release_filter

此函数释放先前分配的节过滤器的所有资源。在此节馈送上正在进行过滤时不应调用该函数。调用此函数后,调用方不应尝试取消引用过滤器指针。

start_filtering

启动节过滤

stop_filtering

停止节过滤

int dvb_dmx_init(struct dvb_demux *demux)

TS 馈送通常映射到解复用器芯片上的硬件 PID 过滤器。使用此 API,客户端可以设置过滤属性以启动/停止特定 TS 馈送上的 TS 数据包过滤。

dmx_ts_cb

Typedef:DVB 解复用器 TS 过滤器回调函数原型

语法

int dmx_ts_cb (const u8 *buffer1, size_t buffer1_length, const u8 *buffer2, size_t buffer2_length, struct dmx_ts_feed *source, u32 *buffer_flags)

参数

const u8 *buffer1

指向已过滤 TS 数据包的起点的指针。

size_t buffer1_length

buffer1 中 TS 数据的长度。

const u8 *buffer2

指向已过滤 TS 数据包的尾部的指针,或 NULL。

size_t buffer2_length

buffer2 中 TS 数据的长度。

struct dmx_ts_feed *source

指示哪个 TS 馈送是回调的源。

u32 *buffer_flags

存储缓冲区标志的地址。这些标志用于通过 DVB 内存映射 API 报告不连续用户,如 enum dmx_buffer_flags 定义的那样。

int dvb_dmx_init(struct dvb_demux *demux)

此函数回调原型由解复用器 API 的客户端提供,从解复用器代码中调用。仅当使用 dmx_demux 处的 start_filtering() 函数启用了 TS 馈送的过滤时,才会调用该函数。任何与过滤器设置匹配的 TS 数据包都会被复制到循环缓冲区。已过滤的 TS 数据包使用此回调函数传递给客户端。期望 buffer1buffer2 回调参数指向循环缓冲区中的地址,但其他实现也是可能的。请注意,被调用方不应尝试释放 buffer1buffer2 参数指向的内存。

调用此函数时,buffer1 参数通常指向循环缓冲区中第一个未传递的 TS 数据包的起点。buffer2 缓冲区参数通常为 NULL,除非接收到的 TS 数据包已超过循环缓冲区的最后一个地址并“环绕”到缓冲区的开头。在后一种情况下,buffer1 参数将包含循环缓冲区中的地址,而 buffer2 参数将包含循环缓冲区的第一个地址。使用此函数传递的字节数(即 buffer1_length + buffer2_length)通常等于 set() 函数中给定的 callback_length 参数的值,但有一个例外:如果在接收 callback_length 字节的 TS 数据之前发生超时,则任何未传递的数据包都会通过调用此函数立即传递给客户端。超时持续时间由 TS 馈送 API 中的 set() 函数控制。

如果接收到 TS 数据包时出现 TS 级前向纠错 (FEC) 无法修复的错误,则应设置 TS 数据包标头的 Transport_error_indicator 标志。不应丢弃 TS 数据包,因为可以通过更高的层协议来纠正错误。如果被调用方处理回调的速度很慢,则循环缓冲区最终可能会填满。如果发生这种情况,解复用器驱动程序应丢弃在缓冲区已满时接收到的任何 TS 数据包,并返回 -EOVERFLOW。

可以通过 dmx_ts_feed.**set** 函数选择返回给回调的数据类型。类型参数决定应返回原始 TS 数据包 (TS_PACKET) 还是仅返回有效负载 (TS_PACKET|TS_PAYLOAD_ONLY)。如果另外设置了 TS_DECODER 位,则流也将发送到硬件 MPEG 解码器。

  • 0,成功时;

  • -EOVERFLOW,缓冲区溢出时。

dmx_section_cb

Typedef:DVB 解复用器 TS 过滤器回调函数原型

语法

int dmx_section_cb (const u8 *buffer1, size_t buffer1_len, const u8 *buffer2, size_t buffer2_len, struct dmx_section_filter *source, u32 *buffer_flags)

参数

const u8 *buffer1

指向已过滤节的起点的指针,例如,在解复用器驱动程序的循环缓冲区中。

size_t buffer1_len

buffer1 中已过滤节数据的长度,包括标头和 CRC。

const u8 *buffer2

指向已过滤节数据的尾部的指针,或 NULL。用于处理循环缓冲区的环绕。

size_t buffer2_len

buffer2 中已过滤节数据的长度,包括标头和 CRC。

struct dmx_section_filter *source

指示哪个节馈送是回调的源。

u32 *buffer_flags

存储缓冲区标志的地址。这些标志用于通过 DVB 内存映射 API 报告不连续用户,如 enum dmx_buffer_flags 定义的那样。

int dvb_dmx_init(struct dvb_demux *demux)

此函数回调原型由解复用器 API 的客户端提供,从解复用器代码中调用。仅当使用函数 dmx_ts_feed.**start_filtering** 启用了节的过滤时,才会调用该函数。当解复用器驱动程序收到与至少一个节过滤器匹配的完整节时,将通过此回调函数通知客户端。通常,为每个接收到的节调用此函数;但是,也可以使用一个回调传递多个节,例如,当系统负载很高时。如果在接收节时发生错误,则应在 success 字段中设置相应的错误类型的情况下调用此函数,无论是否有要传递的数据。节馈送实现应维护已接收节的循环缓冲区。但是,如果节馈送 API 实现为 TS 馈送 API 的客户端,则这不是必需的,因为 TS 馈送实现随后会缓冲接收到的数据。可以使用节馈送 API 中的 dmx_ts_feed.**set** 函数配置循环缓冲区的大小。如果收到新节时循环缓冲区中没有空间,则必须丢弃该节。如果发生这种情况,则下次回调时 success 参数的值应为 DMX_OVERRUN_ERROR。

enum dmx_frontend_source

用于标识前端类型

常量

DMX_MEMORY_FE

解复用器的源是内存。这意味着要过滤的 MPEG-TS 来自用户空间,通过 write() 系统调用。

DMX_FRONTEND_0

解复用器的源是连接到解复用器的前端。

struct dmx_frontend

列出与解复用器关联的前端的结构

定义:

struct dmx_frontend {
    struct list_head connectivity_list;
    enum dmx_frontend_source source;
};

成员

connectivity_list

可以连接到特定解复用器的前端列表;

source

前端的类型。

int dvb_dmx_init(struct dvb_demux *demux)

FIXME:此结构可能很快会被基于媒体控制器的逻辑替换。

基于媒体控制器的逻辑。

enum dmx_demux_caps

MPEG-2 TS 解复用器功能位图

常量

DMX_TS_FILTERING

如果支持 TS 过滤,则设置;

DMX_SECTION_FILTERING

如果支持节过滤,则设置;

DMX_MEMORY_BASED_FILTERING

如果 write() 可用,则设置。

int dvb_dmx_init(struct dvb_demux *demux)

这些标志在 dmx_demux.capabilities 字段中进行 OR 运算

DMX_FE_ENTRY

DMX_FE_ENTRY (list)

将已注册前端列表中的元素从通用类型 struct list_head 强制转换为类型 * struct dmx_frontend

参数

list

struct dmx_frontend 的列表

struct dmx_demux

包含解复用器功能和回调的结构。

定义:

struct dmx_demux {
    enum dmx_demux_caps capabilities;
    struct dmx_frontend *frontend;
    void *priv;
    int (*open)(struct dmx_demux *demux);
    int (*close)(struct dmx_demux *demux);
    int (*write)(struct dmx_demux *demux, const char __user *buf, size_t count);
    int (*allocate_ts_feed)(struct dmx_demux *demux,struct dmx_ts_feed **feed, dmx_ts_cb callback);
    int (*release_ts_feed)(struct dmx_demux *demux, struct dmx_ts_feed *feed);
    int (*allocate_section_feed)(struct dmx_demux *demux,struct dmx_section_feed **feed, dmx_section_cb callback);
    int (*release_section_feed)(struct dmx_demux *demux, struct dmx_section_feed *feed);
    int (*add_frontend)(struct dmx_demux *demux, struct dmx_frontend *frontend);
    int (*remove_frontend)(struct dmx_demux *demux, struct dmx_frontend *frontend);
    struct list_head *(*get_frontends)(struct dmx_demux *demux);
    int (*connect_frontend)(struct dmx_demux *demux, struct dmx_frontend *frontend);
    int (*disconnect_frontend)(struct dmx_demux *demux);
    int (*get_pes_pids)(struct dmx_demux *demux, u16 *pids);
};

成员

capabilities

功能标志的位字段。

frontend

连接到解复用器的前端

priv

指向 API 客户端的私有数据的指针

open

此函数为调用方保留解复用器,并在必要时初始化解复用器。不再需要解复用器时,应调用函数 close。多个客户端应可以同时访问解复用器。因此,函数实现应在调用 open 时递增解复用器使用计数,并在调用 close 时递减它。demux 函数参数包含指向解复用器 API 和实例数据的指针。它返回:成功时返回 0;达到最大使用计数时返回 -EUSERS;参数错误时返回 -EINVAL。

close

此函数为调用方保留解复用器,并在必要时初始化解复用器。不再需要解复用器时,应调用函数 close。多个客户端应可以同时访问解复用器。因此,函数实现应在调用 open 时递增解复用器使用计数,并在调用 close 时递减它。demux 函数参数包含指向解复用器 API 和实例数据的指针。它返回:成功时返回 0;如果解复用器未使用(例如,没有用户),则返回 -ENODEV;参数错误时返回 -EINVAL。

write

此函数向解复用器驱动程序提供包含 TS 数据包的内存缓冲区。解复用器驱动程序软件将从内存读取数据包,而不是从 DVB 前端接收 TS 数据包。具有活动 TS、PES 或节过滤器的此解复用器的任何客户端都将通过解复用器回调 API(请参阅 0)接收已过滤的数据。当缓冲区中的所有数据都被解复用器使用后,该函数将返回。解复用器硬件通常无法从内存读取 TS。如果是这种情况,则必须完全在软件中实现基于内存的过滤。demux 函数参数包含指向解复用器 API 和实例数据的指针。buf 函数参数包含指向内核空间内存中 TS 数据的指针。count 函数参数包含 TS 数据的长度。它返回:成功时返回 0;互斥锁被中断时返回 -ERESTARTSYS;有信号处理挂起时返回 -EINTR;解复用器已移除时返回 -ENODEV;参数错误时返回 -EINVAL。

allocate_ts_feed

分配新的 TS 馈送,该馈送用于过滤承载特定 PID 的 TS 数据包。TS 馈送通常对应于解复用器芯片上的硬件 PID 过滤器。demux 函数参数包含指向解复用器 API 和实例数据的指针。feed 函数参数包含指向 TS 馈送 API 和实例数据的指针。callback 函数参数包含指向用于传递接收到的 TS 数据包的回调函数的指针。它返回:成功时返回 0;互斥锁被中断时返回 -ERESTARTSYS;如果没有更多 TS 馈送可用,则返回 -EBUSY;参数错误时返回 -EINVAL。

release_ts_feed

释放使用 allocate_ts_feed 分配的资源。应在调用此函数之前停止 TS 馈送上的任何正在进行的过滤。demux 函数参数包含指向解复用器 API 和实例数据的指针。feed 函数参数包含指向 TS 馈送 API 和实例数据的指针。它返回:成功时返回 0;参数错误时返回 -EINVAL。

allocate_section_feed

分配新的节馈送,即用于过滤和接收节的解复用器资源。在具有节过滤硬件支持的平台上,节馈送直接映射到解复用器硬件。在其他平台上,TS 数据包首先在硬件中进行 PID 过滤,然后在软件中模拟硬件节过滤器。调用方获取类型为 dmx_section_feed_t 的 API 指针作为输出参数。使用此 API,调用方可以设置过滤参数并开始接收节。demux 函数参数包含指向解复用器 API 和实例数据的指针。feed 函数参数包含指向 TS 馈送 API 和实例数据的指针。callback 函数参数包含指向用于传递接收到的 TS 数据包的回调函数的指针。它返回:成功时返回 0;如果没有更多 TS 馈送可用,则返回 -EBUSY;参数错误时返回 -EINVAL。

release_section_feed

释放使用 allocate_section_feed 分配的资源,包括分配的过滤器。应在调用此函数之前停止节馈送上的任何正在进行的过滤。demux 函数参数包含指向解复用器 API 和实例数据的指针。feed 函数参数包含指向 TS 馈送 API 和实例数据的指针。它返回:成功时返回 0;参数错误时返回 -EINVAL。

add_frontend

注册解复用器和前端之间的连接,即指示可以通过调用 connect_frontend 连接解复用器,以将给定的前端用作 TS 源。此函数的客户端必须为前端结构分配动态或静态内存,并在调用此函数之前初始化其字段。通常在驱动程序初始化期间调用此函数。在成功调用 remove_frontend 之前,调用方不得释放前端结构的内存。demux 函数参数包含指向解复用器 API 和实例数据的指针。frontend 函数参数包含指向前端实例数据的指针。它返回:成功时返回 0;参数错误时返回 -EINVAL。

remove_frontend

指示给定前端(通过调用 add_frontend 注册)不再可以作为此解复用器的 TS 源连接。从系统中移除前端驱动程序或解复用器驱动程序时,应调用该函数。如果正在使用前端,则函数将失败并返回 -EBUSY。成功调用此函数后,如果之前在 add_frontend 操作之前动态分配了前端结构的内存,则调用方可以释放该内存。demux 函数参数包含指向解复用器 API 和实例数据的指针。frontend 函数参数包含指向前端实例数据的指针。它返回:成功时返回 0;如果未找到前端,则返回 -ENODEV,参数错误时返回 -EINVAL。

get_frontends

提供已为此解复用器注册的前端的 API。通过此调用获得的任何前端都可以用作 connect_frontend 的参数。包含文件 demux.h 包含宏 DMX_FE_ENTRY(),用于将通用类型 struct list_head * 的元素转换为类型 struct dmx_frontend *。调用方不得释放通过此函数调用获得的任何元素的内存。**demux** 函数参数包含指向解复用器 API 和实例数据的指针。它返回指向前端接口列表的 struct list_head 指针,如果列表为空,则返回 NULL。

connect_frontend

将前端的 TS 输出连接到解复用器的输入。解复用器只能连接到使用函数 add_frontend 注册到解复用器的前端。根据硬件平台的功能,可以将多个解复用器连接到同一前端,也可能无法连接。不使用时,应通过调用 disconnect_frontend 来释放前端。demux 函数参数包含指向解复用器 API 和实例数据的指针。frontend 函数参数包含指向前端实例数据的指针。它返回:成功时返回 0;参数错误时返回 -EINVAL。

disconnect_frontend

断开解复用器和先前通过 connect_frontend 调用连接的前端。demux 函数参数包含指向解复用器 API 和实例数据的指针。它返回:成功时返回 0;参数错误时返回 -EINVAL。

get_pes_pids

获取 DMX_PES_AUDIO0、DMX_PES_VIDEO0、DMX_PES_TELETEXT0、DMX_PES_SUBTITLE0 和 DMX_PES_PCR0 的 PID。demux 函数参数包含指向解复用器 API 和实例数据的指针。pids 函数参数包含一个包含五个 u16 元素的数组,PID 将存储在其中。它返回:成功时返回 0;参数错误时返回 -EINVAL。