mirror of
https://github.com/moonlight-stream/moonlight-common-c.git
synced 2026-06-17 14:21:30 +00:00
Wait for first IDR frame before enabling RFI
This commit is contained in:
+1
-1
@@ -7,7 +7,7 @@ typedef struct _QUEUED_DECODE_UNIT {
|
|||||||
LINKED_BLOCKING_QUEUE_ENTRY entry;
|
LINKED_BLOCKING_QUEUE_ENTRY entry;
|
||||||
} QUEUED_DECODE_UNIT, *PQUEUED_DECODE_UNIT;
|
} QUEUED_DECODE_UNIT, *PQUEUED_DECODE_UNIT;
|
||||||
|
|
||||||
void freeQueuedDecodeUnit(PQUEUED_DECODE_UNIT qdu);
|
void completeQueuedDecodeUnit(PQUEUED_DECODE_UNIT qdu, int drStatus);
|
||||||
int getNextQueuedDecodeUnit(PQUEUED_DECODE_UNIT* qdu);
|
int getNextQueuedDecodeUnit(PQUEUED_DECODE_UNIT* qdu);
|
||||||
|
|
||||||
#pragma pack(push, 1)
|
#pragma pack(push, 1)
|
||||||
|
|||||||
+20
-10
@@ -15,6 +15,9 @@ static int decodingFrame;
|
|||||||
static int strictIdrFrameWait;
|
static int strictIdrFrameWait;
|
||||||
static unsigned long long firstPacketReceiveTime;
|
static unsigned long long firstPacketReceiveTime;
|
||||||
static int dropStatePending;
|
static int dropStatePending;
|
||||||
|
static int idrFrameProcessed;
|
||||||
|
|
||||||
|
#define DR_CLEANUP -1000
|
||||||
|
|
||||||
#define CONSECUTIVE_DROP_LIMIT 120
|
#define CONSECUTIVE_DROP_LIMIT 120
|
||||||
static unsigned int consecutiveFrameDrops;
|
static unsigned int consecutiveFrameDrops;
|
||||||
@@ -41,6 +44,7 @@ void initializeVideoDepacketizer(int pktSize) {
|
|||||||
decodingFrame = 0;
|
decodingFrame = 0;
|
||||||
firstPacketReceiveTime = 0;
|
firstPacketReceiveTime = 0;
|
||||||
dropStatePending = 0;
|
dropStatePending = 0;
|
||||||
|
idrFrameProcessed = 0;
|
||||||
strictIdrFrameWait = !isReferenceFrameInvalidationEnabled();
|
strictIdrFrameWait = !isReferenceFrameInvalidationEnabled();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -66,7 +70,8 @@ static void dropFrameState(void) {
|
|||||||
dropStatePending = 0;
|
dropStatePending = 0;
|
||||||
|
|
||||||
// We'll need an IDR frame now if we're in strict mode
|
// We'll need an IDR frame now if we're in strict mode
|
||||||
if (strictIdrFrameWait) {
|
// or if we've never seen one before
|
||||||
|
if (strictIdrFrameWait || !idrFrameProcessed) {
|
||||||
waitingForIdrFrame = 1;
|
waitingForIdrFrame = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -95,7 +100,8 @@ static void freeDecodeUnitList(PLINKED_BLOCKING_QUEUE_ENTRY entry) {
|
|||||||
while (entry != NULL) {
|
while (entry != NULL) {
|
||||||
nextEntry = entry->flink;
|
nextEntry = entry->flink;
|
||||||
|
|
||||||
freeQueuedDecodeUnit((PQUEUED_DECODE_UNIT)entry->data);
|
// Complete this with a failure status
|
||||||
|
completeQueuedDecodeUnit((PQUEUED_DECODE_UNIT)entry->data, DR_CLEANUP);
|
||||||
|
|
||||||
entry = nextEntry;
|
entry = nextEntry;
|
||||||
}
|
}
|
||||||
@@ -180,9 +186,19 @@ int getNextQueuedDecodeUnit(PQUEUED_DECODE_UNIT* qdu) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Cleanup a decode unit by freeing the buffer chain and the holder
|
// Cleanup a decode unit by freeing the buffer chain and the holder
|
||||||
void freeQueuedDecodeUnit(PQUEUED_DECODE_UNIT qdu) {
|
void completeQueuedDecodeUnit(PQUEUED_DECODE_UNIT qdu, int drStatus) {
|
||||||
PLENTRY lastEntry;
|
PLENTRY lastEntry;
|
||||||
|
|
||||||
|
if (drStatus == DR_NEED_IDR) {
|
||||||
|
Limelog("Requesting IDR frame on behalf of DR\n");
|
||||||
|
requestDecoderRefresh();
|
||||||
|
}
|
||||||
|
else if (drStatus == DR_OK && qdu->decodeUnit.frameType == FRAME_TYPE_IDR) {
|
||||||
|
// Remember that the IDR frame was processed. We can now use
|
||||||
|
// reference frame invalidation.
|
||||||
|
idrFrameProcessed = 1;
|
||||||
|
}
|
||||||
|
|
||||||
while (qdu->decodeUnit.bufferList != NULL) {
|
while (qdu->decodeUnit.bufferList != NULL) {
|
||||||
lastEntry = qdu->decodeUnit.bufferList;
|
lastEntry = qdu->decodeUnit.bufferList;
|
||||||
qdu->decodeUnit.bufferList = lastEntry->next;
|
qdu->decodeUnit.bufferList = lastEntry->next;
|
||||||
@@ -192,7 +208,6 @@ void freeQueuedDecodeUnit(PQUEUED_DECODE_UNIT qdu) {
|
|||||||
free(qdu);
|
free(qdu);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Returns 1 if the special sequence describes an I-frame
|
// Returns 1 if the special sequence describes an I-frame
|
||||||
static int isSeqReferenceFrameStart(PBUFFER_DESC specialSeq) {
|
static int isSeqReferenceFrameStart(PBUFFER_DESC specialSeq) {
|
||||||
switch (specialSeq->data[specialSeq->offset + specialSeq->length]) {
|
switch (specialSeq->data[specialSeq->offset + specialSeq->length]) {
|
||||||
@@ -267,12 +282,7 @@ static void reassembleFrame(int frameNumber) {
|
|||||||
else {
|
else {
|
||||||
int ret = VideoCallbacks.submitDecodeUnit(&qdu->decodeUnit);
|
int ret = VideoCallbacks.submitDecodeUnit(&qdu->decodeUnit);
|
||||||
|
|
||||||
freeQueuedDecodeUnit(qdu);
|
completeQueuedDecodeUnit(qdu, ret);
|
||||||
|
|
||||||
if (ret == DR_NEED_IDR) {
|
|
||||||
Limelog("Requesting IDR frame on behalf of DR\n");
|
|
||||||
requestDecoderRefresh();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Notify the control connection
|
// Notify the control connection
|
||||||
|
|||||||
+1
-6
@@ -138,12 +138,7 @@ static void DecoderThreadProc(void* context) {
|
|||||||
|
|
||||||
int ret = VideoCallbacks.submitDecodeUnit(&qdu->decodeUnit);
|
int ret = VideoCallbacks.submitDecodeUnit(&qdu->decodeUnit);
|
||||||
|
|
||||||
freeQueuedDecodeUnit(qdu);
|
completeQueuedDecodeUnit(qdu, ret);
|
||||||
|
|
||||||
if (ret == DR_NEED_IDR) {
|
|
||||||
Limelog("Requesting IDR frame on behalf of DR\n");
|
|
||||||
requestDecoderRefresh();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user