mirror of
https://github.com/androidx/media.git
synced 2025-05-09 16:40:55 +08:00
Add work-around for muxer bug where idx1 offset is from 0, not "movi"
location
This commit is contained in:
parent
0ff238df99
commit
9bd93ad98e
@ -399,6 +399,14 @@ public class AviExtractor implements Extractor {
|
||||
w("No video track found");
|
||||
return;
|
||||
}
|
||||
if (remaining < 16) {
|
||||
output.seekMap(new SeekMap.Unseekable(getDuration()));
|
||||
w("Index too short");
|
||||
return;
|
||||
}
|
||||
final ByteBuffer firstEntry = AviExtractor.allocate(16);
|
||||
input.peekFully(firstEntry.array(), 0, 16);
|
||||
|
||||
final int videoId = videoTrack.id;
|
||||
final ByteBuffer indexByteBuffer = allocate(Math.min(remaining, 64 * 1024));
|
||||
final byte[] bytes = indexByteBuffer.array();
|
||||
@ -466,8 +474,10 @@ public class AviExtractor implements Extractor {
|
||||
videoTrack.setKeyFrames(seekIndexes[videoId].getArray());
|
||||
}
|
||||
|
||||
//Work-around a bug where the offset is from the start of the file, not "movi"
|
||||
final long seekOffset = firstEntry.getInt(8) > moviOffset ? 0L : moviOffset;
|
||||
final AviSeekMap seekMap = new AviSeekMap(videoId, videoTrack.clock.durationUs, videoTrack.chunks,
|
||||
keyFrameOffsetsDiv2.getArray(), seekIndexes, moviOffset);
|
||||
keyFrameOffsetsDiv2.getArray(), seekIndexes, seekOffset);
|
||||
|
||||
i("Video chunks=" + videoTrack.chunks + " us=" + seekMap.getDurationUs());
|
||||
|
||||
|
@ -14,10 +14,13 @@ public class AviSeekMap implements SeekMap {
|
||||
final int[] keyFrameOffsetsDiv2;
|
||||
//Seek chunk indexes by streamId
|
||||
final int[][] seekIndexes;
|
||||
final long moviOffset;
|
||||
/**
|
||||
* Usually the same as moviOffset, but sometimes 0 (muxer bug)
|
||||
*/
|
||||
final long seekOffset;
|
||||
|
||||
public AviSeekMap(int videoId, long usDuration, int videoChunks, int[] keyFrameOffsetsDiv2,
|
||||
UnboundedIntArray[] seekIndexes, long moviOffset) {
|
||||
UnboundedIntArray[] seekIndexes, long seekOffset) {
|
||||
this.videoId = videoId;
|
||||
this.videoUsPerChunk = usDuration / videoChunks;
|
||||
this.duration = usDuration;
|
||||
@ -26,7 +29,7 @@ public class AviSeekMap implements SeekMap {
|
||||
for (int i=0;i<seekIndexes.length;i++) {
|
||||
this.seekIndexes[i] = seekIndexes[i].getArray();
|
||||
}
|
||||
this.moviOffset = moviOffset;
|
||||
this.seekOffset = seekOffset;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -56,7 +59,7 @@ public class AviSeekMap implements SeekMap {
|
||||
private SeekPoint getSeekPoint(int index) {
|
||||
long offset = keyFrameOffsetsDiv2[index] * 2L;
|
||||
final long outUs = seekIndexes[videoId][index] * videoUsPerChunk;
|
||||
final long position = offset + moviOffset;
|
||||
final long position = offset + seekOffset;
|
||||
return new SeekPoint(outUs, position);
|
||||
}
|
||||
|
||||
@ -78,7 +81,7 @@ public class AviSeekMap implements SeekMap {
|
||||
}
|
||||
|
||||
public void setFrames(final long position, final long timeUs, final AviTrack[] aviTracks) {
|
||||
final int index = Arrays.binarySearch(keyFrameOffsetsDiv2, (int)((position - moviOffset) / 2));
|
||||
final int index = Arrays.binarySearch(keyFrameOffsetsDiv2, (int)((position - seekOffset) / 2));
|
||||
|
||||
if (index < 0) {
|
||||
throw new IllegalArgumentException("Position: " + position);
|
||||
|
@ -9,7 +9,7 @@ public class AviSeekMapTest {
|
||||
@Test
|
||||
public void setFrames_givenExactSeekPointMatch() {
|
||||
final AviSeekMap aviSeekMap = DataHelper.getAviSeekMap();
|
||||
final long position = aviSeekMap.keyFrameOffsetsDiv2[1] * 2L + aviSeekMap.moviOffset;
|
||||
final long position = aviSeekMap.keyFrameOffsetsDiv2[1] * 2L + aviSeekMap.seekOffset;
|
||||
final int secs = 4;
|
||||
final AviTrack[] aviTracks = new AviTrack[]{DataHelper.getVideoAviTrack(secs),
|
||||
DataHelper.getAudioAviTrack(secs)};
|
||||
|
Loading…
x
Reference in New Issue
Block a user