mirror of
https://github.com/moonlight-stream/moonlight-android.git
synced 2025-07-21 03:52:48 +00:00
Improve tolerance to dropped packets
This commit is contained in:
parent
cbe40fde92
commit
2d55562dd3
@ -19,6 +19,7 @@ public class VideoDepacketizer {
|
|||||||
private int nextFrameNumber = 1;
|
private int nextFrameNumber = 1;
|
||||||
private int startFrameNumber = 1;
|
private int startFrameNumber = 1;
|
||||||
private boolean waitingForNextSuccessfulFrame;
|
private boolean waitingForNextSuccessfulFrame;
|
||||||
|
private boolean waitingForIdrFrame = true;
|
||||||
private long frameStartTime;
|
private long frameStartTime;
|
||||||
private boolean decodingFrame;
|
private boolean decodingFrame;
|
||||||
|
|
||||||
@ -131,6 +132,11 @@ public class VideoDepacketizer {
|
|||||||
// Setup state for the new NAL
|
// Setup state for the new NAL
|
||||||
avcFrameDataChain = new LinkedList<ByteBufferDescriptor>();
|
avcFrameDataChain = new LinkedList<ByteBufferDescriptor>();
|
||||||
avcFrameDataLength = 0;
|
avcFrameDataLength = 0;
|
||||||
|
|
||||||
|
if (cachedSpecialDesc.data[cachedSpecialDesc.offset+cachedSpecialDesc.length] == 0x65) {
|
||||||
|
// This is the NALU code for I-frame data
|
||||||
|
waitingForIdrFrame = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Skip the start sequence
|
// Skip the start sequence
|
||||||
@ -227,16 +233,22 @@ public class VideoDepacketizer {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Drop packets from a previously completed frame
|
||||||
|
if (frameIndex < nextFrameNumber) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Look for a frame start before receiving a frame end
|
// Look for a frame start before receiving a frame end
|
||||||
if (firstPacket && decodingFrame)
|
if (firstPacket && decodingFrame)
|
||||||
{
|
{
|
||||||
LimeLog.warning("Network dropped end of a frame");
|
LimeLog.warning("Network dropped end of a frame");
|
||||||
nextFrameNumber = frameIndex + 1;
|
nextFrameNumber = frameIndex;
|
||||||
|
|
||||||
// Unexpected start of next frame before terminating the last
|
// Unexpected start of next frame before terminating the last
|
||||||
waitingForNextSuccessfulFrame = true;
|
waitingForNextSuccessfulFrame = true;
|
||||||
|
waitingForIdrFrame = true;
|
||||||
|
|
||||||
// Clear the old state and decode this frame
|
// Clear the old state and wait for an IDR
|
||||||
clearAvcFrameState();
|
clearAvcFrameState();
|
||||||
decodingFrame = true;
|
decodingFrame = true;
|
||||||
}
|
}
|
||||||
@ -251,6 +263,8 @@ public class VideoDepacketizer {
|
|||||||
nextFrameNumber = frameIndex + 1;
|
nextFrameNumber = frameIndex + 1;
|
||||||
|
|
||||||
waitingForNextSuccessfulFrame = true;
|
waitingForNextSuccessfulFrame = true;
|
||||||
|
waitingForIdrFrame = true;
|
||||||
|
|
||||||
clearAvcFrameState();
|
clearAvcFrameState();
|
||||||
decodingFrame = false;
|
decodingFrame = false;
|
||||||
return;
|
return;
|
||||||
@ -266,10 +280,11 @@ public class VideoDepacketizer {
|
|||||||
// Make sure this is the next consecutive frame
|
// Make sure this is the next consecutive frame
|
||||||
if (nextFrameNumber < frameIndex) {
|
if (nextFrameNumber < frameIndex) {
|
||||||
LimeLog.warning("Network dropped an entire frame");
|
LimeLog.warning("Network dropped an entire frame");
|
||||||
nextFrameNumber = frameIndex + 1;
|
nextFrameNumber = frameIndex;
|
||||||
|
|
||||||
// Decode this one and hope for the best
|
// Wait until an IDR frame comes
|
||||||
waitingForNextSuccessfulFrame = true;
|
waitingForNextSuccessfulFrame = true;
|
||||||
|
waitingForIdrFrame = true;
|
||||||
clearAvcFrameState();
|
clearAvcFrameState();
|
||||||
}
|
}
|
||||||
else if (nextFrameNumber > frameIndex){
|
else if (nextFrameNumber > frameIndex){
|
||||||
@ -277,10 +292,6 @@ public class VideoDepacketizer {
|
|||||||
decodingFrame = false;
|
decodingFrame = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
// This will be the next expected frame
|
|
||||||
nextFrameNumber = frameIndex + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// We're now decoding a frame
|
// We're now decoding a frame
|
||||||
decodingFrame = true;
|
decodingFrame = true;
|
||||||
@ -295,6 +306,8 @@ public class VideoDepacketizer {
|
|||||||
nextFrameNumber = frameIndex + 1;
|
nextFrameNumber = frameIndex + 1;
|
||||||
|
|
||||||
waitingForNextSuccessfulFrame = true;
|
waitingForNextSuccessfulFrame = true;
|
||||||
|
waitingForIdrFrame = true;
|
||||||
|
|
||||||
clearAvcFrameState();
|
clearAvcFrameState();
|
||||||
decodingFrame = false;
|
decodingFrame = false;
|
||||||
|
|
||||||
@ -324,15 +337,28 @@ public class VideoDepacketizer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ((flags & VideoPacket.FLAG_EOF) != 0) {
|
if ((flags & VideoPacket.FLAG_EOF) != 0) {
|
||||||
reassembleAvcFrame(packet.getFrameIndex());
|
// Move on to the next frame
|
||||||
decodingFrame = false;
|
decodingFrame = false;
|
||||||
|
nextFrameNumber = frameIndex + 1;
|
||||||
|
|
||||||
|
// If waiting for next successful frame and we got here
|
||||||
|
// with an end flag, we can send a message to the server
|
||||||
if (waitingForNextSuccessfulFrame) {
|
if (waitingForNextSuccessfulFrame) {
|
||||||
// This is the next successful frame after a loss event
|
// This is the next successful frame after a loss event
|
||||||
controlListener.connectionDetectedFrameLoss(startFrameNumber, nextFrameNumber - 1);
|
controlListener.connectionDetectedFrameLoss(startFrameNumber, nextFrameNumber - 1);
|
||||||
waitingForNextSuccessfulFrame = false;
|
waitingForNextSuccessfulFrame = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If we need an IDR frame first, then drop this frame
|
||||||
|
if (waitingForIdrFrame) {
|
||||||
|
LimeLog.warning("Waiting for IDR frame");
|
||||||
|
|
||||||
|
clearAvcFrameState();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
reassembleAvcFrame(frameIndex);
|
||||||
|
|
||||||
startFrameNumber = nextFrameNumber;
|
startFrameNumber = nextFrameNumber;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user