mirror of
https://github.com/moonlight-stream/moonlight-android.git
synced 2026-04-22 08:20:12 +00:00
WIP video. Remove WRITE_EXTERNAL_STORAGE permission.
This commit is contained in:
@@ -10,7 +10,6 @@
|
|||||||
|
|
||||||
<uses-permission android:name="android.permission.INTERNET" />
|
<uses-permission android:name="android.permission.INTERNET" />
|
||||||
<uses-permission android:name="android.permission.RECORD_AUDIO" />
|
<uses-permission android:name="android.permission.RECORD_AUDIO" />
|
||||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
|
|
||||||
|
|
||||||
<application
|
<application
|
||||||
android:allowBackup="true"
|
android:allowBackup="true"
|
||||||
|
|||||||
@@ -113,7 +113,7 @@ or to a theme attribute in the form "<code>?[<i>package</i>:][<i>type</i>:]<i>na
|
|||||||
|
|
||||||
<p>Must be a reference to another resource, in the form "<code>@[+][<i>package</i>:]<i>type</i>:<i>name</i></code>"
|
<p>Must be a reference to another resource, in the form "<code>@[+][<i>package</i>:]<i>type</i>:<i>name</i></code>"
|
||||||
or to a theme attribute in the form "<code>?[<i>package</i>:][<i>type</i>:]<i>name</i></code>".
|
or to a theme attribute in the form "<code>?[<i>package</i>:][<i>type</i>:]<i>name</i></code>".
|
||||||
@attr name com.limelight:buttonBarButtonStyle
|
@attr name android:buttonBarButtonStyle
|
||||||
*/
|
*/
|
||||||
public static final int ButtonBarContainerTheme_buttonBarButtonStyle = 1;
|
public static final int ButtonBarContainerTheme_buttonBarButtonStyle = 1;
|
||||||
/**
|
/**
|
||||||
@@ -123,7 +123,7 @@ or to a theme attribute in the form "<code>?[<i>package</i>:][<i>type</i>:]<i>na
|
|||||||
|
|
||||||
<p>Must be a reference to another resource, in the form "<code>@[+][<i>package</i>:]<i>type</i>:<i>name</i></code>"
|
<p>Must be a reference to another resource, in the form "<code>@[+][<i>package</i>:]<i>type</i>:<i>name</i></code>"
|
||||||
or to a theme attribute in the form "<code>?[<i>package</i>:][<i>type</i>:]<i>name</i></code>".
|
or to a theme attribute in the form "<code>?[<i>package</i>:][<i>type</i>:]<i>name</i></code>".
|
||||||
@attr name com.limelight:buttonBarStyle
|
@attr name android:buttonBarStyle
|
||||||
*/
|
*/
|
||||||
public static final int ButtonBarContainerTheme_buttonBarStyle = 0;
|
public static final int ButtonBarContainerTheme_buttonBarStyle = 0;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -6,11 +6,13 @@ import java.io.FileNotFoundException;
|
|||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
import java.net.DatagramPacket;
|
||||||
import java.net.DatagramSocket;
|
import java.net.DatagramSocket;
|
||||||
import java.net.Socket;
|
import java.net.Socket;
|
||||||
import java.net.SocketException;
|
import java.net.SocketException;
|
||||||
import java.net.UnknownHostException;
|
import java.net.UnknownHostException;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
|
import java.nio.ByteOrder;
|
||||||
|
|
||||||
import jlibrtp.DataFrame;
|
import jlibrtp.DataFrame;
|
||||||
import jlibrtp.Participant;
|
import jlibrtp.Participant;
|
||||||
@@ -30,7 +32,6 @@ public class NvVideoStream implements RTPAppIntf {
|
|||||||
private static final int FRAME_RATE = 60;
|
private static final int FRAME_RATE = 60;
|
||||||
private ByteBuffer[] decoderInputBuffers = null;
|
private ByteBuffer[] decoderInputBuffers = null;
|
||||||
private MediaCodec decoder;
|
private MediaCodec decoder;
|
||||||
private BufferedOutputStream output;
|
|
||||||
|
|
||||||
private int frameIndex = 0;
|
private int frameIndex = 0;
|
||||||
|
|
||||||
@@ -39,12 +40,7 @@ public class NvVideoStream implements RTPAppIntf {
|
|||||||
Socket s = new Socket(host, FIRST_FRAME_PORT);
|
Socket s = new Socket(host, FIRST_FRAME_PORT);
|
||||||
return s.getInputStream();
|
return s.getInputStream();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void openFile(String file) throws FileNotFoundException
|
|
||||||
{
|
|
||||||
output = new BufferedOutputStream(new FileOutputStream(new File(file)));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void startVideoStream(final String host, final Surface surface)
|
public void startVideoStream(final String host, final Surface surface)
|
||||||
{
|
{
|
||||||
new Thread(new Runnable() {
|
new Thread(new Runnable() {
|
||||||
@@ -105,13 +101,80 @@ public class NvVideoStream implements RTPAppIntf {
|
|||||||
frameIndex++;
|
frameIndex++;
|
||||||
}
|
}
|
||||||
|
|
||||||
RTPSession session = new RTPSession(rtp, rtcp);
|
final RTPSession session = new RTPSession(rtp, rtcp);
|
||||||
session.addParticipant(new Participant(host, RTP_PORT, RTCP_PORT));
|
session.addParticipant(new Participant(host, RTP_PORT, RTCP_PORT));
|
||||||
session.RTPSessionRegister(NvVideoStream.this, null, null);
|
//session.RTPSessionRegister(NvVideoStream.this, null, null);
|
||||||
|
|
||||||
|
// Ping thread
|
||||||
|
new Thread(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
// PING in ASCII
|
||||||
|
final byte[] pingPacket = new byte[] {0x50, 0x49, 0x4E, 0x47};
|
||||||
|
|
||||||
|
// RTP payload type is 127 (dynamic)
|
||||||
|
session.payloadType(127);
|
||||||
|
|
||||||
|
// Send PING every 100 ms
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
session.sendData(pingPacket);
|
||||||
|
|
||||||
|
try {
|
||||||
|
Thread.sleep(100);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}).start();
|
||||||
|
|
||||||
|
// Receive thread
|
||||||
|
new Thread(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
byte[] packet = new byte[1500];
|
||||||
|
|
||||||
|
// Send PING every 100 ms
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
DatagramPacket dp = new DatagramPacket(packet, 0, packet.length);
|
||||||
|
|
||||||
|
try {
|
||||||
|
rtp.receive(dp);
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
System.out.println("in receiveData");
|
||||||
|
int inputIndex = decoder.dequeueInputBuffer(-1);
|
||||||
|
if (inputIndex >= 0)
|
||||||
|
{
|
||||||
|
ByteBuffer buf = decoderInputBuffers[inputIndex];
|
||||||
|
NvVideoPacket nvVideo = new NvVideoPacket(dp.getData());
|
||||||
|
|
||||||
|
buf.clear();
|
||||||
|
buf.put(nvVideo.data);
|
||||||
|
|
||||||
|
System.out.println(nvVideo);
|
||||||
|
if (nvVideo.length == 0xc803) {
|
||||||
|
decoder.queueInputBuffer(inputIndex,
|
||||||
|
0, nvVideo.length,
|
||||||
|
0, 0);
|
||||||
|
frameIndex++;
|
||||||
|
} else {
|
||||||
|
decoder.queueInputBuffer(inputIndex,
|
||||||
|
0, 0,
|
||||||
|
0, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}).start();
|
||||||
|
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
System.out.println("in background infinite loop");
|
|
||||||
BufferInfo info = new BufferInfo();
|
BufferInfo info = new BufferInfo();
|
||||||
System.out.println("dequeuing outputbuffer");
|
System.out.println("dequeuing outputbuffer");
|
||||||
int outIndex = decoder.dequeueOutputBuffer(info, -1);
|
int outIndex = decoder.dequeueOutputBuffer(info, -1);
|
||||||
@@ -144,44 +207,6 @@ public class NvVideoStream implements RTPAppIntf {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void receiveData(DataFrame frame, Participant participant) {
|
public void receiveData(DataFrame frame, Participant participant) {
|
||||||
System.out.println("in receiveData");
|
|
||||||
int inputIndex = decoder.dequeueInputBuffer(-1);
|
|
||||||
if (inputIndex >= 0)
|
|
||||||
{
|
|
||||||
ByteBuffer buf = decoderInputBuffers[inputIndex];
|
|
||||||
|
|
||||||
buf.clear();
|
|
||||||
|
|
||||||
buf.put(frame.getConcatenatedData());
|
|
||||||
|
|
||||||
if (buf.position() != 1024)
|
|
||||||
{
|
|
||||||
System.out.println("Data length: "+buf.position());
|
|
||||||
System.out.println(buf.get()+" "+buf.get()+" "+buf.get());
|
|
||||||
}
|
|
||||||
|
|
||||||
byte[] nvHeader = new byte[32];
|
|
||||||
byte[] oldBuffer = buf.array();
|
|
||||||
byte[] newBuffer = new byte[oldBuffer.length - nvHeader.length];
|
|
||||||
System.out.println("removing crap from buffer");
|
|
||||||
for (int i = 0; i < oldBuffer.length; i++) {
|
|
||||||
if (i < nvHeader.length) {
|
|
||||||
nvHeader[i] = oldBuffer[i];
|
|
||||||
} else {
|
|
||||||
newBuffer[i - nvHeader.length] = oldBuffer[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
System.out.println("nvHeader: " + nvHeader.length + "oldBuffer: " + oldBuffer.length +
|
|
||||||
"newBuffer: " + newBuffer.length);
|
|
||||||
buf.clear();
|
|
||||||
buf.put(newBuffer);
|
|
||||||
if (oldBuffer.length == 0xc803) {
|
|
||||||
decoder.queueInputBuffer(inputIndex,
|
|
||||||
0, buf.position(),
|
|
||||||
0, 0);
|
|
||||||
frameIndex++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -199,4 +224,33 @@ public class NvVideoStream implements RTPAppIntf {
|
|||||||
private static long computePresentationTime(int frameIndex) {
|
private static long computePresentationTime(int frameIndex) {
|
||||||
return 132 + frameIndex * 1000000 / FRAME_RATE;
|
return 132 + frameIndex * 1000000 / FRAME_RATE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class NvVideoPacket {
|
||||||
|
byte[] preamble;
|
||||||
|
short length;
|
||||||
|
byte[] extra;
|
||||||
|
byte[] data;
|
||||||
|
|
||||||
|
public NvVideoPacket(byte[] payload)
|
||||||
|
{
|
||||||
|
ByteBuffer bb = ByteBuffer.wrap(payload).order(ByteOrder.LITTLE_ENDIAN);
|
||||||
|
|
||||||
|
preamble = new byte[12+16];
|
||||||
|
extra = new byte[38];
|
||||||
|
|
||||||
|
bb.get(preamble);
|
||||||
|
length = bb.getShort();
|
||||||
|
bb.get(extra);
|
||||||
|
data = new byte[length];
|
||||||
|
|
||||||
|
if (bb.remaining() + length <= payload.length)
|
||||||
|
bb.get(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toString()
|
||||||
|
{
|
||||||
|
return "";//String.format("Length: %d | %02x %02x %02x %02x %02x %02x %02x %02x",
|
||||||
|
//length, data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7]);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user