mirror of
https://github.com/moonlight-stream/moonlight-common-c.git
synced 2025-08-18 01:15:46 +00:00
Add support for 5.1 surround sound with GFE 2.7
This commit is contained in:
parent
1b3b57ed2f
commit
a13e68b042
@ -17,13 +17,36 @@ static unsigned short lastSeq;
|
|||||||
|
|
||||||
#define RTP_PORT 48000
|
#define RTP_PORT 48000
|
||||||
|
|
||||||
#define MAX_PACKET_SIZE 100
|
#define MAX_PACKET_SIZE 250
|
||||||
|
|
||||||
// This is much larger than we should typically have buffered, but
|
// This is much larger than we should typically have buffered, but
|
||||||
// it needs to be. We need a cushion in case our thread gets blocked
|
// it needs to be. We need a cushion in case our thread gets blocked
|
||||||
// for longer than normal.
|
// for longer than normal.
|
||||||
#define RTP_RECV_BUFFER (64 * MAX_PACKET_SIZE)
|
#define RTP_RECV_BUFFER (64 * MAX_PACKET_SIZE)
|
||||||
|
|
||||||
|
#define SAMPLE_RATE 48000
|
||||||
|
|
||||||
|
static OPUS_MULTISTREAM_CONFIGURATION opusStereoConfig = {
|
||||||
|
.sampleRate = SAMPLE_RATE,
|
||||||
|
.channelCount = 2,
|
||||||
|
.streams = 1,
|
||||||
|
.coupledStreams = 1,
|
||||||
|
.mapping = {0, 1}
|
||||||
|
};
|
||||||
|
|
||||||
|
static OPUS_MULTISTREAM_CONFIGURATION opus51SurroundConfig = {
|
||||||
|
.sampleRate = SAMPLE_RATE,
|
||||||
|
.channelCount = 6,
|
||||||
|
.streams = 4,
|
||||||
|
.coupledStreams = 2,
|
||||||
|
.mapping = {0, 4, 1, 5, 2, 3}
|
||||||
|
};
|
||||||
|
|
||||||
|
static POPUS_MULTISTREAM_CONFIGURATION opusConfigArray[] = {
|
||||||
|
&opusStereoConfig,
|
||||||
|
&opus51SurroundConfig,
|
||||||
|
};
|
||||||
|
|
||||||
typedef struct _QUEUED_AUDIO_PACKET {
|
typedef struct _QUEUED_AUDIO_PACKET {
|
||||||
// data must remain at the front
|
// data must remain at the front
|
||||||
char data[MAX_PACKET_SIZE];
|
char data[MAX_PACKET_SIZE];
|
||||||
@ -242,7 +265,8 @@ void stopAudioStream(void) {
|
|||||||
int startAudioStream(void) {
|
int startAudioStream(void) {
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
AudioCallbacks.init();
|
AudioCallbacks.init(StreamConfig.audioConfiguration,
|
||||||
|
opusConfigArray[StreamConfig.audioConfiguration]);
|
||||||
|
|
||||||
rtpSocket = bindUdpSocket(RemoteAddr.ss_family, RTP_RECV_BUFFER);
|
rtpSocket = bindUdpSocket(RemoteAddr.ss_family, RTP_RECV_BUFFER);
|
||||||
if (rtpSocket == INVALID_SOCKET) {
|
if (rtpSocket == INVALID_SOCKET) {
|
||||||
|
@ -10,7 +10,7 @@ static DECODER_RENDERER_CALLBACKS fakeDrCallbacks = {
|
|||||||
.submitDecodeUnit = fakeDrSubmitDecodeUnit,
|
.submitDecodeUnit = fakeDrSubmitDecodeUnit,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void fakeArInit(void) {}
|
static void fakeArInit(int audioConfiguration, POPUS_MULTISTREAM_CONFIGURATION opusConfig) {}
|
||||||
static void fakeArCleanup(void) {}
|
static void fakeArCleanup(void) {}
|
||||||
static void fakeArDecodeAndPlaySample(char* sampleData, int sampleLength) {}
|
static void fakeArDecodeAndPlaySample(char* sampleData, int sampleLength) {}
|
||||||
|
|
||||||
|
@ -29,6 +29,10 @@ typedef struct _STREAM_CONFIGURATION {
|
|||||||
// streaming optimizations. If unsure, set to 0.
|
// streaming optimizations. If unsure, set to 0.
|
||||||
int streamingRemotely;
|
int streamingRemotely;
|
||||||
|
|
||||||
|
// Specifies the channel configuration of the audio stream.
|
||||||
|
// See AUDIO_CONFIGURATION_XXX constants below.
|
||||||
|
int audioConfiguration;
|
||||||
|
|
||||||
// AES encryption data for the remote input stream. This must be
|
// AES encryption data for the remote input stream. This must be
|
||||||
// the same as what was passed as rikey and rikeyid
|
// the same as what was passed as rikey and rikeyid
|
||||||
// in /launch and /resume requests.
|
// in /launch and /resume requests.
|
||||||
@ -59,6 +63,12 @@ typedef struct _DECODE_UNIT {
|
|||||||
PLENTRY bufferList;
|
PLENTRY bufferList;
|
||||||
} DECODE_UNIT, *PDECODE_UNIT;
|
} DECODE_UNIT, *PDECODE_UNIT;
|
||||||
|
|
||||||
|
// Specifies that the audio stream should be encoded in stereo (default)
|
||||||
|
#define AUDIO_CONFIGURATION_STEREO 0
|
||||||
|
|
||||||
|
// Specifies that the audio stream should be in 5.1 surround sound if the PC is able
|
||||||
|
#define AUDIO_CONFIGURATION_51_SURROUND 1
|
||||||
|
|
||||||
// If set in the renderer capabilities field, this flag will cause audio/video data to
|
// If set in the renderer capabilities field, this flag will cause audio/video data to
|
||||||
// be submitted directly from the receive thread. This should only be specified if the
|
// be submitted directly from the receive thread. This should only be specified if the
|
||||||
// renderer is non-blocking. This flag is valid on both audio and video renderers.
|
// renderer is non-blocking. This flag is valid on both audio and video renderers.
|
||||||
@ -97,8 +107,21 @@ typedef struct _DECODER_RENDERER_CALLBACKS {
|
|||||||
// Use this function to zero the video callbacks when allocated on the stack or heap
|
// Use this function to zero the video callbacks when allocated on the stack or heap
|
||||||
void LiInitializeVideoCallbacks(PDECODER_RENDERER_CALLBACKS drCallbacks);
|
void LiInitializeVideoCallbacks(PDECODER_RENDERER_CALLBACKS drCallbacks);
|
||||||
|
|
||||||
// This callback initializes the audio renderer
|
// This structure provides the Opus multistream decoder parameters required to successfully
|
||||||
typedef void(*AudioRendererInit)(void);
|
// decode the audio stream being sent from the computer. See opus_multistream_decoder_init docs
|
||||||
|
// for details about these fields.
|
||||||
|
typedef struct _OPUS_MULTISTREAM_CONFIGURATION {
|
||||||
|
int sampleRate;
|
||||||
|
int channelCount;
|
||||||
|
int streams;
|
||||||
|
int coupledStreams;
|
||||||
|
const unsigned char mapping[6];
|
||||||
|
} OPUS_MULTISTREAM_CONFIGURATION, *POPUS_MULTISTREAM_CONFIGURATION;
|
||||||
|
|
||||||
|
// This callback initializes the audio renderer. The audio configuration parameter
|
||||||
|
// provides the negotiated audio configuration. This may differ from the one
|
||||||
|
// specified in the stream configuration.
|
||||||
|
typedef void(*AudioRendererInit)(int audioConfiguration, POPUS_MULTISTREAM_CONFIGURATION opusConfig);
|
||||||
|
|
||||||
// This callback performs the final teardown of the audio decoder
|
// This callback performs the final teardown of the audio decoder
|
||||||
typedef void(*AudioRendererCleanup)(void);
|
typedef void(*AudioRendererCleanup)(void);
|
||||||
|
@ -5,6 +5,12 @@
|
|||||||
#define MAX_SDP_HEADER_LEN 128
|
#define MAX_SDP_HEADER_LEN 128
|
||||||
#define MAX_SDP_TAIL_LEN 128
|
#define MAX_SDP_TAIL_LEN 128
|
||||||
|
|
||||||
|
#define CHANNEL_COUNT_STEREO 2
|
||||||
|
#define CHANNEL_COUNT_51_SURROUND 6
|
||||||
|
|
||||||
|
#define CHANNEL_MASK_STEREO 0x3
|
||||||
|
#define CHANNEL_MASK_51_SURROUND 0xFC
|
||||||
|
|
||||||
typedef struct _SDP_OPTION {
|
typedef struct _SDP_OPTION {
|
||||||
char name[MAX_OPTION_NAME_LEN+1];
|
char name[MAX_OPTION_NAME_LEN+1];
|
||||||
void* payload;
|
void* payload;
|
||||||
@ -134,6 +140,8 @@ static int addGen4Options(PSDP_OPTION *head, char* addrStr) {
|
|||||||
char payloadStr[92];
|
char payloadStr[92];
|
||||||
int err = 0;
|
int err = 0;
|
||||||
unsigned char slicesPerFrame;
|
unsigned char slicesPerFrame;
|
||||||
|
int audioChannelCount;
|
||||||
|
int audioChannelMask;
|
||||||
|
|
||||||
sprintf(payloadStr, "rtsp://%s:48010", addrStr);
|
sprintf(payloadStr, "rtsp://%s:48010", addrStr);
|
||||||
err |= addAttributeString(head, "x-nv-general.serverAddress", payloadStr);
|
err |= addAttributeString(head, "x-nv-general.serverAddress", payloadStr);
|
||||||
@ -149,6 +157,26 @@ static int addGen4Options(PSDP_OPTION *head, char* addrStr) {
|
|||||||
sprintf(payloadStr, "%d", slicesPerFrame);
|
sprintf(payloadStr, "%d", slicesPerFrame);
|
||||||
err |= addAttributeString(head, "x-nv-video[0].videoEncoderSlicesPerFrame", payloadStr);
|
err |= addAttributeString(head, "x-nv-video[0].videoEncoderSlicesPerFrame", payloadStr);
|
||||||
|
|
||||||
|
if (StreamConfig.audioConfiguration == AUDIO_CONFIGURATION_51_SURROUND) {
|
||||||
|
audioChannelCount = CHANNEL_COUNT_51_SURROUND;
|
||||||
|
audioChannelMask = CHANNEL_MASK_51_SURROUND;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
audioChannelCount = CHANNEL_COUNT_STEREO;
|
||||||
|
audioChannelMask = CHANNEL_MASK_STEREO;
|
||||||
|
}
|
||||||
|
|
||||||
|
sprintf(payloadStr, "%d", audioChannelCount);
|
||||||
|
err |= addAttributeString(head, "x-nv-audio.surround.numChannels", payloadStr);
|
||||||
|
sprintf(payloadStr, "%d", audioChannelMask);
|
||||||
|
err |= addAttributeString(head, "x-nv-audio.surround.channelMask", payloadStr);
|
||||||
|
if (audioChannelCount > 2) {
|
||||||
|
err |= addAttributeString(head, "x-nv-audio.surround.enable", "1");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
err |= addAttributeString(head, "x-nv-audio.surround.enable", "0");
|
||||||
|
}
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user