It seems like there aren’t any suitable data structures included in FreeRTOS to re-order incoming UDP into their sequential order (based on the RTP sequence ID) before passing it on when reading from a typical socket.
I’ve implemented a MessageQueue so far, but realized xQueuePeek is only to the top of the queue, so there is no way to traverse the queue to see if I still have the option to insert this out of order packet into the MessageQueue (rather than discarding it).
I suppose this could be done rater in pure C with a fixed size array then use one of the Semaphore options, but still want to check if anyone else has approached this using FreeRTOS constructs.
There is nothing built in - but happy to accept pull requests should you implement something Interested in how @htibosch does this for his audio streaming use cases.
I have had to do anything like that, but my guess is you don’t want to be copying the frames around, but you might want to make a linked list that you put things in sorted by the sequence ID, and perhaps the built in xList structure might work, but I might be more tempted to just code up a sorted linked list of the data blocks.
If you are required to use the UDP protocol, then RTP might indeed be useful.
Does your UDP stream come from the Internet, or from a local device?
If you can use TCP, I would recommend trying that. TCP will make sure the packets arrive in the right order.
But also: TCP already has a smart buffering mechanism.
I once made an internet-radio application that connects to a live stream, and plays it on a DAC. Before it starts playing, it will wait for a “full reception buffer”.
FreeRTOS+TCP has a special mechanism, rarely mentioned: the application can send stop/resume to the TCP sliding window.
First you set the TCP sliding windows parameters using the socket option FREERTOS_SO_WIN_PROPERTIES.
For an audio player, the TX sizes will be very small, the RX size will be large.
And then you can configure a lower and an upper limit of the reception stream:
LowHighWater_t xLimits;
xLimits.uxLittleSpace = 2048U; /**< Send a STOP when buffer space drops below X bytes */
xLimits.uxEnoughSpace = 8192U; /**< Send a GO when buffer space grows above X bytes */
FreeRTOS_setsockopt( xSocket,
0,
FREERTOS_SO_SET_LOW_HIGH_WATER,
( void * ) &xLimits,
sizeof( xLimits ) );