Use monotonic system time for rendering timestamps. This is required now in Android 6.0 since these timestamps are propagated to the codec.

This commit is contained in:
Cameron Gutman 2015-08-17 18:40:25 -07:00
parent 932ce435b5
commit 7023760782
4 changed files with 18 additions and 14 deletions

Binary file not shown.

View File

@ -177,10 +177,10 @@ public class AndroidCpuDecoderRenderer extends EnhancedDecoderRenderer {
rendererThread = new Thread() { rendererThread = new Thread() {
@Override @Override
public void run() { public void run() {
long nextFrameTime = System.currentTimeMillis(); long nextFrameTime = MediaCodecHelper.getMonotonicMillis();
while (!isInterrupted()) while (!isInterrupted())
{ {
long diff = nextFrameTime - System.currentTimeMillis(); long diff = nextFrameTime - MediaCodecHelper.getMonotonicMillis();
if (diff > WAIT_CEILING_MS) { if (diff > WAIT_CEILING_MS) {
try { try {
@ -203,7 +203,7 @@ public class AndroidCpuDecoderRenderer extends EnhancedDecoderRenderer {
} }
private long computePresentationTimeMs(int frameRate) { private long computePresentationTimeMs(int frameRate) {
return System.currentTimeMillis() + (1000 / frameRate); return MediaCodecHelper.getMonotonicMillis() + (1000 / frameRate);
} }
@Override @Override
@ -251,7 +251,7 @@ public class AndroidCpuDecoderRenderer extends EnhancedDecoderRenderer {
boolean success = (AvcDecoder.decode(data, 0, decodeUnit.getDataLength()) == 0); boolean success = (AvcDecoder.decode(data, 0, decodeUnit.getDataLength()) == 0);
if (success) { if (success) {
long timeAfterDecode = System.currentTimeMillis(); long timeAfterDecode = MediaCodecHelper.getMonotonicMillis();
// Add delta time to the totals (excluding probable outliers) // Add delta time to the totals (excluding probable outliers)
long delta = timeAfterDecode - decodeUnit.getReceiveTimestamp(); long delta = timeAfterDecode - decodeUnit.getReceiveTimestamp();

View File

@ -169,7 +169,7 @@ public class MediaCodecDecoderRenderer extends EnhancedDecoderRenderer {
videoDecoder.releaseOutputBuffer(lastIndex, true); videoDecoder.releaseOutputBuffer(lastIndex, true);
// Add delta time to the totals (excluding probable outliers) // Add delta time to the totals (excluding probable outliers)
long delta = System.currentTimeMillis() - (presentationTimeUs / 1000); long delta = MediaCodecHelper.getMonotonicMillis() - (presentationTimeUs / 1000);
if (delta >= 0 && delta < 1000) { if (delta >= 0 && delta < 1000) {
decoderTimeMs += delta; decoderTimeMs += delta;
totalTimeMs += delta; totalTimeMs += delta;
@ -201,14 +201,14 @@ public class MediaCodecDecoderRenderer extends EnhancedDecoderRenderer {
int index; int index;
long startTime, queueTime; long startTime, queueTime;
startTime = System.currentTimeMillis(); startTime = MediaCodecHelper.getMonotonicMillis();
index = videoDecoder.dequeueInputBuffer(wait ? (infiniteWait ? -1 : 3000) : 0); index = videoDecoder.dequeueInputBuffer(wait ? (infiniteWait ? -1 : 3000) : 0);
if (index < 0) { if (index < 0) {
return index; return index;
} }
queueTime = System.currentTimeMillis(); queueTime = MediaCodecHelper.getMonotonicMillis();
if (queueTime - startTime >= 20) { if (queueTime - startTime >= 20) {
LimeLog.warning("Queue input buffer ran long: " + (queueTime - startTime) + " ms"); LimeLog.warning("Queue input buffer ran long: " + (queueTime - startTime) + " ms");
@ -236,7 +236,7 @@ public class MediaCodecDecoderRenderer extends EnhancedDecoderRenderer {
inputIndex = dequeueInputBuffer(false, false); inputIndex = dequeueInputBuffer(false, false);
du = depacketizer.pollNextDecodeUnit(); du = depacketizer.pollNextDecodeUnit();
if (du != null) { if (du != null) {
lastDuDequeueTime = System.currentTimeMillis(); lastDuDequeueTime = MediaCodecHelper.getMonotonicMillis();
notifyDuReceived(du); notifyDuReceived(du);
} }
@ -278,7 +278,7 @@ public class MediaCodecDecoderRenderer extends EnhancedDecoderRenderer {
if (du == null) { if (du == null) {
du = depacketizer.pollNextDecodeUnit(); du = depacketizer.pollNextDecodeUnit();
if (du != null) { if (du != null) {
lastDuDequeueTime = System.currentTimeMillis(); lastDuDequeueTime = MediaCodecHelper.getMonotonicMillis();
notifyDuReceived(du); notifyDuReceived(du);
} }
} }
@ -286,7 +286,7 @@ public class MediaCodecDecoderRenderer extends EnhancedDecoderRenderer {
// If we've got both a decode unit and an input buffer, we'll // If we've got both a decode unit and an input buffer, we'll
// submit now. Otherwise, we wait until we have one. // submit now. Otherwise, we wait until we have one.
if (du != null && inputIndex >= 0) { if (du != null && inputIndex >= 0) {
long submissionTime = System.currentTimeMillis(); long submissionTime = MediaCodecHelper.getMonotonicMillis();
if (submissionTime - lastDuDequeueTime >= 20) { if (submissionTime - lastDuDequeueTime >= 20) {
LimeLog.warning("Receiving an input buffer took too long: "+(submissionTime - lastDuDequeueTime)+" ms"); LimeLog.warning("Receiving an input buffer took too long: "+(submissionTime - lastDuDequeueTime)+" ms");
} }
@ -317,7 +317,7 @@ public class MediaCodecDecoderRenderer extends EnhancedDecoderRenderer {
videoDecoder.releaseOutputBuffer(lastIndex, true); videoDecoder.releaseOutputBuffer(lastIndex, true);
// Add delta time to the totals (excluding probable outliers) // Add delta time to the totals (excluding probable outliers)
long delta = System.currentTimeMillis()-(presentationTimeUs/1000); long delta = MediaCodecHelper.getMonotonicMillis()-(presentationTimeUs/1000);
if (delta >= 0 && delta < 1000) { if (delta >= 0 && delta < 1000) {
decoderTimeMs += delta; decoderTimeMs += delta;
totalTimeMs += delta; totalTimeMs += delta;
@ -435,7 +435,7 @@ public class MediaCodecDecoderRenderer extends EnhancedDecoderRenderer {
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
private void submitDecodeUnit(DecodeUnit decodeUnit, int inputBufferIndex) { private void submitDecodeUnit(DecodeUnit decodeUnit, int inputBufferIndex) {
long timestampUs = System.currentTimeMillis() * 1000; long timestampUs = System.nanoTime() / 1000;
if (timestampUs <= lastTimestampUs) { if (timestampUs <= lastTimestampUs) {
// We can't submit multiple buffers with the same timestamp // We can't submit multiple buffers with the same timestamp
// so bump it up by one before queuing // so bump it up by one before queuing
@ -608,7 +608,7 @@ public class MediaCodecDecoderRenderer extends EnhancedDecoderRenderer {
// Queue the new SPS // Queue the new SPS
queueInputBuffer(inputIndex, queueInputBuffer(inputIndex,
0, inputBuffer.position(), 0, inputBuffer.position(),
System.currentTimeMillis() * 1000, System.nanoTime() / 1000,
MediaCodec.BUFFER_FLAG_CODEC_CONFIG); MediaCodec.BUFFER_FLAG_CODEC_CONFIG);
LimeLog.info("SPS replay complete"); LimeLog.info("SPS replay complete");
@ -649,7 +649,7 @@ public class MediaCodecDecoderRenderer extends EnhancedDecoderRenderer {
} }
private void notifyDuReceived(DecodeUnit du) { private void notifyDuReceived(DecodeUnit du) {
long currentTime = System.currentTimeMillis(); long currentTime = MediaCodecHelper.getMonotonicMillis();
long delta = currentTime-du.getReceiveTimestamp(); long delta = currentTime-du.getReceiveTimestamp();
if (delta >= 0 && delta < 1000) { if (delta >= 0 && delta < 1000) {
totalTimeMs += currentTime-du.getReceiveTimestamp(); totalTimeMs += currentTime-du.getReceiveTimestamp();

View File

@ -84,6 +84,10 @@ public class MediaCodecHelper {
return false; return false;
} }
public static long getMonotonicMillis() {
return System.nanoTime() / 1000000L;
}
@TargetApi(Build.VERSION_CODES.KITKAT) @TargetApi(Build.VERSION_CODES.KITKAT)
public static boolean decoderSupportsAdaptivePlayback(String decoderName, MediaCodecInfo decoderInfo) { public static boolean decoderSupportsAdaptivePlayback(String decoderName, MediaCodecInfo decoderInfo) {
/* /*