mirror of
https://github.com/samsonjs/media.git
synced 2026-04-03 10:55:48 +00:00
Expose new non-discarding SampleQueue read/skip methods
------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=159555748
This commit is contained in:
parent
0ffc3ffd29
commit
467fd2535c
2 changed files with 112 additions and 33 deletions
|
|
@ -133,6 +133,9 @@ public class SampleQueueTest extends TestCase {
|
|||
assertReadFormat(true, TEST_FORMAT_1);
|
||||
// Otherwise should read the sample.
|
||||
assertSampleRead(1000, true, TEST_DATA, 0, ALLOCATION_SIZE);
|
||||
// Allocation should still be held.
|
||||
assertAllocationCount(1);
|
||||
sampleQueue.discardToRead();
|
||||
// The allocation should have been released.
|
||||
assertAllocationCount(0);
|
||||
|
||||
|
|
@ -147,6 +150,9 @@ public class SampleQueueTest extends TestCase {
|
|||
assertReadFormat(true, TEST_FORMAT_1);
|
||||
// Read the sample.
|
||||
assertSampleRead(2000, false, TEST_DATA, 0, ALLOCATION_SIZE - 1);
|
||||
// Allocation should still be held.
|
||||
assertAllocationCount(1);
|
||||
sampleQueue.discardToRead();
|
||||
// The last byte written to the sample queue may belong to a sample whose metadata has yet to be
|
||||
// written, so an allocation should still be held.
|
||||
assertAllocationCount(1);
|
||||
|
|
@ -158,6 +164,9 @@ public class SampleQueueTest extends TestCase {
|
|||
assertReadFormat(true, TEST_FORMAT_1);
|
||||
// Read the sample.
|
||||
assertSampleRead(3000, false, TEST_DATA, ALLOCATION_SIZE - 1, 1);
|
||||
// Allocation should still be held.
|
||||
assertAllocationCount(1);
|
||||
sampleQueue.discardToRead();
|
||||
// The allocation should have been released.
|
||||
assertAllocationCount(0);
|
||||
}
|
||||
|
|
@ -168,6 +177,8 @@ public class SampleQueueTest extends TestCase {
|
|||
sampleQueue.getLargestQueuedTimestampUs());
|
||||
assertAllocationCount(10);
|
||||
assertReadTestData();
|
||||
assertAllocationCount(10);
|
||||
sampleQueue.discardToRead();
|
||||
assertAllocationCount(0);
|
||||
}
|
||||
|
||||
|
|
@ -177,12 +188,42 @@ public class SampleQueueTest extends TestCase {
|
|||
assertAllocationCount(20);
|
||||
assertReadTestData(TEST_FORMAT_2);
|
||||
assertReadTestData(TEST_FORMAT_2);
|
||||
assertAllocationCount(20);
|
||||
sampleQueue.discardToRead();
|
||||
assertAllocationCount(0);
|
||||
}
|
||||
|
||||
public void testReadMultiWithRewind() {
|
||||
writeTestData();
|
||||
assertReadTestData();
|
||||
assertEquals(8, sampleQueue.getReadIndex());
|
||||
assertAllocationCount(10);
|
||||
// Rewind.
|
||||
sampleQueue.rewind();
|
||||
assertAllocationCount(10);
|
||||
// Read again.
|
||||
assertEquals(0, sampleQueue.getReadIndex());
|
||||
assertReadTestData();
|
||||
}
|
||||
|
||||
public void testRewindAfterDiscard() {
|
||||
writeTestData();
|
||||
assertReadTestData();
|
||||
sampleQueue.discardToRead();
|
||||
assertAllocationCount(0);
|
||||
// Rewind.
|
||||
sampleQueue.rewind();
|
||||
assertAllocationCount(0);
|
||||
// Can't read again.
|
||||
assertEquals(8, sampleQueue.getReadIndex());
|
||||
assertReadEndOfStream(false);
|
||||
}
|
||||
|
||||
public void testSkipAll() {
|
||||
writeTestData();
|
||||
sampleQueue.skipAll();
|
||||
sampleQueue.skipAll2();
|
||||
assertAllocationCount(10);
|
||||
sampleQueue.discardToRead();
|
||||
assertAllocationCount(0);
|
||||
// Despite skipping all samples, we should still read the last format, since this is the
|
||||
// expected format for a subsequent sample.
|
||||
|
|
@ -194,7 +235,9 @@ public class SampleQueueTest extends TestCase {
|
|||
public void testSkipAllRetainsUnassignedData() {
|
||||
sampleQueue.format(TEST_FORMAT_1);
|
||||
sampleQueue.sampleData(new ParsableByteArray(TEST_DATA), ALLOCATION_SIZE);
|
||||
sampleQueue.skipAll();
|
||||
sampleQueue.skipAll2();
|
||||
assertAllocationCount(1);
|
||||
sampleQueue.discardToRead();
|
||||
// Skipping shouldn't discard data that may belong to a sample whose metadata has yet to be
|
||||
// written.
|
||||
assertAllocationCount(1);
|
||||
|
|
@ -207,12 +250,14 @@ public class SampleQueueTest extends TestCase {
|
|||
// Once the metadata has been written, check the sample can be read as expected.
|
||||
assertSampleRead(0, true, TEST_DATA, 0, ALLOCATION_SIZE);
|
||||
assertNoSamplesToRead(TEST_FORMAT_1);
|
||||
assertAllocationCount(1);
|
||||
sampleQueue.discardToRead();
|
||||
assertAllocationCount(0);
|
||||
}
|
||||
|
||||
public void testSkipToKeyframeBeforeBuffer() {
|
||||
writeTestData();
|
||||
boolean result = sampleQueue.skipToKeyframeBefore(TEST_SAMPLE_TIMESTAMPS[0] - 1, false);
|
||||
boolean result = sampleQueue.skipToKeyframeBefore2(TEST_SAMPLE_TIMESTAMPS[0] - 1, false);
|
||||
// Should fail and have no effect.
|
||||
assertFalse(result);
|
||||
assertReadTestData();
|
||||
|
|
@ -221,7 +266,7 @@ public class SampleQueueTest extends TestCase {
|
|||
|
||||
public void testSkipToKeyframeStartOfBuffer() {
|
||||
writeTestData();
|
||||
boolean result = sampleQueue.skipToKeyframeBefore(TEST_SAMPLE_TIMESTAMPS[0], false);
|
||||
boolean result = sampleQueue.skipToKeyframeBefore2(TEST_SAMPLE_TIMESTAMPS[0], false);
|
||||
// Should succeed but have no effect (we're already at the first frame).
|
||||
assertTrue(result);
|
||||
assertReadTestData();
|
||||
|
|
@ -230,7 +275,7 @@ public class SampleQueueTest extends TestCase {
|
|||
|
||||
public void testSkipToKeyframeEndOfBuffer() {
|
||||
writeTestData();
|
||||
boolean result = sampleQueue.skipToKeyframeBefore(
|
||||
boolean result = sampleQueue.skipToKeyframeBefore2(
|
||||
TEST_SAMPLE_TIMESTAMPS[TEST_SAMPLE_TIMESTAMPS.length - 1], false);
|
||||
// Should succeed and skip to 2nd keyframe.
|
||||
assertTrue(result);
|
||||
|
|
@ -240,7 +285,7 @@ public class SampleQueueTest extends TestCase {
|
|||
|
||||
public void testSkipToKeyframeAfterBuffer() {
|
||||
writeTestData();
|
||||
boolean result = sampleQueue.skipToKeyframeBefore(
|
||||
boolean result = sampleQueue.skipToKeyframeBefore2(
|
||||
TEST_SAMPLE_TIMESTAMPS[TEST_SAMPLE_TIMESTAMPS.length - 1] + 1, false);
|
||||
// Should fail and have no effect.
|
||||
assertFalse(result);
|
||||
|
|
@ -250,7 +295,7 @@ public class SampleQueueTest extends TestCase {
|
|||
|
||||
public void testSkipToKeyframeAfterBufferAllowed() {
|
||||
writeTestData();
|
||||
boolean result = sampleQueue.skipToKeyframeBefore(
|
||||
boolean result = sampleQueue.skipToKeyframeBefore2(
|
||||
TEST_SAMPLE_TIMESTAMPS[TEST_SAMPLE_TIMESTAMPS.length - 1] + 1, true);
|
||||
// Should succeed and skip to 2nd keyframe.
|
||||
assertTrue(result);
|
||||
|
|
@ -305,6 +350,8 @@ public class SampleQueueTest extends TestCase {
|
|||
writeTestData();
|
||||
assertReadTestData(null, 0, 3);
|
||||
sampleQueue.discardUpstreamSamples(8);
|
||||
assertAllocationCount(10);
|
||||
sampleQueue.discardToRead();
|
||||
assertAllocationCount(7);
|
||||
sampleQueue.discardUpstreamSamples(7);
|
||||
assertAllocationCount(6);
|
||||
|
|
@ -359,6 +406,7 @@ public class SampleQueueTest extends TestCase {
|
|||
* Asserts correct reading of standard test data from {@code sampleQueue}.
|
||||
*
|
||||
* @param startFormat The format of the last sample previously read from {@code sampleQueue}.
|
||||
* @param firstSampleIndex The index of the first sample that's expected to be read.
|
||||
*/
|
||||
private void assertReadTestData(Format startFormat, int firstSampleIndex) {
|
||||
assertReadTestData(startFormat, firstSampleIndex,
|
||||
|
|
@ -428,7 +476,7 @@ public class SampleQueueTest extends TestCase {
|
|||
*/
|
||||
private void assertReadNothing(boolean formatRequired) {
|
||||
clearFormatHolderAndInputBuffer();
|
||||
int result = sampleQueue.readData(formatHolder, inputBuffer, formatRequired, false, 0);
|
||||
int result = sampleQueue.readData2(formatHolder, inputBuffer, formatRequired, false, 0);
|
||||
assertEquals(C.RESULT_NOTHING_READ, result);
|
||||
// formatHolder should not be populated.
|
||||
assertNull(formatHolder.format);
|
||||
|
|
@ -445,7 +493,7 @@ public class SampleQueueTest extends TestCase {
|
|||
*/
|
||||
private void assertReadEndOfStream(boolean formatRequired) {
|
||||
clearFormatHolderAndInputBuffer();
|
||||
int result = sampleQueue.readData(formatHolder, inputBuffer, formatRequired, true, 0);
|
||||
int result = sampleQueue.readData2(formatHolder, inputBuffer, formatRequired, true, 0);
|
||||
assertEquals(C.RESULT_BUFFER_READ, result);
|
||||
// formatHolder should not be populated.
|
||||
assertNull(formatHolder.format);
|
||||
|
|
@ -465,7 +513,7 @@ public class SampleQueueTest extends TestCase {
|
|||
*/
|
||||
private void assertReadFormat(boolean formatRequired, Format format) {
|
||||
clearFormatHolderAndInputBuffer();
|
||||
int result = sampleQueue.readData(formatHolder, inputBuffer, formatRequired, false, 0);
|
||||
int result = sampleQueue.readData2(formatHolder, inputBuffer, formatRequired, false, 0);
|
||||
assertEquals(C.RESULT_FORMAT_READ, result);
|
||||
// formatHolder should be populated.
|
||||
assertEquals(format, formatHolder.format);
|
||||
|
|
@ -487,7 +535,7 @@ public class SampleQueueTest extends TestCase {
|
|||
private void assertSampleRead(long timeUs, boolean isKeyframe, byte[] sampleData, int offset,
|
||||
int length) {
|
||||
clearFormatHolderAndInputBuffer();
|
||||
int result = sampleQueue.readData(formatHolder, inputBuffer, false, false, 0);
|
||||
int result = sampleQueue.readData2(formatHolder, inputBuffer, false, false, 0);
|
||||
assertEquals(C.RESULT_BUFFER_READ, result);
|
||||
// formatHolder should not be populated.
|
||||
assertNull(formatHolder.format);
|
||||
|
|
|
|||
|
|
@ -224,17 +224,50 @@ public final class SampleQueue implements TrackOutput {
|
|||
}
|
||||
|
||||
/**
|
||||
* Skips all samples currently in the buffer.
|
||||
* Rewinds the read position to the first sample in the queue.
|
||||
*/
|
||||
public void skipAll() {
|
||||
metadataQueue.skipAll();
|
||||
// TODO - Remove the following block and expose explicit discard operations.
|
||||
public void rewind() {
|
||||
metadataQueue.rewind();
|
||||
readAllocationNode = firstAllocationNode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Discards samples up to the current read position.
|
||||
*/
|
||||
public void discardToRead() {
|
||||
long nextOffset = metadataQueue.discardToRead();
|
||||
if (nextOffset != C.POSITION_UNSET) {
|
||||
dropDownstreamTo(nextOffset);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link #skipAll2()} followed by {@link #discardToRead()}.
|
||||
*/
|
||||
@Deprecated
|
||||
public void skipAll() {
|
||||
skipAll2();
|
||||
discardToRead();
|
||||
}
|
||||
|
||||
/**
|
||||
* Skips all samples currently in the buffer.
|
||||
*/
|
||||
public void skipAll2() {
|
||||
metadataQueue.skipAll();
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link #skipToKeyframeBefore2(long, boolean)} followed by
|
||||
* {@link #discardToRead()}.
|
||||
*/
|
||||
@Deprecated
|
||||
public boolean skipToKeyframeBefore(long timeUs, boolean allowTimeBeyondBuffer) {
|
||||
boolean success = skipToKeyframeBefore2(timeUs, allowTimeBeyondBuffer);
|
||||
discardToRead();
|
||||
return success;
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempts to skip to the keyframe before or at the specified time. Succeeds only if the buffer
|
||||
* contains a keyframe with a timestamp of {@code timeUs} or earlier. If
|
||||
|
|
@ -246,18 +279,21 @@ public final class SampleQueue implements TrackOutput {
|
|||
* of the buffer.
|
||||
* @return Whether the skip was successful.
|
||||
*/
|
||||
public boolean skipToKeyframeBefore(long timeUs, boolean allowTimeBeyondBuffer) {
|
||||
boolean success = metadataQueue.skipToKeyframeBefore(timeUs, allowTimeBeyondBuffer);
|
||||
if (success) {
|
||||
// TODO - Remove the following block and expose explicit discard operations.
|
||||
long nextOffset = metadataQueue.discardToRead();
|
||||
if (nextOffset != C.POSITION_UNSET) {
|
||||
dropDownstreamTo(nextOffset);
|
||||
}
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
public boolean skipToKeyframeBefore2(long timeUs, boolean allowTimeBeyondBuffer) {
|
||||
return metadataQueue.skipToKeyframeBefore(timeUs, allowTimeBeyondBuffer);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link #readData2(FormatHolder, DecoderInputBuffer, boolean, boolean, long)}
|
||||
* followed by {@link #discardToRead()}.
|
||||
*/
|
||||
@Deprecated
|
||||
public int readData(FormatHolder formatHolder, DecoderInputBuffer buffer, boolean formatRequired,
|
||||
boolean loadingFinished, long decodeOnlyUntilUs) {
|
||||
int result = readData2(formatHolder, buffer, formatRequired, loadingFinished,
|
||||
decodeOnlyUntilUs);
|
||||
discardToRead();
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -276,7 +312,7 @@ public final class SampleQueue implements TrackOutput {
|
|||
* @return The result, which can be {@link C#RESULT_NOTHING_READ}, {@link C#RESULT_FORMAT_READ} or
|
||||
* {@link C#RESULT_BUFFER_READ}.
|
||||
*/
|
||||
public int readData(FormatHolder formatHolder, DecoderInputBuffer buffer, boolean formatRequired,
|
||||
public int readData2(FormatHolder formatHolder, DecoderInputBuffer buffer, boolean formatRequired,
|
||||
boolean loadingFinished, long decodeOnlyUntilUs) {
|
||||
int result = metadataQueue.readData(formatHolder, buffer, formatRequired, loadingFinished,
|
||||
downstreamFormat, extrasHolder);
|
||||
|
|
@ -296,11 +332,6 @@ public final class SampleQueue implements TrackOutput {
|
|||
// Write the sample data into the holder.
|
||||
buffer.ensureSpaceForWrite(extrasHolder.size);
|
||||
readData(extrasHolder.offset, buffer.data, extrasHolder.size);
|
||||
// TODO - Remove the following block and expose explicit discard operations.
|
||||
long nextOffset = metadataQueue.discardToRead();
|
||||
if (nextOffset != C.POSITION_UNSET) {
|
||||
dropDownstreamTo(nextOffset);
|
||||
}
|
||||
}
|
||||
return C.RESULT_BUFFER_READ;
|
||||
case C.RESULT_NOTHING_READ:
|
||||
|
|
|
|||
Loading…
Reference in a new issue