Return all available audio data after FEC block timer expires

This commit is contained in:
Cameron Gutman 2021-06-01 20:01:26 -05:00
parent 3dff15b8c4
commit 683208ddc8
2 changed files with 25 additions and 11 deletions

View File

@ -348,28 +348,41 @@ 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. // violated queue constraints with this FEC block.
if (enforceQueueConstraints(queue)) { if (enforceQueueConstraints(queue)) {
// We need to discard this FEC block and point the next RTP sequence number to the next block // Return all available audio data even if there are discontinuities
queue->nextRtpSequenceNumber = queue->blockHead->fecHeader.baseSequenceNumber + RTPA_DATA_SHARDS; queue->blockHead->allowDiscontinuity = true;
return RTPQ_RET_PACKET_READY;
// NOTE: Here we elect to just throw away the entire FEC block. We could play back the source
// data that we have, but this is easier. It's also unclear whether playback of partial data
// after a significant delay is actually worse than dropping it due to causing additional
// latency to accumulate in the audio pipeline.
freeFecBlockHead(queue);
} }
return queueHasPacketReady(queue) ? RTPQ_RET_PACKET_READY : 0; return queueHasPacketReady(queue) ? RTPQ_RET_PACKET_READY : 0;
} }
PRTP_PACKET RtpaGetQueuedPacket(PRTP_AUDIO_QUEUE queue, uint16_t customHeaderLength, uint16_t* length) { PRTP_PACKET RtpaGetQueuedPacket(PRTP_AUDIO_QUEUE queue, uint16_t customHeaderLength, uint16_t* length) {
PRTPA_FEC_BLOCK nextBlock = queue->blockHead; // If we're returning audio data even with discontinuities, find the next data packet
if (queue->blockHead != NULL && queue->blockHead->allowDiscontinuity) {
PRTPA_FEC_BLOCK nextBlock = queue->blockHead;
if (nextBlock == NULL) { while (nextBlock->nextDataPacketIndex < RTPA_DATA_SHARDS) {
return NULL; LC_ASSERT(nextBlock->fecHeader.baseSequenceNumber + nextBlock->nextDataPacketIndex == queue->nextRtpSequenceNumber);
if (nextBlock->marks[nextBlock->nextDataPacketIndex]) {
// This packet is missing. Skip it.
nextBlock->nextDataPacketIndex++;
queue->nextRtpSequenceNumber++;
}
else {
LC_ASSERT(queueHasPacketReady(queue));
break;
}
}
// If we've read everything from this FEC block, remove and free it
if (nextBlock->nextDataPacketIndex == RTPA_DATA_SHARDS) {
freeFecBlockHead(queue);
}
} }
// Return the next RTP sequence number by indexing into the most recent FEC block // Return the next RTP sequence number by indexing into the most recent FEC block
if (queueHasPacketReady(queue)) { if (queueHasPacketReady(queue)) {
PRTPA_FEC_BLOCK nextBlock = queue->blockHead;
PRTP_PACKET packet = malloc(customHeaderLength + sizeof(RTP_PACKET) + nextBlock->blockSize); PRTP_PACKET packet = malloc(customHeaderLength + sizeof(RTP_PACKET) + nextBlock->blockSize);
if (packet == NULL) { if (packet == NULL) {
return NULL; return NULL;

View File

@ -35,6 +35,7 @@ typedef struct _RTPA_FEC_BLOCK {
// Used when dequeuing data from FEC blocks for the caller // Used when dequeuing data from FEC blocks for the caller
uint8_t nextDataPacketIndex; uint8_t nextDataPacketIndex;
bool allowDiscontinuity;
uint16_t blockSize; uint16_t blockSize;