mirror of
https://github.com/moonlight-stream/moonlight-android.git
synced 2025-07-21 03:52:48 +00:00
Add support for direct submission of buffers to the renderers without a separate thread
This commit is contained in:
parent
cf3ac50d22
commit
63ee6ef79a
@ -11,9 +11,16 @@ public class AudioDepacketizer {
|
||||
private LinkedBlockingQueue<ByteBufferDescriptor> decodedUnits =
|
||||
new LinkedBlockingQueue<ByteBufferDescriptor>(DU_LIMIT);
|
||||
|
||||
private AudioRenderer directSubmitRenderer;
|
||||
|
||||
// Sequencing state
|
||||
private short lastSequenceNumber;
|
||||
|
||||
public AudioDepacketizer(AudioRenderer directSubmitRenderer)
|
||||
{
|
||||
this.directSubmitRenderer = directSubmitRenderer;
|
||||
}
|
||||
|
||||
private void decodeData(byte[] data, int off, int len)
|
||||
{
|
||||
// Submit this data to the decoder
|
||||
@ -24,8 +31,10 @@ public class AudioDepacketizer {
|
||||
// Return value of decode is frames (shorts) decoded per channel
|
||||
decodeLen *= 2*OpusDecoder.getChannelCount();
|
||||
|
||||
// Put it on the decoded queue
|
||||
if (!decodedUnits.offer(new ByteBufferDescriptor(pcmData, 0, decodeLen))) {
|
||||
if (directSubmitRenderer != null) {
|
||||
directSubmitRenderer.playDecodedAudio(pcmData, 0, decodeLen);
|
||||
}
|
||||
else if (!decodedUnits.offer(new ByteBufferDescriptor(pcmData, 0, decodeLen))) {
|
||||
System.out.println("Audio player too slow! Forced to drop decoded samples");
|
||||
// Clear out the queue
|
||||
decodedUnits.clear();
|
||||
|
@ -1,6 +1,11 @@
|
||||
package com.limelight.nvstream.av.audio;
|
||||
|
||||
public interface AudioRenderer {
|
||||
// playDecodedAudio() is lightweight, so don't use an extra thread for playback
|
||||
public static final int CAPABILITY_DIRECT_SUBMIT = 0x1;
|
||||
|
||||
public int getCapabilities();
|
||||
|
||||
public void streamInitialized(int channelCount, int sampleRate);
|
||||
|
||||
public void playDecodedAudio(byte[] audioData, int offset, int length);
|
||||
|
@ -23,7 +23,7 @@ public class AudioStream {
|
||||
|
||||
private DatagramSocket rtp;
|
||||
|
||||
private AudioDepacketizer depacketizer = new AudioDepacketizer();
|
||||
private AudioDepacketizer depacketizer;
|
||||
|
||||
private LinkedList<Thread> threads = new LinkedList<Thread>();
|
||||
|
||||
@ -79,7 +79,9 @@ public class AudioStream {
|
||||
|
||||
startDepacketizerThread();
|
||||
|
||||
if ((streamListener.getCapabilities() & AudioRenderer.CAPABILITY_DIRECT_SUBMIT) == 0) {
|
||||
startDecoderThread();
|
||||
}
|
||||
|
||||
startUdpPingThread();
|
||||
}
|
||||
@ -102,6 +104,13 @@ public class AudioStream {
|
||||
}
|
||||
|
||||
streamListener.streamInitialized(OpusDecoder.getChannelCount(), OpusDecoder.getSampleRate());
|
||||
|
||||
if ((streamListener.getCapabilities() & AudioRenderer.CAPABILITY_DIRECT_SUBMIT) != 0) {
|
||||
depacketizer = new AudioDepacketizer(streamListener);
|
||||
}
|
||||
else {
|
||||
depacketizer = new AudioDepacketizer(null);
|
||||
}
|
||||
}
|
||||
|
||||
private void startDepacketizerThread()
|
||||
|
@ -7,6 +7,11 @@ public interface VideoDecoderRenderer {
|
||||
public static final int FLAG_FORCE_HARDWARE_DECODING = 0x2;
|
||||
public static final int FLAG_FORCE_SOFTWARE_DECODING = 0x4;
|
||||
|
||||
// SubmitDecodeUnit() is lightweight, so don't use an extra thread for decoding
|
||||
public static final int CAPABILITY_DIRECT_SUBMIT = 0x1;
|
||||
|
||||
public int getCapabilities();
|
||||
|
||||
public void setup(int width, int height, int redrawRate, Object renderTarget, int drFlags);
|
||||
|
||||
public void start();
|
||||
|
@ -22,12 +22,14 @@ public class VideoDepacketizer {
|
||||
private ByteBufferDescriptor cachedDesc = new ByteBufferDescriptor(null, 0, 0);
|
||||
|
||||
private ConnectionStatusListener controlListener;
|
||||
private VideoDecoderRenderer directSubmitDr;
|
||||
|
||||
private static final int DU_LIMIT = 7;
|
||||
private static final int DU_LIMIT = 15;
|
||||
private LinkedBlockingQueue<DecodeUnit> decodedUnits = new LinkedBlockingQueue<DecodeUnit>(DU_LIMIT);
|
||||
|
||||
public VideoDepacketizer(ConnectionStatusListener controlListener)
|
||||
public VideoDepacketizer(VideoDecoderRenderer directSubmitDr, ConnectionStatusListener controlListener)
|
||||
{
|
||||
this.directSubmitDr = directSubmitDr;
|
||||
this.controlListener = controlListener;
|
||||
}
|
||||
|
||||
@ -43,7 +45,11 @@ public class VideoDepacketizer {
|
||||
if (avcNalDataChain != null && avcNalDataLength != 0) {
|
||||
// Construct the H264 decode unit
|
||||
DecodeUnit du = new DecodeUnit(DecodeUnit.TYPE_H264, avcNalDataChain, avcNalDataLength, 0);
|
||||
if (!decodedUnits.offer(du)) {
|
||||
if (directSubmitDr != null) {
|
||||
// Submit directly to the decoder
|
||||
directSubmitDr.submitDecodeUnit(du);
|
||||
}
|
||||
else if (!decodedUnits.offer(du)) {
|
||||
// We need a new IDR frame since we're discarding data now
|
||||
System.out.println("Video decoder is too slow! Forced to drop decode units");
|
||||
decodedUnits.clear();
|
||||
|
@ -35,6 +35,7 @@ public class VideoStream {
|
||||
private LinkedList<Thread> threads = new LinkedList<Thread>();
|
||||
|
||||
private NvConnectionListener listener;
|
||||
private ConnectionStatusListener avConnListener;
|
||||
private VideoDepacketizer depacketizer;
|
||||
private StreamConfiguration streamConfig;
|
||||
|
||||
@ -47,7 +48,7 @@ public class VideoStream {
|
||||
{
|
||||
this.host = host;
|
||||
this.listener = listener;
|
||||
this.depacketizer = new VideoDepacketizer(avConnListener);
|
||||
this.avConnListener = avConnListener;
|
||||
this.streamConfig = streamConfig;
|
||||
}
|
||||
|
||||
@ -134,6 +135,13 @@ public class VideoStream {
|
||||
if (decRend != null) {
|
||||
decRend.setup(streamConfig.getWidth(), streamConfig.getHeight(),
|
||||
60, renderTarget, drFlags);
|
||||
|
||||
if ((decRend.getCapabilities() & VideoDecoderRenderer.CAPABILITY_DIRECT_SUBMIT) != 0) {
|
||||
depacketizer = new VideoDepacketizer(decRend, avConnListener);
|
||||
}
|
||||
else {
|
||||
depacketizer = new VideoDepacketizer(null, avConnListener);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -164,8 +172,10 @@ public class VideoStream {
|
||||
// Start the depacketizer thread to deal with the RTP data
|
||||
startDepacketizerThread();
|
||||
|
||||
// Start decoding the data we're receiving
|
||||
// Start a decode thread if we're not doing direct submit
|
||||
if ((decRend.getCapabilities() & VideoDecoderRenderer.CAPABILITY_DIRECT_SUBMIT) == 0) {
|
||||
startDecoderThread();
|
||||
}
|
||||
|
||||
// Start the renderer
|
||||
decRend.start();
|
||||
|
Loading…
x
Reference in New Issue
Block a user