mirror of
https://github.com/moonlight-stream/moonlight-common-c.git
synced 2025-08-17 17:05:50 +00:00
Return all available audio data after FEC block timer expires
This commit is contained in:
parent
3dff15b8c4
commit
683208ddc8
@ -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;
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user