mirror of
https://github.com/samsonjs/media.git
synced 2026-04-27 15:07:40 +00:00
Add MediaChunkIterator for FakeAdaptiveDataSet.
------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=203102464
This commit is contained in:
parent
55ce085a0d
commit
97120bc6cb
3 changed files with 124 additions and 31 deletions
|
|
@ -0,0 +1,69 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2018 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package com.google.android.exoplayer2.source.chunk;
|
||||||
|
|
||||||
|
import java.util.NoSuchElementException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base class for {@link MediaChunkIterator}s. Handles {@link #next()} and {@link #isEnded()}, and
|
||||||
|
* provides a bounds check for child classes.
|
||||||
|
*/
|
||||||
|
public abstract class BaseMediaChunkIterator implements MediaChunkIterator {
|
||||||
|
|
||||||
|
private final long fromIndex;
|
||||||
|
private final long toIndex;
|
||||||
|
|
||||||
|
private long currentIndex;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates base iterator.
|
||||||
|
*
|
||||||
|
* @param fromIndex The index at which the iterator will start.
|
||||||
|
* @param toIndex The last available index.
|
||||||
|
*/
|
||||||
|
public BaseMediaChunkIterator(long fromIndex, long toIndex) {
|
||||||
|
this.fromIndex = fromIndex;
|
||||||
|
this.toIndex = toIndex;
|
||||||
|
currentIndex = fromIndex - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isEnded() {
|
||||||
|
return currentIndex > toIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean next() {
|
||||||
|
currentIndex++;
|
||||||
|
return !isEnded();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Verifies that the iterator points to a valid element.
|
||||||
|
*
|
||||||
|
* @throws NoSuchElementException If the iterator does not point to a valid element.
|
||||||
|
*/
|
||||||
|
protected void checkInBounds() {
|
||||||
|
if (currentIndex < fromIndex || currentIndex > toIndex) {
|
||||||
|
throw new NoSuchElementException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Returns the current index this iterator is pointing to. */
|
||||||
|
protected long getCurrentIndex() {
|
||||||
|
return currentIndex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -30,6 +30,7 @@ import com.google.android.exoplayer2.extractor.mkv.MatroskaExtractor;
|
||||||
import com.google.android.exoplayer2.extractor.mp4.FragmentedMp4Extractor;
|
import com.google.android.exoplayer2.extractor.mp4.FragmentedMp4Extractor;
|
||||||
import com.google.android.exoplayer2.extractor.rawcc.RawCcExtractor;
|
import com.google.android.exoplayer2.extractor.rawcc.RawCcExtractor;
|
||||||
import com.google.android.exoplayer2.source.BehindLiveWindowException;
|
import com.google.android.exoplayer2.source.BehindLiveWindowException;
|
||||||
|
import com.google.android.exoplayer2.source.chunk.BaseMediaChunkIterator;
|
||||||
import com.google.android.exoplayer2.source.chunk.Chunk;
|
import com.google.android.exoplayer2.source.chunk.Chunk;
|
||||||
import com.google.android.exoplayer2.source.chunk.ChunkExtractorWrapper;
|
import com.google.android.exoplayer2.source.chunk.ChunkExtractorWrapper;
|
||||||
import com.google.android.exoplayer2.source.chunk.ChunkHolder;
|
import com.google.android.exoplayer2.source.chunk.ChunkHolder;
|
||||||
|
|
@ -55,7 +56,6 @@ import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.NoSuchElementException;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A default {@link DashChunkSource} implementation.
|
* A default {@link DashChunkSource} implementation.
|
||||||
|
|
@ -509,13 +509,9 @@ public class DefaultDashChunkSource implements DashChunkSource {
|
||||||
// Protected classes.
|
// Protected classes.
|
||||||
|
|
||||||
/** {@link MediaChunkIterator} wrapping a {@link RepresentationHolder}. */
|
/** {@link MediaChunkIterator} wrapping a {@link RepresentationHolder}. */
|
||||||
protected static final class RepresentationSegmentIterator implements MediaChunkIterator {
|
protected static final class RepresentationSegmentIterator extends BaseMediaChunkIterator {
|
||||||
|
|
||||||
private final RepresentationHolder representationHolder;
|
private final RepresentationHolder representationHolder;
|
||||||
private final long firstSegmentNum;
|
|
||||||
private final long lastAvailableSegmentNum;
|
|
||||||
|
|
||||||
private long segmentNum;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates iterator.
|
* Creates iterator.
|
||||||
|
|
@ -526,28 +522,15 @@ public class DefaultDashChunkSource implements DashChunkSource {
|
||||||
*/
|
*/
|
||||||
public RepresentationSegmentIterator(
|
public RepresentationSegmentIterator(
|
||||||
RepresentationHolder representation, long segmentNum, long lastAvailableSegmentNum) {
|
RepresentationHolder representation, long segmentNum, long lastAvailableSegmentNum) {
|
||||||
|
super(/* fromIndex= */ segmentNum, /* toIndex= */ lastAvailableSegmentNum);
|
||||||
this.representationHolder = representation;
|
this.representationHolder = representation;
|
||||||
this.firstSegmentNum = segmentNum;
|
|
||||||
this.segmentNum = segmentNum - 1;
|
|
||||||
this.lastAvailableSegmentNum = lastAvailableSegmentNum;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isEnded() {
|
public DataSpec getDataSpec() {
|
||||||
return segmentNum > lastAvailableSegmentNum;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean next() {
|
|
||||||
segmentNum++;
|
|
||||||
return segmentNum <= lastAvailableSegmentNum;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public @Nullable DataSpec getDataSpec() {
|
|
||||||
checkInBounds();
|
checkInBounds();
|
||||||
Representation representation = representationHolder.representation;
|
Representation representation = representationHolder.representation;
|
||||||
RangedUri segmentUri = representationHolder.getSegmentUrl(segmentNum);
|
RangedUri segmentUri = representationHolder.getSegmentUrl(getCurrentIndex());
|
||||||
Uri resolvedUri = segmentUri.resolveUri(representation.baseUrl);
|
Uri resolvedUri = segmentUri.resolveUri(representation.baseUrl);
|
||||||
String cacheKey = representation.getCacheKey();
|
String cacheKey = representation.getCacheKey();
|
||||||
return new DataSpec(resolvedUri, segmentUri.start, segmentUri.length, cacheKey);
|
return new DataSpec(resolvedUri, segmentUri.start, segmentUri.length, cacheKey);
|
||||||
|
|
@ -556,19 +539,13 @@ public class DefaultDashChunkSource implements DashChunkSource {
|
||||||
@Override
|
@Override
|
||||||
public long getChunkStartTimeUs() {
|
public long getChunkStartTimeUs() {
|
||||||
checkInBounds();
|
checkInBounds();
|
||||||
return representationHolder.getSegmentStartTimeUs(segmentNum);
|
return representationHolder.getSegmentStartTimeUs(getCurrentIndex());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public long getChunkEndTimeUs() {
|
public long getChunkEndTimeUs() {
|
||||||
checkInBounds();
|
checkInBounds();
|
||||||
return representationHolder.getSegmentEndTimeUs(segmentNum);
|
return representationHolder.getSegmentEndTimeUs(getCurrentIndex());
|
||||||
}
|
|
||||||
|
|
||||||
private void checkInBounds() {
|
|
||||||
if (segmentNum < firstSegmentNum || segmentNum > lastAvailableSegmentNum) {
|
|
||||||
throw new NoSuchElementException();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -15,9 +15,14 @@
|
||||||
*/
|
*/
|
||||||
package com.google.android.exoplayer2.testutil;
|
package com.google.android.exoplayer2.testutil;
|
||||||
|
|
||||||
|
import android.net.Uri;
|
||||||
import com.google.android.exoplayer2.C;
|
import com.google.android.exoplayer2.C;
|
||||||
import com.google.android.exoplayer2.Format;
|
import com.google.android.exoplayer2.Format;
|
||||||
import com.google.android.exoplayer2.source.TrackGroup;
|
import com.google.android.exoplayer2.source.TrackGroup;
|
||||||
|
import com.google.android.exoplayer2.source.chunk.BaseMediaChunkIterator;
|
||||||
|
import com.google.android.exoplayer2.source.chunk.MediaChunkIterator;
|
||||||
|
import com.google.android.exoplayer2.testutil.FakeDataSet.FakeData.Segment;
|
||||||
|
import com.google.android.exoplayer2.upstream.DataSpec;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -63,6 +68,49 @@ public final class FakeAdaptiveDataSet extends FakeDataSet {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** {@link MediaChunkIterator} for the chunks defined by a fake adaptive data set. */
|
||||||
|
public static final class Iterator extends BaseMediaChunkIterator {
|
||||||
|
|
||||||
|
private final FakeAdaptiveDataSet dataSet;
|
||||||
|
private final int trackGroupIndex;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create iterator.
|
||||||
|
*
|
||||||
|
* @param dataSet The data set to iterate over.
|
||||||
|
* @param trackGroupIndex The index of the track group to iterate over.
|
||||||
|
* @param chunkIndex The chunk index to which the iterator points initially.
|
||||||
|
*/
|
||||||
|
public Iterator(FakeAdaptiveDataSet dataSet, int trackGroupIndex, int chunkIndex) {
|
||||||
|
super(/* fromIndex= */ chunkIndex, /* toIndex= */ dataSet.getChunkCount() - 1);
|
||||||
|
this.dataSet = dataSet;
|
||||||
|
this.trackGroupIndex = trackGroupIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public DataSpec getDataSpec() {
|
||||||
|
checkInBounds();
|
||||||
|
String uri = dataSet.getUri(trackGroupIndex);
|
||||||
|
int chunkIndex = (int) getCurrentIndex();
|
||||||
|
Segment fakeDataChunk = dataSet.getData(uri).getSegments().get(chunkIndex);
|
||||||
|
return new DataSpec(
|
||||||
|
Uri.parse(uri), fakeDataChunk.byteOffset, fakeDataChunk.length, /* key= */ null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getChunkStartTimeUs() {
|
||||||
|
checkInBounds();
|
||||||
|
return dataSet.getStartTime((int) getCurrentIndex());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getChunkEndTimeUs() {
|
||||||
|
checkInBounds();
|
||||||
|
int chunkIndex = (int) getCurrentIndex();
|
||||||
|
return dataSet.getStartTime(chunkIndex) + dataSet.getChunkDuration(chunkIndex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private final int chunkCount;
|
private final int chunkCount;
|
||||||
private final long chunkDurationUs;
|
private final long chunkDurationUs;
|
||||||
private final long lastChunkDurationUs;
|
private final long lastChunkDurationUs;
|
||||||
|
|
@ -124,5 +172,4 @@ public final class FakeAdaptiveDataSet extends FakeDataSet {
|
||||||
public int getChunkIndexByPosition(long positionUs) {
|
public int getChunkIndexByPosition(long positionUs) {
|
||||||
return (int) (positionUs / chunkDurationUs);
|
return (int) (positionUs / chunkDurationUs);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue