Wait for first IDR frame before enabling RFI

This commit is contained in:
Cameron Gutman
2019-01-19 14:44:48 -08:00
parent a653f4d3e0
commit 12eebe0039
3 changed files with 22 additions and 17 deletions
+1 -1
View File
@@ -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
View File
@@ -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
View File
@@ -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();
}
} }
} }