I’m developing an embedded app for a custom hardware device (using an NXP i.MX 8M+ running Linux, for those who are interested). The hardware is being developed in-house as a part of the same project.
The BSP is including GStreamer version 1.20.3. Compiled via a Yocto project based on NXP’s imx-5.15.71-2.2.1.xml
BSP manifest.
In my app, I need to receive video from its two MIPI camera devices and one PDM microphone. I’m encoding the video to H.264 (using a vendor-supplied hardware encoder plugin, vpuenc_h264
) and passing each stream to mpegtsmux
, and then saving to MP4 files (one for each camera’s feed).
A subset of the GST pipeline this app uses (content not needed to illustrate the problem omitted) is:
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
This part works great.
When I want to mux the audio in to the stream to be included with the video in the files, I can add it to one of the muxes this way:
alsasrc device=\"hw:0,0\"
! audio/x-raw, format=S16LE, rate=22050, channels=1
! queue ! audioconvert ! avenc_aac name=audio_aac
! mux1.
This also works great. But if I try to take the AAC-encoded audio and split it with a tee so it goes to both muxes, it doesn’t work:
alsasrc device=\"hw:0,0\"
! audio/x-raw, format=S16LE, rate=22050, channels=1
! queue ! audioconvert ! avenc_aac name=audio_aac
! tee name=taudio
taudio. ! mux1.
taudio. ! mux2.
The above fails. If I turn on GST debugging, I see these messages (plus an identical set of messages for the second mux).
DEBUG GST_ELEMENT_PADS gstutils.c:1948:gst_element_link_pads_full: linked pad audio_aac:src to pad taudio:sink
INFO GST_PARENTAGE gstbin.c:4377:gst_bin_get_by_name: [pipeline0]: looking up child element taudio
INFO GST_PARENTAGE gstbin.c:4377:gst_bin_get_by_name: [pipeline0]: looking up child element mux1
INFO GST_PIPELINE gst/parse/grammar.y:683:gst_parse_perform_link: linking pad taudio of GstTee named taudio to pad mux1 of GstMpegTsMux named mux1 (0/0) with caps "(NULL)"
INFO GST_ELEMENT_PADS gstutils.c:1816:gst_element_link_pads_full: trying to link element taudio:(any) to element mux1:(any)
DEBUG GST_ELEMENT_PADS gstutils.c:1925:gst_element_link_pads_full: looping through allowed src and dest pads
DEBUG GST_ELEMENT_PADS gstutils.c:1928:gst_element_link_pads_full: trying src pad taudio:sink
DEBUG GST_ELEMENT_PADS gstutils.c:1991:gst_element_link_pads_full: trying dest pad mux1:src
DEBUG GST_ELEMENT_PADS gstutils.c:1991:gst_element_link_pads_full: trying dest pad mux1:sink_65
DEBUG GST_ELEMENT_PADS gstutils.c:2043:gst_element_link_pads_full: we might have request pads on both sides, checking...
DEBUG GST_ELEMENT_PADS gstutils.c:2097:gst_element_link_pads_full: no link possible from taudio to mux1
INFO default gstutils.c:2206:gst_element_link_pads_filtered: Could not link pads: taudio:(null) - mux1:(null)
ERROR GST_PIPELINE gst/parse/grammar.y:773:gst_parse_perform_link: could not link taudio to mux1
DEBUG GST_ELEMENT_PADS gstutils.c:1948:gst_element_link_pads_full: linked pad audio_aac:src to pad taudio:sink
INFO GST_PARENTAGE gstbin.c:4377:gst_bin_get_by_name: [pipeline0]: looking up child element taudio
INFO GST_PARENTAGE gstbin.c:4377:gst_bin_get_by_name: [pipeline0]: looking up child element mux1
INFO GST_PIPELINE gst/parse/grammar.y:683:gst_parse_perform_link: linking pad taudio of GstTee named taudio to pad mux1 of GstMpegTsMux named mux1 (0/0) with caps "(NULL)"
INFO GST_ELEMENT_PADS gstutils.c:1816:gst_element_link_pads_full: trying to link element taudio:(any) to element mux1:(any)
DEBUG GST_ELEMENT_PADS gstutils.c:1925:gst_element_link_pads_full: looping through allowed src and dest pads
DEBUG GST_ELEMENT_PADS gstutils.c:1928:gst_element_link_pads_full: trying src pad taudio:sink
DEBUG GST_ELEMENT_PADS gstutils.c:1991:gst_element_link_pads_full: trying dest pad mux1:src
DEBUG GST_ELEMENT_PADS gstutils.c:1991:gst_element_link_pads_full: trying dest pad mux1:sink_65
DEBUG GST_ELEMENT_PADS gstutils.c:2043:gst_element_link_pads_full: we might have request pads on both sides, checking...
DEBUG GST_ELEMENT_PADS gstutils.c:2097:gst_element_link_pads_full: no link possible from taudio to mux1
INFO default gstutils.c:2206:gst_element_link_pads_filtered: Could not link pads: taudio:(null) - mux1:(null)
ERROR GST_PIPELINE gst/parse/grammar.y:773:gst_parse_perform_link: could not link taudio to mux1
If, however, I tee the audio before the AAC encoding, the result is good:
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.
The above works as expected. I get two MP4 files with audio.
Any idea why I can tee raw audio but not AAC-encoded audio? Is it a bug in GST? Or am I doing something wrong?