Commit c67f1876 by olly Committed by Oliver Woodman

Move Format equality check back to write side of sample queue

PiperOrigin-RevId: 258752996
parent e25340be
......@@ -62,6 +62,7 @@ import com.google.android.exoplayer2.util.Util;
private boolean upstreamKeyframeRequired;
private boolean upstreamFormatRequired;
private Format upstreamFormat;
private Format upstreamCommittedFormat;
private int upstreamSourceId;
public SampleMetadataQueue() {
......@@ -96,6 +97,7 @@ import com.google.android.exoplayer2.util.Util;
largestDiscardedTimestampUs = Long.MIN_VALUE;
largestQueuedTimestampUs = Long.MIN_VALUE;
isLastSampleQueued = false;
upstreamCommittedFormat = null;
if (resetUpstreamFormat) {
upstreamFormat = null;
upstreamFormatRequired = true;
......@@ -227,7 +229,7 @@ import com.google.android.exoplayer2.util.Util;
return SampleQueue.PEEK_RESULT_NOTHING;
}
int relativeReadIndex = getRelativeIndex(readPosition);
if (!formats[relativeReadIndex].equals(downstreamFormat)) {
if (formats[relativeReadIndex] != downstreamFormat) {
return SampleQueue.PEEK_RESULT_FORMAT;
} else {
return (flags[relativeReadIndex] & C.BUFFER_FLAG_ENCRYPTED) != 0
......@@ -274,8 +276,7 @@ import com.google.android.exoplayer2.util.Util;
if (loadingFinished || isLastSampleQueued) {
buffer.setFlags(C.BUFFER_FLAG_END_OF_STREAM);
return C.RESULT_BUFFER_READ;
} else if (upstreamFormat != null
&& (formatRequired || !upstreamFormat.equals(downstreamFormat))) {
} else if (upstreamFormat != null && (formatRequired || upstreamFormat != downstreamFormat)) {
formatHolder.format = upstreamFormat;
return C.RESULT_FORMAT_READ;
} else {
......@@ -284,7 +285,7 @@ import com.google.android.exoplayer2.util.Util;
}
int relativeReadIndex = getRelativeIndex(readPosition);
if (formatRequired || !formats[relativeReadIndex].equals(downstreamFormat)) {
if (formatRequired || formats[relativeReadIndex] != downstreamFormat) {
formatHolder.format = formats[relativeReadIndex];
return C.RESULT_FORMAT_READ;
}
......@@ -422,7 +423,16 @@ import com.google.android.exoplayer2.util.Util;
}
upstreamFormatRequired = false;
if (Util.areEqual(format, upstreamFormat)) {
// The format is unchanged. If format and upstreamFormat are different objects, we keep the
// current upstreamFormat so we can detect format changes in read() using cheap referential
// equality.
return false;
} else if (Util.areEqual(format, upstreamCommittedFormat)) {
// The format has changed back to the format of the last committed sample. If they are
// different objects, we revert back to using upstreamCommittedFormat as the upstreamFormat so
// we can detect format changes in read() using cheap referential equality.
upstreamFormat = upstreamCommittedFormat;
return true;
} else {
upstreamFormat = format;
return true;
......@@ -450,6 +460,7 @@ import com.google.android.exoplayer2.util.Util;
cryptoDatas[relativeEndIndex] = cryptoData;
formats[relativeEndIndex] = upstreamFormat;
sourceIds[relativeEndIndex] = upstreamSourceId;
upstreamCommittedFormat = upstreamFormat;
length++;
if (length == capacity) {
......
......@@ -129,10 +129,10 @@ public final class SampleQueueTest {
}
@Test
public void testReadFormatDeduplicated() {
public void testEqualFormatsDeduplicated() {
sampleQueue.format(FORMAT_1);
assertReadFormat(false, FORMAT_1);
// If the same format is input then it should be de-duplicated (i.e. not output again).
// If the same format is written then it should not cause a format change on the read side.
sampleQueue.format(FORMAT_1);
assertNoSamplesToRead(FORMAT_1);
// The same applies for a format that's equal (but a different object).
......@@ -141,6 +141,33 @@ public final class SampleQueueTest {
}
@Test
public void testMultipleFormatsDeduplicated() {
sampleQueue.format(FORMAT_1);
sampleQueue.sampleData(new ParsableByteArray(DATA), ALLOCATION_SIZE);
sampleQueue.sampleMetadata(0, C.BUFFER_FLAG_KEY_FRAME, ALLOCATION_SIZE, 0, null);
// Writing multiple formats should not cause a format change on the read side, provided the last
// format to be written is equal to the format of the previous sample.
sampleQueue.format(FORMAT_2);
sampleQueue.format(FORMAT_1_COPY);
sampleQueue.sampleData(new ParsableByteArray(DATA), ALLOCATION_SIZE);
sampleQueue.sampleMetadata(1000, C.BUFFER_FLAG_KEY_FRAME, ALLOCATION_SIZE, 0, null);
assertReadFormat(false, FORMAT_1);
assertReadSample(0, true, DATA, 0, ALLOCATION_SIZE);
// Assert the second sample is read without a format change.
assertReadSample(1000, true, DATA, 0, ALLOCATION_SIZE);
// The same applies if the queue is empty when the formats are written.
sampleQueue.format(FORMAT_2);
sampleQueue.format(FORMAT_1);
sampleQueue.sampleData(new ParsableByteArray(DATA), ALLOCATION_SIZE);
sampleQueue.sampleMetadata(2000, C.BUFFER_FLAG_KEY_FRAME, ALLOCATION_SIZE, 0, null);
// Assert the third sample is read without a format change.
assertReadSample(2000, true, DATA, 0, ALLOCATION_SIZE);
}
@Test
public void testReadSingleSamples() {
sampleQueue.sampleData(new ParsableByteArray(DATA), ALLOCATION_SIZE);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment