为何GStreamer中Tee可分流原始音频却无法分流AAC编码音频?
问题:GStreamer中Tee可处理原始音频却无法处理AAC编码后音频的原因?
问题背景
在基于NXP i.MX 8M+(Linux系统)的嵌入式应用开发中,使用GStreamer实现双MIPI摄像头+H.264编码+MP4保存,同时混入PDM麦克风音频的场景:
- 双摄像头的视频Pipeline运行正常:
v4l2src device=/dev/video0 ! video/x-raw, width=1280, height=720, framerate=30/1, format=GRAY8 ! queue ! vpuenc_h264 ! h264parse ! mpegtsmux name=mux1 ! filesink v4l2src device=/dev/video1 ! video/x-raw, width=1280, height=720, framerate=30/1, format=GRAY8 ! queue ! vpuenc_h264 ! h264parse ! mpegtsmux name=mux2 ! filesink
- 音频单路混入复用器可行:
alsasrc device="hw:0,0" ! audio/x-raw, format=S16LE, rate=22050, channels=1 ! queue ! audioconvert ! avenc_aac name=audio_aac ! mux1.
- 但用Tee将AAC编码后的音频分流至两个复用器时失败,报错:
ERROR GST_PIPELINE gst/parse/grammar.y:773:gst_parse_perform_link: could not link taudio to mux1 ERROR GST_PIPELINE gst/parse/grammar.y:773:gst_parse_perform_link: could not link taudio to mux2
- 调试日志显示链接时caps为NULL,无法建立链接;而在AAC编码前用Tee分流原始音频则运行正常:
alsasrc device="hw:0,0" ! audio/x-raw, format=S16LE, rate=22050, channels=1 ! queue ! tee name=taudio taudio. ! audioconvert ! avenc_aac name=audio_aac1 ! mux1. taudio. ! audioconvert ! avenc_aac name=audio_aac2 ! mux2.
原因分析
核心问题是Tee输出与mpegtsmux请求式Pad的Caps协商机制差异:
- 原始音频流的Caps明确性:原始
audio/x-raw流的Caps在Pipeline定义时就完全确定(格式、采样率、通道数都明确指定),Tee分流后,每个分支的avenc_aac能向mpegtsmux传递明确的音频编码格式信息,mpegtsmux可以据此创建对应的音频接收请求Pad(request pad),完成链接。 - AAC编码后流的Caps延迟确定:
avenc_aac输出的AAC流Caps(比如AAC profile、具体编码参数等)需要在Pipeline运行时才能完全确定,链接阶段Tee的输出Pad没有携带明确的Caps信息。而mpegtsmux作为依赖请求式Pad的元素,必须提前知道输入流的Caps类型才能创建对应的接收Pad,无法识别Caps为NULL的流,因此链接失败。 - 从调试日志里的
linking pad taudio of GstTee named taudio to pad mux1 of GstMpegTsMux named mux1 (0/0) with caps "(NULL)"也能直接验证这一点:链接时Caps为空,mpegtsmux无法判断流类型,拒绝创建接收Pad。
修复方案
有两种可行的解决方式:
方式1:添加aacparse明确Caps
在avenc_aac后加入aacparse元素,它会解析AAC流并明确输出Caps,让Tee能带着确定的Caps与mpegtsmux协商:
alsasrc device="hw:0,0" ! audio/x-raw, format=S16LE, rate=22050, channels=1 ! queue ! audioconvert ! avenc_aac name=audio_aac ! aacparse ! tee name=taudio taudio. ! mux1. taudio. ! mux2.
方式2:手动强制指定Caps
在avenc_aac后直接指定AAC流的Caps,提前明确格式信息:
alsasrc device="hw:0,0" ! audio/x-raw, format=S16LE, rate=22050, channels=1 ! queue ! audioconvert ! avenc_aac name=audio_aac ! audio/mpeg, mpegversion=4, stream-format=raw, rate=22050, channels=1 ! tee name=taudio taudio. ! mux1. taudio. ! mux2.
内容的提问来源于stack exchange,提问作者David C.
相关产品推荐
相关产品推荐

