From 812f356868e5afaa45e5a0e96ac70e5c0da8bbac Mon Sep 17 00:00:00 2001 From: Iwan Timmer Date: Fri, 24 Jul 2015 10:38:37 +0200 Subject: [PATCH] Add capability to combine video receive and decode thread --- limelight-common/Limelight.h | 1 + limelight-common/VideoDepacketizer.c | 45 ++++++++++++++++++---------- limelight-common/VideoStream.c | 20 +++++++++---- 3 files changed, 45 insertions(+), 21 deletions(-) diff --git a/limelight-common/Limelight.h b/limelight-common/Limelight.h index d82021d..f446409 100644 --- a/limelight-common/Limelight.h +++ b/limelight-common/Limelight.h @@ -71,6 +71,7 @@ typedef struct _DECODER_RENDERER_CALLBACKS { DecoderRendererSetup setup; DecoderRendererCleanup cleanup; DecoderRendererSubmitDecodeUnit submitDecodeUnit; + int capabilities; } DECODER_RENDERER_CALLBACKS, *PDECODER_RENDERER_CALLBACKS; // This callback initializes the audio renderer diff --git a/limelight-common/VideoDepacketizer.c b/limelight-common/VideoDepacketizer.c index 8932824..d4ba3c4 100644 --- a/limelight-common/VideoDepacketizer.c +++ b/limelight-common/VideoDepacketizer.c @@ -29,7 +29,9 @@ typedef struct _BUFFER_DESC { /* Init */ void initializeVideoDepacketizer(int pktSize) { - LbqInitializeLinkedBlockingQueue(&decodeUnitQueue, 15); + if ((VideoCallbacks.capabilities & CAPABILITY_DIRECT_SUBMIT) == 0) { + LbqInitializeLinkedBlockingQueue(&decodeUnitQueue, 15); + } nominalPacketDataLength = pktSize - sizeof(NV_VIDEO_PACKET); nextFrameNumber = 1; @@ -91,7 +93,9 @@ static void freeDecodeUnitList(PLINKED_BLOCKING_QUEUE_ENTRY entry) { /* Cleanup video depacketizer and free malloced memory */ void destroyVideoDepacketizer(void) { - freeDecodeUnitList(LbqDestroyLinkedBlockingQueue(&decodeUnitQueue)); + if ((VideoCallbacks.capabilities & CAPABILITY_DIRECT_SUBMIT) == 0) { + freeDecodeUnitList(LbqDestroyLinkedBlockingQueue(&decodeUnitQueue)); + } cleanupAvcFrameState(); } @@ -183,23 +187,34 @@ static void reassembleAvcFrame(int frameNumber) { nalChainHead = NULL; nalChainDataLength = 0; - if (LbqOfferQueueItem(&decodeUnitQueue, qdu, &qdu->entry) == LBQ_BOUND_EXCEEDED) { - Limelog("Video decode unit queue overflow\n"); + if ((VideoCallbacks.capabilities & CAPABILITY_DIRECT_SUBMIT) == 0) { + if (LbqOfferQueueItem(&decodeUnitQueue, qdu, &qdu->entry) == LBQ_BOUND_EXCEEDED) { + Limelog("Video decode unit queue overflow\n"); - // Clear frame state and wait for an IDR - nalChainHead = qdu->decodeUnit.bufferList; - nalChainDataLength = qdu->decodeUnit.fullLength; - dropAvcFrameState(); + // Clear frame state and wait for an IDR + nalChainHead = qdu->decodeUnit.bufferList; + nalChainDataLength = qdu->decodeUnit.fullLength; + dropAvcFrameState(); - // Free the DU - free(qdu); + // Free the DU + free(qdu); - // Flush the decode unit queue - freeDecodeUnitList(LbqFlushQueueItems(&decodeUnitQueue)); + // Flush the decode unit queue + freeDecodeUnitList(LbqFlushQueueItems(&decodeUnitQueue)); - // FIXME: Get proper lower bound - connectionSinkTooSlow(0, frameNumber); - return; + // FIXME: Get proper lower bound + connectionSinkTooSlow(0, frameNumber); + return; + } + } else { + int ret = VideoCallbacks.submitDecodeUnit(&qdu->decodeUnit); + + freeQueuedDecodeUnit(qdu); + + if (ret == DR_NEED_IDR) { + Limelog("Request IDR frame on behalf of DR\n"); + requestIdrOnDemand(); + } } // Notify the control connection diff --git a/limelight-common/VideoStream.c b/limelight-common/VideoStream.c index 51adbfd..ca977eb 100644 --- a/limelight-common/VideoStream.c +++ b/limelight-common/VideoStream.c @@ -150,7 +150,9 @@ int readFirstFrame(void) { void stopVideoStream(void) { PltInterruptThread(&udpPingThread); PltInterruptThread(&receiveThread); - PltInterruptThread(&decoderThread); + if ((VideoCallbacks.capabilities & CAPABILITY_DIRECT_SUBMIT) == 0) { + PltInterruptThread(&decoderThread); + } if (firstFrameSocket != INVALID_SOCKET) { closesocket(firstFrameSocket); @@ -163,11 +165,15 @@ void stopVideoStream(void) { PltJoinThread(&udpPingThread); PltJoinThread(&receiveThread); - PltJoinThread(&decoderThread); + if ((VideoCallbacks.capabilities & CAPABILITY_DIRECT_SUBMIT) == 0) { + PltJoinThread(&decoderThread); + } PltCloseThread(&udpPingThread); PltCloseThread(&receiveThread); - PltCloseThread(&decoderThread); + if ((VideoCallbacks.capabilities & CAPABILITY_DIRECT_SUBMIT) == 0) { + PltCloseThread(&decoderThread); + } VideoCallbacks.cleanup(); } @@ -191,9 +197,11 @@ int startVideoStream(void* rendererContext, int drFlags) { return err; } - err = PltCreateThread(DecoderThreadProc, NULL, &decoderThread); - if (err != 0) { - return err; + if ((VideoCallbacks.capabilities & CAPABILITY_DIRECT_SUBMIT) == 0) { + err = PltCreateThread(DecoderThreadProc, NULL, &decoderThread); + if (err != 0) { + return err; + } } if (ServerMajorVersion == 3) {