Add capability to combine video receive and decode thread

This commit is contained in:
Iwan Timmer 2015-07-24 10:38:37 +02:00
parent c829d9c742
commit 812f356868
3 changed files with 45 additions and 21 deletions

View File

@ -71,6 +71,7 @@ typedef struct _DECODER_RENDERER_CALLBACKS {
DecoderRendererSetup setup; DecoderRendererSetup setup;
DecoderRendererCleanup cleanup; DecoderRendererCleanup cleanup;
DecoderRendererSubmitDecodeUnit submitDecodeUnit; DecoderRendererSubmitDecodeUnit submitDecodeUnit;
int capabilities;
} DECODER_RENDERER_CALLBACKS, *PDECODER_RENDERER_CALLBACKS; } DECODER_RENDERER_CALLBACKS, *PDECODER_RENDERER_CALLBACKS;
// This callback initializes the audio renderer // This callback initializes the audio renderer

View File

@ -29,7 +29,9 @@ typedef struct _BUFFER_DESC {
/* Init */ /* Init */
void initializeVideoDepacketizer(int pktSize) { void initializeVideoDepacketizer(int pktSize) {
LbqInitializeLinkedBlockingQueue(&decodeUnitQueue, 15); if ((VideoCallbacks.capabilities & CAPABILITY_DIRECT_SUBMIT) == 0) {
LbqInitializeLinkedBlockingQueue(&decodeUnitQueue, 15);
}
nominalPacketDataLength = pktSize - sizeof(NV_VIDEO_PACKET); nominalPacketDataLength = pktSize - sizeof(NV_VIDEO_PACKET);
nextFrameNumber = 1; nextFrameNumber = 1;
@ -91,7 +93,9 @@ static void freeDecodeUnitList(PLINKED_BLOCKING_QUEUE_ENTRY entry) {
/* Cleanup video depacketizer and free malloced memory */ /* Cleanup video depacketizer and free malloced memory */
void destroyVideoDepacketizer(void) { void destroyVideoDepacketizer(void) {
freeDecodeUnitList(LbqDestroyLinkedBlockingQueue(&decodeUnitQueue)); if ((VideoCallbacks.capabilities & CAPABILITY_DIRECT_SUBMIT) == 0) {
freeDecodeUnitList(LbqDestroyLinkedBlockingQueue(&decodeUnitQueue));
}
cleanupAvcFrameState(); cleanupAvcFrameState();
} }
@ -183,23 +187,34 @@ static void reassembleAvcFrame(int frameNumber) {
nalChainHead = NULL; nalChainHead = NULL;
nalChainDataLength = 0; nalChainDataLength = 0;
if (LbqOfferQueueItem(&decodeUnitQueue, qdu, &qdu->entry) == LBQ_BOUND_EXCEEDED) { if ((VideoCallbacks.capabilities & CAPABILITY_DIRECT_SUBMIT) == 0) {
Limelog("Video decode unit queue overflow\n"); if (LbqOfferQueueItem(&decodeUnitQueue, qdu, &qdu->entry) == LBQ_BOUND_EXCEEDED) {
Limelog("Video decode unit queue overflow\n");
// Clear frame state and wait for an IDR // Clear frame state and wait for an IDR
nalChainHead = qdu->decodeUnit.bufferList; nalChainHead = qdu->decodeUnit.bufferList;
nalChainDataLength = qdu->decodeUnit.fullLength; nalChainDataLength = qdu->decodeUnit.fullLength;
dropAvcFrameState(); dropAvcFrameState();
// Free the DU // Free the DU
free(qdu); free(qdu);
// Flush the decode unit queue // Flush the decode unit queue
freeDecodeUnitList(LbqFlushQueueItems(&decodeUnitQueue)); freeDecodeUnitList(LbqFlushQueueItems(&decodeUnitQueue));
// FIXME: Get proper lower bound // FIXME: Get proper lower bound
connectionSinkTooSlow(0, frameNumber); connectionSinkTooSlow(0, frameNumber);
return; 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 // Notify the control connection

View File

@ -150,7 +150,9 @@ int readFirstFrame(void) {
void stopVideoStream(void) { void stopVideoStream(void) {
PltInterruptThread(&udpPingThread); PltInterruptThread(&udpPingThread);
PltInterruptThread(&receiveThread); PltInterruptThread(&receiveThread);
PltInterruptThread(&decoderThread); if ((VideoCallbacks.capabilities & CAPABILITY_DIRECT_SUBMIT) == 0) {
PltInterruptThread(&decoderThread);
}
if (firstFrameSocket != INVALID_SOCKET) { if (firstFrameSocket != INVALID_SOCKET) {
closesocket(firstFrameSocket); closesocket(firstFrameSocket);
@ -163,11 +165,15 @@ void stopVideoStream(void) {
PltJoinThread(&udpPingThread); PltJoinThread(&udpPingThread);
PltJoinThread(&receiveThread); PltJoinThread(&receiveThread);
PltJoinThread(&decoderThread); if ((VideoCallbacks.capabilities & CAPABILITY_DIRECT_SUBMIT) == 0) {
PltJoinThread(&decoderThread);
}
PltCloseThread(&udpPingThread); PltCloseThread(&udpPingThread);
PltCloseThread(&receiveThread); PltCloseThread(&receiveThread);
PltCloseThread(&decoderThread); if ((VideoCallbacks.capabilities & CAPABILITY_DIRECT_SUBMIT) == 0) {
PltCloseThread(&decoderThread);
}
VideoCallbacks.cleanup(); VideoCallbacks.cleanup();
} }
@ -191,9 +197,11 @@ int startVideoStream(void* rendererContext, int drFlags) {
return err; return err;
} }
err = PltCreateThread(DecoderThreadProc, NULL, &decoderThread); if ((VideoCallbacks.capabilities & CAPABILITY_DIRECT_SUBMIT) == 0) {
if (err != 0) { err = PltCreateThread(DecoderThreadProc, NULL, &decoderThread);
return err; if (err != 0) {
return err;
}
} }
if (ServerMajorVersion == 3) { if (ServerMajorVersion == 3) {