3.3. 数字电视解复用器 kABI¶
3.3.1. 数字电视解复用器¶
内核数字电视解复用器 kABI 定义了一个驱动程序内部接口,用于将底层、硬件特定的驱动程序注册到与硬件无关的解复用层。它仅对数字电视设备驱动程序编写者感兴趣。此 kABI 的头文件名为 demux.h
,位于 include/media
中。
应该为系统中的每个解复用器实现解复用器 kABI。它用于选择解复用器的 TS 源并管理解复用器资源。当解复用器客户端通过解复用器 kABI 分配资源时,它会收到指向该资源 kABI 的指针。
每个解复用器都从 DVB 前端或从内存接收其 TS 输入,这是通过此解复用器 kABI 设置的。在具有多个前端的系统中,除非在硬件平台中固定,否则可以使用 kABI 选择其中一个 DVB 前端作为解复用器的 TS 源。
解复用器 kABI 仅控制前端与其与解复用器的连接;用于设置其他前端参数(例如调谐)的 kABI 通过数字电视前端 kABI 定义。
实现抽象接口解复用器的函数应定义为静态或模块私有,并注册到解复用器核心以进行外部访问。不需要实现结构体 dmx_demux
中的每个函数。例如,解复用器接口可能支持节过滤,但不支持 PES 过滤。kABI 客户端应在调用函数之前检查任何函数指针的值:NULL
的值表示该函数不可用。
每当解复用器 API 的函数修改共享数据时,都应解决丢失更新和竞争条件问题的可能性,例如通过使用互斥锁保护部分代码。
请注意,从下半部上下文调用的函数不得休眠。即使是不使用 GFP_ATOMIC
的简单内存分配,如果需要交换,也可能导致内核线程进入休眠状态。例如,Linux 内核从下半部上下文中调用网络设备接口的函数。因此,如果从网络设备代码调用解复用器 kABI 函数,则该函数不得休眠。
3.3.2. 解复用器回调 API¶
此内核空间 API 包括将过滤后的数据传递给解复用器客户端的回调函数。与其他 DVB kABI 不同,这些函数由客户端提供,并从解复用器代码调用。
此抽象接口的函数指针不像其他解复用器 API 那样打包到结构中,因为回调函数是注册和独立使用的。例如,API 客户端可以提供多个用于接收 TS 数据包的回调函数,而没有用于 PES 数据包或节的回调。
实现回调 API 的函数不需要是可重入的:当解复用器驱动程序调用其中一个函数时,驱动程序不允许在原始调用返回之前再次调用该函数。如果回调是由硬件中断触发的,建议使用 Linux 下半部机制或启动 tasklet,而不是直接从硬件中断调用回调函数。
此机制由 dmx_ts_cb()
和 dmx_section_cb()
回调实现。
3.3.3. 数字电视解复用器设备注册函数和数据结构¶
-
enum dmxdev_type¶
解复用器过滤器类型。
常量
DMXDEV_TYPE_NONE
未设置过滤器。
DMXDEV_TYPE_SEC
节过滤器。
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];
};
成员
filter
一个描述 dmxdev 过滤器的联合。目前仅用于节过滤器。
filter.sec
一个
struct dmx_section_filter
指针。仅适用于节过滤器。feed
一个描述 dmxdev 源的联合。根据过滤器类型,它可以是 feed.ts 或 feed.sec。
feed.ts
一个
struct list_head
列表。用于 TS 和 PES 源。feed.sec
一个
struct dmx_section_feed
指针。仅适用于节源。params
一个联合体,用于描述 dmxdev 过滤器参数。根据过滤器类型,它可以是 params.sec 或 params.pes。
params.sec
一个嵌入的
struct dmx_sct_filter_params
结构体。仅用于 section 过滤器。params.pes
一个嵌入的
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
定时器,用于检查 feed 超时。仅用于 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
的指针。filter
指向
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¶
解复用器 feed 的类型。
常量
DMX_TYPE_TS
feed 处于 TS 模式。
DMX_TYPE_SEC
feed 处于 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;
};
成员
filter
由
struct dmx_section_filter
定义的 Section 过滤器。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。根据 feed 类型,它可以是 feed.ts 或 feed.sec。
feed.ts
一个指向
struct dmx_ts_feed
的指针。仅用于 TS feed。feed.sec
一个
struct dmx_section_feed
指针。仅适用于节源。cb
一个联合体,用于描述数字电视回调。根据 feed 类型,它可以是 cb.ts 或 cb.sec。
cb.ts
一个
dmx_ts_cb()
回调函数指针。仅用于 TS feed。cb.sec
一个
dmx_section_cb()
回调函数指针。仅用于 section feed。demux
指向
struct dvb_demux
的指针。priv
DVB 驱动程序可以选择使用的私有数据。
type
过滤器的类型,由
enum dvb_dmx_filter_type
定义。state
过滤器的状态,由
enum dvb_dmx_state
定义。pid
要过滤的 PID。
timeout
feed 超时。
filter
指向
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,则表示检测到不连续性。它用于防止从上一节中馈送垃圾数据。
peslen
PES(打包基本流)的长度。
list_head
数字电视解复用器 feed 列表的头部。
index
每个 feed 的唯一索引。可以用作硬件 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
最大 DVB 过滤器数量。
feednum
最大 DVB feed 数量。
start_feed
为了启动 DVB feed 而调用的回调例程。
stop_feed
为了停止 DVB feed 而调用的回调例程。
write_to_decoder
如果馈送是 TS 并且被路由到 A/V 解码器,则在新接收到 TS 数据包时调用的回调例程。仅在 av7110-av.c 中使用。
check_crc32
用于检查 CRC 的回调例程。如果未初始化,则 dvb_demux 将使用内部的例程。
memcopy
用于内存复制接收数据的回调例程。如果未初始化,dvb_demux 将默认使用
memcpy()
。users
已打开的 demux 文件描述符的数量计数器。目前,限制为 10 个用户。
filter
指向
struct dvb_demux_filter
的指针。feed
指向
struct dvb_demux_feed
的指针。frontend_list
struct list_head
,包含 demux 使用的前端。pesfilter
struct dvb_demux_feed
的数组,其中包含将要过滤的 PES 类型。pids
已过滤的节目 ID 列表。
feed_list
struct list_head
,包含馈送。tsbuf
内部用于存储 TS 数据包的临时缓冲区。
tsbufp
内部使用的临时缓冲区索引。
mutex
指向
struct mutex
的指针,用于保护馈送设置逻辑。lock
指向
spinlock_t
的指针,用于保护缓冲区处理。cnt_storage
用于 TS/TEI 连续性检查的缓冲区。
speed_last_time
用于 TS 速度检查的
ktime_t
。speed_pkts_cnt
用于 TS 速度检查的数据包计数。
参数
struct dvb_demux *demux
要初始化的
struct dvb_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 *demux
要释放的
struct dvb_demux
。
描述
DVB 核心在内部在 demux 中分配数据。此例程释放这些数据。请注意,结构体本身不会被释放,因为它可能嵌入在其他结构体中。
-
void dvb_dmx_swfilter_packets(struct dvb_demux *demux, const u8 *buf, size_t count)¶
对一个包含多个 188 字节的 MPEG-TS 数据包的缓冲区使用 dvb 软件过滤器。
参数
struct dvb_demux *demux
指向
struct dvb_demux
的指针const u8 *buf
包含要过滤的数据的缓冲区
size_t count
大小为 188 的 MPEG-TS 数据包的数量。
描述
此例程将丢弃不以 0x47 开头的 DVB 数据包。
如果 DVB 解复用器填充的 MPEG-TS 缓冲区已经对齐,则使用此例程。
注意
buf 的大小应等于 count * 188
。
-
void dvb_dmx_swfilter(struct dvb_demux *demux, const u8 *buf, size_t count)¶
对一个包含多个 188 字节的 MPEG-TS 数据包的缓冲区使用 dvb 软件过滤器。
参数
struct dvb_demux *demux
指向
struct dvb_demux
的指针const u8 *buf
包含要过滤的数据的缓冲区
size_t count
大小为 188 的 MPEG-TS 数据包的数量。
描述
如果 DVB 数据包不以 0x47 开头,它将查找第一个以 0x47 开头的字节。
如果 DVB 解复用器填充的缓冲区可能不以数据包起始标记 (0x47) 开头,则使用此例程。
注意
buf 的大小应等于 count * 188
。
-
void dvb_dmx_swfilter_204(struct dvb_demux *demux, const u8 *buf, size_t count)¶
对一个包含多个 204 字节的 MPEG-TS 数据包的缓冲区使用 dvb 软件过滤器。
参数
struct dvb_demux *demux
指向
struct dvb_demux
的指针const u8 *buf
包含要过滤的数据的缓冲区
size_t count
大小为 204 的 MPEG-TS 数据包的数量。
描述
如果 DVB 数据包不以 0x47 开头,它将查找第一个以 0x47 开头的字节。
如果 DVB 解复用器填充的缓冲区可能不以数据包起始标记 (0x47) 开头,则使用此例程。
注意
buf 的大小应等于 count * 204
。
-
void dvb_dmx_swfilter_raw(struct dvb_demux *demux, const u8 *buf, size_t count)¶
使原始数据可用于用户空间,而不进行过滤
参数
struct dvb_demux *demux
指向
struct dvb_demux
的指针const u8 *buf
包含数据的缓冲区
size_t count
要传递的数据包的数量。每个数据包的实际大小取决于
dvb_demux->feed
->cb.ts 逻辑。
描述
如果驱动程序需要将原始有效负载传递到用户空间,而不经过内核解复用器,则可以使用它。这意味着支持一些不基于 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 发送到 demux 设备,而不是 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 过滤
描述
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 客户端私有数据的指针。
描述
filter_mask 控制将 filter_value 的哪些位与 section 头部/有效负载进行比较。在 filter_mask 中二进制值为 1 的位,相应的位会被比较。过滤器只接受所有测试位位置都等于 filter_value 的 section。
-
struct dmx_section_feed¶
包含 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
如果非零,则检查过滤后的 section 的 CRC 值。
set
设置 section 过滤器
allocate_filter
此函数用于在解复用器上分配 section 过滤器。只有在没有在此 section feed 上进行过滤时才应调用它。如果无法分配过滤器,则函数将失败并返回 -ENOSPC。
release_filter
此函数释放先前分配的 section 过滤器的所有资源。在 此 section feed 上进行过滤时,不应调用此函数。调用此函数后,调用者不应尝试取消引用过滤器指针。
start_filtering
开始 section 过滤
stop_filtering
停止 section 过滤
描述
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 feed 是回调的来源。
u32 *buffer_flags
存储缓冲区标志的地址。这些标志用于通过 DVB 内存映射 API 报告不连续性用户,如
enum dmx_buffer_flags
中定义。
描述
此函数回调原型由解复用器 API 的客户端提供,从解复用器代码中调用。仅当使用 dmx_demux
的 start_filtering() 函数启用 TS feed 上的过滤时,才会调用该函数。任何与过滤器设置匹配的 TS 数据包都会被复制到一个循环缓冲区中。过滤后的 TS 数据包使用此回调函数传递给客户端。预期 buffer1 和 buffer2 回调参数指向循环缓冲区内的地址,但也可能存在其他实现。请注意,被调用方不应尝试释放 buffer1 和 buffer2 参数指向的内存。
调用此函数时,buffer1 参数通常指向循环缓冲区中第一个未传递的 TS 数据包的起始位置。buffer2 缓冲区参数通常为 NULL,除非接收到的 TS 数据包已跨越循环缓冲区的最后一个地址并“包裹”到缓冲区的开头。在后一种情况下,buffer1 参数将包含循环缓冲区内的地址,而 buffer2 参数将包含循环缓冲区的第一个地址。此函数传递的字节数(即 buffer1_length + buffer2_length)通常等于 set() 函数中给出的 callback_length 参数的值,但有一个例外:如果在接收 callback_length 字节的 TS 数据之前发生超时,则任何未传递的数据包都会立即通过调用此函数传递给客户端。超时持续时间由 TS Feed API 中的 set() 函数控制。
如果接收到的 TS 数据包出现 TS 级别前向纠错 (FEC) 无法修复的错误,则应设置 TS 数据包头部的 Transport_error_indicator 标志。TS 数据包不应被丢弃,因为该错误可能由更高层协议纠正。如果被调用方在处理回调时速度较慢,则循环缓冲区最终可能会填满。如果发生这种情况,解复用器驱动程序应丢弃缓冲区已满时收到的任何 TS 数据包,并返回 -EOVERFLOW。
可以使用 dmx_ts_feed
.**set** 函数选择返回到回调的数据类型。type 参数决定应返回原始 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
指向过滤后的 section 开始位置的指针,例如在解复用器驱动程序的循环缓冲区内。
size_t buffer1_len
buffer1 中过滤后的 section 数据的长度,包括头部和 CRC。
const u8 *buffer2
指向过滤后的 section 数据尾部的指针,或 NULL。用于处理循环缓冲区的回绕。
size_t buffer2_len
buffer2 中过滤后的 section 数据的长度,包括头部和 CRC。
struct dmx_section_filter *source
指示哪个 section feed 是回调的来源。
u32 *buffer_flags
存储缓冲区标志的地址。这些标志用于通过 DVB 内存映射 API 报告不连续性用户,如
enum dmx_buffer_flags
中定义。
描述
此函数回调原型由解复用器 API 的客户端提供,从解复用器代码中调用。仅当使用函数 dmx_ts_feed
.**start_filtering** 启用 section 过滤时,才会调用该函数。当解复用器驱动程序接收到与至少一个 section 过滤器匹配的完整 section 时,会通过此回调函数通知客户端。通常,为每个接收到的 section 调用此函数;但是,也可以使用一个回调传递多个 section,例如,当系统负载较高时。如果在接收 section 时发生错误,则应调用此函数,并在 success 字段中设置相应的错误类型,无论是否有数据要传递。Section Feed 实现应为接收到的 section 维护一个循环缓冲区。但是,如果 Section Feed API 是作为 TS Feed API 的客户端实现的,则不需要这样做,因为 TS Feed 实现会缓冲接收到的数据。可以使用 Section Feed API 中的 dmx_ts_feed
.**set** 函数配置循环缓冲区的大小。如果在接收新 section 时循环缓冲区中没有空间,则必须丢弃该 section。如果发生这种情况,则下次回调时 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
前端的类型。
描述
- FIXME:此结构体很可能很快会被一些
基于媒体控制器的逻辑取代。
-
enum dmx_demux_caps¶
MPEG-2 TS 解复用器功能位图
常量
DMX_TS_FILTERING
如果支持 TS 过滤,则设置此项;
DMX_SECTION_FILTERING
如果支持 section 过滤,则设置此项;
DMX_MEMORY_BASED_FILTERING
如果 write() 可用,则设置此项。
描述
这些标志在 dmx_demux.capabilities
字段中进行“或”运算。
-
DMX_FE_ENTRY¶
DMX_FE_ENTRY (列表)
将已注册前端列表中的元素从通用类型 struct list_head 转换为类型 *
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
功能标志的位字段。
前端
连接到解复用器的前端
priv
指向 API 客户端私有数据的指针
打开
此函数为调用者预留解复用器,并在必要时初始化解复用器。当不再需要解复用器时,应调用 close 函数。允许多个客户端同时访问解复用器。因此,函数实现应在调用 open 时增加解复用器的使用计数,并在调用 close 时减少它。 demux 函数参数包含指向解复用器 API 和实例数据的指针。它返回:成功时返回 0;如果达到最大使用计数,则返回 -EUSERS;参数错误则返回 -EINVAL。
关闭
此函数为调用者预留解复用器,并在必要时初始化解复用器。当不再需要解复用器时,应调用 close 函数。允许多个客户端同时访问解复用器。因此,函数实现应在调用 open 时增加解复用器的使用计数,并在调用 close 时减少它。 demux 函数参数包含指向解复用器 API 和实例数据的指针。它返回:成功时返回 0;如果解复用器未使用(例如,没有用户),则返回 -ENODEV;参数错误则返回 -EINVAL。
写入
此函数为解复用器驱动程序提供一个包含 TS 数据包的内存缓冲区。解复用器驱动程序软件将从内存读取数据包,而不是从 DVB 前端接收 TS 数据包。任何具有活动 TS、PES 或 Section 过滤器的此解复用器的客户端都将通过解复用器回调 API(参见 0)接收过滤后的数据。当缓冲区中的所有数据都被解复用器消耗完毕后,该函数返回。解复用器硬件通常无法从内存读取 TS。如果是这种情况,基于内存的过滤必须完全在软件中实现。 demux 函数参数包含指向解复用器 API 和实例数据的指针。 buf 函数参数包含指向内核空间内存中 TS 数据的指针。 count 函数参数包含 TS 数据的长度。它返回:成功时返回 0;如果互斥锁被中断,则返回 -ERESTARTSYS;如果有信号处理挂起,则返回 -EINTR;如果解复用器被移除,则返回 -ENODEV;参数错误则返回 -EINVAL。
allocate_ts_feed
分配一个新的 TS feed,用于过滤携带特定 PID 的 TS 数据包。 TS feed 通常对应于解复用器芯片上的硬件 PID 过滤器。 demux 函数参数包含指向解复用器 API 和实例数据的指针。 feed 函数参数包含指向 TS feed API 和实例数据的指针。 callback 函数参数包含指向用于传递接收到的 TS 数据包的回调函数的指针。它返回:成功时返回 0;如果互斥锁被中断,则返回 -ERESTARTSYS;如果没有更多可用的 TS feed,则返回 -EBUSY;参数错误则返回 -EINVAL。
release_ts_feed
释放使用 allocate_ts_feed 分配的资源。在调用此函数之前,应停止在 TS feed 上进行的任何过滤操作。 demux 函数参数包含指向解复用器 API 和实例数据的指针。 feed 函数参数包含指向 TS feed API 和实例数据的指针。它返回:成功时返回 0;参数错误则返回 -EINVAL。
allocate_section_feed
分配一个新的 section feed,即用于过滤和接收 section 的解复用器资源。在具有硬件支持 section 过滤的平台上,section feed 直接映射到解复用器硬件。在其他平台上,TS 数据包首先在硬件中进行 PID 过滤,然后在软件中模拟硬件 section 过滤器。调用者获取 dmx_section_feed_t 类型的 API 指针作为输出参数。使用此 API,调用者可以设置过滤参数并开始接收 section。 demux 函数参数包含指向解复用器 API 和实例数据的指针。 feed 函数参数包含指向 TS feed API 和实例数据的指针。 callback 函数参数包含指向用于传递接收到的 TS 数据包的回调函数的指针。它返回:成功时返回 0;如果没有更多可用的 TS feed,则返回 -EBUSY;参数错误则返回 -EINVAL。
release_section_feed
释放使用 allocate_section_feed 分配的资源,包括已分配的过滤器。在调用此函数之前,应停止在 section feed 上进行的任何过滤操作。 demux 函数参数包含指向解复用器 API 和实例数据的指针。 feed 函数参数包含指向 TS feed 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 的参数。include 文件 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。