mirror of
https://github.com/moonlight-stream/moonlight-embedded.git
synced 2026-04-20 23:30:37 +00:00
Update to new VideoDecoderRenderer API
This commit is contained in:
@@ -56,7 +56,7 @@ public class Limelight implements NvConnectionListener {
|
|||||||
/*
|
/*
|
||||||
* Creates a connection to the host and starts up the stream.
|
* Creates a connection to the host and starts up the stream.
|
||||||
*/
|
*/
|
||||||
private void startUp(StreamConfiguration streamConfig, List<String> inputs, String mappingFile, String audioDevice, boolean tests, boolean debug) {
|
private void startUp(StreamConfiguration streamConfig, List<String> inputs, String mappingFile, String audioDevice, boolean tests) {
|
||||||
if (tests) {
|
if (tests) {
|
||||||
boolean test = true;
|
boolean test = true;
|
||||||
String vm = System.getProperties().getProperty("java.vm.name");
|
String vm = System.getProperties().getProperty("java.vm.name");
|
||||||
@@ -105,7 +105,7 @@ public class Limelight implements NvConnectionListener {
|
|||||||
conn.start(PlatformBinding.getDeviceName(), null,
|
conn.start(PlatformBinding.getDeviceName(), null,
|
||||||
VideoDecoderRenderer.FLAG_PREFER_QUALITY,
|
VideoDecoderRenderer.FLAG_PREFER_QUALITY,
|
||||||
PlatformBinding.getAudioRenderer(audioDevice),
|
PlatformBinding.getAudioRenderer(audioDevice),
|
||||||
PlatformBinding.getVideoDecoderRenderer(debug));
|
PlatformBinding.getVideoDecoderRenderer());
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -405,7 +405,7 @@ public class Limelight implements NvConnectionListener {
|
|||||||
if (action.equals("fake"))
|
if (action.equals("fake"))
|
||||||
limelight.startUpFake(streamConfig, video);
|
limelight.startUpFake(streamConfig, video);
|
||||||
else
|
else
|
||||||
limelight.startUp(streamConfig, inputs, mapping, audio, tests, debug.intValue() <= Level.WARNING.intValue());
|
limelight.startUp(streamConfig, inputs, mapping, audio, tests);
|
||||||
} else if (action.equals("pair"))
|
} else if (action.equals("pair"))
|
||||||
limelight.pair();
|
limelight.pair();
|
||||||
else if (action.equals("list"))
|
else if (action.equals("list"))
|
||||||
|
|||||||
@@ -11,7 +11,6 @@ import com.limelight.binding.video.ImxDecoderRenderer;
|
|||||||
import com.limelight.binding.crypto.PcCryptoProvider;
|
import com.limelight.binding.crypto.PcCryptoProvider;
|
||||||
import com.limelight.binding.video.OmxDecoder;
|
import com.limelight.binding.video.OmxDecoder;
|
||||||
import com.limelight.binding.video.OmxDecoderRenderer;
|
import com.limelight.binding.video.OmxDecoderRenderer;
|
||||||
import com.limelight.binding.video.AbstractVideoRenderer;
|
|
||||||
import com.limelight.nvstream.av.audio.AudioDecoderRenderer;
|
import com.limelight.nvstream.av.audio.AudioDecoderRenderer;
|
||||||
import com.limelight.nvstream.av.video.VideoDecoderRenderer;
|
import com.limelight.nvstream.av.video.VideoDecoderRenderer;
|
||||||
import com.limelight.nvstream.http.LimelightCryptoProvider;
|
import com.limelight.nvstream.http.LimelightCryptoProvider;
|
||||||
@@ -27,14 +26,13 @@ public class PlatformBinding {
|
|||||||
* Gets an instance of a video decoder/renderer.
|
* Gets an instance of a video decoder/renderer.
|
||||||
* @return a video decoder and renderer
|
* @return a video decoder and renderer
|
||||||
*/
|
*/
|
||||||
public static VideoDecoderRenderer getVideoDecoderRenderer(boolean debug) {
|
public static VideoDecoderRenderer getVideoDecoderRenderer() {
|
||||||
AbstractVideoRenderer renderer = null;
|
VideoDecoderRenderer renderer = null;
|
||||||
if (OmxDecoder.load())
|
if (OmxDecoder.load())
|
||||||
renderer = new OmxDecoderRenderer();
|
renderer = new OmxDecoderRenderer();
|
||||||
else if (ImxDecoder.load())
|
else if (ImxDecoder.load())
|
||||||
renderer = new ImxDecoderRenderer();
|
renderer = new ImxDecoderRenderer();
|
||||||
|
|
||||||
renderer.debug = debug;
|
|
||||||
return renderer;
|
return renderer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,93 +0,0 @@
|
|||||||
package com.limelight.binding.video;
|
|
||||||
|
|
||||||
import com.limelight.LimeLog;
|
|
||||||
import com.limelight.nvstream.av.DecodeUnit;
|
|
||||||
import com.limelight.nvstream.av.video.VideoDecoderRenderer;
|
|
||||||
import com.limelight.nvstream.av.video.VideoDepacketizer;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Abstract implementation of a video decoder.
|
|
||||||
* @author Iwan Timmer
|
|
||||||
*/
|
|
||||||
public abstract class AbstractVideoRenderer implements VideoDecoderRenderer {
|
|
||||||
|
|
||||||
private Thread thread;
|
|
||||||
private boolean running;
|
|
||||||
|
|
||||||
private int dataSize;
|
|
||||||
private long last;
|
|
||||||
|
|
||||||
private long endToEndLatency;
|
|
||||||
private long decodeLatency;
|
|
||||||
private long packets;
|
|
||||||
private long maxLatency;
|
|
||||||
|
|
||||||
public boolean debug;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean start(final VideoDepacketizer depacketizer) {
|
|
||||||
last = System.currentTimeMillis();
|
|
||||||
thread = new Thread(new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
while (running) {
|
|
||||||
try {
|
|
||||||
DecodeUnit decodeUnit = depacketizer.takeNextDecodeUnit();
|
|
||||||
long latency = System.currentTimeMillis()-decodeUnit.getReceiveTimestamp();
|
|
||||||
endToEndLatency += latency;
|
|
||||||
|
|
||||||
dataSize += decodeUnit.getDataLength();
|
|
||||||
decodeUnit(decodeUnit);
|
|
||||||
|
|
||||||
latency = System.currentTimeMillis()-decodeUnit.getReceiveTimestamp();
|
|
||||||
decodeLatency += latency;
|
|
||||||
|
|
||||||
if (latency>maxLatency)
|
|
||||||
maxLatency = latency;
|
|
||||||
|
|
||||||
if (debug && System.currentTimeMillis()>last+2000) {
|
|
||||||
int bitrate = (dataSize/2)/1024;
|
|
||||||
System.out.println("Video " + bitrate + "kB/s " + maxLatency + "ms");
|
|
||||||
maxLatency = 0;
|
|
||||||
dataSize = 0;
|
|
||||||
last = System.currentTimeMillis();
|
|
||||||
}
|
|
||||||
depacketizer.freeDecodeUnit(decodeUnit);
|
|
||||||
} catch (InterruptedException ex) { }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
running = true;
|
|
||||||
thread.start();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void stop() {
|
|
||||||
running = false;
|
|
||||||
thread.interrupt();
|
|
||||||
try {
|
|
||||||
thread.join();
|
|
||||||
} catch (InterruptedException ex) {
|
|
||||||
LimeLog.severe(ex.getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public abstract void decodeUnit(DecodeUnit decodeUnit);
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getCapabilities() {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getAverageEndToEndLatency() {
|
|
||||||
return (int) (endToEndLatency / packets);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getAverageDecoderLatency() {
|
|
||||||
return (int) (decodeLatency / packets);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -3,6 +3,8 @@ package com.limelight.binding.video;
|
|||||||
import com.limelight.LimeLog;
|
import com.limelight.LimeLog;
|
||||||
import com.limelight.nvstream.av.ByteBufferDescriptor;
|
import com.limelight.nvstream.av.ByteBufferDescriptor;
|
||||||
import com.limelight.nvstream.av.DecodeUnit;
|
import com.limelight.nvstream.av.DecodeUnit;
|
||||||
|
import com.limelight.nvstream.av.video.VideoDecoderRenderer;
|
||||||
|
import com.limelight.nvstream.av.video.VideoDepacketizer;
|
||||||
import java.io.FileNotFoundException;
|
import java.io.FileNotFoundException;
|
||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@@ -12,13 +14,12 @@ import java.io.OutputStream;
|
|||||||
* Implementation of a video decoder and renderer.
|
* Implementation of a video decoder and renderer.
|
||||||
* @author Iwan Timmer
|
* @author Iwan Timmer
|
||||||
*/
|
*/
|
||||||
public class FakeVideoRenderer extends AbstractVideoRenderer {
|
public class FakeVideoRenderer extends VideoDecoderRenderer {
|
||||||
|
|
||||||
private OutputStream out;
|
private OutputStream out;
|
||||||
|
|
||||||
public FakeVideoRenderer(String videoFile) {
|
public FakeVideoRenderer(String videoFile) {
|
||||||
try {
|
try {
|
||||||
this.debug = true;
|
|
||||||
if (videoFile!=null)
|
if (videoFile!=null)
|
||||||
out = new FileOutputStream(videoFile);
|
out = new FileOutputStream(videoFile);
|
||||||
} catch (FileNotFoundException e) {
|
} catch (FileNotFoundException e) {
|
||||||
@@ -34,8 +35,6 @@ public class FakeVideoRenderer extends AbstractVideoRenderer {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void stop() {
|
public void stop() {
|
||||||
super.stop();
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (out!=null)
|
if (out!=null)
|
||||||
out.close();
|
out.close();
|
||||||
@@ -49,7 +48,7 @@ public class FakeVideoRenderer extends AbstractVideoRenderer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void decodeUnit(DecodeUnit decodeUnit) {
|
public void directSubmitDecodeUnit(DecodeUnit decodeUnit) {
|
||||||
if (out!=null) {
|
if (out!=null) {
|
||||||
try {
|
try {
|
||||||
for (ByteBufferDescriptor buf:decodeUnit.getBufferList())
|
for (ByteBufferDescriptor buf:decodeUnit.getBufferList())
|
||||||
@@ -59,5 +58,15 @@ public class FakeVideoRenderer extends AbstractVideoRenderer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean start(VideoDepacketizer depacketizer) {
|
||||||
|
throw new UnsupportedOperationException("CAPABILITY_DIRECT_SUBMIT requires directSubmitDecodeUnit()");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getCapabilities() {
|
||||||
|
return CAPABILITY_DIRECT_SUBMIT;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,8 @@ package com.limelight.binding.video;
|
|||||||
import com.limelight.LimeLog;
|
import com.limelight.LimeLog;
|
||||||
import com.limelight.nvstream.av.ByteBufferDescriptor;
|
import com.limelight.nvstream.av.ByteBufferDescriptor;
|
||||||
import com.limelight.nvstream.av.DecodeUnit;
|
import com.limelight.nvstream.av.DecodeUnit;
|
||||||
|
import com.limelight.nvstream.av.video.VideoDecoderRenderer;
|
||||||
|
import com.limelight.nvstream.av.video.VideoDepacketizer;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@@ -10,7 +12,7 @@ import java.util.List;
|
|||||||
* Implementation of a video decoder and renderer.
|
* Implementation of a video decoder and renderer.
|
||||||
* @author Iwan Timmer
|
* @author Iwan Timmer
|
||||||
*/
|
*/
|
||||||
public class ImxDecoderRenderer extends AbstractVideoRenderer {
|
public class ImxDecoderRenderer extends VideoDecoderRenderer {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean setup(int width, int height, int redrawRate, Object renderTarget, int drFlags) {
|
public boolean setup(int width, int height, int redrawRate, Object renderTarget, int drFlags) {
|
||||||
@@ -21,9 +23,12 @@ public class ImxDecoderRenderer extends AbstractVideoRenderer {
|
|||||||
public void release() {
|
public void release() {
|
||||||
ImxDecoder.destroy();
|
ImxDecoder.destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void stop() { }
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void decodeUnit(DecodeUnit decodeUnit) {
|
public void directSubmitDecodeUnit(DecodeUnit decodeUnit) {
|
||||||
List<ByteBufferDescriptor> units = decodeUnit.getBufferList();
|
List<ByteBufferDescriptor> units = decodeUnit.getBufferList();
|
||||||
|
|
||||||
boolean ok = true;
|
boolean ok = true;
|
||||||
@@ -38,4 +43,15 @@ public class ImxDecoderRenderer extends AbstractVideoRenderer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean start(VideoDepacketizer depacketizer) {
|
||||||
|
throw new UnsupportedOperationException("CAPABILITY_DIRECT_SUBMIT requires directSubmitDecodeUnit()");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getCapabilities() {
|
||||||
|
return CAPABILITY_DIRECT_SUBMIT;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,8 @@ package com.limelight.binding.video;
|
|||||||
import com.limelight.LimeLog;
|
import com.limelight.LimeLog;
|
||||||
import com.limelight.nvstream.av.ByteBufferDescriptor;
|
import com.limelight.nvstream.av.ByteBufferDescriptor;
|
||||||
import com.limelight.nvstream.av.DecodeUnit;
|
import com.limelight.nvstream.av.DecodeUnit;
|
||||||
|
import com.limelight.nvstream.av.video.VideoDecoderRenderer;
|
||||||
|
import com.limelight.nvstream.av.video.VideoDepacketizer;
|
||||||
|
|
||||||
import org.jcodec.codecs.h264.io.model.SeqParameterSet;
|
import org.jcodec.codecs.h264.io.model.SeqParameterSet;
|
||||||
import org.jcodec.codecs.h264.io.model.VUIParameters;
|
import org.jcodec.codecs.h264.io.model.VUIParameters;
|
||||||
@@ -14,10 +16,8 @@ import java.nio.ByteBuffer;
|
|||||||
* Implementation of a video decoder and renderer.
|
* Implementation of a video decoder and renderer.
|
||||||
* @author Iwan Timmer
|
* @author Iwan Timmer
|
||||||
*/
|
*/
|
||||||
public class OmxDecoderRenderer extends AbstractVideoRenderer {
|
public class OmxDecoderRenderer extends VideoDecoderRenderer {
|
||||||
|
|
||||||
private final static byte[] BITSTREAM_RESTRICTIONS = new byte[] {(byte) 0xF1, (byte) 0x83, 0x2A, 0x00};
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean setup(int width, int height, int redrawRate, Object renderTarget, int drFlags) {
|
public boolean setup(int width, int height, int redrawRate, Object renderTarget, int drFlags) {
|
||||||
return OmxDecoder.init() == 0;
|
return OmxDecoder.init() == 0;
|
||||||
@@ -25,7 +25,6 @@ public class OmxDecoderRenderer extends AbstractVideoRenderer {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void stop() {
|
public void stop() {
|
||||||
super.stop();
|
|
||||||
OmxDecoder.stop();
|
OmxDecoder.stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -35,7 +34,7 @@ public class OmxDecoderRenderer extends AbstractVideoRenderer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void decodeUnit(DecodeUnit decodeUnit) {
|
public void directSubmitDecodeUnit(DecodeUnit decodeUnit) {
|
||||||
List<ByteBufferDescriptor> units = decodeUnit.getBufferList();
|
List<ByteBufferDescriptor> units = decodeUnit.getBufferList();
|
||||||
|
|
||||||
ByteBufferDescriptor header = units.get(0);
|
ByteBufferDescriptor header = units.get(0);
|
||||||
@@ -87,4 +86,14 @@ public class OmxDecoderRenderer extends AbstractVideoRenderer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean start(VideoDepacketizer depacketizer) {
|
||||||
|
throw new UnsupportedOperationException("CAPABILITY_DIRECT_SUBMIT requires directSubmitDecodeUnit()");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getCapabilities() {
|
||||||
|
return CAPABILITY_DIRECT_SUBMIT;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user