2.3. 属性类型¶
要调谐到数字电视的物理频道并开始解码,需要更改一组参数,以控制调谐器、解调器、线性低噪声放大器 (LNA) 以及通过卫星设备控制 - SEC(在卫星系统上)设置天线子系统。实际参数特定于每个特定的数字电视标准,并且可能会随着数字电视规范的发展而变化。
在过去(直到 DVB API 版本 3 - DVBv3),使用的策略是使用一个联合体,其中包含调谐 DVB-S、DVB-C、DVB-T 和 ATSC 传输系统所需的参数。问题在于,随着第二代标准的出现,该联合体的大小不足以组合这些新标准所需的结构体。此外,扩展它会破坏用户空间。
因此,传统的基于联合体/结构体的方法被弃用,转而采用属性集方法。在这种方法中,FE_GET_PROPERTY 和 FE_SET_PROPERTY 用于设置前端并读取其状态。
实际操作由一组 dtv_property cmd/data 对确定。通过一个 ioctl,可以获取/设置多达 64 个属性。
本节介绍设置前端的新推荐方法,它支持所有数字电视传输系统。
注意
在 Linux DVB API 版本 3 中,设置前端是通过 struct
dvb_frontend_parameters
完成的。请勿在支持较新标准的硬件上使用 DVB API 版本 3 的调用。此类 API 不提供或仅提供对新标准和/或新硬件的非常有限的支持。
如今,大多数前端都支持多种传输系统。只有通过 DVB API 版本 5 的调用,才可以在前端支持的多种传输系统之间切换。
DVB API 版本 5 也称为 *S2API*,因为添加到它的第一个新标准是 DVB-S2。
示例:为了将硬件设置为调谐到 651 kHz 的 DVB-C 频道,使用 256-QAM 调制,FEC 3/4 和 5.217 Mbauds 的符号率,应将这些属性发送到 FE_SET_PROPERTY ioctl
DTV_DELIVERY_SYSTEM = SYS_DVBC_ANNEX_A
DTV_FREQUENCY = 651000000
DTV_MODULATION = QAM_256
DTV_INVERSION = INVERSION_AUTO
DTV_SYMBOL_RATE = 5217000
DTV_INNER_FEC = FEC_3_4
完成上述操作的代码在 示例:设置数字电视前端属性 中显示。
#include <stdio.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <linux/dvb/frontend.h>
static struct dtv_property props[] = {
{ .cmd = DTV_DELIVERY_SYSTEM, .u.data = SYS_DVBC_ANNEX_A },
{ .cmd = DTV_FREQUENCY, .u.data = 651000000 },
{ .cmd = DTV_MODULATION, .u.data = QAM_256 },
{ .cmd = DTV_INVERSION, .u.data = INVERSION_AUTO },
{ .cmd = DTV_SYMBOL_RATE, .u.data = 5217000 },
{ .cmd = DTV_INNER_FEC, .u.data = FEC_3_4 },
{ .cmd = DTV_TUNE }
};
static struct dtv_properties dtv_prop = {
.num = 6, .props = props
};
int main(void)
{
int fd = open("/dev/dvb/adapter0/frontend0", O_RDWR);
if (!fd) {
perror ("open");
return -1;
}
if (ioctl(fd, FE_SET_PROPERTY, &dtv_prop) == -1) {
perror("ioctl");
return -1;
}
printf("Frontend set\\n");
return 0;
}
注意
虽然可以直接像上面的示例一样调用内核代码,但强烈建议使用 libdvbv5,因为它提供了抽象来处理支持的数字电视标准,并为诸如程序扫描和读/写频道描述符文件之类的常用操作提供方法。