目标
本教程展示GStreamer是如何进行数字音频传输的。
介绍
在常见的模拟格式外,高端的音频系统通常都接受数字格式,压缩的非压缩的都能接受。因为音频信号是从电脑传到音箱,用一种更有弹性的形态会更能保证质量。
典型的连接是通过S/PDIF线缆,可以是光缆或者同轴电缆。
在这种情况下,GStreamer是不需要做音频的解码的,可以运行在pass-through模式下,简单的输出编码后的数据,让外接的音频系统进行解码。
GStreamer音频sink的内部实现
首先,在系统层级必须支持数字音频的输出。实现这点需要操作系统的支持,但通常有一个音频控制面板,然后有个“Digital Audio Output”的选项。
对每个平台的GStreamer的音频sink(Linux下的pulsesink,OS X下的osxaudiosink,Windows下的directsoundsink),可以检测数字音频输出是否可用以及根据接收到的编码后的数据来调整cap。比如,这些element通常是接收audio/x-raw-int或者audio/x-raw-float数据,当数字音频输出打开的时候,他们可以接收audio/mpeg、audio/x-ac3、audio/x-eac3以及audio/x-dts。
那么,当playbin2在建立解码pipeline时,它会发现音频sink可以直接和编码后的数据相连,这样就需要一个音频解码器了。这个过程是自动完成的,并不需要应用介入。
在Linux上,还存在其他的音频sink,比如:alsasink的工作就不一样。
数据格式的预警
当系统层打开了数字音频输出功能后,无论在S/PDIF线缆后面的实际音频解码器是否支持这些格式,GStreamer的音频sink会自动列出所有的数字音频Cap。这样做的原因有两个,一个是没法获得一个外接的解码器支持的格式,另一个是线缆的连接可能会脱落(并非永远可靠)。
比如,我们在系统的音频控制面板里面打开了数字音频输出,directsoundsink会在audio/x-raw-int之外自动显示audio/x-ac3、audio/x-eac3和audio/x-dts,但是一个外接的解码器可能只能接受原始流。
要解决这个问题需要最终用户的介入,因为只有最终用户才能知道外接的解码器能支持什么格式的数据。
在一些系统里面,最简单的方法就是告诉操作系统外接的音频解码器能接受的格式。这样的话,GStreamer的音频sink只需要提供这些格式的cap就可以了。这些可以接受的音频格式通常都是在操作系统的音频配置面板上选择的,数字音频输出也是在这里打开。但是,并非所有的音频驱动都支持这样做。
另一个解决方案是使用包含一个capsfilter element和一个audio sink的客制化的sink bin。这样外接解码器支持的格式就可以在caps filter上过滤,保证不符合的都过滤掉。这样应用就不再依赖用户对系统的配置,虽然还是需要用户的介入,但不再需要考虑音频驱动是否提供选择项了。
请注意,不要使用autoaudiosink这个音频sink,因为它只支持raw数据,会忽略所有压缩过的格式。