Finish 5.1 surround sound support

This commit is contained in:
Cameron Gutman 2015-10-18 15:25:16 -07:00
parent fbd61d2a21
commit 886ef425e6
4 changed files with 52 additions and 22 deletions

View File

@ -5,6 +5,15 @@ import com.limelight.nvstream.http.NvApp;
public class StreamConfiguration { public class StreamConfiguration {
public static final int INVALID_APP_ID = 0; public static final int INVALID_APP_ID = 0;
public static final int AUDIO_CONFIGURATION_STEREO = 1;
public static final int AUDIO_CONFIGURATION_5_1 = 2;
private static final int CHANNEL_COUNT_STEREO = 2;
private static final int CHANNEL_COUNT_5_1 = 6;
private static final int CHANNEL_MASK_STEREO = 0x3;
private static final int CHANNEL_MASK_5_1 = 0xFC;
private NvApp app; private NvApp app;
private int width, height; private int width, height;
private int refreshRate; private int refreshRate;
@ -66,9 +75,16 @@ public class StreamConfiguration {
return this; return this;
} }
public StreamConfiguration.Builder setAudioParameters(int audioChannelMask, int audioChannelCount) { public StreamConfiguration.Builder setAudioConfiguration(int audioConfig) {
config.audioChannelCount = audioChannelCount; if (audioConfig == AUDIO_CONFIGURATION_STEREO) {
config.audioChannelMask = audioChannelMask; config.audioChannelCount = CHANNEL_COUNT_STEREO;
config.audioChannelMask = CHANNEL_MASK_STEREO;
}
else if (audioConfig == AUDIO_CONFIGURATION_5_1) {
config.audioChannelCount = CHANNEL_COUNT_5_1;
config.audioChannelMask = CHANNEL_MASK_5_1;
}
return this; return this;
} }
@ -87,8 +103,8 @@ public class StreamConfiguration {
this.maxPacketSize = 1024; this.maxPacketSize = 1024;
this.sops = true; this.sops = true;
this.enableAdaptiveResolution = false; this.enableAdaptiveResolution = false;
this.audioChannelCount = 2; this.audioChannelCount = CHANNEL_COUNT_STEREO;
this.audioChannelMask = 0x3; this.audioChannelMask = CHANNEL_MASK_STEREO;
} }
public int getWidth() { public int getWidth() {

View File

@ -11,9 +11,7 @@ public class AudioDepacketizer {
private static final int DU_LIMIT = 30; private static final int DU_LIMIT = 30;
private AbstractPopulatedBufferList<ByteBufferDescriptor> decodedUnits; private AbstractPopulatedBufferList<ByteBufferDescriptor> decodedUnits;
private final int channelCount;
// Direct submit state // Direct submit state
private AudioRenderer directSubmitRenderer; private AudioRenderer directSubmitRenderer;
private byte[] directSubmitData; private byte[] directSubmitData;
@ -24,10 +22,9 @@ public class AudioDepacketizer {
// Sequencing state // Sequencing state
private short lastSequenceNumber; private short lastSequenceNumber;
public AudioDepacketizer(AudioRenderer directSubmitRenderer, final int channelCount, final int bufferSizeShorts) public AudioDepacketizer(AudioRenderer directSubmitRenderer, final int bufferSizeShorts)
{ {
this.directSubmitRenderer = directSubmitRenderer; this.directSubmitRenderer = directSubmitRenderer;
this.channelCount = channelCount;
if (directSubmitRenderer != null) { if (directSubmitRenderer != null) {
this.directSubmitData = new byte[bufferSizeShorts*2]; this.directSubmitData = new byte[bufferSizeShorts*2];
} }
@ -68,9 +65,6 @@ public class AudioDepacketizer {
} }
if (decodeLen > 0) { if (decodeLen > 0) {
// Return value of decode is frames (shorts) decoded per channel
decodeLen *= 2*channelCount;
if (directSubmitRenderer != null) { if (directSubmitRenderer != null) {
directSubmitRenderer.playDecodedAudio(directSubmitData, 0, decodeLen); directSubmitRenderer.playDecodedAudio(directSubmitData, 0, decodeLen);
} }

View File

@ -19,7 +19,7 @@ public class AudioStream {
private static final int SHORTS_PER_CHANNEL = 240; private static final int SHORTS_PER_CHANNEL = 240;
private static final int RTP_RECV_BUFFER = 64 * 1024; private static final int RTP_RECV_BUFFER = 64 * 1024;
private static final int MAX_PACKET_SIZE = 100; private static final int MAX_PACKET_SIZE = 250;
private DatagramSocket rtp; private DatagramSocket rtp;
@ -93,14 +93,36 @@ public class AudioStream {
rtp.setReceiveBufferSize(RTP_RECV_BUFFER); rtp.setReceiveBufferSize(RTP_RECV_BUFFER);
} }
private static final int[] STREAMS_2 = new int[] {1, 1};
private static final int[] STREAMS_5_1 = new int[] {4, 2};
private static final byte[] MAPPING_2 = new byte[] {0, 1};
private static final byte[] MAPPING_5_1 = new byte[] {0, 4, 1, 5, 2, 3};
private boolean setupAudio() private boolean setupAudio()
{ {
int err; int err;
err = OpusDecoder.init(SAMPLE_RATE, context.streamConfig.getAudioChannelCount(), int channels = context.streamConfig.getAudioChannelCount();
1, 1, new byte[]{0, 1, 2, 3, 4, 5, 6}); byte[] mapping;
int[] streams;
if (channels == 2) {
mapping = MAPPING_2;
streams = STREAMS_2;
}
else if (channels == 6) {
mapping = MAPPING_5_1;
streams = STREAMS_5_1;
}
else {
throw new IllegalStateException("Unsupported surround configuration");
}
err = OpusDecoder.init(SAMPLE_RATE, SHORTS_PER_CHANNEL, channels,
streams[0], streams[1], mapping);
if (err != 0) { if (err != 0) {
throw new IllegalStateException("Opus decoder failed to initialize"); throw new IllegalStateException("Opus decoder failed to initialize: "+err);
} }
if (!streamListener.streamInitialized(context.streamConfig.getAudioChannelCount(), if (!streamListener.streamInitialized(context.streamConfig.getAudioChannelCount(),
@ -111,12 +133,10 @@ public class AudioStream {
} }
if ((streamListener.getCapabilities() & AudioRenderer.CAPABILITY_DIRECT_SUBMIT) != 0) { if ((streamListener.getCapabilities() & AudioRenderer.CAPABILITY_DIRECT_SUBMIT) != 0) {
depacketizer = new AudioDepacketizer(streamListener, context.streamConfig.getAudioChannelCount(), depacketizer = new AudioDepacketizer(streamListener, context.streamConfig.getAudioChannelCount()*SHORTS_PER_CHANNEL);
context.streamConfig.getAudioChannelCount()*SHORTS_PER_CHANNEL);
} }
else { else {
depacketizer = new AudioDepacketizer(null, context.streamConfig.getAudioChannelCount(), depacketizer = new AudioDepacketizer(null, context.streamConfig.getAudioChannelCount()*SHORTS_PER_CHANNEL);
context.streamConfig.getAudioChannelCount()*SHORTS_PER_CHANNEL);
} }
return true; return true;

View File

@ -5,7 +5,7 @@ public class OpusDecoder {
System.loadLibrary("nv_opus_dec"); System.loadLibrary("nv_opus_dec");
} }
public static native int init(int sampleRate, int channelCount, int streams, int coupledStreams, byte[] mapping); public static native int init(int sampleRate, int samplesPerChannel, int channelCount, int streams, int coupledStreams, byte[] mapping);
public static native void destroy(); public static native void destroy();
public static native int decode(byte[] indata, int inoff, int inlen, byte[] outpcmdata); public static native int decode(byte[] indata, int inoff, int inlen, byte[] outpcmdata);
} }