播放教程9:数字音频传输
目标
本教程展示GStreamer是如何进行数字音频传输的。
介绍
除了常见的模拟格式外,高端音频系统通常还接受数字形式的压缩或未压缩数据。这样做很方便,因为音频信号从计算机传输到扬声器时,其形式更能抵抗干扰和噪声,从而获得更高的质量。
这种连接通常通过S/PDIF电缆进行,该电缆可以是光纤的(带有TOSLINK连接器)或者是同轴的(带有RCA连接器)。S/PDIF也被称为IEC 60958类型II(1998年之前称为IEC 958)。
在这种方案中,GStreamer不需要执行音频解码;它只需输出编码数据,以直通模式工作,并让外部音频系统执行解码。
GStreamer音频sink的内部工作原理
首先,必须在系统级别启用数字音频输出。实现这一目标的方法取决于操作系统,但通常涉及进入音频控制面板并激活一个标记为“数字音频输出”或类似的复选框。
GStreamer在每个平台上的主要音频接收器,对于Linux是Pulse Audio(pulsesink),对于OS X是osxaudiosink,对于Windows是Direct Sound(directsoundsink),它们能够检测到数字音频输出何时可用,并相应地更改它们的输入caps以接受编码数据。例如,这些元素通常接受audio/x-raw数据:当系统中启用了数字音频输出时,它们也可能接受audio/mpeg、audio/x-ac3、audio/x-eac3或audio/x-dts。
然后,当playbin构建解码管道时,它意识到音频接收器可以直接连接到编码数据(通常来自demuxer),因此不需要解码器。这个过程是自动的,不需要应用程序采取任何行动。
在Linux上,还存在其他音频接收器,如Alsa(alsasink),其工作方式不同(需要通过接收器的设备属性手动选择“数字设备”)。然而,Pulse Audio是Linux上通常首选的音频接收器。
数字格式的注意事项
当在系统级别启用数字音频输出时,GStreamer的音频接收器会自动公开所有可能的数字音频caps,无论S/PDIF电缆末端的实际音频解码器是否能够解码所有这些格式。之所以这样做,是因为没有机制可以查询外部音频解码器支持哪些格式,实际上,在这个过程中甚至可以断开电缆。
例如,在系统的控制面板中启用数字音频输出后,directsoundsink将自动公开audio/x-ac3、audio/x-eac3和audio/x-dts caps,以及audio/x-raw。然而,某个特定的外部解码器可能只理解原始整数流,并尝试将压缩数据按原样播放(相信我们,这对你的耳朵来说是一种痛苦的体验)。
解决这个问题需要用户干预,因为只有用户知道外部解码器支持的格式。
在某些系统上,最简单的解决方案是告知操作系统外部音频解码器可以接受的格式。这样,GStreamer的音频接收器将只提供这些格式。通常可以从操作系统的音频配置面板中选择可接受的音频格式,与启用数字音频输出的位置相同,但不幸的是,这个选项并非在所有音频驱动程序中都可用。
另一种解决方案涉及使用自定义sinkbin(参见播放教程7:自定义playbin接收器),其中包括一个capsfilter元素(参见基础教程14:实用元素)和一个音频接收器。然后在capsfiler中设置外部解码器支持的caps,以避免输出错误的格式。这使得应用程序能够强制使用适当的格式,而不是依赖用户正确配置系统。这仍然需要用户干预,但无论音频驱动程序提供哪些选项都可以使用。
请不要使用autoaudiosink作为音频接收器,因为它目前只支持原始音频,会忽略任何压缩格式。
结论
本教程展示了GStreamer如何处理数字音频。特别是,它展示了:
- 使用playbin的应用程序不需要做任何特殊的事情来启用数字音频输出:这是通过操作系统的音频控制面板来管理的。