Reorder video stream initialization to vastly reduce the chance we'd miss the initial IDR frame

This commit is contained in:
Cameron Gutman 2014-11-19 10:42:29 -08:00
parent c819f2f0e3
commit ff4570abac

View File

@ -84,11 +84,11 @@ public class VideoStream {
} catch (InterruptedException e) { } } catch (InterruptedException e) { }
} }
if (startedRendering) {
decRend.stop();
}
if (decRend != null) { if (decRend != null) {
if (startedRendering) {
decRend.stop();
}
decRend.release(); decRend.release();
} }
@ -117,9 +117,9 @@ public class VideoStream {
offset += bytesRead; offset += bytesRead;
} }
VideoPacket packet = new VideoPacket(firstFrame); // We can actually ignore this data. It's the act of reading it that matters.
packet.initializeWithLengthNoRtpHeader(offset); // If this changes, we'll need to move this call before startReceiveThread()
depacketizer.addInputData(packet); // to avoid state corruption in the depacketizer
} finally { } finally {
firstFrameSocket.close(); firstFrameSocket.close();
firstFrameSocket = null; firstFrameSocket = null;
@ -134,15 +134,28 @@ public class VideoStream {
public boolean setupDecoderRenderer(VideoDecoderRenderer decRend, Object renderTarget, int drFlags) { public boolean setupDecoderRenderer(VideoDecoderRenderer decRend, Object renderTarget, int drFlags) {
this.decRend = decRend; this.decRend = decRend;
depacketizer = new VideoDepacketizer(avConnListener, streamConfig.getMaxPacketSize());
if (decRend != null) { if (decRend != null) {
if (!decRend.setup(streamConfig.getWidth(), streamConfig.getHeight(), try {
60, renderTarget, drFlags)) { if (!decRend.setup(streamConfig.getWidth(), streamConfig.getHeight(),
60, renderTarget, drFlags)) {
return false;
}
if (!decRend.start(depacketizer)) {
abort();
return false;
}
startedRendering = true;
} catch (Exception e) {
e.printStackTrace();
return false; return false;
} }
} }
depacketizer = new VideoDepacketizer(avConnListener, streamConfig.getMaxPacketSize());
return true; return true;
} }
@ -154,13 +167,6 @@ public class VideoStream {
throw new IOException("Video decoder failed to initialize. Please restart your device and try again."); throw new IOException("Video decoder failed to initialize. Please restart your device and try again.");
} }
// Start the renderer
if (!decRend.start(depacketizer)) {
abort();
return false;
}
startedRendering = true;
// Open RTP sockets and start session // Open RTP sockets and start session
setupRtpSession(); setupRtpSession();
@ -169,18 +175,16 @@ public class VideoStream {
// the reference frame // the reference frame
startUdpPingThread(); startUdpPingThread();
// Read the first frame to start the UDP video stream
// This MUST be called before the normal UDP receive thread
// starts in order to avoid state corruption caused by two
// threads simultaneously adding input data.
readFirstFrame();
if (decRend != null) { if (decRend != null) {
// Start the receive thread early to avoid missing // Start the receive thread early to avoid missing
// early packets // early packets that are part of the IDR frame
startReceiveThread(); startReceiveThread();
} }
// Now that we're ready, read the first frame to start the
// UDP video stream
readFirstFrame();
return true; return true;
} }