From 8d90498f791940f95374423963997abb2ce40429 Mon Sep 17 00:00:00 2001 From: Dustin Date: Tue, 18 Jan 2022 23:04:14 -0700 Subject: [PATCH] Minor Tweaks --- .../extractor/avi/AviExtractor.java | 39 +++++++++++-------- .../extractor/avi/AviHeaderBox.java | 5 ++- .../exoplayer2/extractor/avi/AviTrack.java | 6 ++- 3 files changed, 31 insertions(+), 19 deletions(-) diff --git a/library/extractor/src/main/java/com/google/android/exoplayer2/extractor/avi/AviExtractor.java b/library/extractor/src/main/java/com/google/android/exoplayer2/extractor/avi/AviExtractor.java index 8d682aca4f..b1b3388260 100644 --- a/library/extractor/src/main/java/com/google/android/exoplayer2/extractor/avi/AviExtractor.java +++ b/library/extractor/src/main/java/com/google/android/exoplayer2/extractor/avi/AviExtractor.java @@ -49,14 +49,16 @@ public class AviExtractor implements Extractor { static final int IDX1 = 'i' | ('d' << 8) | ('x' << 16) | ('1' << 24); static final int JUNK = 'J' | ('U' << 8) | ('N' << 16) | ('K' << 24); + static final int REC_ = 'r' | ('e' << 8) | ('c' << 16) | (' ' << 24); static final long SEEK_GAP = 2_000_000L; //Time between seek points in micro seconds private int state; private ExtractorOutput output; private AviHeaderBox aviHeader; + private long durationUs = C.TIME_UNSET; private SparseArray idTrackMap = new SparseArray<>(); - //After the movi position + //At the start of the movi tag private long moviOffset; private long moviEnd; private AviSeekMap aviSeekMap; @@ -154,14 +156,9 @@ public class AviExtractor implements Extractor { } return listBox; } - long getDuration() { - if (aviHeader == null) { - return C.TIME_UNSET; - } - return aviHeader.getFrames() * (long)aviHeader.getMicroSecPerFrame(); + return durationUs; } - @Override public void init(ExtractorOutput output) { this.state = STATE_READ_TRACKS; @@ -185,6 +182,8 @@ public class AviExtractor implements Extractor { if (aviHeader == null) { throw new IOException("AviHeader not found"); } + //This is usually wrong, so it will be overwritten by video if present + durationUs = aviHeader.getFrames() * (long)aviHeader.getMicroSecPerFrame(); headerChildren.remove(aviHeader); //headerChildren should only be Stream Lists now @@ -228,6 +227,7 @@ public class AviExtractor implements Extractor { idTrackMap.put('0' | (('0' + streamId) << 8) | ('d' << 16) | ('c' << 24), new AviTrack(streamId, trackOutput, streamHeader)); + durationUs = streamHeader.getUsPerSample() * streamHeader.getLength(); } else if (streamHeader.isAudio()) { final AudioFormat audioFormat = streamFormat.getAudioFormat(); final TrackOutput trackOutput = output.track(streamId, C.TRACK_TYPE_AUDIO); @@ -329,7 +329,9 @@ public class AviExtractor implements Extractor { final int id = indexByteBuffer.getInt(); final AviTrack aviTrack = idTrackMap.get(id); if (aviTrack == null) { - Log.w(TAG, "Unknown Track Type: " + AviUtil.toString(id)); + if (id != AviExtractor.REC_) { + Log.w(TAG, "Unknown Track Type: " + AviUtil.toString(id)); + } indexByteBuffer.position(indexByteBuffer.position() + 12); continue; } @@ -366,14 +368,16 @@ public class AviExtractor implements Extractor { entry.getValue().pack(); idFrameArray.put(entry.getKey(), entry.getValue().array); final AviTrack aviTrack = idTrackMap.get(entry.getKey()); - //Sometimes this value is way off - long calcUsPerSample = (getDuration()/aviTrack.frame); - float deltaPercent = Math.abs(calcUsPerSample - aviTrack.usPerSample) / (float)aviTrack.usPerSample; - if (deltaPercent >.01) { - aviTrack.usPerSample = getDuration()/aviTrack.frame; - Log.d(TAG, "Frames act=" + getDuration() + " calc=" + (aviTrack.usPerSample * aviTrack.frame)); + //If the index isn't sparse, double check the audio length + if (videoTrack.frame == videoTrack.streamHeaderBox.getLength()) { + //Sometimes this value is way off + long calcUsPerSample = (getDuration()/aviTrack.frame); + float deltaPercent = Math.abs(calcUsPerSample - aviTrack.usPerSample) / (float)aviTrack.usPerSample; + if (deltaPercent >.01) { + aviTrack.usPerSample = getDuration()/aviTrack.frame; + Log.d(TAG, "Frames act=" + getDuration() + " calc=" + (aviTrack.usPerSample * aviTrack.frame)); + } } - } final AviSeekMap seekMap = new AviSeekMap(videoTrack, seekFrameRate, videoSeekOffset.array, idFrameArray, moviOffset, getDuration()); @@ -415,8 +419,9 @@ public class AviExtractor implements Extractor { } return RESULT_SEEK; } else { - //Log.d(TAG, "Sample pos=" + (input.getPosition() - 8) + " size=" + sampleSize + " video=" + sampleTrack.isVideo()); + //sampleOffset = (int)(input.getPosition() - 8 - moviOffset); sampleRemaining = sampleSize - sampleTrack.trackOutput.sampleData(input, sampleSize, false); + //Log.d(TAG, "Sample pos=" + (input.getPosition() - 8) + " size=" + sampleSize + " video=" + sampleTrack.isVideo()); } } if (sampleRemaining != 0) { @@ -424,7 +429,7 @@ public class AviExtractor implements Extractor { } sampleTrack.trackOutput.sampleMetadata( sampleTrack.getUs(), sampleTrack.isKeyFrame() ? C.BUFFER_FLAG_KEY_FRAME : 0 , sampleSize, 0, null); - //Log.d(TAG, "Frame: " + (sampleTrack.isVideo()? 'V' : 'A') + " us=" + sampleTrack.getUs()); + //Log.d(TAG, "Frame: " + (sampleTrack.isVideo()? 'V' : 'A') + " us=" + sampleTrack.getUs() + " size=" + sampleSize); sampleTrack.advance(); return RESULT_CONTINUE; } diff --git a/library/extractor/src/main/java/com/google/android/exoplayer2/extractor/avi/AviHeaderBox.java b/library/extractor/src/main/java/com/google/android/exoplayer2/extractor/avi/AviHeaderBox.java index ad8146ea3e..c541763bba 100644 --- a/library/extractor/src/main/java/com/google/android/exoplayer2/extractor/avi/AviHeaderBox.java +++ b/library/extractor/src/main/java/com/google/android/exoplayer2/extractor/avi/AviHeaderBox.java @@ -26,7 +26,10 @@ public class AviHeaderBox extends ResidentBox { } //4 = dwMaxBytesPerSec - //8 = dwPaddingGranularity + //Always 0, but should be 2 +// int getPaddingGranularity() { +// return byteBuffer.getInt(8); +// } int getFlags() { return byteBuffer.getInt(12); diff --git a/library/extractor/src/main/java/com/google/android/exoplayer2/extractor/avi/AviTrack.java b/library/extractor/src/main/java/com/google/android/exoplayer2/extractor/avi/AviTrack.java index 3114b319d1..9aa2937268 100644 --- a/library/extractor/src/main/java/com/google/android/exoplayer2/extractor/avi/AviTrack.java +++ b/library/extractor/src/main/java/com/google/android/exoplayer2/extractor/avi/AviTrack.java @@ -55,7 +55,11 @@ public class AviTrack { if (allKeyFrames) { return true; } - return keyFrames != null && Arrays.binarySearch(keyFrames, frame) >= 0; + if (keyFrames != null) { + return Arrays.binarySearch(keyFrames, frame) >= 0; + } + //Hack: Exo needs at least one frame before it starts playback + return frame == 0; } public void setKeyFrames(int[] keyFrames) {