Commit 7038c8fb by tonihei Committed by Oliver Woodman

Add chunk size variation to fake adaptive data set.

The chunk size of real video data varies around the given average bitrate.
To account for this fact in the fake adaptive data set, the chunk size varies
randomly with a given standard deviation. The standard deviation used for the
BandwidthProfileSimulator is based on the chunk size variation measured on the
1 hour playlist of real media.

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=172068110
parent 3ae4143b
......@@ -18,6 +18,7 @@ package com.google.android.exoplayer2.testutil;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.Format;
import com.google.android.exoplayer2.source.TrackGroup;
import java.util.Random;
/**
* Fake data set emulating the data of an adaptive media source.
......@@ -30,46 +31,81 @@ public final class FakeAdaptiveDataSet extends FakeDataSet {
*/
public static final class Factory {
private static final Random random = new Random();
private final long chunkDurationUs;
private final double bitratePercentStdDev;
public Factory(long chunkDurationUs) {
/**
* Set up factory for {@link FakeAdaptiveDataSet}s with a chunk duration and the standard
* deviation of the chunk size.
*
* @param chunkDurationUs The chunk duration to use in microseconds.
* @param bitratePercentStdDev The standard deviation used to generate the chunk sizes centered
* around the average bitrate of the {@link Format}s. The standard deviation is given in
* percent (of the average size).
*/
public Factory(long chunkDurationUs, double bitratePercentStdDev) {
this.chunkDurationUs = chunkDurationUs;
this.bitratePercentStdDev = bitratePercentStdDev;
}
/**
* Returns a new {@link FakeAdaptiveDataSet} for the given {@link TrackGroup}.
*
* @param trackGroup The {@link TrackGroup} for which the data set is to be created.
* @param mediaDurationUs The total duration of the fake data set in microseconds.
*/
public FakeAdaptiveDataSet createDataSet(TrackGroup trackGroup, long mediaDurationUs) {
return new FakeAdaptiveDataSet(trackGroup, mediaDurationUs, chunkDurationUs);
return new FakeAdaptiveDataSet(trackGroup, mediaDurationUs, chunkDurationUs,
bitratePercentStdDev, random);
}
}
private final long chunkCount;
private final int chunkCount;
private final long chunkDurationUs;
private final long lastChunkDurationUs;
public FakeAdaptiveDataSet(TrackGroup trackGroup, long mediaDurationUs, long chunkDurationUs) {
/**
* Create {@link FakeAdaptiveDataSet} using a {@link TrackGroup} and meta data about the media.
*
* @param trackGroup The {@link TrackGroup} for which the data set is to be created.
* @param mediaDurationUs The total duration of the fake data set in microseconds.
* @param chunkDurationUs The chunk duration to use in microseconds.
* @param bitratePercentStdDev The standard deviation used to generate the chunk sizes centered
* around the average bitrate of the {@link Format}s in the {@link TrackGroup}. The standard
* deviation is given in percent (of the average size).
* @param random A {@link Random} instance used to generate random chunk sizes.
*/
/* package */ FakeAdaptiveDataSet(TrackGroup trackGroup, long mediaDurationUs,
long chunkDurationUs, double bitratePercentStdDev, Random random) {
this.chunkDurationUs = chunkDurationUs;
int trackCount = trackGroup.length;
long lastChunkDurationUs = mediaDurationUs % chunkDurationUs;
int fullChunks = (int) (mediaDurationUs / chunkDurationUs);
for (int i = 0; i < trackCount; i++) {
this.lastChunkDurationUs = lastChunkDurationUs == 0 ? chunkDurationUs : lastChunkDurationUs;
this.chunkCount = lastChunkDurationUs == 0 ? fullChunks : fullChunks + 1;
double[] bitrateFactors = new double[chunkCount];
for (int i = 0; i < chunkCount; i++) {
bitrateFactors[i] = 1.0 + random.nextGaussian() * bitratePercentStdDev / 100.0;
}
for (int i = 0; i < trackGroup.length; i++) {
String uri = getUri(i);
Format format = trackGroup.getFormat(i);
int chunkLength = (int) (format.bitrate * chunkDurationUs / (8 * C.MICROS_PER_SECOND));
double avgChunkLength = format.bitrate * chunkDurationUs / (8 * C.MICROS_PER_SECOND);
FakeData newData = this.newData(uri);
for (int j = 0; j < fullChunks; j++) {
newData.appendReadData(chunkLength);
newData.appendReadData((int) (avgChunkLength * bitrateFactors[j]));
}
if (lastChunkDurationUs > 0) {
int lastChunkLength = (int) (format.bitrate * (mediaDurationUs % chunkDurationUs)
/ (8 * C.MICROS_PER_SECOND));
int lastChunkLength = (int) (format.bitrate * bitrateFactors[bitrateFactors.length - 1]
* (mediaDurationUs % chunkDurationUs) / (8 * C.MICROS_PER_SECOND));
newData.appendReadData(lastChunkLength);
}
}
this.lastChunkDurationUs = lastChunkDurationUs == 0 ? chunkDurationUs : lastChunkDurationUs;
this.chunkCount = lastChunkDurationUs == 0 ? fullChunks : fullChunks + 1;
}
public long getChunkCount() {
public int getChunkCount() {
return chunkCount;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment