From a8d98284a784d7e1f17d87bda220ee41e51c6560 Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Thu, 18 Feb 2016 13:23:03 -0500 Subject: [PATCH] When a decoder requests an IDR frame, don't submit another frame until the IDR frame arrives --- limelight-common/Limelight-internal.h | 1 + limelight-common/VideoDepacketizer.c | 20 ++++++++++++++++++-- limelight-common/VideoStream.c | 2 +- 3 files changed, 20 insertions(+), 3 deletions(-) diff --git a/limelight-common/Limelight-internal.h b/limelight-common/Limelight-internal.h index 5a1b09d..0dc15b5 100644 --- a/limelight-common/Limelight-internal.h +++ b/limelight-common/Limelight-internal.h @@ -40,6 +40,7 @@ void destroyVideoDepacketizer(void); void processRtpPayload(PNV_VIDEO_PACKET videoPacket, int length); void queueRtpPacket(PRTP_PACKET rtpPacket, int length); void stopVideoDepacketizer(void); +void requestDecoderRefresh(void); void initializeVideoStream(void); void destroyVideoStream(void); diff --git a/limelight-common/VideoDepacketizer.c b/limelight-common/VideoDepacketizer.c index 193070b..0a383b0 100644 --- a/limelight-common/VideoDepacketizer.c +++ b/limelight-common/VideoDepacketizer.c @@ -225,8 +225,8 @@ static void reassembleAvcFrame(int frameNumber) { freeQueuedDecodeUnit(qdu); if (ret == DR_NEED_IDR) { - Limelog("Request IDR frame on behalf of DR\n"); - requestIdrOnDemand(); + Limelog("Requesting IDR frame on behalf of DR\n"); + requestDecoderRefresh(); } } @@ -330,6 +330,22 @@ static void processRtpPayloadSlow(PNV_VIDEO_PACKET videoPacket, PBUFFER_DESC cur } } +// Dumps the decode unit queue and ensures the next frame submitted to the decoder will be +// an IDR frame +void requestDecoderRefresh(void) { + // Wait for the next IDR frame + waitingForIdrFrame = 1; + + // Flush the decode unit queue and pending state + dropAvcFrameState(); + if ((VideoCallbacks.capabilities & CAPABILITY_DIRECT_SUBMIT) == 0) { + freeDecodeUnitList(LbqFlushQueueItems(&decodeUnitQueue)); + } + + // Request the IDR frame + requestIdrOnDemand(); +} + // Return 1 if packet is the first one in the frame static int isFirstPacket(char flags) { // Clear the picture data flag diff --git a/limelight-common/VideoStream.c b/limelight-common/VideoStream.c index b3464d5..5e7ea73 100644 --- a/limelight-common/VideoStream.c +++ b/limelight-common/VideoStream.c @@ -136,7 +136,7 @@ static void DecoderThreadProc(void* context) { if (ret == DR_NEED_IDR) { Limelog("Requesting IDR frame on behalf of DR\n"); - requestIdrOnDemand(); + requestDecoderRefresh(); } } }