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.ts 或 feed.sec。
feed.ts
a
struct list_head
列表。用于 TS 和 PES 馈送。feed.sec
a
struct dmx_section_feed
指针。仅用于 Section 馈送。params
描述 dmxdev 筛选器参数的联合。根据筛选器类型,它可以是 params.sec 或 params.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
的指针。
参数
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
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.ts 或 feed.sec。
feed.ts
a
struct dmx_ts_feed
指针。仅用于 TS 馈送。feed.sec
a
struct dmx_section_feed
指针。仅用于 Section 馈送。cb
描述数字电视回调的联合。根据馈送类型,它可以是 cb.ts 或 cb.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)¶
一个典型的用例是
参数
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
。
参数
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 数据包使用此回调函数传递给客户端。期望 buffer1 和 buffer2 回调参数指向循环缓冲区中的地址,但其他实现也是可能的。请注意,被调用方不应尝试释放 buffer1 和 buffer2 参数指向的内存。
调用此函数时,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_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()
,用于将通用类型 structlist_head
* 的元素转换为类型 structdmx_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。