Improve audio recovery when a prior FEC block was completely lost

We now start playing the latest FEC block immediately, instead of needlessly
waiting for a second FEC block to realize we've lost a full block and need
to skip forward.
This commit is contained in:
Cameron Gutman 2022-10-24 23:38:23 -05:00
parent 7ba4eea417
commit 21998586d1

View File

@ -505,10 +505,12 @@ static bool enforceQueueConstraints(PRTP_AUDIO_QUEUE queue) {
return false; return false;
} }
// We will consider the FEC block irrecoverably lost if either: // We will consider the FEC block irrecoverably lost if any of the following are true:
// 1) We have not received OOS data, yet this data is from a future FEC block // 1) We have not received OOS data, yet this data is from a future FEC block
// 2) The entire duration of the audio in the FEC block has elapsed (plus a little bit) // 2) The packet we're waiting on precedes our earliest FEC block (likely means a previous FEC block was completely lost)
if (!queue->receivedOosData || // 3) The entire duration of the audio in the FEC block has elapsed (plus a little bit)
if ((!queue->receivedOosData && queue->blockHead != queue->blockTail) ||
isBefore16(queue->nextRtpSequenceNumber, queue->blockHead->fecHeader.baseSequenceNumber) ||
PltGetMillis() - queue->blockHead->queueTimeMs > (uint32_t)(AudioPacketDuration * RTPA_DATA_SHARDS) + RTPQ_OOS_WAIT_TIME_MS) { PltGetMillis() - queue->blockHead->queueTimeMs > (uint32_t)(AudioPacketDuration * RTPA_DATA_SHARDS) + RTPQ_OOS_WAIT_TIME_MS) {
// Only print the head FEC block state if that was the block we were waiting on. // Only print the head FEC block state if that was the block we were waiting on.
// If we were actually waiting on a previous block, printing the current block is misleading. // If we were actually waiting on a previous block, printing the current block is misleading.
@ -621,11 +623,9 @@ int RtpaAddPacket(PRTP_AUDIO_QUEUE queue, PRTP_PACKET packet, uint16_t length) {
} }
// We don't have enough to proceed. Let's ensure we haven't // We don't have enough to proceed. Let's ensure we haven't
// violated queue constraints with this FEC block. We will only // violated queue constraints with this FEC block.
// enforce the queue time limit if we have received a packet LC_ASSERT(fecBlock == queue->blockHead || queue->blockHead != queue->blockTail);
// from the next FEC block to ensure we don't needlessly time out if (enforceQueueConstraints(queue)) {
// a block if we aren't getting any other audio data in the meantime.
if (fecBlock != queue->blockHead && enforceQueueConstraints(queue)) {
// Return all available audio data even if there are discontinuities // Return all available audio data even if there are discontinuities
queue->blockHead->allowDiscontinuity = true; queue->blockHead->allowDiscontinuity = true;