move everything out of subdirectory

This commit is contained in:
Aaron Neyer
2013-12-15 14:12:57 -05:00
parent 71aacf1305
commit fed46a2a49
151 changed files with 191 additions and 2359 deletions
@@ -0,0 +1,27 @@
package com.limelight.binding;
import java.net.InetAddress;
import java.net.UnknownHostException;
import com.limelight.binding.audio.JavaxAudioRenderer;
import com.limelight.binding.video.SwingCpuDecoderRenderer;
import com.limelight.nvstream.av.audio.AudioRenderer;
import com.limelight.nvstream.av.video.VideoDecoderRenderer;
public class PlatformBinding {
public static VideoDecoderRenderer getVideoDecoderRenderer() {
return new SwingCpuDecoderRenderer();
}
public static String getDeviceName() {
try {
return InetAddress.getLocalHost().getHostName();
} catch (UnknownHostException e) {
return "LimelightPC";
}
}
public static AudioRenderer getAudioRenderer() {
return new JavaxAudioRenderer();
}
}
@@ -0,0 +1,52 @@
package com.limelight.binding.audio;
import java.nio.ByteBuffer;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.SourceDataLine;
import com.limelight.nvstream.av.audio.AudioRenderer;
import com.limelight.nvstream.av.audio.OpusDecoder;
public class JavaxAudioRenderer implements AudioRenderer {
private SourceDataLine soundLine;
@Override
public void playDecodedAudio(short[] pcmData, int offset, int length) {
if (soundLine != null) {
byte[] pcmDataBytes = new byte[length * 2];
ByteBuffer.wrap(pcmDataBytes).asShortBuffer().put(pcmData, offset, length);
if (soundLine.available() < length) {
soundLine.write(pcmDataBytes, 0, soundLine.available());
}
else {
soundLine.write(pcmDataBytes, 0, pcmDataBytes.length);
}
}
}
@Override
public void streamClosing() {
if (soundLine != null) {
soundLine.close();
}
}
@Override
public void streamInitialized(int channelCount, int sampleRate) {
AudioFormat audioFormat = new AudioFormat(sampleRate, 16, channelCount, true, true);
DataLine.Info info = new DataLine.Info(SourceDataLine.class, audioFormat, OpusDecoder.getMaxOutputShorts());
try {
soundLine = (SourceDataLine) AudioSystem.getLine(info);
soundLine.open(audioFormat, OpusDecoder.getMaxOutputShorts()*4*2);
soundLine.start();
} catch (LineUnavailableException e) {
soundLine = null;
}
}
}
@@ -0,0 +1,159 @@
package com.limelight.binding.video;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferInt;
import java.nio.ByteBuffer;
import javax.swing.JFrame;
import com.limelight.nvstream.av.ByteBufferDescriptor;
import com.limelight.nvstream.av.DecodeUnit;
import com.limelight.nvstream.av.video.VideoDecoderRenderer;
import com.limelight.nvstream.av.video.cpu.AvcDecoder;
public class SwingCpuDecoderRenderer implements VideoDecoderRenderer {
private Thread rendererThread;
private int targetFps;
private int width, height;
private Graphics graphics;
private JFrame frame;
private BufferedImage image;
private static final int DECODER_BUFFER_SIZE = 92*1024;
private ByteBuffer decoderBuffer;
// Only sleep if the difference is above this value
private static final int WAIT_CEILING_MS = 8;
@Override
public void setup(int width, int height, Object renderTarget, int drFlags) {
this.targetFps = 30;
this.width = width;
this.height = height;
// Single threaded low latency decode is ideal
int avcFlags = AvcDecoder.LOW_LATENCY_DECODE;
int threadCount = 1;
// Hack to work around the bad Java native library loader
// which can't resolve native library dependencies
if (System.getProperty("os.name").contains("Windows")) {
System.loadLibrary("avutil-52");
System.loadLibrary("postproc-52");
System.loadLibrary("pthreadVC2");
}
int err = AvcDecoder.init(width, height, avcFlags, threadCount);
if (err != 0) {
throw new IllegalStateException("AVC decoder initialization failure: "+err);
}
frame = (JFrame)renderTarget;
graphics = frame.getGraphics();
image = new BufferedImage(width, height,
BufferedImage.TYPE_INT_BGR);
decoderBuffer = ByteBuffer.allocate(DECODER_BUFFER_SIZE + AvcDecoder.getInputPaddingSize());
System.out.println("Using software decoding");
}
@Override
public void start() {
rendererThread = new Thread() {
@Override
public void run() {
long nextFrameTime = System.currentTimeMillis();
int[] imageBuffer = ((DataBufferInt)image.getRaster().getDataBuffer()).getData();
while (!isInterrupted())
{
long diff = nextFrameTime - System.currentTimeMillis();
if (diff < WAIT_CEILING_MS) {
// We must call Thread.sleep in order to be interruptable
diff = 0;
}
try {
Thread.sleep(diff);
} catch (InterruptedException e) {
return;
}
nextFrameTime = computePresentationTimeMs(targetFps);
double widthScale = (double)frame.getWidth() / width;
double heightScale = (double)frame.getHeight() / height;
double lowerScale = Math.min(widthScale, heightScale);
int newWidth = (int)(width * lowerScale);
int newHeight = (int)(height * lowerScale);
int dx1 = 0;
int dy1 = 0;
if (frame.getWidth() > newWidth) {
dx1 = (frame.getWidth()-newWidth)/4;
}
if (frame.getHeight() > newHeight) {
dy1 = (frame.getHeight()-newHeight)/4;
}
if (AvcDecoder.getRgbFrameInt(imageBuffer, imageBuffer.length)) {
graphics.drawImage(image, dx1, dy1, dx1+newWidth, dy1+newHeight, 0, 0, width, height, null);
}
}
}
};
rendererThread.setName("Video - Renderer (CPU)");
rendererThread.start();
}
private long computePresentationTimeMs(int frameRate) {
return System.currentTimeMillis() + (1000 / frameRate);
}
@Override
public void stop() {
rendererThread.interrupt();
try {
rendererThread.join();
} catch (InterruptedException e) { }
}
@Override
public void release() {
AvcDecoder.destroy();
}
@Override
public boolean submitDecodeUnit(DecodeUnit decodeUnit) {
byte[] data;
// Use the reserved decoder buffer if this decode unit will fit
if (decodeUnit.getDataLength() <= DECODER_BUFFER_SIZE) {
decoderBuffer.clear();
for (ByteBufferDescriptor bbd : decodeUnit.getBufferList()) {
decoderBuffer.put(bbd.data, bbd.offset, bbd.length);
}
data = decoderBuffer.array();
}
else {
data = new byte[decodeUnit.getDataLength()+AvcDecoder.getInputPaddingSize()];
int offset = 0;
for (ByteBufferDescriptor bbd : decodeUnit.getBufferList()) {
System.arraycopy(bbd.data, bbd.offset, data, offset, bbd.length);
offset += bbd.length;
}
}
return (AvcDecoder.decode(data, 0, decodeUnit.getDataLength()) == 0);
}
}