mirror of
https://github.com/androidx/media.git
synced 2025-05-07 15:40:37 +08:00
Clean up max dimension handling.
This commit is contained in:
parent
4a9ff7b094
commit
cb85dc25aa
@ -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;
|
||||
|
@ -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()) {
|
||||
|
@ -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;
|
||||
|
@ -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.
|
||||
* <p>
|
||||
* 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.
|
||||
* <p>
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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.
|
||||
|
@ -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;
|
||||
|
@ -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<Variant> masterPlaylistVariants = ((HlsMasterPlaylist) playlist).variants;
|
||||
variants = buildOrderedVariants(masterPlaylistVariants, variantIndices);
|
||||
@ -208,13 +208,13 @@ public class HlsChunkSource {
|
||||
}
|
||||
if (variants.length <= 1 || adaptiveMode == ADAPTIVE_MODE_NONE) {
|
||||
// We won't be adapting between different variants.
|
||||
this.maxWidth = -1;
|
||||
this.maxHeight = -1;
|
||||
this.adaptiveMaxWidth = MediaFormat.NO_VALUE;
|
||||
this.adaptiveMaxHeight = MediaFormat.NO_VALUE;
|
||||
} else {
|
||||
// We will be adapting between different variants.
|
||||
// TODO: We should allow the default values to be passed through the constructor.
|
||||
this.maxWidth = maxWidth > 0 ? maxWidth : 1920;
|
||||
this.maxHeight = maxHeight > 0 ? maxHeight : 1080;
|
||||
this.adaptiveMaxWidth = maxWidth > 0 ? maxWidth : 1920;
|
||||
this.adaptiveMaxHeight = maxHeight > 0 ? maxHeight : 1080;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -223,20 +223,6 @@ public class HlsChunkSource {
|
||||
return live ? C.UNKNOWN_TIME_US : durationUs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adaptive 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.
|
||||
*
|
||||
* @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.
|
||||
*/
|
||||
public MediaFormat getWithMaxVideoDimensions(MediaFormat format) {
|
||||
return (maxWidth == -1 || maxHeight == -1) ? format
|
||||
: format.copyWithMaxVideoDimensions(maxWidth, maxHeight);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the next {@link Chunk} that should be loaded.
|
||||
*
|
||||
@ -348,7 +334,7 @@ public class HlsChunkSource {
|
||||
Extractor extractor = chunkUri.getLastPathSegment().endsWith(AAC_FILE_EXTENSION)
|
||||
? new AdtsExtractor(startTimeUs) : new TsExtractor(startTimeUs);
|
||||
extractorWrapper = new HlsExtractorWrapper(trigger, format, startTimeUs, extractor,
|
||||
switchingVariantSpliced);
|
||||
switchingVariantSpliced, adaptiveMaxWidth, adaptiveMaxHeight);
|
||||
} else {
|
||||
extractorWrapper = previousTsChunk.extractorWrapper;
|
||||
}
|
||||
|
@ -27,6 +27,7 @@ import com.google.android.exoplayer.extractor.SeekMap;
|
||||
import com.google.android.exoplayer.extractor.TrackOutput;
|
||||
import com.google.android.exoplayer.upstream.Allocator;
|
||||
import com.google.android.exoplayer.util.Assertions;
|
||||
import com.google.android.exoplayer.util.MimeTypes;
|
||||
|
||||
import android.util.SparseArray;
|
||||
|
||||
@ -44,7 +45,10 @@ public final class HlsExtractorWrapper implements ExtractorOutput {
|
||||
private final Extractor extractor;
|
||||
private final SparseArray<DefaultTrackOutput> sampleQueues;
|
||||
private final boolean shouldSpliceIn;
|
||||
private final int adaptiveMaxWidth;
|
||||
private final int adaptiveMaxHeight;
|
||||
|
||||
private MediaFormat[] sampleQueueFormats;
|
||||
private Allocator allocator;
|
||||
|
||||
private volatile boolean tracksBuilt;
|
||||
@ -54,12 +58,14 @@ public final class HlsExtractorWrapper implements ExtractorOutput {
|
||||
private boolean spliceConfigured;
|
||||
|
||||
public HlsExtractorWrapper(int trigger, Format format, long startTimeUs, Extractor extractor,
|
||||
boolean shouldSpliceIn) {
|
||||
boolean shouldSpliceIn, int adaptiveMaxWidth, int adaptiveMaxHeight) {
|
||||
this.trigger = trigger;
|
||||
this.format = format;
|
||||
this.startTimeUs = startTimeUs;
|
||||
this.extractor = extractor;
|
||||
this.shouldSpliceIn = shouldSpliceIn;
|
||||
this.adaptiveMaxWidth = adaptiveMaxWidth;
|
||||
this.adaptiveMaxHeight = adaptiveMaxHeight;
|
||||
sampleQueues = new SparseArray<>();
|
||||
}
|
||||
|
||||
@ -86,6 +92,15 @@ public final class HlsExtractorWrapper implements ExtractorOutput {
|
||||
}
|
||||
}
|
||||
prepared = true;
|
||||
sampleQueueFormats = new MediaFormat[sampleQueues.size()];
|
||||
for (int i = 0; i < sampleQueueFormats.length; i++) {
|
||||
MediaFormat format = sampleQueues.valueAt(i).getFormat();
|
||||
if (MimeTypes.isVideo(format.mimeType) && (adaptiveMaxWidth != MediaFormat.NO_VALUE
|
||||
|| adaptiveMaxHeight != MediaFormat.NO_VALUE)) {
|
||||
format = format.copyWithMaxVideoDimensions(adaptiveMaxWidth, adaptiveMaxHeight);
|
||||
}
|
||||
sampleQueueFormats[i] = format;
|
||||
}
|
||||
}
|
||||
return prepared;
|
||||
}
|
||||
@ -169,7 +184,7 @@ public final class HlsExtractorWrapper implements ExtractorOutput {
|
||||
*/
|
||||
public MediaFormat getMediaFormat(int track) {
|
||||
Assertions.checkState(isPrepared());
|
||||
return sampleQueues.valueAt(track).getFormat();
|
||||
return sampleQueueFormats[track];
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -138,11 +138,11 @@ public final class HlsSampleSource implements SampleSource, SampleSourceReader,
|
||||
mediaFormats = new MediaFormat[trackCount];
|
||||
long durationUs = chunkSource.getDurationUs();
|
||||
for (int i = 0; i < trackCount; i++) {
|
||||
mediaFormats[i] = extractor.getMediaFormat(i).copyWithDurationUs(durationUs);
|
||||
if (MimeTypes.isVideo(mediaFormats[i].mimeType)) {
|
||||
mediaFormats[i] = chunkSource.getWithMaxVideoDimensions(mediaFormats[i])
|
||||
.copyAsAdaptive();
|
||||
MediaFormat format = extractor.getMediaFormat(i).copyWithDurationUs(durationUs);
|
||||
if (MimeTypes.isVideo(format.mimeType)) {
|
||||
format = format.copyAsAdaptive();
|
||||
}
|
||||
mediaFormats[i] = format;
|
||||
}
|
||||
prepared = true;
|
||||
return true;
|
||||
@ -294,8 +294,7 @@ public final class HlsSampleSource implements SampleSource, SampleSourceReader,
|
||||
}
|
||||
|
||||
MediaFormat mediaFormat = extractor.getMediaFormat(track);
|
||||
if (mediaFormat != null && !mediaFormat.equals(downstreamMediaFormats[track], true)) {
|
||||
mediaFormat = chunkSource.getWithMaxVideoDimensions(mediaFormat);
|
||||
if (mediaFormat != null && !mediaFormat.equals(downstreamMediaFormats[track])) {
|
||||
formatHolder.format = mediaFormat;
|
||||
downstreamMediaFormats[track] = mediaFormat;
|
||||
return FORMAT_READ;
|
||||
|
@ -196,15 +196,6 @@ public class SmoothStreamingChunkSource implements ChunkSource,
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public final MediaFormat getWithMaxVideoDimensions(MediaFormat format) {
|
||||
if (enabledTrack.isAdaptive() && MimeTypes.isVideo(format.mimeType)) {
|
||||
return format.copyWithMaxVideoDimensions(
|
||||
enabledTrack.adaptiveMaxWidth, enabledTrack.adaptiveMaxHeight);
|
||||
}
|
||||
return format;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void continueBuffering(long playbackPositionUs) {
|
||||
if (manifestFetcher == null || !currentManifest.isLive || fatalError != null) {
|
||||
@ -323,10 +314,10 @@ public class SmoothStreamingChunkSource implements ChunkSource,
|
||||
int manifestTrackKey = getManifestTrackKey(enabledTrack.elementIndex, manifestTrackIndex);
|
||||
Uri uri = streamElement.buildRequestUri(manifestTrackIndex, chunkIndex);
|
||||
Chunk mediaChunk = newMediaChunk(selectedFormat, uri, null,
|
||||
extractorWrappers.get(manifestTrackKey),
|
||||
drmInitData, dataSource, currentAbsoluteChunkIndex, isLastChunk, chunkStartTimeUs,
|
||||
chunkEndTimeUs, evaluation.trigger,
|
||||
mediaFormats.get(manifestTrackKey));
|
||||
extractorWrappers.get(manifestTrackKey), drmInitData, dataSource, currentAbsoluteChunkIndex,
|
||||
isLastChunk, chunkStartTimeUs, chunkEndTimeUs, evaluation.trigger,
|
||||
mediaFormats.get(manifestTrackKey), enabledTrack.adaptiveMaxWidth,
|
||||
enabledTrack.adaptiveMaxHeight);
|
||||
out.chunk = mediaChunk;
|
||||
}
|
||||
|
||||
@ -480,14 +471,14 @@ public class SmoothStreamingChunkSource implements ChunkSource,
|
||||
private static MediaChunk newMediaChunk(Format formatInfo, Uri uri, String cacheKey,
|
||||
ChunkExtractorWrapper extractorWrapper, DrmInitData drmInitData, DataSource dataSource,
|
||||
int chunkIndex, boolean isLast, long chunkStartTimeUs, long chunkEndTimeUs,
|
||||
int trigger, MediaFormat mediaFormat) {
|
||||
int trigger, MediaFormat mediaFormat, int adaptiveMaxWidth, int adaptiveMaxHeight) {
|
||||
long offset = 0;
|
||||
DataSpec dataSpec = new DataSpec(uri, offset, -1, cacheKey);
|
||||
// In SmoothStreaming each chunk contains sample timestamps relative to the start of the chunk.
|
||||
// To convert them the absolute timestamps, we need to set sampleOffsetUs to -chunkStartTimeUs.
|
||||
return new ContainerMediaChunk(dataSource, dataSpec, trigger, formatInfo, chunkStartTimeUs,
|
||||
chunkEndTimeUs, chunkIndex, isLast, chunkStartTimeUs, extractorWrapper, mediaFormat,
|
||||
drmInitData, true, Chunk.NO_PARENT_ID);
|
||||
adaptiveMaxWidth, adaptiveMaxHeight, drmInitData, true, Chunk.NO_PARENT_ID);
|
||||
}
|
||||
|
||||
private static int getManifestTrackKey(int elementIndex, int trackIndex) {
|
||||
@ -538,17 +529,17 @@ public class SmoothStreamingChunkSource implements ChunkSource,
|
||||
this.elementIndex = elementIndex;
|
||||
this.fixedFormat = fixedFormat;
|
||||
this.adaptiveFormats = null;
|
||||
this.adaptiveMaxWidth = -1;
|
||||
this.adaptiveMaxHeight = -1;
|
||||
this.adaptiveMaxWidth = MediaFormat.NO_VALUE;
|
||||
this.adaptiveMaxHeight = MediaFormat.NO_VALUE;
|
||||
}
|
||||
|
||||
public ExposedTrack(MediaFormat format, int elementIndex, Format[] adaptiveFormats,
|
||||
int maxWidth, int maxHeight) {
|
||||
int adaptiveMaxWidth, int adaptiveMaxHeight) {
|
||||
this.format = format;
|
||||
this.elementIndex = elementIndex;
|
||||
this.adaptiveFormats = adaptiveFormats;
|
||||
this.adaptiveMaxWidth = maxWidth;
|
||||
this.adaptiveMaxHeight = maxHeight;
|
||||
this.adaptiveMaxWidth = adaptiveMaxWidth;
|
||||
this.adaptiveMaxHeight = adaptiveMaxHeight;
|
||||
this.fixedFormat = null;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user