diff --git a/Limelight/Stream/Connection.m b/Limelight/Stream/Connection.m index 39ca7fa..4fdd313 100644 --- a/Limelight/Stream/Connection.m +++ b/Limelight/Stream/Connection.m @@ -324,6 +324,7 @@ void ClLogMessage(const char* format, ...) LiInitializeVideoCallbacks(&_drCallbacks); _drCallbacks.setup = DrDecoderSetup; _drCallbacks.submitDecodeUnit = DrSubmitDecodeUnit; + _drCallbacks.capabilities = CAPABILITY_DIRECT_SUBMIT; // RFI doesn't work properly with HEVC on iOS 11 with an iPhone SE (at least) // It doesnt work on macOS either, tested with Network Link Conditioner. diff --git a/Limelight/Stream/VideoDecoderRenderer.m b/Limelight/Stream/VideoDecoderRenderer.m index 96b852c..151b251 100644 --- a/Limelight/Stream/VideoDecoderRenderer.m +++ b/Limelight/Stream/VideoDecoderRenderer.m @@ -269,8 +269,13 @@ if (displayLayer.status == AVQueuedSampleBufferRenderingStatusFailed) { Log(LOG_E, @"Display layer rendering failed: %@", displayLayer.error); - // Recreate the display layer - [self reinitializeDisplayLayer]; + // Recreate the display layer on the main thread. + // We need to use dispatch_sync() or we may miss + // some parameter sets while the layer is being + // recreated. + dispatch_sync(dispatch_get_main_queue(), ^{ + [self reinitializeDisplayLayer]; + }); // Request an IDR frame to initialize the new decoder free(data); @@ -337,14 +342,19 @@ CFDictionarySetValue(dict, kCMSampleAttachmentKey_NotSync, kCFBooleanFalse); CFDictionarySetValue(dict, kCMSampleAttachmentKey_DependsOnOthers, kCFBooleanFalse); } - - [displayLayer enqueueSampleBuffer:sampleBuffer]; + #if !TARGET_OS_IPHONE _view.frameCount++; #endif - // Dereference the buffers - CFRelease(blockBuffer); - CFRelease(sampleBuffer); + + // Enqueue video samples on the main thread + dispatch_async(dispatch_get_main_queue(), ^{ + [self->displayLayer enqueueSampleBuffer:sampleBuffer]; + + // Dereference the buffers + CFRelease(blockBuffer); + CFRelease(sampleBuffer); + }); return DR_OK; }