Looking at the HDMI driver source (actually bcm2835_xxx.c files instead of the upstream vc4_hdmi code) - we can only guess what messages to the VC4 module do
https://github.com/raspberrypi/linu...cm2835-audio/vc_vchi_audioserv_defs.h#L19-L30 .
But IIUC, at XRUN the snd_pcm_stop is called
https://github.com/raspberrypi/linu..._services/bcm2835-audio/bcm2835-pcm.c#L61-L66 , sending message VC_AUDIO_MSG_TYPE_STOP
https://github.com/raspberrypi/linu...vices/bcm2835-audio/bcm2835-vchiq.c#L295-L299
Upon that CDSP calls snd_pcm_prepare, which in
https://github.com/raspberrypi/linu...ervices/bcm2835-audio/bcm2835-pcm.c#L212-L214 sends only configuration message
https://github.com/raspberrypi/linu...vices/bcm2835-audio/bcm2835-vchiq.c#L269-L286
Upon that write messages followed by samples are sent in
https://github.com/raspberrypi/linu...4_services/bcm2835-audio/bcm2835-vchiq.c#L328 , time-controlled by VC_AUDIO_MSG_TYPE_COMPLETE callback from the VC4 in
https://github.com/raspberrypi/linu...4_services/bcm2835-audio/bcm2835-vchiq.c#L115 ->
https://github.com/raspberrypi/linu..._services/bcm2835-audio/bcm2835-pcm.c#L52-L82 , advancing position of the stream + informing the client via snd_pcm_period_elapsed.
But there is no VC_AUDIO_MSG_TYPE_START being sent in this sequence, unlike when the stream starts in a regular way via pcm.start(). The sequence in CDSP is the recommended one, but maybe the VC4 core needs the VC_AUDIO_MSG_TYPE_START message to restart the stream "correctly". Because at regular start the sequence of messages is VC_AUDIO_MSG_TYPE_OPEN -> VC_AUDIO_MSG_TYPE_CONFIG -> VC_AUDIO_MSG_TYPE_START -> VC_AUDIO_MSG_TYPE_WRITE (maybe config swapped with start, I did not check all the details). But in the xrun -> prepare the VC_AUDIO_MSG_TYPE_START is not called, only VC_AUDIO_MSG_TYPE_STOP -> VC_AUDIO_MSG_TYPE_CONFIG -> VC_AUDIO_MSG_TYPE_WRITE .
I looked at the HDMI protocol. The audio packets and channel control are quite nicely designed, VC4 does all this internally (nothing in the linux driver, it just sends the control/data messages). Basically each packet contains 4 subpackets which carry 2ch samples (i.e. 8ch max). For 2ch the subpackets carry stereo samples sequentially, for 8ch they carry 4 stereo samples for the whole audio frame. Each subpacket has a bit flag in the packet header telling the receiver whether the subpacket is being used and contains valid data. Maybe the HDMI extractor "blindly" keeps copying the valid subpackets to each I2S data line on a round-robin basis. A missing = invalid packet would then break the 8-channels alignment. Maybe the HDMI transmitter outputs packets with some of the subpackets missing when it receives new data until the VC_AUDIO_MSG_TYPE_START (kind of restart) msg is received. I do not know, just blindly guessing.
Nevertheless I wonder what adding 'pcmdevice.start()?;' behind
https://github.com/HEnquist/camilla...b68d1bc8c21045f250054a/src/alsadevice.rs#L139 or
'bcm2835_audio_start(alsa_stream)' to the prepare method
https://github.com/raspberrypi/linu...c04_services/bcm2835-audio/bcm2835-pcm.c#L217 would do, just for the sake of troubleshooting this issue. If it worked (for AVRs and the extractor), maybe we could ask RPi people to add the VC_AUDIO_MSG_TYPE_START message to the prepare method.
Adding the line to CDSP is much easier but the pcm.start() call does much more than just sending the VC_AUDIO_MSG_TYPE_START message.