From 59481c085a7f774c5d30374636f8bc75da7c676c Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Sat, 4 May 2019 15:33:48 -0700 Subject: [PATCH] Add support for requesting 20 ms audio frames for slow Opus decoders --- src/AudioStream.c | 14 ++++++++------ src/Connection.c | 1 + src/Limelight-internal.h | 1 + src/Limelight.h | 1 + src/SdpGenerator.c | 19 +++++++++++++++++++ 5 files changed, 30 insertions(+), 6 deletions(-) diff --git a/src/AudioStream.c b/src/AudioStream.c index d8160fa..20a0479 100644 --- a/src/AudioStream.c +++ b/src/AudioStream.c @@ -161,7 +161,7 @@ static void ReceiveThreadProc(void* context) { PQUEUED_AUDIO_PACKET packet; int queueStatus; int useSelect; - int packetsToDrop = 100; + int packetsToDrop = 500 / AudioPacketDuration; packet = NULL; @@ -321,17 +321,17 @@ void stopAudioStream(void) { int startAudioStream(void* audioContext, int arFlags) { int err; - POPUS_MULTISTREAM_CONFIGURATION chosenConfig; + OPUS_MULTISTREAM_CONFIGURATION chosenConfig; if (StreamConfig.audioConfiguration == AUDIO_CONFIGURATION_STEREO) { - chosenConfig = &opusStereoConfig; + chosenConfig = opusStereoConfig; } else if (StreamConfig.audioConfiguration == AUDIO_CONFIGURATION_51_SURROUND) { if (HighQualitySurroundEnabled) { - chosenConfig = &opus51HighSurroundConfig; + chosenConfig = opus51HighSurroundConfig; } else { - chosenConfig = &opus51SurroundConfig; + chosenConfig = opus51SurroundConfig; } } else { @@ -339,7 +339,9 @@ int startAudioStream(void* audioContext, int arFlags) { return -1; } - err = AudioCallbacks.init(StreamConfig.audioConfiguration, chosenConfig, audioContext, arFlags); + chosenConfig.samplesPerFrame = 48 * AudioPacketDuration; + + err = AudioCallbacks.init(StreamConfig.audioConfiguration, &chosenConfig, audioContext, arFlags); if (err != 0) { return err; } diff --git a/src/Connection.c b/src/Connection.c index 3361087..5bf2991 100644 --- a/src/Connection.c +++ b/src/Connection.c @@ -20,6 +20,7 @@ int NegotiatedVideoFormat; volatile int ConnectionInterrupted; int HighQualitySurroundEnabled; int OriginalVideoBitrate; +int AudioPacketDuration; // Connection stages static const char* stageNames[STAGE_MAX] = { diff --git a/src/Limelight-internal.h b/src/Limelight-internal.h index 4c14ed6..f706684 100644 --- a/src/Limelight-internal.h +++ b/src/Limelight-internal.h @@ -22,6 +22,7 @@ extern int NegotiatedVideoFormat; extern volatile int ConnectionInterrupted; extern int HighQualitySurroundEnabled; extern int OriginalVideoBitrate; +extern int AudioPacketDuration; #ifndef UINT24_MAX #define UINT24_MAX 0xFFFFFF diff --git a/src/Limelight.h b/src/Limelight.h index fdd065b..7e40eb2 100644 --- a/src/Limelight.h +++ b/src/Limelight.h @@ -228,6 +228,7 @@ typedef struct _OPUS_MULTISTREAM_CONFIGURATION { int channelCount; int streams; int coupledStreams; + int samplesPerFrame; unsigned char mapping[6]; } OPUS_MULTISTREAM_CONFIGURATION, *POPUS_MULTISTREAM_CONFIGURATION; diff --git a/src/SdpGenerator.c b/src/SdpGenerator.c index 2019585..cc48b76 100644 --- a/src/SdpGenerator.c +++ b/src/SdpGenerator.c @@ -368,11 +368,30 @@ static PSDP_OPTION getAttributesList(char*urlSafeAddr) { // Let the audio stream code know that it needs to disable coupled streams when // decoding this audio stream. HighQualitySurroundEnabled = 1; + + // Use 5 ms frames since we don't have a slow decoder + AudioPacketDuration = 5; } else { err |= addAttributeString(&optionHead, "x-nv-audio.surround.AudioQuality", "0"); HighQualitySurroundEnabled = 0; + + if ((AudioCallbacks.capabilities & CAPABILITY_SLOW_OPUS_DECODER) == 0) { + // Use 5 ms packets by default for lowest latency + AudioPacketDuration = 5; + } + else { + // Use 20 ms packets for slow decoders to save CPU and bandwidth + AudioPacketDuration = 20; + } } + + sprintf(payloadStr, "%d", AudioPacketDuration); + err |= addAttributeString(&optionHead, "x-nv-aqos.packetDuration", payloadStr); + } + else { + // 5 ms duration for legacy servers + AudioPacketDuration = 5; } }