From 9240090983d588bf7c40138c9a23ac1403c551f7 Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Wed, 5 Oct 2022 00:46:56 -0500 Subject: [PATCH] Add LiRequestIdrFrame() API for requesting an IDR frame on demand --- src/ControlStream.c | 8 ++++---- src/Limelight-internal.h | 1 - src/Limelight.h | 7 +++++++ src/VideoDepacketizer.c | 8 ++++---- 4 files changed, 15 insertions(+), 9 deletions(-) diff --git a/src/ControlStream.c b/src/ControlStream.c index eb2bcea..60238ed 100644 --- a/src/ControlStream.c +++ b/src/ControlStream.c @@ -312,20 +312,20 @@ void queueFrameInvalidationTuple(int startFrame, int endFrame) { // Too many invalidation tuples, so we need an IDR frame now Limelog("RFI range list reached maximum size limit\n"); free(qfit); - requestIdrOnDemand(); + LiRequestIdrFrame(); } } else { - requestIdrOnDemand(); + LiRequestIdrFrame(); } } else { - requestIdrOnDemand(); + LiRequestIdrFrame(); } } // Request an IDR frame on demand by the decoder -void requestIdrOnDemand(void) { +void LiRequestIdrFrame(void) { // Any reference frame invalidation requests should be dropped now. // We require a full IDR frame to recover. freeFrameInvalidationList(LbqFlushQueueItems(&invalidReferenceFrameTuples)); diff --git a/src/Limelight-internal.h b/src/Limelight-internal.h index 1181223..ef06a07 100644 --- a/src/Limelight-internal.h +++ b/src/Limelight-internal.h @@ -83,7 +83,6 @@ int initializeControlStream(void); int startControlStream(void); int stopControlStream(void); void destroyControlStream(void); -void requestIdrOnDemand(void); void connectionDetectedFrameLoss(int startFrame, int endFrame); void connectionReceivedCompleteFrame(int frameIndex); void connectionSawFrame(int frameIndex); diff --git a/src/Limelight.h b/src/Limelight.h index 9cd1cbf..ed39c77 100644 --- a/src/Limelight.h +++ b/src/Limelight.h @@ -693,6 +693,13 @@ void LiCompleteVideoFrame(VIDEO_FRAME_HANDLE handle, int drStatus); // See ConnListenerSetHdrMode() for more details. bool LiGetCurrentHostDisplayHdrMode(void); +// This function requests an IDR frame from the host. Typically this is done using DR_NEED_IDR, but clients +// processing frames asynchronously may need to reset their decoder state even after returning DR_OK for +// the prior frame. Rather than wait for a new frame and return DR_NEED_IDR for that one, they can just +// call this API instead. Note that this function does not guarantee that the *next* frame will be an IDR +// frame, just that an IDR frame will arrive soon. +void LiRequestIdrFrame(void); + #ifdef __cplusplus } #endif diff --git a/src/VideoDepacketizer.c b/src/VideoDepacketizer.c index 6380e03..0cefd2d 100644 --- a/src/VideoDepacketizer.c +++ b/src/VideoDepacketizer.c @@ -113,7 +113,7 @@ static void dropFrameState(void) { // Request an IDR frame waitingForIdrFrame = true; - requestIdrOnDemand(); + LiRequestIdrFrame(); } cleanupFrameState(); @@ -415,7 +415,7 @@ static void reassembleFrame(int frameNumber) { // Request an IDR frame to recover (RFI recovery is not supported here) waitingForIdrFrame = true; - requestIdrOnDemand(); + LiRequestIdrFrame(); return; } } @@ -608,7 +608,7 @@ void requestDecoderRefresh(void) { dropStatePending = true; // Request the IDR frame - requestIdrOnDemand(); + LiRequestIdrFrame(); } // Return 1 if packet is the first one in the frame @@ -843,7 +843,7 @@ static void processRtpPayload(PNV_VIDEO_PACKET videoPacket, int length, // detection of the recovery of the network. Requesting an IDR frame while // the network is unstable will just contribute to congestion collapse. if (waitingForNextSuccessfulFrame) { - requestIdrOnDemand(); + LiRequestIdrFrame(); } } else {