mirror of
https://github.com/moonlight-stream/moonlight-common-c.git
synced 2025-08-17 17:05:50 +00:00
Add a fast path to drop the audio FEC block with in-order packets
If we have not seen any OOS audio data lately, we can assume that seeing the next FEC block means the previous block has completed transmission. If we don't have it all by then, just assume it was lost and move on. This reduces the perception of audio loss by reducing the change that we cause the audio device to underrun.
This commit is contained in:
parent
c64ba99654
commit
b471edbb80
@ -129,6 +129,23 @@ static PRTPA_FEC_BLOCK getFecBlockForRtpPacket(PRTP_AUDIO_QUEUE queue, PRTP_PACK
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Remember if we've received out-of-sequence packets lately. We can use
|
||||
// this knowledge to more quickly give up on FEC blocks.
|
||||
if (isBefore16(packet->sequenceNumber, queue->oldestRtpBaseSequenceNumber)) {
|
||||
queue->lastOosSequenceNumber = packet->sequenceNumber;
|
||||
if (!queue->receivedOosData) {
|
||||
Limelog("Leaving fast audio recovery mode after OOS audio data (%u < %u)\n",
|
||||
packet->sequenceNumber, queue->oldestRtpBaseSequenceNumber);
|
||||
queue->receivedOosData = true;
|
||||
}
|
||||
}
|
||||
// This condition looks odd, but it's just a simple way to check if we've gone
|
||||
// more than 32767 packets without an OOS packet.
|
||||
else if (queue->receivedOosData && isBefore16(queue->oldestRtpBaseSequenceNumber, queue->lastOosSequenceNumber)) {
|
||||
Limelog("Entering fast audio recovery mode after sequenced audio data\n");
|
||||
queue->receivedOosData = false;
|
||||
}
|
||||
|
||||
// This is a data packet, so we will need to synthesize an FEC header
|
||||
fecBlockPayloadType = packet->packetType;
|
||||
fecBlockBaseSeqNum = (packet->sequenceNumber / RTPA_DATA_SHARDS) * RTPA_DATA_SHARDS;
|
||||
@ -393,9 +410,11 @@ static bool enforceQueueConstraints(PRTP_AUDIO_QUEUE queue) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// We will consider the FEC block irrecoverably lost if the entire duration of the
|
||||
// audio in the FEC block has elapsed (plus a little bit) without completing the block.
|
||||
if (PltGetMillis() - queue->blockHead->queueTimeMs > (uint32_t)(AudioPacketDuration * RTPA_DATA_SHARDS) + RTPQ_OOS_WAIT_TIME_MS) {
|
||||
// We will consider the FEC block irrecoverably lost if either:
|
||||
// 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)
|
||||
if (!queue->receivedOosData ||
|
||||
PltGetMillis() - queue->blockHead->queueTimeMs > (uint32_t)(AudioPacketDuration * RTPA_DATA_SHARDS) + RTPQ_OOS_WAIT_TIME_MS) {
|
||||
Limelog("Unable to recover audio data block %u to %u (%u+%u=%u received < %u needed)\n",
|
||||
queue->blockHead->fecHeader.baseSequenceNumber,
|
||||
queue->blockHead->fecHeader.baseSequenceNumber + RTPA_DATA_SHARDS - 1,
|
||||
|
@ -52,6 +52,9 @@ typedef struct _RTP_AUDIO_QUEUE {
|
||||
|
||||
uint16_t nextRtpSequenceNumber;
|
||||
uint16_t oldestRtpBaseSequenceNumber;
|
||||
|
||||
uint16_t lastOosSequenceNumber;
|
||||
bool receivedOosData;
|
||||
} RTP_AUDIO_QUEUE, *PRTP_AUDIO_QUEUE;
|
||||
|
||||
#define RTPQ_RET_PACKET_CONSUMED 0x1
|
||||
|
Loading…
x
Reference in New Issue
Block a user