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 个属性。

本节介绍设置前端的新推荐方法,它支持所有数字电视传输系统。

注意

  1. 在 Linux DVB API 版本 3 中,通过结构体 dvb_frontend_parameters完成前端设置。

  2. 请勿在支持较新标准的硬件上使用 DVB API 版本 3 调用。此类 API 不提供或仅提供非常有限的对新标准和/或新硬件的支持。

  3. 如今,大多数前端都支持多种传输系统。只有通过 DVB API 版本 5 调用才能在前端支持的多种传输系统之间切换。

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

DTV_TUNE

执行上述操作的代码在 示例:设置数字电视前端属性中显示。

示例:设置数字电视前端属性
#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,因为它提供了与支持的数字电视标准一起工作的抽象,并提供了用于诸如程序扫描和读取/写入频道描述符文件等常用操作的方法。