mirror of
https://github.com/moonlight-stream/moonlight-android.git
synced 2025-07-20 03:23:07 +00:00
Rename AvBufferX -> AvByteBufferX and create AvShortBufferX
This commit is contained in:
parent
62a9040cb8
commit
34e87ca899
@ -3,29 +3,22 @@ package com.limelight.nvstream;
|
||||
import java.io.IOException;
|
||||
import java.net.DatagramPacket;
|
||||
import java.net.DatagramSocket;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.SocketException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
|
||||
import jlibrtp.Participant;
|
||||
import jlibrtp.RTPSession;
|
||||
|
||||
import com.limelight.nvstream.av.AvBufferDescriptor;
|
||||
import com.limelight.nvstream.av.AvBufferPool;
|
||||
import com.limelight.nvstream.av.AvDecodeUnit;
|
||||
import com.limelight.nvstream.av.AvByteBufferDescriptor;
|
||||
import com.limelight.nvstream.av.AvByteBufferPool;
|
||||
import com.limelight.nvstream.av.AvRtpPacket;
|
||||
import com.limelight.nvstream.av.AvShortBufferDescriptor;
|
||||
import com.limelight.nvstream.av.audio.AvAudioDepacketizer;
|
||||
import com.limelight.nvstream.av.audio.OpusDecoder;
|
||||
|
||||
import android.media.AudioFormat;
|
||||
import android.media.AudioManager;
|
||||
import android.media.AudioTrack;
|
||||
import android.media.MediaCodec;
|
||||
import android.media.MediaFormat;
|
||||
import android.net.rtp.AudioGroup;
|
||||
import android.net.rtp.AudioStream;
|
||||
import android.view.Surface;
|
||||
|
||||
public class NvAudioStream {
|
||||
public static final int RTP_PORT = 48000;
|
||||
@ -40,7 +33,7 @@ public class NvAudioStream {
|
||||
|
||||
private AvAudioDepacketizer depacketizer = new AvAudioDepacketizer();
|
||||
|
||||
private AvBufferPool pool = new AvBufferPool(1500);
|
||||
private AvByteBufferPool pool = new AvByteBufferPool(1500);
|
||||
|
||||
public void startAudioStream(final String host)
|
||||
{
|
||||
@ -147,7 +140,8 @@ public class NvAudioStream {
|
||||
public void run() {
|
||||
for (;;)
|
||||
{
|
||||
short[] samples;
|
||||
AvShortBufferDescriptor samples;
|
||||
|
||||
try {
|
||||
samples = depacketizer.getNextDecodedData();
|
||||
} catch (InterruptedException e) {
|
||||
@ -155,7 +149,7 @@ public class NvAudioStream {
|
||||
return;
|
||||
}
|
||||
|
||||
track.write(samples, 0, samples.length);
|
||||
track.write(samples.data, samples.offset, samples.length);
|
||||
}
|
||||
}
|
||||
}).start();
|
||||
@ -168,7 +162,7 @@ public class NvAudioStream {
|
||||
@Override
|
||||
public void run() {
|
||||
DatagramPacket packet = new DatagramPacket(pool.allocate(), 1500);
|
||||
AvBufferDescriptor desc = new AvBufferDescriptor(null, 0, 0);
|
||||
AvByteBufferDescriptor desc = new AvByteBufferDescriptor(null, 0, 0);
|
||||
|
||||
for (;;)
|
||||
{
|
||||
|
@ -10,8 +10,8 @@ import java.net.UnknownHostException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
|
||||
import com.limelight.nvstream.av.AvBufferDescriptor;
|
||||
import com.limelight.nvstream.av.AvBufferPool;
|
||||
import com.limelight.nvstream.av.AvByteBufferDescriptor;
|
||||
import com.limelight.nvstream.av.AvByteBufferPool;
|
||||
import com.limelight.nvstream.av.AvDecodeUnit;
|
||||
import com.limelight.nvstream.av.AvRtpPacket;
|
||||
import com.limelight.nvstream.av.video.AvVideoDepacketizer;
|
||||
@ -37,7 +37,7 @@ public class NvVideoStream {
|
||||
private RTPSession session;
|
||||
private DatagramSocket rtp;
|
||||
|
||||
private AvBufferPool pool = new AvBufferPool(1500);
|
||||
private AvByteBufferPool pool = new AvByteBufferPool(1500);
|
||||
|
||||
private AvVideoDepacketizer depacketizer = new AvVideoDepacketizer();
|
||||
|
||||
@ -176,7 +176,7 @@ public class NvVideoStream {
|
||||
buf.clear();
|
||||
|
||||
// Copy data from our buffer list into the input buffer
|
||||
for (AvBufferDescriptor desc : du.getBufferList())
|
||||
for (AvByteBufferDescriptor desc : du.getBufferList())
|
||||
{
|
||||
buf.put(desc.data, desc.offset, desc.length);
|
||||
|
||||
@ -234,7 +234,7 @@ public class NvVideoStream {
|
||||
@Override
|
||||
public void run() {
|
||||
DatagramPacket packet = new DatagramPacket(pool.allocate(), 1500);
|
||||
AvBufferDescriptor desc = new AvBufferDescriptor(null, 0, 0);
|
||||
AvByteBufferDescriptor desc = new AvByteBufferDescriptor(null, 0, 0);
|
||||
|
||||
for (;;)
|
||||
{
|
||||
|
@ -1,18 +1,18 @@
|
||||
package com.limelight.nvstream.av;
|
||||
|
||||
public class AvBufferDescriptor {
|
||||
public class AvByteBufferDescriptor {
|
||||
public byte[] data;
|
||||
public int offset;
|
||||
public int length;
|
||||
|
||||
public AvBufferDescriptor(byte[] data, int offset, int length)
|
||||
public AvByteBufferDescriptor(byte[] data, int offset, int length)
|
||||
{
|
||||
this.data = data;
|
||||
this.offset = offset;
|
||||
this.length = length;
|
||||
}
|
||||
|
||||
public AvBufferDescriptor(AvBufferDescriptor desc)
|
||||
public AvByteBufferDescriptor(AvByteBufferDescriptor desc)
|
||||
{
|
||||
this.data = desc.data;
|
||||
this.offset = desc.offset;
|
@ -2,11 +2,11 @@ package com.limelight.nvstream.av;
|
||||
|
||||
import java.util.LinkedList;
|
||||
|
||||
public class AvBufferPool {
|
||||
public class AvByteBufferPool {
|
||||
private LinkedList<byte[]> bufferList = new LinkedList<byte[]>();
|
||||
private int bufferSize;
|
||||
|
||||
public AvBufferPool(int size)
|
||||
public AvByteBufferPool(int size)
|
||||
{
|
||||
this.bufferSize = size;
|
||||
}
|
@ -8,11 +8,11 @@ public class AvDecodeUnit {
|
||||
public static final int TYPE_OPUS = 2;
|
||||
|
||||
private int type;
|
||||
private List<AvBufferDescriptor> bufferList;
|
||||
private List<AvByteBufferDescriptor> bufferList;
|
||||
private int dataLength;
|
||||
private int flags;
|
||||
|
||||
public AvDecodeUnit(int type, List<AvBufferDescriptor> bufferList, int dataLength, int flags)
|
||||
public AvDecodeUnit(int type, List<AvByteBufferDescriptor> bufferList, int dataLength, int flags)
|
||||
{
|
||||
this.type = type;
|
||||
this.bufferList = bufferList;
|
||||
@ -30,7 +30,7 @@ public class AvDecodeUnit {
|
||||
return flags;
|
||||
}
|
||||
|
||||
public List<AvBufferDescriptor> getBufferList()
|
||||
public List<AvByteBufferDescriptor> getBufferList()
|
||||
{
|
||||
return bufferList;
|
||||
}
|
||||
|
@ -6,11 +6,11 @@ public class AvRtpPacket {
|
||||
|
||||
private byte packetType;
|
||||
private short seqNum;
|
||||
private AvBufferDescriptor buffer;
|
||||
private AvByteBufferDescriptor buffer;
|
||||
|
||||
public AvRtpPacket(AvBufferDescriptor buffer)
|
||||
public AvRtpPacket(AvByteBufferDescriptor buffer)
|
||||
{
|
||||
this.buffer = new AvBufferDescriptor(buffer);
|
||||
this.buffer = new AvByteBufferDescriptor(buffer);
|
||||
|
||||
ByteBuffer bb = ByteBuffer.wrap(buffer.data, buffer.offset, buffer.length);
|
||||
|
||||
@ -34,8 +34,8 @@ public class AvRtpPacket {
|
||||
return seqNum;
|
||||
}
|
||||
|
||||
public AvBufferDescriptor getNewPayloadDescriptor()
|
||||
public AvByteBufferDescriptor getNewPayloadDescriptor()
|
||||
{
|
||||
return new AvBufferDescriptor(buffer.data, buffer.offset+12, buffer.length-12);
|
||||
return new AvByteBufferDescriptor(buffer.data, buffer.offset+12, buffer.length-12);
|
||||
}
|
||||
}
|
||||
|
21
src/com/limelight/nvstream/av/AvShortBufferDescriptor.java
Normal file
21
src/com/limelight/nvstream/av/AvShortBufferDescriptor.java
Normal file
@ -0,0 +1,21 @@
|
||||
package com.limelight.nvstream.av;
|
||||
|
||||
public class AvShortBufferDescriptor {
|
||||
public short[] data;
|
||||
public int offset;
|
||||
public int length;
|
||||
|
||||
public AvShortBufferDescriptor(short[] data, int offset, int length)
|
||||
{
|
||||
this.data = data;
|
||||
this.offset = offset;
|
||||
this.length = length;
|
||||
}
|
||||
|
||||
public AvShortBufferDescriptor(AvShortBufferDescriptor desc)
|
||||
{
|
||||
this.data = desc.data;
|
||||
this.offset = desc.offset;
|
||||
this.length = desc.length;
|
||||
}
|
||||
}
|
30
src/com/limelight/nvstream/av/AvShortBufferPool.java
Normal file
30
src/com/limelight/nvstream/av/AvShortBufferPool.java
Normal file
@ -0,0 +1,30 @@
|
||||
package com.limelight.nvstream.av;
|
||||
|
||||
import java.util.LinkedList;
|
||||
|
||||
public class AvShortBufferPool {
|
||||
private LinkedList<short[]> bufferList = new LinkedList<short[]>();
|
||||
private int bufferSize;
|
||||
|
||||
public AvShortBufferPool(int size)
|
||||
{
|
||||
this.bufferSize = size;
|
||||
}
|
||||
|
||||
public synchronized short[] allocate()
|
||||
{
|
||||
if (bufferList.isEmpty())
|
||||
{
|
||||
return new short[bufferSize];
|
||||
}
|
||||
else
|
||||
{
|
||||
return bufferList.removeFirst();
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void free(short[] buffer)
|
||||
{
|
||||
bufferList.addFirst(buffer);
|
||||
}
|
||||
}
|
@ -2,11 +2,16 @@ package com.limelight.nvstream.av.audio;
|
||||
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
|
||||
import com.limelight.nvstream.av.AvBufferDescriptor;
|
||||
import com.limelight.nvstream.av.AvByteBufferDescriptor;
|
||||
import com.limelight.nvstream.av.AvRtpPacket;
|
||||
import com.limelight.nvstream.av.AvShortBufferDescriptor;
|
||||
import com.limelight.nvstream.av.AvShortBufferPool;
|
||||
|
||||
public class AvAudioDepacketizer {
|
||||
private LinkedBlockingQueue<short[]> decodedUnits = new LinkedBlockingQueue<short[]>();
|
||||
private LinkedBlockingQueue<AvShortBufferDescriptor> decodedUnits =
|
||||
new LinkedBlockingQueue<AvShortBufferDescriptor>();
|
||||
|
||||
private AvShortBufferPool pool = new AvShortBufferPool(OpusDecoder.getMaxOutputShorts());
|
||||
|
||||
// Sequencing state
|
||||
private short lastSequenceNumber;
|
||||
@ -34,25 +39,22 @@ public class AvAudioDepacketizer {
|
||||
lastSequenceNumber = seq;
|
||||
|
||||
// This is all the depacketizing we need to do
|
||||
AvBufferDescriptor rtpPayload = packet.getNewPayloadDescriptor();
|
||||
AvByteBufferDescriptor rtpPayload = packet.getNewPayloadDescriptor();
|
||||
|
||||
// Submit this data to the decoder
|
||||
short[] pcmData = new short[OpusDecoder.getMaxOutputShorts()];
|
||||
|
||||
short[] pcmData = pool.allocate();
|
||||
int decodeLen = OpusDecoder.decode(rtpPayload.data, rtpPayload.offset, rtpPayload.length, pcmData);
|
||||
|
||||
// Return value of decode is frames decoded per channel
|
||||
decodeLen *= OpusDecoder.getChannelCount();
|
||||
|
||||
if (decodeLen > 0) {
|
||||
// Jank!
|
||||
short[] trimmedPcmData = new short[decodeLen];
|
||||
System.arraycopy(pcmData, 0, trimmedPcmData, 0, decodeLen);
|
||||
decodedUnits.add(trimmedPcmData);
|
||||
// Return value of decode is frames decoded per channel
|
||||
decodeLen *= OpusDecoder.getChannelCount();
|
||||
|
||||
// Put it on the decoded queue
|
||||
decodedUnits.add(new AvShortBufferDescriptor(pcmData, 0, decodeLen));
|
||||
}
|
||||
}
|
||||
|
||||
public short[] getNextDecodedData() throws InterruptedException
|
||||
public AvShortBufferDescriptor getNextDecodedData() throws InterruptedException
|
||||
{
|
||||
return decodedUnits.take();
|
||||
}
|
||||
|
@ -3,7 +3,7 @@ package com.limelight.nvstream.av.video;
|
||||
import java.util.LinkedList;
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
|
||||
import com.limelight.nvstream.av.AvBufferDescriptor;
|
||||
import com.limelight.nvstream.av.AvByteBufferDescriptor;
|
||||
import com.limelight.nvstream.av.AvDecodeUnit;
|
||||
import com.limelight.nvstream.av.AvRtpPacket;
|
||||
|
||||
@ -12,7 +12,7 @@ import android.media.MediaCodec;
|
||||
public class AvVideoDepacketizer {
|
||||
|
||||
// Current NAL state
|
||||
private LinkedList<AvBufferDescriptor> avcNalDataChain = null;
|
||||
private LinkedList<AvByteBufferDescriptor> avcNalDataChain = null;
|
||||
private int avcNalDataLength = 0;
|
||||
private int currentlyDecoding;
|
||||
|
||||
@ -29,8 +29,8 @@ public class AvVideoDepacketizer {
|
||||
int flags = 0;
|
||||
|
||||
// Check if this is a special NAL unit
|
||||
AvBufferDescriptor header = avcNalDataChain.getFirst();
|
||||
AvBufferDescriptor specialSeq = NAL.getSpecialSequenceDescriptor(header);
|
||||
AvByteBufferDescriptor header = avcNalDataChain.getFirst();
|
||||
AvByteBufferDescriptor specialSeq = NAL.getSpecialSequenceDescriptor(header);
|
||||
|
||||
if (specialSeq != null)
|
||||
{
|
||||
@ -85,7 +85,7 @@ public class AvVideoDepacketizer {
|
||||
|
||||
public void addInputData(AvVideoPacket packet)
|
||||
{
|
||||
AvBufferDescriptor location = packet.getNewPayloadDescriptor();
|
||||
AvByteBufferDescriptor location = packet.getNewPayloadDescriptor();
|
||||
|
||||
while (location.length != 0)
|
||||
{
|
||||
@ -93,7 +93,7 @@ public class AvVideoDepacketizer {
|
||||
int start = location.offset;
|
||||
|
||||
// Check for a special sequence
|
||||
AvBufferDescriptor specialSeq = NAL.getSpecialSequenceDescriptor(location);
|
||||
AvByteBufferDescriptor specialSeq = NAL.getSpecialSequenceDescriptor(location);
|
||||
if (specialSeq != null)
|
||||
{
|
||||
if (NAL.isAvcStartSequence(specialSeq))
|
||||
@ -108,7 +108,7 @@ public class AvVideoDepacketizer {
|
||||
reassembleAvcNal();
|
||||
|
||||
// Setup state for the new NAL
|
||||
avcNalDataChain = new LinkedList<AvBufferDescriptor>();
|
||||
avcNalDataChain = new LinkedList<AvByteBufferDescriptor>();
|
||||
avcNalDataLength = 0;
|
||||
}
|
||||
}
|
||||
@ -141,7 +141,7 @@ public class AvVideoDepacketizer {
|
||||
}
|
||||
}
|
||||
|
||||
AvBufferDescriptor data = new AvBufferDescriptor(location.data, start, location.offset-start);
|
||||
AvByteBufferDescriptor data = new AvByteBufferDescriptor(location.data, start, location.offset-start);
|
||||
|
||||
if (currentlyDecoding == AvDecodeUnit.TYPE_H264 && avcNalDataChain != null)
|
||||
{
|
||||
@ -172,7 +172,7 @@ public class AvVideoDepacketizer {
|
||||
lastSequenceNumber = seq;
|
||||
|
||||
// Pass the payload to the non-sequencing parser
|
||||
AvBufferDescriptor rtpPayload = packet.getNewPayloadDescriptor();
|
||||
AvByteBufferDescriptor rtpPayload = packet.getNewPayloadDescriptor();
|
||||
addInputData(new AvVideoPacket(rtpPayload));
|
||||
}
|
||||
|
||||
@ -185,7 +185,7 @@ public class AvVideoDepacketizer {
|
||||
class NAL {
|
||||
|
||||
// This assumes that the buffer passed in is already a special sequence
|
||||
public static boolean isAvcStartSequence(AvBufferDescriptor specialSeq)
|
||||
public static boolean isAvcStartSequence(AvByteBufferDescriptor specialSeq)
|
||||
{
|
||||
if (specialSeq.length != 3 && specialSeq.length != 4)
|
||||
return false;
|
||||
@ -195,7 +195,7 @@ class NAL {
|
||||
}
|
||||
|
||||
// This assumes that the buffer passed in is already a special sequence
|
||||
public static boolean isUnknownStartSequence(AvBufferDescriptor specialSeq)
|
||||
public static boolean isUnknownStartSequence(AvByteBufferDescriptor specialSeq)
|
||||
{
|
||||
if (specialSeq.length != 3)
|
||||
return false;
|
||||
@ -205,7 +205,7 @@ class NAL {
|
||||
}
|
||||
|
||||
// This assumes that the buffer passed in is already a special sequence
|
||||
public static boolean isAvcFrameStart(AvBufferDescriptor specialSeq)
|
||||
public static boolean isAvcFrameStart(AvByteBufferDescriptor specialSeq)
|
||||
{
|
||||
if (specialSeq.length != 4)
|
||||
return false;
|
||||
@ -215,7 +215,7 @@ class NAL {
|
||||
}
|
||||
|
||||
// Returns a buffer descriptor describing the start sequence
|
||||
public static AvBufferDescriptor getSpecialSequenceDescriptor(AvBufferDescriptor buffer)
|
||||
public static AvByteBufferDescriptor getSpecialSequenceDescriptor(AvByteBufferDescriptor buffer)
|
||||
{
|
||||
// NAL start sequence is 00 00 00 01 or 00 00 01
|
||||
if (buffer.length < 3)
|
||||
@ -233,19 +233,19 @@ class NAL {
|
||||
buffer.data[buffer.offset+3] == 0x01)
|
||||
{
|
||||
// It's the AVC start sequence 00 00 00 01
|
||||
return new AvBufferDescriptor(buffer.data, buffer.offset, 4);
|
||||
return new AvByteBufferDescriptor(buffer.data, buffer.offset, 4);
|
||||
}
|
||||
else
|
||||
{
|
||||
// It's 00 00 00
|
||||
return new AvBufferDescriptor(buffer.data, buffer.offset, 3);
|
||||
return new AvByteBufferDescriptor(buffer.data, buffer.offset, 3);
|
||||
}
|
||||
}
|
||||
else if (buffer.data[buffer.offset+2] == 0x01 ||
|
||||
buffer.data[buffer.offset+2] == 0x02)
|
||||
{
|
||||
// These are easy: 00 00 01 or 00 00 02
|
||||
return new AvBufferDescriptor(buffer.data, buffer.offset, 3);
|
||||
return new AvByteBufferDescriptor(buffer.data, buffer.offset, 3);
|
||||
}
|
||||
else if (buffer.data[buffer.offset+2] == 0x03)
|
||||
{
|
||||
@ -267,7 +267,7 @@ class NAL {
|
||||
else
|
||||
{
|
||||
// It's not a standard replacement so it's a special sequence
|
||||
return new AvBufferDescriptor(buffer.data, buffer.offset, 3);
|
||||
return new AvByteBufferDescriptor(buffer.data, buffer.offset, 3);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,17 +1,17 @@
|
||||
package com.limelight.nvstream.av.video;
|
||||
|
||||
import com.limelight.nvstream.av.AvBufferDescriptor;
|
||||
import com.limelight.nvstream.av.AvByteBufferDescriptor;
|
||||
|
||||
public class AvVideoPacket {
|
||||
private AvBufferDescriptor buffer;
|
||||
private AvByteBufferDescriptor buffer;
|
||||
|
||||
public AvVideoPacket(AvBufferDescriptor rtpPayload)
|
||||
public AvVideoPacket(AvByteBufferDescriptor rtpPayload)
|
||||
{
|
||||
buffer = new AvBufferDescriptor(rtpPayload);
|
||||
buffer = new AvByteBufferDescriptor(rtpPayload);
|
||||
}
|
||||
|
||||
public AvBufferDescriptor getNewPayloadDescriptor()
|
||||
public AvByteBufferDescriptor getNewPayloadDescriptor()
|
||||
{
|
||||
return new AvBufferDescriptor(buffer.data, buffer.offset+56, buffer.length-56);
|
||||
return new AvByteBufferDescriptor(buffer.data, buffer.offset+56, buffer.length-56);
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user