mirror of
https://github.com/moonlight-stream/moonlight-common-c.git
synced 2025-08-17 08:55:48 +00:00
Add a free FEC block cache to avoid memory allocations
This commit is contained in:
parent
fb9aab0e57
commit
f01103af23
@ -81,6 +81,43 @@ static void validateFecBlockState(PRTP_AUDIO_QUEUE queue) {
|
||||
#endif
|
||||
}
|
||||
|
||||
static PRTPA_FEC_BLOCK allocateFecBlock(PRTP_AUDIO_QUEUE queue, uint32_t blockSize) {
|
||||
PRTPA_FEC_BLOCK block = queue->freeBlockHead;
|
||||
|
||||
if (block != NULL) {
|
||||
LC_ASSERT(queue->freeBlockCount > 0);
|
||||
|
||||
// If the block size matches, we're good to go
|
||||
if (block->blockSize == blockSize) {
|
||||
// Advance the free block list to the next entry
|
||||
queue->freeBlockHead = block->next;
|
||||
queue->freeBlockCount--;
|
||||
|
||||
// Return the new block
|
||||
return block;
|
||||
}
|
||||
else {
|
||||
// The block size didn't match. This should never happen with GFE
|
||||
// because it uses constant sized data shards, but Sunshine can
|
||||
// trigger this condition. If it does happen, let's free the cached
|
||||
// entry so we can populate the cache with correctly sized blocks.
|
||||
queue->freeBlockHead = block->next;
|
||||
queue->freeBlockCount--;
|
||||
|
||||
// Free the existing block
|
||||
free(block);
|
||||
}
|
||||
}
|
||||
else {
|
||||
LC_ASSERT(queue->freeBlockCount == 0);
|
||||
}
|
||||
|
||||
// We either didn't have any free entries or the block
|
||||
// size didn't match, so allocate a new FEC block now.
|
||||
uint16_t dataPacketSize = blockSize + sizeof(RTP_PACKET);
|
||||
return malloc(sizeof(*block) + (RTPA_DATA_SHARDS * dataPacketSize) + (RTPA_FEC_SHARDS * blockSize));
|
||||
}
|
||||
|
||||
static void freeFecBlockHead(PRTP_AUDIO_QUEUE queue) {
|
||||
PRTPA_FEC_BLOCK blockHead = queue->blockHead;
|
||||
|
||||
@ -97,7 +134,16 @@ static void freeFecBlockHead(PRTP_AUDIO_QUEUE queue) {
|
||||
|
||||
validateFecBlockState(queue);
|
||||
|
||||
free(blockHead);
|
||||
if (queue->freeBlockCount >= RTPA_CACHED_FEC_BLOCK_LIMIT) {
|
||||
// Too many entries cached, so just free this one
|
||||
free(blockHead);
|
||||
}
|
||||
else {
|
||||
// Place this entry at the head of the free list for better cache behavior
|
||||
blockHead->next = queue->freeBlockHead;
|
||||
queue->freeBlockHead = blockHead;
|
||||
queue->freeBlockCount++;
|
||||
}
|
||||
}
|
||||
|
||||
void RtpaCleanupQueue(PRTP_AUDIO_QUEUE queue) {
|
||||
@ -109,6 +155,15 @@ void RtpaCleanupQueue(PRTP_AUDIO_QUEUE queue) {
|
||||
|
||||
queue->blockTail = NULL;
|
||||
|
||||
while (queue->freeBlockHead != NULL) {
|
||||
PRTPA_FEC_BLOCK block = queue->freeBlockHead;
|
||||
queue->freeBlockHead = block->next;
|
||||
queue->freeBlockCount--;
|
||||
free(block);
|
||||
}
|
||||
|
||||
LC_ASSERT(queue->freeBlockCount == 0);
|
||||
|
||||
reed_solomon_release(queue->rs);
|
||||
queue->rs = NULL;
|
||||
}
|
||||
@ -227,9 +282,9 @@ static PRTPA_FEC_BLOCK getFecBlockForRtpPacket(PRTP_AUDIO_QUEUE queue, PRTP_PACK
|
||||
existingBlock = existingBlock->next;
|
||||
}
|
||||
|
||||
// We didn't find an existing FEC block, so we'll have to make one
|
||||
// We didn't find an existing FEC block, so we'll have to allocate one
|
||||
uint16_t dataPacketSize = blockSize + sizeof(RTP_PACKET);
|
||||
PRTPA_FEC_BLOCK block = malloc(sizeof(*block) + (RTPA_DATA_SHARDS * dataPacketSize) + (RTPA_FEC_SHARDS * blockSize));
|
||||
PRTPA_FEC_BLOCK block = allocateFecBlock(queue, blockSize);
|
||||
if (block == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
@ -12,6 +12,9 @@
|
||||
#define RTPA_FEC_SHARDS 2
|
||||
#define RTPA_TOTAL_SHARDS (RTPA_DATA_SHARDS + RTPA_FEC_SHARDS)
|
||||
|
||||
// Maximum number of FEC block entries to cache
|
||||
#define RTPA_CACHED_FEC_BLOCK_LIMIT 4
|
||||
|
||||
typedef struct _AUDIO_FEC_HEADER {
|
||||
uint8_t fecShardIndex;
|
||||
uint8_t payloadType;
|
||||
@ -50,6 +53,9 @@ typedef struct _RTP_AUDIO_QUEUE {
|
||||
|
||||
reed_solomon* rs;
|
||||
|
||||
PRTPA_FEC_BLOCK freeBlockHead;
|
||||
uint16_t freeBlockCount;
|
||||
|
||||
uint16_t nextRtpSequenceNumber;
|
||||
uint16_t oldestRtpBaseSequenceNumber;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user