mirror of
https://github.com/androidx/media.git
synced 2025-05-07 23:50:44 +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 upstreamKeyframeRequired;
|
||||||
private boolean upstreamFormatRequired;
|
private boolean upstreamFormatRequired;
|
||||||
private Format upstreamFormat;
|
private Format upstreamFormat;
|
||||||
|
private Format upstreamCommittedFormat;
|
||||||
private int upstreamSourceId;
|
private int upstreamSourceId;
|
||||||
|
|
||||||
public SampleMetadataQueue() {
|
public SampleMetadataQueue() {
|
||||||
@ -96,6 +97,7 @@ import com.google.android.exoplayer2.util.Util;
|
|||||||
largestDiscardedTimestampUs = Long.MIN_VALUE;
|
largestDiscardedTimestampUs = Long.MIN_VALUE;
|
||||||
largestQueuedTimestampUs = Long.MIN_VALUE;
|
largestQueuedTimestampUs = Long.MIN_VALUE;
|
||||||
isLastSampleQueued = false;
|
isLastSampleQueued = false;
|
||||||
|
upstreamCommittedFormat = null;
|
||||||
if (resetUpstreamFormat) {
|
if (resetUpstreamFormat) {
|
||||||
upstreamFormat = null;
|
upstreamFormat = null;
|
||||||
upstreamFormatRequired = true;
|
upstreamFormatRequired = true;
|
||||||
@ -227,7 +229,7 @@ import com.google.android.exoplayer2.util.Util;
|
|||||||
return SampleQueue.PEEK_RESULT_NOTHING;
|
return SampleQueue.PEEK_RESULT_NOTHING;
|
||||||
}
|
}
|
||||||
int relativeReadIndex = getRelativeIndex(readPosition);
|
int relativeReadIndex = getRelativeIndex(readPosition);
|
||||||
if (!formats[relativeReadIndex].equals(downstreamFormat)) {
|
if (formats[relativeReadIndex] != downstreamFormat) {
|
||||||
return SampleQueue.PEEK_RESULT_FORMAT;
|
return SampleQueue.PEEK_RESULT_FORMAT;
|
||||||
} else {
|
} else {
|
||||||
return (flags[relativeReadIndex] & C.BUFFER_FLAG_ENCRYPTED) != 0
|
return (flags[relativeReadIndex] & C.BUFFER_FLAG_ENCRYPTED) != 0
|
||||||
@ -274,8 +276,7 @@ import com.google.android.exoplayer2.util.Util;
|
|||||||
if (loadingFinished || isLastSampleQueued) {
|
if (loadingFinished || isLastSampleQueued) {
|
||||||
buffer.setFlags(C.BUFFER_FLAG_END_OF_STREAM);
|
buffer.setFlags(C.BUFFER_FLAG_END_OF_STREAM);
|
||||||
return C.RESULT_BUFFER_READ;
|
return C.RESULT_BUFFER_READ;
|
||||||
} else if (upstreamFormat != null
|
} else if (upstreamFormat != null && (formatRequired || upstreamFormat != downstreamFormat)) {
|
||||||
&& (formatRequired || !upstreamFormat.equals(downstreamFormat))) {
|
|
||||||
formatHolder.format = upstreamFormat;
|
formatHolder.format = upstreamFormat;
|
||||||
return C.RESULT_FORMAT_READ;
|
return C.RESULT_FORMAT_READ;
|
||||||
} else {
|
} else {
|
||||||
@ -284,7 +285,7 @@ import com.google.android.exoplayer2.util.Util;
|
|||||||
}
|
}
|
||||||
|
|
||||||
int relativeReadIndex = getRelativeIndex(readPosition);
|
int relativeReadIndex = getRelativeIndex(readPosition);
|
||||||
if (formatRequired || !formats[relativeReadIndex].equals(downstreamFormat)) {
|
if (formatRequired || formats[relativeReadIndex] != downstreamFormat) {
|
||||||
formatHolder.format = formats[relativeReadIndex];
|
formatHolder.format = formats[relativeReadIndex];
|
||||||
return C.RESULT_FORMAT_READ;
|
return C.RESULT_FORMAT_READ;
|
||||||
}
|
}
|
||||||
@ -422,7 +423,16 @@ import com.google.android.exoplayer2.util.Util;
|
|||||||
}
|
}
|
||||||
upstreamFormatRequired = false;
|
upstreamFormatRequired = false;
|
||||||
if (Util.areEqual(format, upstreamFormat)) {
|
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;
|
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 {
|
} else {
|
||||||
upstreamFormat = format;
|
upstreamFormat = format;
|
||||||
return true;
|
return true;
|
||||||
@ -450,6 +460,7 @@ import com.google.android.exoplayer2.util.Util;
|
|||||||
cryptoDatas[relativeEndIndex] = cryptoData;
|
cryptoDatas[relativeEndIndex] = cryptoData;
|
||||||
formats[relativeEndIndex] = upstreamFormat;
|
formats[relativeEndIndex] = upstreamFormat;
|
||||||
sourceIds[relativeEndIndex] = upstreamSourceId;
|
sourceIds[relativeEndIndex] = upstreamSourceId;
|
||||||
|
upstreamCommittedFormat = upstreamFormat;
|
||||||
|
|
||||||
length++;
|
length++;
|
||||||
if (length == capacity) {
|
if (length == capacity) {
|
||||||
|
@ -129,10 +129,10 @@ public final class SampleQueueTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testReadFormatDeduplicated() {
|
public void testEqualFormatsDeduplicated() {
|
||||||
sampleQueue.format(FORMAT_1);
|
sampleQueue.format(FORMAT_1);
|
||||||
assertReadFormat(false, 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);
|
sampleQueue.format(FORMAT_1);
|
||||||
assertNoSamplesToRead(FORMAT_1);
|
assertNoSamplesToRead(FORMAT_1);
|
||||||
// The same applies for a format that's equal (but a different object).
|
// The same applies for a format that's equal (but a different object).
|
||||||
@ -140,6 +140,33 @@ public final class SampleQueueTest {
|
|||||||
assertNoSamplesToRead(FORMAT_1);
|
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
|
@Test
|
||||||
public void testReadSingleSamples() {
|
public void testReadSingleSamples() {
|
||||||
sampleQueue.sampleData(new ParsableByteArray(DATA), ALLOCATION_SIZE);
|
sampleQueue.sampleData(new ParsableByteArray(DATA), ALLOCATION_SIZE);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user