diff --git a/src/Limelight.h b/src/Limelight.h index a7078a3..0daf70b 100644 --- a/src/Limelight.h +++ b/src/Limelight.h @@ -151,6 +151,12 @@ typedef struct _DECODE_UNIT { // Frame type int frameType; + // Optional host processing latency of the frame, in 1/10 ms units. + // Zero when the host doesn't provide the latency data + // or frame processing latency is not applicable to the current frame + // (happens when the frame is repeated). + uint16_t frameHostProcessingLatency; + // Receive time of first buffer. This value uses an implementation-defined epoch, // but the same epoch as enqueueTimeMs and LiGetMillis(). uint64_t receiveTimeMs; diff --git a/src/VideoDepacketizer.c b/src/VideoDepacketizer.c index c86c868..738019e 100644 --- a/src/VideoDepacketizer.c +++ b/src/VideoDepacketizer.c @@ -16,6 +16,7 @@ static unsigned int lastPacketInStream; static bool decodingFrame; static bool strictIdrFrameWait; static uint64_t syntheticPtsBase; +static uint16_t frameHostProcessingLatency; static uint64_t firstPacketReceiveTime; static unsigned int firstPacketPresentationTime; static bool dropStatePending; @@ -64,6 +65,7 @@ void initializeVideoDepacketizer(int pktSize) { lastPacketInStream = UINT32_MAX; decodingFrame = false; syntheticPtsBase = 0; + frameHostProcessingLatency = 0; firstPacketReceiveTime = 0; firstPacketPresentationTime = 0; dropStatePending = false; @@ -449,6 +451,7 @@ static void reassembleFrame(int frameNumber) { qdu->decodeUnit.bufferList = nalChainHead; qdu->decodeUnit.fullLength = nalChainDataLength; qdu->decodeUnit.frameNumber = frameNumber; + qdu->decodeUnit.frameHostProcessingLatency = frameHostProcessingLatency; qdu->decodeUnit.receiveTimeMs = firstPacketReceiveTime; qdu->decodeUnit.presentationTimeMs = firstPacketPresentationTime; qdu->decodeUnit.enqueueTimeMs = LiGetMillis(); @@ -834,6 +837,13 @@ static void processRtpPayload(PNV_VIDEO_PACKET videoPacket, int length, } } + // Sunshine can provide host processing latency of the frame + if (IS_SUNSHINE()) { + BYTE_BUFFER bb; + BbInitializeWrappedBuffer(&bb, currentPos.data, currentPos.offset + 1, 2, BYTE_ORDER_LITTLE); + BbGet16(&bb, &frameHostProcessingLatency); + } + if (APP_VERSION_AT_LEAST(7, 1, 450)) { // >= 7.1.450 uses 2 different header lengths based on the first byte: // 0x01 indicates an 8 byte header