9.1.1. bttv 驱动

9.1.1.1. bttv 和声音迷你指南

市面上有很多基于 bt848/849/878/879 的不同板卡。让视频工作通常不是什么大问题,因为这完全由 bt8xx 芯片处理,该芯片在所有板卡上都很常见。但是,在每块板卡上,声音的处理方式略有不同。

为了正确处理抓取卡,在 bttv-cards.c 中有一个数组 tvcards[],其中保存了每个板卡所需的信息。只有使用正确的条目,声音才能工作(对于视频来说,通常没有区别)。bttv 驱动程序会向内核日志打印一行,说明使用了哪种卡类型。像这样

bttv0: model: BT848(Hauppauge old) [autodetected]

您应该验证这是正确的。如果不是,您必须将正确的板卡类型作为 insmod 参数传递,例如 insmod bttv card=2。文件 BTTV 卡列表 包含了 card 的有效参数列表。

如果您的卡未在其中列出,您可以检查源代码中是否有尚未列出的新条目。如果您的卡没有条目,您可以检查现有条目之一是否对您有效(只是试错...)。

有些板卡有一个额外的处理器用于声音,以进行立体声解码和其他不错的功能。例如,Hauppauge 使用 msp34xx 芯片。如果您的板卡有一个,您可能必须加载一个辅助模块,如 msp3400,才能使声音工作。如果您的板卡上使用的芯片没有辅助模块:很遗憾。开始编写一个新的。好吧,您可能需要先查看 video4linux 邮件列表存档...

当然,您需要正确安装的声卡,除非您将扬声器直接连接到抓取卡。提示:还要检查混音器设置。例如,ALSA 默认情况下会使所有内容静音。

9.1.1.1.1. 声音如何工作的详细说明

仍然不起作用?看起来需要进行一些驱动程序破解。下面为您提供一份自行操作的说明。

bt8xx 芯片有 32 个通用引脚和用于控制这些引脚的寄存器。其中一个寄存器是输出使能寄存器 (BT848_GPIO_OUT_EN),它说明了哪些引脚由 bt848 芯片主动驱动。另一个寄存器是数据寄存器 (BT848_GPIO_DATA),您可以在其中获取/设置这些引脚的状态。它们可以用于输入和输出。

大多数抓取卡供应商使用这些引脚来控制一个执行声音路由的外部芯片。但是,每个板卡都略有不同。某些公司也使用这些引脚来驱动遥控接收器芯片。某些板卡使用 i2c 总线而不是 gpio 引脚来连接多路复用芯片。

如上所述,有一个数组保存每个已知板卡所需的信息。您基本上必须为您的板卡创建新的一行。重要的字段是这两个

struct tvcard
{
      [ ... ]
      u32 gpiomask;
      u32 audiomux[6]; /* Tuner, Radio, external, internal, mute, stereo */
};

gpiomask 指定哪些引脚用于控制音频多路复用芯片。输出使能寄存器 (BT848_GPIO_OUT_EN) 中相应的位将被设置,因为这些引脚必须由 bt848 芯片驱动。

audiomux[] 数组保存不同输入(即调谐器/静音/...的哪些引脚必须为高电平/低电平)的数据值。这将被写入数据寄存器 (BT848_GPIO_DATA) 以切换音频多路复用器。

您必须做的是找出 gpiomask 和 audiomux 数组的正确值。如果您有 Windows 并且安装了您的卡的驱动程序,您可以检查是否可以读取 Windows 驱动程序使用的这些寄存器值。可以从 http://btwincap.sourceforge.net/download.html 获取执行此操作的工具。

您还可以在 Windows 应用程序的 *.ini 文件中进行挖掘。您可以查看板卡,了解哪些 gpio 引脚已连接,然后开始试错...

从 0.7.41 版本开始,bttv 有许多 insmod 选项,使 gpio 调试更容易

bttv_gpio=0/1

启用/禁用 gpio 调试消息

gpiomask=n

设置 gpiomask 值

audiomux=i,j,...

设置 audiomux 数组的值

audioall=a

设置 audiomux 数组的值(所有数组元素的一个值,用于检查特定值具有哪些效果)。

使用 bttv_gpio=1 打印的消息如下所示

bttv0: gpio: en=00000027, out=00000024 in=00ffffd8 [audio: off]

en  =   output _en_able register (BT848_GPIO_OUT_EN)
out =   _out_put bits of the data register (BT848_GPIO_DATA),
        i.e. BT848_GPIO_DATA & BT848_GPIO_OUT_EN
in  =   _in_put bits of the data register,
        i.e. BT848_GPIO_DATA & ~BT848_GPIO_OUT_EN