mirror of
https://github.com/androidx/media.git
synced 2025-05-07 07:30:22 +08:00
Move Format equality check back to write side of sample queue
PiperOrigin-RevId: 258752996
This commit is contained in:
parent
e25340be3d
commit
c67f18764f
@ -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).
|
||||
@ -140,6 +140,33 @@ public final class SampleQueueTest {
|
||||
assertNoSamplesToRead(FORMAT_1);
|
||||
}
|
||||
|
||||
@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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user