mirror of
https://github.com/samsonjs/media.git
synced 2026-03-27 09:45:47 +00:00
More AviExtractor tests
This commit is contained in:
parent
66c240f1bd
commit
432ff5ea70
5 changed files with 191 additions and 6 deletions
|
|
@ -351,7 +351,8 @@ public class AviExtractor implements Extractor {
|
|||
return RESULT_SEEK;
|
||||
}
|
||||
|
||||
private AviTrack getVideoTrack() {
|
||||
@VisibleForTesting
|
||||
AviTrack getVideoTrack() {
|
||||
for (@Nullable AviTrack aviTrack : aviTracks) {
|
||||
if (aviTrack != null && aviTrack.isVideo()) {
|
||||
return aviTrack;
|
||||
|
|
@ -510,7 +511,7 @@ public class AviExtractor implements Extractor {
|
|||
final AviTrack aviTrack = getAviTrack(chunkId);
|
||||
if (aviTrack == null) {
|
||||
seekPosition.position = alignPosition(input.getPosition() + size);
|
||||
Log.w(TAG, "Unknown tag=" + toString(chunkId) + " pos=" + (input.getPosition() - 8)
|
||||
w("Unknown tag=" + toString(chunkId) + " pos=" + (input.getPosition() - 8)
|
||||
+ " size=" + size + " moviEnd=" + moviEnd);
|
||||
return RESULT_SEEK;
|
||||
}
|
||||
|
|
@ -590,6 +591,27 @@ public class AviExtractor implements Extractor {
|
|||
this.aviTracks = aviTracks;
|
||||
}
|
||||
|
||||
@VisibleForTesting(otherwise = VisibleForTesting.NONE)
|
||||
void setAviHeader(final AviHeaderBox aviHeaderBox) {
|
||||
aviHeader = aviHeaderBox;
|
||||
}
|
||||
|
||||
@VisibleForTesting(otherwise = VisibleForTesting.NONE)
|
||||
void setMovi(final int offset, final int end) {
|
||||
moviOffset = offset;
|
||||
moviEnd = end;
|
||||
}
|
||||
|
||||
@VisibleForTesting(otherwise = VisibleForTesting.NONE)
|
||||
AviTrack getChunkHandler() {
|
||||
return chunkHandler;
|
||||
}
|
||||
|
||||
@VisibleForTesting(otherwise = VisibleForTesting.NONE)
|
||||
void setChunkHandler(final AviTrack aviTrack) {
|
||||
chunkHandler = aviTrack;
|
||||
}
|
||||
|
||||
private static void w(String message) {
|
||||
try {
|
||||
Log.w(TAG, message);
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
package com.google.android.exoplayer2.extractor.avi;
|
||||
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
public class AviHeaderBox extends ResidentBox {
|
||||
|
|
@ -49,4 +50,9 @@ public class AviHeaderBox extends ResidentBox {
|
|||
// 28 - dwSuggestedBufferSize
|
||||
// 32 - dwWidth
|
||||
// 36 - dwHeight
|
||||
|
||||
@VisibleForTesting(otherwise = VisibleForTesting.NONE)
|
||||
void setFlags(int flags) {
|
||||
byteBuffer.putInt(12, flags);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,10 +1,14 @@
|
|||
package com.google.android.exoplayer2.extractor.avi;
|
||||
|
||||
import com.google.android.exoplayer2.Format;
|
||||
import com.google.android.exoplayer2.extractor.Extractor;
|
||||
import com.google.android.exoplayer2.extractor.ExtractorInput;
|
||||
import com.google.android.exoplayer2.extractor.PositionHolder;
|
||||
import com.google.android.exoplayer2.extractor.SeekMap;
|
||||
import com.google.android.exoplayer2.testutil.FakeExtractorInput;
|
||||
import com.google.android.exoplayer2.testutil.FakeExtractorOutput;
|
||||
import com.google.android.exoplayer2.testutil.FakeTrackOutput;
|
||||
import com.google.android.exoplayer2.util.MimeTypes;
|
||||
import java.io.IOException;
|
||||
import java.nio.ByteBuffer;
|
||||
import org.junit.Assert;
|
||||
|
|
@ -296,4 +300,153 @@ public class AviExtractorTest {
|
|||
|
||||
Assert.assertTrue(listBox.getChildren().get(0) instanceof AviHeaderBox);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void findMovi_givenMoviListAndIndex() throws IOException {
|
||||
final AviExtractor aviExtractor = new AviExtractor();
|
||||
aviExtractor.setAviHeader(DataHelper.createAviHeaderBox());
|
||||
final FakeExtractorOutput fakeExtractorOutput = new FakeExtractorOutput();
|
||||
aviExtractor.init(fakeExtractorOutput);
|
||||
|
||||
ByteBuffer byteBuffer = AviExtractor.allocate(12);
|
||||
byteBuffer.putInt(ListBox.LIST);
|
||||
byteBuffer.putInt(64*1024);
|
||||
byteBuffer.putInt(AviExtractor.MOVI);
|
||||
final ExtractorInput input = new FakeExtractorInput.Builder().setData(byteBuffer.array()).build();
|
||||
aviExtractor.findMovi(input, new PositionHolder());
|
||||
Assert.assertEquals(aviExtractor.state, AviExtractor.STATE_READ_IDX1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void findMovi_givenMoviListAndNoIndex() throws IOException {
|
||||
final AviExtractor aviExtractor = new AviExtractor();
|
||||
final AviHeaderBox aviHeaderBox = DataHelper.createAviHeaderBox();
|
||||
aviHeaderBox.setFlags(0);
|
||||
aviExtractor.setAviHeader(aviHeaderBox);
|
||||
final FakeExtractorOutput fakeExtractorOutput = new FakeExtractorOutput();
|
||||
aviExtractor.init(fakeExtractorOutput);
|
||||
|
||||
ByteBuffer byteBuffer = AviExtractor.allocate(12);
|
||||
byteBuffer.putInt(ListBox.LIST);
|
||||
byteBuffer.putInt(64*1024);
|
||||
byteBuffer.putInt(AviExtractor.MOVI);
|
||||
final ExtractorInput input = new FakeExtractorInput.Builder().setData(byteBuffer.array()).build();
|
||||
aviExtractor.state = AviExtractor.STATE_FIND_MOVI;
|
||||
aviExtractor.read(input, new PositionHolder());
|
||||
Assert.assertEquals(aviExtractor.state, AviExtractor.STATE_READ_TRACKS);
|
||||
Assert.assertTrue(fakeExtractorOutput.seekMap instanceof SeekMap.Unseekable);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void findMovi_givenJunk() throws IOException {
|
||||
final AviExtractor aviExtractor = new AviExtractor();
|
||||
aviExtractor.setAviHeader(DataHelper.createAviHeaderBox());
|
||||
final FakeExtractorOutput fakeExtractorOutput = new FakeExtractorOutput();
|
||||
aviExtractor.init(fakeExtractorOutput);
|
||||
|
||||
ByteBuffer byteBuffer = AviExtractor.allocate(12);
|
||||
byteBuffer.putInt(AviExtractor.JUNK);
|
||||
byteBuffer.putInt(64*1024);
|
||||
final ExtractorInput input = new FakeExtractorInput.Builder().setData(byteBuffer.array()).build();
|
||||
final PositionHolder positionHolder = new PositionHolder();
|
||||
aviExtractor.findMovi(input, positionHolder);
|
||||
Assert.assertEquals(64 * 1024 + 8, positionHolder.position);
|
||||
}
|
||||
|
||||
private AviExtractor setupReadSamples() {
|
||||
final AviExtractor aviExtractor = new AviExtractor();
|
||||
aviExtractor.setAviHeader(DataHelper.createAviHeaderBox());
|
||||
final FakeExtractorOutput fakeExtractorOutput = new FakeExtractorOutput();
|
||||
aviExtractor.init(fakeExtractorOutput);
|
||||
|
||||
final AviTrack aviTrack = DataHelper.getVideoAviTrack(9);
|
||||
aviExtractor.setAviTracks(new AviTrack[]{aviTrack});
|
||||
final Format format = new Format.Builder().setSampleMimeType(MimeTypes.VIDEO_MP4V).build();
|
||||
aviTrack.trackOutput.format(format);
|
||||
|
||||
aviExtractor.state = AviExtractor.STATE_READ_SAMPLES;
|
||||
aviExtractor.setMovi(DataHelper.MOVI_OFFSET, 128*1024);
|
||||
return aviExtractor;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void readSamples_givenAtEndOfInput() throws IOException {
|
||||
AviExtractor aviExtractor = setupReadSamples();
|
||||
aviExtractor.setMovi(0, 0);
|
||||
final AviTrack aviTrack = aviExtractor.getVideoTrack();
|
||||
final ByteBuffer byteBuffer = AviExtractor.allocate(32);
|
||||
byteBuffer.putInt(aviTrack.chunkId);
|
||||
byteBuffer.putInt(24);
|
||||
|
||||
final ExtractorInput input = new FakeExtractorInput.Builder().setData(byteBuffer.array()).build();
|
||||
Assert.assertEquals(Extractor.RESULT_END_OF_INPUT, aviExtractor.read(input, new PositionHolder()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void readSamples_completeChunk() throws IOException {
|
||||
AviExtractor aviExtractor = setupReadSamples();
|
||||
final AviTrack aviTrack = aviExtractor.getVideoTrack();
|
||||
final ByteBuffer byteBuffer = AviExtractor.allocate(32);
|
||||
byteBuffer.putInt(aviTrack.chunkId);
|
||||
byteBuffer.putInt(24);
|
||||
|
||||
final ExtractorInput input = new FakeExtractorInput.Builder().setData(byteBuffer.array())
|
||||
.build();
|
||||
Assert.assertEquals(Extractor.RESULT_CONTINUE, aviExtractor.read(input, new PositionHolder()));
|
||||
|
||||
final FakeTrackOutput fakeTrackOutput = (FakeTrackOutput) aviTrack.trackOutput;
|
||||
Assert.assertEquals(24, fakeTrackOutput.getSampleData(0).length);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void readSamples_fragmentedChunk() throws IOException {
|
||||
AviExtractor aviExtractor = setupReadSamples();
|
||||
final AviTrack aviTrack = aviExtractor.getVideoTrack();
|
||||
final int size = 24 + 16;
|
||||
final ByteBuffer byteBuffer = AviExtractor.allocate(32);
|
||||
byteBuffer.putInt(aviTrack.chunkId);
|
||||
byteBuffer.putInt(size);
|
||||
|
||||
final ExtractorInput chunk0 = new FakeExtractorInput.Builder().setData(byteBuffer.array())
|
||||
.build();
|
||||
Assert.assertEquals(Extractor.RESULT_CONTINUE, aviExtractor.read(chunk0, new PositionHolder()));
|
||||
|
||||
final ExtractorInput chunk1 = new FakeExtractorInput.Builder().setData(new byte[16])
|
||||
.build();
|
||||
Assert.assertEquals(Extractor.RESULT_CONTINUE, aviExtractor.read(chunk1, new PositionHolder()));
|
||||
|
||||
final FakeTrackOutput fakeTrackOutput = (FakeTrackOutput) aviTrack.trackOutput;
|
||||
Assert.assertEquals(size, fakeTrackOutput.getSampleData(0).length);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void seek_givenPosition0() throws IOException {
|
||||
final AviExtractor aviExtractor = setupReadSamples();
|
||||
final AviTrack aviTrack = aviExtractor.getVideoTrack();
|
||||
aviExtractor.setChunkHandler(aviTrack);
|
||||
aviTrack.getClock().setIndex(10);
|
||||
|
||||
aviExtractor.seek(0L, 0L);
|
||||
|
||||
Assert.assertNull(aviExtractor.getChunkHandler());
|
||||
Assert.assertEquals(0, aviTrack.getClock().getIndex());
|
||||
Assert.assertEquals(aviExtractor.state, AviExtractor.STATE_SEEK_START);
|
||||
|
||||
|
||||
final ExtractorInput input = new FakeExtractorInput.Builder().setData(new byte[0]).build();
|
||||
final PositionHolder positionHolder = new PositionHolder();
|
||||
Assert.assertEquals(Extractor.RESULT_SEEK, aviExtractor.read(input, positionHolder));
|
||||
Assert.assertEquals(DataHelper.MOVI_OFFSET + 4, positionHolder.position);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void seek_givenKeyFrame() throws IOException {
|
||||
final AviExtractor aviExtractor = setupReadSamples();
|
||||
final AviSeekMap aviSeekMap = DataHelper.getAviSeekMap();
|
||||
aviExtractor.aviSeekMap = aviSeekMap;
|
||||
final AviTrack aviTrack = aviExtractor.getVideoTrack();
|
||||
final long position = DataHelper.MOVI_OFFSET + aviSeekMap.keyFrameOffsetsDiv2[1] * 2L;
|
||||
aviExtractor.seek(position, 0L);
|
||||
Assert.assertEquals(aviSeekMap.seekIndexes[aviTrack.id][1], aviTrack.getClock().getIndex());
|
||||
}
|
||||
}
|
||||
|
|
@ -8,9 +8,7 @@ public class AviHeaderBoxTest {
|
|||
|
||||
@Test
|
||||
public void getters() {
|
||||
final ByteBuffer byteBuffer = DataHelper.createAviHeader();
|
||||
final AviHeaderBox aviHeaderBox = new AviHeaderBox(AviHeaderBox.AVIH,
|
||||
byteBuffer.capacity(), byteBuffer);
|
||||
final AviHeaderBox aviHeaderBox = DataHelper.createAviHeaderBox();
|
||||
Assert.assertEquals(DataHelper.VIDEO_US, aviHeaderBox.getMicroSecPerFrame());
|
||||
Assert.assertTrue(aviHeaderBox.hasIndex());
|
||||
Assert.assertFalse(aviHeaderBox.mustUseIndex());
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ public class DataHelper {
|
|||
static final int VIDEO_SIZE = 4096;
|
||||
static final int AUDIO_SIZE = 256;
|
||||
static final int AUDIO_ID = 1;
|
||||
static final int MOVI_OFFSET = 4096;
|
||||
private static final long AUDIO_US = VIDEO_US / AUDIO_PER_VIDEO;
|
||||
|
||||
//Base path "\ExoPlayer\library\extractor\."
|
||||
|
|
@ -124,7 +125,7 @@ public class DataHelper {
|
|||
audioArray.add(0);
|
||||
audioArray.add(128);
|
||||
return new AviSeekMap(0, 100L, 8, keyFrameOffsetsDiv2,
|
||||
new UnboundedIntArray[]{videoArray, audioArray}, 4096);
|
||||
new UnboundedIntArray[]{videoArray, audioArray}, MOVI_OFFSET);
|
||||
}
|
||||
|
||||
private static void putIndex(final ByteBuffer byteBuffer, int chunkId, int flags, int offset,
|
||||
|
|
@ -186,4 +187,9 @@ public class DataHelper {
|
|||
byteBuffer.clear();
|
||||
return byteBuffer;
|
||||
}
|
||||
|
||||
public static AviHeaderBox createAviHeaderBox() {
|
||||
final ByteBuffer byteBuffer = createAviHeader();
|
||||
return new AviHeaderBox(AviHeaderBox.AVIH, byteBuffer.capacity(), byteBuffer);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue