diff --git a/library/src/androidTest/java/com/google/android/exoplayer/dash/DashChunkSourceTest.java b/library/src/androidTest/java/com/google/android/exoplayer/dash/DashChunkSourceTest.java index 5dc06b8c1f..cd8c52277a 100644 --- a/library/src/androidTest/java/com/google/android/exoplayer/dash/DashChunkSourceTest.java +++ b/library/src/androidTest/java/com/google/android/exoplayer/dash/DashChunkSourceTest.java @@ -18,7 +18,6 @@ package com.google.android.exoplayer.dash; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; -import com.google.android.exoplayer.MediaFormat; import com.google.android.exoplayer.TimeRange; import com.google.android.exoplayer.TrackRenderer; import com.google.android.exoplayer.chunk.ChunkOperationHolder; @@ -85,23 +84,14 @@ public class DashChunkSourceTest extends InstrumentationTestCase { private static final Format WIDE_VIDEO = new Format("3", "video/mp4", WIDE_WIDTH, 50, -1, -1, -1, 1000); - @Mock private DataSource mockDataSource; + @Mock + private DataSource mockDataSource; @Override public void setUp() throws Exception { TestUtil.setUpMockito(this); } - public void testMaxVideoDimensions() { - DashChunkSource chunkSource = new DashChunkSource(generateVodMpd(), AdaptationSet.TYPE_VIDEO, - null, null, null); - MediaFormat format = MediaFormat.createVideoFormat("video/h264", 5000, 1, 1, 1, 1, 1, null); - format = chunkSource.getWithMaxVideoDimensions(format); - - assertEquals(WIDE_WIDTH, format.maxWidth); - assertEquals(TALL_HEIGHT, format.maxHeight); - } - public void testGetAvailableRangeOnVod() { DashChunkSource chunkSource = new DashChunkSource(generateVodMpd(), AdaptationSet.TYPE_VIDEO, null, null, mock(FormatEvaluator.class)); @@ -192,22 +182,6 @@ public class DashChunkSourceTest extends InstrumentationTestCase { checkSegmentRequestSequenceOnMultiPeriodLive(chunkSource); } - public void testMaxVideoDimensionsLegacy() { - SingleSegmentBase segmentBase1 = new SingleSegmentBase("https://example.com/1.mp4"); - Representation representation1 = - Representation.newInstance(0, 0, null, 0, TALL_VIDEO, segmentBase1); - - SingleSegmentBase segmentBase2 = new SingleSegmentBase("https://example.com/2.mp4"); - Representation representation2 = - Representation.newInstance(0, 0, null, 0, WIDE_VIDEO, segmentBase2); - - DashChunkSource chunkSource = new DashChunkSource(null, null, representation1, representation2); - MediaFormat format = MediaFormat.createVideoFormat("video/h264", 5000, 1, 1, 1, 1, 1, null); - format = chunkSource.getWithMaxVideoDimensions(format); - - assertEquals(WIDE_WIDTH, format.maxWidth); - assertEquals(TALL_HEIGHT, format.maxHeight); - } public void testLiveEdgeNoLatency() { long startTimeMs = 0; diff --git a/library/src/main/java/com/google/android/exoplayer/MediaFormat.java b/library/src/main/java/com/google/android/exoplayer/MediaFormat.java index 1151d79575..650f6cac4b 100644 --- a/library/src/main/java/com/google/android/exoplayer/MediaFormat.java +++ b/library/src/main/java/com/google/android/exoplayer/MediaFormat.java @@ -323,25 +323,12 @@ public final class MediaFormat { if (obj == null || getClass() != obj.getClass()) { return false; } - return equalsInternal((MediaFormat) obj, false); - } - - public boolean equals(MediaFormat other, boolean ignoreMaxDimensions) { - if (this == other) { - return true; - } - if (other == null) { - return false; - } - return equalsInternal(other, ignoreMaxDimensions); - } - - private boolean equalsInternal(MediaFormat other, boolean ignoreMaxDimensions) { + MediaFormat other = (MediaFormat) obj; if (adaptive != other.adaptive || bitrate != other.bitrate || maxInputSize != other.maxInputSize || width != other.width || height != other.height || rotationDegrees != other.rotationDegrees || pixelWidthHeightRatio != other.pixelWidthHeightRatio - || (!ignoreMaxDimensions && (maxWidth != other.maxWidth || maxHeight != other.maxHeight)) + || maxWidth != other.maxWidth || maxHeight != other.maxHeight || channelCount != other.channelCount || sampleRate != other.sampleRate || !Util.areEqual(language, other.language) || !Util.areEqual(mimeType, other.mimeType) || initializationData.size() != other.initializationData.size()) { diff --git a/library/src/main/java/com/google/android/exoplayer/chunk/ChunkSampleSource.java b/library/src/main/java/com/google/android/exoplayer/chunk/ChunkSampleSource.java index 4b63a911d8..e87f9eca3e 100644 --- a/library/src/main/java/com/google/android/exoplayer/chunk/ChunkSampleSource.java +++ b/library/src/main/java/com/google/android/exoplayer/chunk/ChunkSampleSource.java @@ -232,8 +232,7 @@ public class ChunkSampleSource implements SampleSource, SampleSourceReader, Load if (haveSamples || currentChunk.isMediaFormatFinal) { MediaFormat mediaFormat = currentChunk.getMediaFormat(); - if (!mediaFormat.equals(downstreamMediaFormat, true)) { - mediaFormat = chunkSource.getWithMaxVideoDimensions(mediaFormat); + if (!mediaFormat.equals(downstreamMediaFormat)) { formatHolder.format = mediaFormat; formatHolder.drmInitData = currentChunk.getDrmInitData(); downstreamMediaFormat = mediaFormat; diff --git a/library/src/main/java/com/google/android/exoplayer/chunk/ChunkSource.java b/library/src/main/java/com/google/android/exoplayer/chunk/ChunkSource.java index 64d7b10c3e..00fcb7a628 100644 --- a/library/src/main/java/com/google/android/exoplayer/chunk/ChunkSource.java +++ b/library/src/main/java/com/google/android/exoplayer/chunk/ChunkSource.java @@ -76,19 +76,6 @@ public interface ChunkSource { */ void enable(int track); - /** - * Adaptive video {@link ChunkSource} implementations must return a copy of the provided - * {@link MediaFormat} with the maximum video dimensions set. Other implementations can return - * the provided {@link MediaFormat} directly. - *
- * This method should only be called when the source is enabled. - * - * @param format The format to be copied or returned. - * @return A copy of the provided {@link MediaFormat} with the maximum video dimensions set, or - * the provided format. - */ - MediaFormat getWithMaxVideoDimensions(MediaFormat format); - /** * Indicates to the source that it should still be checking for updates to the stream. *
diff --git a/library/src/main/java/com/google/android/exoplayer/chunk/ContainerMediaChunk.java b/library/src/main/java/com/google/android/exoplayer/chunk/ContainerMediaChunk.java
index 6e4655c34f..26efddebd5 100644
--- a/library/src/main/java/com/google/android/exoplayer/chunk/ContainerMediaChunk.java
+++ b/library/src/main/java/com/google/android/exoplayer/chunk/ContainerMediaChunk.java
@@ -36,6 +36,8 @@ public class ContainerMediaChunk extends BaseMediaChunk implements SingleTrackOu
private final ChunkExtractorWrapper extractorWrapper;
private final long sampleOffsetUs;
+ private final int adaptiveMaxWidth;
+ private final int adaptiveMaxHeight;
private MediaFormat mediaFormat;
private DrmInitData drmInitData;
@@ -56,6 +58,12 @@ public class ContainerMediaChunk extends BaseMediaChunk implements SingleTrackOu
* @param extractorWrapper A wrapped extractor to use for parsing the data.
* @param mediaFormat The {@link MediaFormat} of the chunk, if known. May be null if the data is
* known to define its own format.
+ * @param adaptiveMaxWidth If this chunk contains video and is part of an adaptive playback, this
+ * is the maximum width of the video in pixels that will be encountered during the playback.
+ * {@link MediaFormat#NO_VALUE} otherwise.
+ * @param adaptiveMaxHeight If this chunk contains video and is part of an adaptive playback, this
+ * is the maximum height of the video in pixels that will be encountered during the playback.
+ * {@link MediaFormat#NO_VALUE} otherwise.
* @param drmInitData The {@link DrmInitData} for the chunk. Null if the media is not drm
* protected. May also be null if the data is known to define its own initialization data.
* @param isMediaFormatFinal True if {@code mediaFormat} and {@code drmInitData} are known to be
@@ -64,13 +72,16 @@ public class ContainerMediaChunk extends BaseMediaChunk implements SingleTrackOu
*/
public ContainerMediaChunk(DataSource dataSource, DataSpec dataSpec, int trigger, Format format,
long startTimeUs, long endTimeUs, int chunkIndex, boolean isLastChunk, long sampleOffsetUs,
- ChunkExtractorWrapper extractorWrapper, MediaFormat mediaFormat, DrmInitData drmInitData,
- boolean isMediaFormatFinal, int parentId) {
+ ChunkExtractorWrapper extractorWrapper, MediaFormat mediaFormat, int adaptiveMaxWidth,
+ int adaptiveMaxHeight, DrmInitData drmInitData, boolean isMediaFormatFinal, int parentId) {
super(dataSource, dataSpec, trigger, format, startTimeUs, endTimeUs, chunkIndex, isLastChunk,
isMediaFormatFinal, parentId);
this.extractorWrapper = extractorWrapper;
this.sampleOffsetUs = sampleOffsetUs;
- this.mediaFormat = getAdjustedMediaFormat(mediaFormat, sampleOffsetUs);
+ this.adaptiveMaxWidth = adaptiveMaxWidth;
+ this.adaptiveMaxHeight = adaptiveMaxHeight;
+ this.mediaFormat = getAdjustedMediaFormat(mediaFormat, sampleOffsetUs, adaptiveMaxWidth,
+ adaptiveMaxHeight);
this.drmInitData = drmInitData;
}
@@ -103,7 +114,8 @@ public class ContainerMediaChunk extends BaseMediaChunk implements SingleTrackOu
@Override
public final void format(MediaFormat mediaFormat) {
- this.mediaFormat = getAdjustedMediaFormat(mediaFormat, sampleOffsetUs);
+ this.mediaFormat = getAdjustedMediaFormat(mediaFormat, sampleOffsetUs, adaptiveMaxWidth,
+ adaptiveMaxHeight);
}
@Override
@@ -163,10 +175,16 @@ public class ContainerMediaChunk extends BaseMediaChunk implements SingleTrackOu
// Private methods.
- private static MediaFormat getAdjustedMediaFormat(MediaFormat format, long sampleOffsetUs) {
- if (sampleOffsetUs != 0 && format != null
- && format.subsampleOffsetUs != MediaFormat.OFFSET_SAMPLE_RELATIVE) {
- return format.copyWithSubsampleOffsetUs(format.subsampleOffsetUs + sampleOffsetUs);
+ private static MediaFormat getAdjustedMediaFormat(MediaFormat format, long sampleOffsetUs,
+ int adaptiveMaxWidth, int adaptiveMaxHeight) {
+ if (format == null) {
+ return null;
+ }
+ if (sampleOffsetUs != 0 && format.subsampleOffsetUs != MediaFormat.OFFSET_SAMPLE_RELATIVE) {
+ format = format.copyWithSubsampleOffsetUs(format.subsampleOffsetUs + sampleOffsetUs);
+ }
+ if (adaptiveMaxWidth != MediaFormat.NO_VALUE || adaptiveMaxHeight != MediaFormat.NO_VALUE) {
+ format = format.copyWithMaxVideoDimensions(adaptiveMaxWidth, adaptiveMaxHeight);
}
return format;
}
diff --git a/library/src/main/java/com/google/android/exoplayer/chunk/MultiTrackChunkSource.java b/library/src/main/java/com/google/android/exoplayer/chunk/MultiTrackChunkSource.java
index 5bb43be5b5..2a51262b7c 100644
--- a/library/src/main/java/com/google/android/exoplayer/chunk/MultiTrackChunkSource.java
+++ b/library/src/main/java/com/google/android/exoplayer/chunk/MultiTrackChunkSource.java
@@ -108,11 +108,6 @@ public final class MultiTrackChunkSource implements ChunkSource, ExoPlayerCompon
selectedSource.maybeThrowError();
}
- @Override
- public MediaFormat getWithMaxVideoDimensions(MediaFormat format) {
- return selectedSource.getWithMaxVideoDimensions(format);
- }
-
@Override
public void handleMessage(int what, Object msg) throws ExoPlaybackException {
Assertions.checkState(!enabled);
diff --git a/library/src/main/java/com/google/android/exoplayer/chunk/SingleSampleChunkSource.java b/library/src/main/java/com/google/android/exoplayer/chunk/SingleSampleChunkSource.java
index 7f753ae557..c600504350 100644
--- a/library/src/main/java/com/google/android/exoplayer/chunk/SingleSampleChunkSource.java
+++ b/library/src/main/java/com/google/android/exoplayer/chunk/SingleSampleChunkSource.java
@@ -69,11 +69,6 @@ public final class SingleSampleChunkSource implements ChunkSource {
return mediaFormat;
}
- @Override
- public MediaFormat getWithMaxVideoDimensions(MediaFormat format) {
- return format;
- }
-
@Override
public void enable(int track) {
// Do nothing.
diff --git a/library/src/main/java/com/google/android/exoplayer/dash/DashChunkSource.java b/library/src/main/java/com/google/android/exoplayer/dash/DashChunkSource.java
index 8f56f68307..952f0c1a48 100644
--- a/library/src/main/java/com/google/android/exoplayer/dash/DashChunkSource.java
+++ b/library/src/main/java/com/google/android/exoplayer/dash/DashChunkSource.java
@@ -271,11 +271,10 @@ public class DashChunkSource implements ChunkSource {
processManifest(currentManifest);
- String mimeType = "";
long totalDurationUs = 0;
- int maxHeight = 0;
int maxWidth = 0;
-
+ int maxHeight = 0;
+ String mimeType = "";
for (int i = 0; i < periodHolders.size(); i++) {
PeriodHolder periodHolder = periodHolders.valueAt(i);
if (totalDurationUs != TrackRenderer.UNKNOWN_TIME_US) {
@@ -285,21 +284,15 @@ public class DashChunkSource implements ChunkSource {
totalDurationUs += periodHolder.durationUs;
}
}
- mimeType = periodHolder.mimeType;
- maxHeight = Math.max(maxHeight, periodHolder.maxHeight);
maxWidth = Math.max(maxWidth, periodHolder.maxWidth);
+ maxHeight = Math.max(maxHeight, periodHolder.maxHeight);
+ mimeType = periodHolder.mimeType;
}
+ this.maxWidth = maxWidth == 0 ? MediaFormat.NO_VALUE : maxWidth;
+ this.maxHeight = maxHeight == 0 ? MediaFormat.NO_VALUE : maxHeight;
// TODO: Remove this and pass proper formats instead (b/22996976).
this.mediaFormat = MediaFormat.createFormatForMimeType(mimeType, MediaFormat.NO_VALUE,
totalDurationUs);
- this.maxHeight = maxHeight;
- this.maxWidth = maxWidth;
- }
-
- @Override
- public final MediaFormat getWithMaxVideoDimensions(MediaFormat format) {
- return MimeTypes.isVideo(mediaFormat.mimeType)
- ? format.copyWithMaxVideoDimensions(maxWidth, maxHeight) : format;
}
@Override
@@ -606,8 +599,8 @@ public class DashChunkSource implements ChunkSource {
boolean isMediaFormatFinal = (mediaFormat != null);
return new ContainerMediaChunk(dataSource, dataSpec, trigger, representation.format,
startTimeUs, endTimeUs, segmentNum, isLastSegment, sampleOffsetUs,
- representationHolder.extractorWrapper, mediaFormat, drmInitData, isMediaFormatFinal,
- periodHolder.manifestIndex);
+ representationHolder.extractorWrapper, mediaFormat, maxWidth, maxHeight, drmInitData,
+ isMediaFormatFinal, periodHolder.manifestIndex);
}
}
@@ -854,8 +847,8 @@ public class DashChunkSource implements ChunkSource {
formats = new Format[representationCount];
representationHolders = new HashMap<>(representationCount);
- int maxWidth = -1;
- int maxHeight = -1;
+ int maxWidth = 0;
+ int maxHeight = 0;
String mimeType = "";
for (int i = 0; i < representationCount; i++) {
int representationIndex = representationIndices != null ? representationIndices[i] : i;
diff --git a/library/src/main/java/com/google/android/exoplayer/hls/HlsChunkSource.java b/library/src/main/java/com/google/android/exoplayer/hls/HlsChunkSource.java
index 815473e6d7..aa89804e9d 100644
--- a/library/src/main/java/com/google/android/exoplayer/hls/HlsChunkSource.java
+++ b/library/src/main/java/com/google/android/exoplayer/hls/HlsChunkSource.java
@@ -119,8 +119,8 @@ public class HlsChunkSource {
private final BandwidthMeter bandwidthMeter;
private final int adaptiveMode;
private final String baseUri;
- private final int maxWidth;
- private final int maxHeight;
+ private final int adaptiveMaxWidth;
+ private final int adaptiveMaxHeight;
private final long minBufferDurationToSwitchUpUs;
private final long maxBufferDurationToSwitchDownUs;
@@ -184,8 +184,8 @@ public class HlsChunkSource {
variantBlacklistTimes = new long[1];
setMediaPlaylist(0, (HlsMediaPlaylist) playlist);
// We won't be adapting between different variants.
- maxWidth = -1;
- maxHeight = -1;
+ adaptiveMaxWidth = MediaFormat.NO_VALUE;
+ adaptiveMaxHeight = MediaFormat.NO_VALUE;
} else {
List