mirror of
https://github.com/moonlight-stream/moonlight-common-c.git
synced 2026-04-12 18:56:13 +00:00
Forward Error Correction (#24)
* Preperation for FEC by adding new queue which buffers whole frames * Add code for creating recovered RTP packet * Add checks before repair missing packets * Initial implementation for single FEC packet * Implement FEC for multiple packets
This commit is contained in:
committed by
Cameron Gutman
parent
dbb7cee399
commit
9bf8d361a1
@@ -1,7 +1,7 @@
|
||||
#include "Limelight-internal.h"
|
||||
#include "PlatformSockets.h"
|
||||
#include "PlatformThreads.h"
|
||||
#include "RtpReorderQueue.h"
|
||||
#include "RtpFecQueue.h"
|
||||
|
||||
#define FIRST_FRAME_MAX 1500
|
||||
#define FIRST_FRAME_TIMEOUT_SEC 10
|
||||
@@ -11,7 +11,7 @@
|
||||
|
||||
#define RTP_RECV_BUFFER (512 * 1024)
|
||||
|
||||
static RTP_REORDER_QUEUE rtpQueue;
|
||||
static RTP_FEC_QUEUE rtpQueue;
|
||||
|
||||
static SOCKET rtpSocket = INVALID_SOCKET;
|
||||
static SOCKET firstFrameSocket = INVALID_SOCKET;
|
||||
@@ -25,16 +25,17 @@ static PLT_THREAD decoderThread;
|
||||
// the RTP queue will wait for missing/reordered packets.
|
||||
#define RTP_QUEUE_DELAY 10
|
||||
|
||||
|
||||
// Initialize the video stream
|
||||
void initializeVideoStream(void) {
|
||||
initializeVideoDepacketizer(StreamConfig.packetSize);
|
||||
RtpqInitializeQueue(&rtpQueue, RTPQ_DEFAULT_MAX_SIZE, RTP_QUEUE_DELAY);
|
||||
RtpfInitializeQueue(&rtpQueue); //TODO RTP_QUEUE_DELAY
|
||||
}
|
||||
|
||||
// Clean up the video stream
|
||||
void destroyVideoStream(void) {
|
||||
destroyVideoDepacketizer();
|
||||
RtpqCleanupQueue(&rtpQueue);
|
||||
RtpfCleanupQueue(&rtpQueue);
|
||||
}
|
||||
|
||||
// UDP Ping proc
|
||||
@@ -66,7 +67,7 @@ static void ReceiveThreadProc(void* context) {
|
||||
int queueStatus;
|
||||
|
||||
receiveSize = StreamConfig.packetSize + MAX_RTP_HEADER_SIZE;
|
||||
bufferSize = receiveSize + sizeof(int) + sizeof(RTP_QUEUE_ENTRY);
|
||||
bufferSize = receiveSize + sizeof(int) + sizeof(RTPFEC_QUEUE_ENTRY);
|
||||
buffer = NULL;
|
||||
|
||||
while (!PltIsThreadInterrupted(&receiveThread)) {
|
||||
@@ -98,20 +99,16 @@ static void ReceiveThreadProc(void* context) {
|
||||
packet = (PRTP_PACKET)&buffer[0];
|
||||
packet->sequenceNumber = htons(packet->sequenceNumber);
|
||||
|
||||
queueStatus = RtpqAddPacket(&rtpQueue, packet, (PRTP_QUEUE_ENTRY)&buffer[receiveSize + sizeof(int)]);
|
||||
if (queueStatus == RTPQ_RET_HANDLE_IMMEDIATELY) {
|
||||
// queueRtpPacket() copies the data it needs to we can reuse the buffer
|
||||
queueRtpPacket(packet, err);
|
||||
}
|
||||
else if (queueStatus == RTPQ_RET_QUEUED_PACKETS_READY) {
|
||||
queueStatus = RtpfAddPacket(&rtpQueue, packet, (PRTPFEC_QUEUE_ENTRY)&buffer[receiveSize + sizeof(int)]);
|
||||
if (queueStatus == RTPF_RET_QUEUED_PACKETS_READY) {
|
||||
// The packet queue now has packets ready
|
||||
while ((buffer = (char*)RtpqGetQueuedPacket(&rtpQueue)) != NULL) {
|
||||
while ((buffer = (char*)RtpfGetQueuedPacket(&rtpQueue)) != NULL) {
|
||||
memcpy(&err, &buffer[receiveSize], sizeof(int));
|
||||
queueRtpPacket((PRTP_PACKET)buffer, err);
|
||||
free(buffer);
|
||||
}
|
||||
}
|
||||
else if (queueStatus == RTPQ_RET_QUEUED_NOTHING_READY) {
|
||||
else if (queueStatus == RTPF_RET_QUEUED_NOTHING_READY) {
|
||||
// The queue owns the buffer
|
||||
buffer = NULL;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user