Commit 6c6d50d3 by rohks Committed by Tianyi Feng

Add field measured throughput (mtp)

Updated `ExoTrackSelection` to provide the most recent bitrate estimate, enabling the inclusion of measured throughput (mtp) as a CMCD-Request field in Common Media Client Data (CMCD) logging.

Additionally, made changes to the `checkArgument` methods in `CmcdLog` to prevent the use of default values in certain cases.

#minor-release

PiperOrigin-RevId: 549369529
(cherry picked from commit 79696182226b10dce2ac2756f317d217a8bcf23c)
parent e7a8283d
...@@ -613,6 +613,11 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; ...@@ -613,6 +613,11 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
} }
@Override @Override
public long getLatestBitrateEstimate() {
return trackSelection.getLatestBitrateEstimate();
}
@Override
public boolean equals(@Nullable Object o) { public boolean equals(@Nullable Object o) {
if (this == o) { if (this == o) {
return true; return true;
......
...@@ -323,6 +323,7 @@ public class AdaptiveTrackSelection extends BaseTrackSelection { ...@@ -323,6 +323,7 @@ public class AdaptiveTrackSelection extends BaseTrackSelection {
private @C.SelectionReason int reason; private @C.SelectionReason int reason;
private long lastBufferEvaluationMs; private long lastBufferEvaluationMs;
@Nullable private MediaChunk lastBufferEvaluationMediaChunk; @Nullable private MediaChunk lastBufferEvaluationMediaChunk;
private long latestBitrateEstimate;
/** /**
* @param group The {@link TrackGroup}. * @param group The {@link TrackGroup}.
...@@ -414,6 +415,7 @@ public class AdaptiveTrackSelection extends BaseTrackSelection { ...@@ -414,6 +415,7 @@ public class AdaptiveTrackSelection extends BaseTrackSelection {
playbackSpeed = 1f; playbackSpeed = 1f;
reason = C.SELECTION_REASON_UNKNOWN; reason = C.SELECTION_REASON_UNKNOWN;
lastBufferEvaluationMs = C.TIME_UNSET; lastBufferEvaluationMs = C.TIME_UNSET;
latestBitrateEstimate = Long.MIN_VALUE;
} }
@CallSuper @CallSuper
...@@ -547,6 +549,11 @@ public class AdaptiveTrackSelection extends BaseTrackSelection { ...@@ -547,6 +549,11 @@ public class AdaptiveTrackSelection extends BaseTrackSelection {
return queueSize; return queueSize;
} }
@Override
public long getLatestBitrateEstimate() {
return latestBitrateEstimate;
}
/** /**
* Called when updating the selected track to determine whether a candidate track can be selected. * Called when updating the selected track to determine whether a candidate track can be selected.
* *
...@@ -685,8 +692,8 @@ public class AdaptiveTrackSelection extends BaseTrackSelection { ...@@ -685,8 +692,8 @@ public class AdaptiveTrackSelection extends BaseTrackSelection {
} }
private long getTotalAllocatableBandwidth(long chunkDurationUs) { private long getTotalAllocatableBandwidth(long chunkDurationUs) {
long cautiousBandwidthEstimate = latestBitrateEstimate = bandwidthMeter.getBitrateEstimate();
(long) (bandwidthMeter.getBitrateEstimate() * bandwidthFraction); long cautiousBandwidthEstimate = (long) (latestBitrateEstimate * bandwidthFraction);
long timeToFirstByteEstimateUs = bandwidthMeter.getTimeToFirstByteEstimateUs(); long timeToFirstByteEstimateUs = bandwidthMeter.getTimeToFirstByteEstimateUs();
if (timeToFirstByteEstimateUs == C.TIME_UNSET || chunkDurationUs == C.TIME_UNSET) { if (timeToFirstByteEstimateUs == C.TIME_UNSET || chunkDurationUs == C.TIME_UNSET) {
return (long) (cautiousBandwidthEstimate / playbackSpeed); return (long) (cautiousBandwidthEstimate / playbackSpeed);
......
...@@ -294,4 +294,14 @@ public interface ExoTrackSelection extends TrackSelection { ...@@ -294,4 +294,14 @@ public interface ExoTrackSelection extends TrackSelection {
* android.os.SystemClock#elapsedRealtime()}. * android.os.SystemClock#elapsedRealtime()}.
*/ */
boolean isTrackExcluded(int index, long nowMs); boolean isTrackExcluded(int index, long nowMs);
/**
* Returns the most recent bitrate estimate utilised for track selection.
*
* <p>The default behavior is to return {@link Long#MIN_VALUE}, indicating that the bitrate
* estimate was not computed for the track selection decision.
*/
default long getLatestBitrateEstimate() {
return Long.MIN_VALUE;
}
} }
...@@ -71,7 +71,8 @@ public final class CmcdConfiguration { ...@@ -71,7 +71,8 @@ public final class CmcdConfiguration {
KEY_STREAM_TYPE, KEY_STREAM_TYPE,
KEY_VERSION, KEY_VERSION,
KEY_TOP_BITRATE, KEY_TOP_BITRATE,
KEY_OBJECT_DURATION KEY_OBJECT_DURATION,
KEY_MEASURED_THROUGHPUT
}) })
@Documented @Documented
@Target(TYPE_USE) @Target(TYPE_USE)
...@@ -94,6 +95,7 @@ public final class CmcdConfiguration { ...@@ -94,6 +95,7 @@ public final class CmcdConfiguration {
public static final String KEY_VERSION = "v"; public static final String KEY_VERSION = "v";
public static final String KEY_TOP_BITRATE = "tb"; public static final String KEY_TOP_BITRATE = "tb";
public static final String KEY_OBJECT_DURATION = "d"; public static final String KEY_OBJECT_DURATION = "d";
public static final String KEY_MEASURED_THROUGHPUT = "mtp";
/** /**
* Factory for {@link CmcdConfiguration} instances. * Factory for {@link CmcdConfiguration} instances.
...@@ -285,4 +287,12 @@ public final class CmcdConfiguration { ...@@ -285,4 +287,12 @@ public final class CmcdConfiguration {
public boolean isObjectDurationLoggingAllowed() { public boolean isObjectDurationLoggingAllowed() {
return requestConfig.isKeyAllowed(KEY_OBJECT_DURATION); return requestConfig.isKeyAllowed(KEY_OBJECT_DURATION);
} }
/**
* Returns whether logging object duration is allowed based on the {@linkplain RequestConfig
* request configuration}.
*/
public boolean isMeasuredThroughputLoggingAllowed() {
return requestConfig.isKeyAllowed(KEY_MEASURED_THROUGHPUT);
}
} }
...@@ -85,7 +85,8 @@ public final class CmcdLog { ...@@ -85,7 +85,8 @@ public final class CmcdLog {
* @param trackSelection The {@linkplain ExoTrackSelection track selection}. * @param trackSelection The {@linkplain ExoTrackSelection track selection}.
* @param bufferedDurationUs The duration of media currently buffered from the current playback * @param bufferedDurationUs The duration of media currently buffered from the current playback
* position, in microseconds. * position, in microseconds.
* @param chunkDurationUs The duration of current media chunk being requested, in microseconds. * @param chunkDurationUs The duration of current media chunk being requested, in microseconds. If
* the duration is not known, it can be set to {@link C#TIME_UNSET}.
* @param streamingFormat The streaming format of the media content. Must be one of the allowed * @param streamingFormat The streaming format of the media content. Must be one of the allowed
* streaming formats specified by the {@link StreamingFormat} annotation. * streaming formats specified by the {@link StreamingFormat} annotation.
* @param isLive {@code true} if the media content is being streamed live, {@code false} * @param isLive {@code true} if the media content is being streamed live, {@code false}
...@@ -116,7 +117,7 @@ public final class CmcdLog { ...@@ -116,7 +117,7 @@ public final class CmcdLog {
} }
cmcdObject.setTopBitrateKbps(topBitrate / 1000); cmcdObject.setTopBitrateKbps(topBitrate / 1000);
} }
if (cmcdConfiguration.isObjectDurationLoggingAllowed()) { if (cmcdConfiguration.isObjectDurationLoggingAllowed() && chunkDurationUs != C.TIME_UNSET) {
cmcdObject.setObjectDurationMs(chunkDurationUs / 1000); cmcdObject.setObjectDurationMs(chunkDurationUs / 1000);
} }
...@@ -126,6 +127,10 @@ public final class CmcdLog { ...@@ -126,6 +127,10 @@ public final class CmcdLog {
if (cmcdConfiguration.isBufferLengthLoggingAllowed()) { if (cmcdConfiguration.isBufferLengthLoggingAllowed()) {
cmcdRequest.setBufferLengthMs(bufferedDurationUs / 1000); cmcdRequest.setBufferLengthMs(bufferedDurationUs / 1000);
} }
if (cmcdConfiguration.isMeasuredThroughputLoggingAllowed()
&& trackSelection.getLatestBitrateEstimate() != Long.MIN_VALUE) {
cmcdRequest.setMeasuredThroughputInKbps(trackSelection.getLatestBitrateEstimate() / 1000);
}
CmcdLog.CmcdSession.Builder cmcdSession = CmcdLog.CmcdSession.Builder cmcdSession =
new CmcdLog.CmcdSession.Builder() new CmcdLog.CmcdSession.Builder()
...@@ -216,12 +221,11 @@ public final class CmcdLog { ...@@ -216,12 +221,11 @@ public final class CmcdLog {
/** /**
* Sets the {@link CmcdObject#objectDurationMs}. The default value is {@link C#TIME_UNSET}. * Sets the {@link CmcdObject#objectDurationMs}. The default value is {@link C#TIME_UNSET}.
* *
* @throws IllegalArgumentException If {@code objectDurationMs} is not equal to {@link * @throws IllegalArgumentException If {@code objectDurationMs} is negative.
* C#TIME_UNSET} and is non-positive.
*/ */
@CanIgnoreReturnValue @CanIgnoreReturnValue
public Builder setObjectDurationMs(long objectDurationMs) { public Builder setObjectDurationMs(long objectDurationMs) {
checkArgument(objectDurationMs == C.TIME_UNSET || objectDurationMs >= 0); checkArgument(objectDurationMs >= 0);
this.objectDurationMs = objectDurationMs; this.objectDurationMs = objectDurationMs;
return this; return this;
} }
...@@ -319,25 +323,39 @@ public final class CmcdLog { ...@@ -319,25 +323,39 @@ public final class CmcdLog {
/** Builder for {@link CmcdRequest} instances. */ /** Builder for {@link CmcdRequest} instances. */
public static final class Builder { public static final class Builder {
private long bufferLengthMs; private long bufferLengthMs;
private long measuredThroughputInKbps;
@Nullable private String customData; @Nullable private String customData;
/** Creates a new instance with default values. */ /** Creates a new instance with default values. */
public Builder() { public Builder() {
this.bufferLengthMs = C.TIME_UNSET; this.bufferLengthMs = C.TIME_UNSET;
this.measuredThroughputInKbps = Long.MIN_VALUE;
} }
/** /**
* Sets the {@link CmcdRequest#bufferLengthMs}. Rounded to nearest 100 ms. The default value * Sets the {@link CmcdRequest#bufferLengthMs}. Rounded to nearest 100 ms. The default value
* is {@link C#TIME_UNSET}. * is {@link C#TIME_UNSET}.
* *
* @throws IllegalArgumentException If {@code bufferLengthMs} is not equal to {@link * @throws IllegalArgumentException If {@code bufferLengthMs} is negative.
* C#TIME_UNSET} and is non-positive.
*/ */
@CanIgnoreReturnValue @CanIgnoreReturnValue
public Builder setBufferLengthMs(long bufferLengthMs) { public Builder setBufferLengthMs(long bufferLengthMs) {
checkArgument(bufferLengthMs == C.TIME_UNSET || bufferLengthMs >= 0); checkArgument(bufferLengthMs >= 0);
this.bufferLengthMs = this.bufferLengthMs = ((bufferLengthMs + 50) / 100) * 100;
bufferLengthMs == C.TIME_UNSET ? bufferLengthMs : ((bufferLengthMs + 50) / 100) * 100; return this;
}
/**
* Sets the {@link CmcdRequest#measuredThroughputInKbps}. Rounded to nearest 100 kbps. The
* default value is {@link Long#MIN_VALUE}.
*
* @throws IllegalArgumentException If {@code measuredThroughputInKbps} is negative.
*/
@CanIgnoreReturnValue
public Builder setMeasuredThroughputInKbps(long measuredThroughputInKbps) {
checkArgument(measuredThroughputInKbps >= 0);
this.measuredThroughputInKbps = ((measuredThroughputInKbps + 50) / 100) * 100;
return this; return this;
} }
...@@ -361,6 +379,19 @@ public final class CmcdLog { ...@@ -361,6 +379,19 @@ public final class CmcdLog {
*/ */
public final long bufferLengthMs; public final long bufferLengthMs;
/** /**
* The throughput between client and server, as measured by the client, or {@link
* Long#MIN_VALUE} if unset.
*
* <p>This value MUST be rounded to the nearest 100 kbps. This value, however derived, SHOULD be
* the value that the client is using to make its next Adaptive Bitrate switching decision. If
* the client is connected to multiple servers concurrently, it must take care to report only
* the throughput measured against the receiving server. If the client has multiple concurrent
* connections to the server, then the intent is that this value communicates the aggregate
* throughput the client sees across all those connections.
*/
public final long measuredThroughputInKbps;
/**
* Custom data where the values of the keys vary with each request, or {@code null} if unset. * Custom data where the values of the keys vary with each request, or {@code null} if unset.
* *
* <p>The String consists of key-value pairs separated by commas.<br> * <p>The String consists of key-value pairs separated by commas.<br>
...@@ -370,6 +401,7 @@ public final class CmcdLog { ...@@ -370,6 +401,7 @@ public final class CmcdLog {
private CmcdRequest(Builder builder) { private CmcdRequest(Builder builder) {
this.bufferLengthMs = builder.bufferLengthMs; this.bufferLengthMs = builder.bufferLengthMs;
this.measuredThroughputInKbps = builder.measuredThroughputInKbps;
this.customData = builder.customData; this.customData = builder.customData;
} }
...@@ -386,6 +418,11 @@ public final class CmcdLog { ...@@ -386,6 +418,11 @@ public final class CmcdLog {
headerValue.append( headerValue.append(
Util.formatInvariant("%s=%d,", CmcdConfiguration.KEY_BUFFER_LENGTH, bufferLengthMs)); Util.formatInvariant("%s=%d,", CmcdConfiguration.KEY_BUFFER_LENGTH, bufferLengthMs));
} }
if (measuredThroughputInKbps != Long.MIN_VALUE) {
headerValue.append(
Util.formatInvariant(
"%s=%d,", CmcdConfiguration.KEY_MEASURED_THROUGHPUT, measuredThroughputInKbps));
}
if (!TextUtils.isEmpty(customData)) { if (!TextUtils.isEmpty(customData)) {
headerValue.append(Util.formatInvariant("%s,", customData)); headerValue.append(Util.formatInvariant("%s,", customData));
} }
...@@ -580,7 +617,7 @@ public final class CmcdLog { ...@@ -580,7 +617,7 @@ public final class CmcdLog {
* The default value is {@link C#RATE_UNSET_INT}. * The default value is {@link C#RATE_UNSET_INT}.
* *
* @throws IllegalArgumentException If {@code maximumRequestedThroughputKbps} is not equal to * @throws IllegalArgumentException If {@code maximumRequestedThroughputKbps} is not equal to
* {@link C#RATE_UNSET_INT} and is non-positive. * {@link C#RATE_UNSET_INT} and is negative.
*/ */
@CanIgnoreReturnValue @CanIgnoreReturnValue
public Builder setMaximumRequestedThroughputKbps(int maximumRequestedThroughputKbps) { public Builder setMaximumRequestedThroughputKbps(int maximumRequestedThroughputKbps) {
......
...@@ -108,6 +108,20 @@ public final class AdaptiveTrackSelectionTest { ...@@ -108,6 +108,20 @@ public final class AdaptiveTrackSelectionTest {
} }
@Test @Test
public void initial_updateSelectedTrack_returnsCorrectLatestBitrateEstimate() {
Format format1 = videoFormat(/* bitrate= */ 500, /* width= */ 320, /* height= */ 240);
Format format2 = videoFormat(/* bitrate= */ 1000, /* width= */ 640, /* height= */ 480);
TrackGroup trackGroup = new TrackGroup(format1, format2);
when(mockBandwidthMeter.getBitrateEstimate()).thenReturn(2000L);
AdaptiveTrackSelection adaptiveTrackSelection =
prepareAdaptiveTrackSelectionWithBandwidthFraction(
trackGroup, /* bandwidthFraction= */ 0.5f);
assertThat(adaptiveTrackSelection.getLatestBitrateEstimate()).isEqualTo(2000L);
}
@Test
public void updateSelectedTrackDoNotSwitchUpIfNotBufferedEnough() { public void updateSelectedTrackDoNotSwitchUpIfNotBufferedEnough() {
Format format1 = videoFormat(/* bitrate= */ 500, /* width= */ 320, /* height= */ 240); Format format1 = videoFormat(/* bitrate= */ 500, /* width= */ 320, /* height= */ 240);
Format format2 = videoFormat(/* bitrate= */ 1000, /* width= */ 640, /* height= */ 480); Format format2 = videoFormat(/* bitrate= */ 1000, /* width= */ 640, /* height= */ 480);
......
...@@ -61,6 +61,7 @@ public class CmcdLogTest { ...@@ -61,6 +61,7 @@ public class CmcdLogTest {
when(trackSelection.getSelectedFormat()).thenReturn(format); when(trackSelection.getSelectedFormat()).thenReturn(format);
when(trackSelection.getTrackGroup()) when(trackSelection.getTrackGroup())
.thenReturn(new TrackGroup(format, new Format.Builder().setPeakBitrate(1_000_000).build())); .thenReturn(new TrackGroup(format, new Format.Builder().setPeakBitrate(1_000_000).build()));
when(trackSelection.getLatestBitrateEstimate()).thenReturn(500_000L);
CmcdLog cmcdLog = CmcdLog cmcdLog =
CmcdLog.createInstance( CmcdLog.createInstance(
cmcdConfiguration, cmcdConfiguration,
...@@ -78,7 +79,7 @@ public class CmcdLogTest { ...@@ -78,7 +79,7 @@ public class CmcdLogTest {
"CMCD-Object", "CMCD-Object",
"br=840,tb=1000,d=3000,key1=value1", "br=840,tb=1000,d=3000,key1=value1",
"CMCD-Request", "CMCD-Request",
"bl=1800,key2=\"stringValue\"", "bl=1800,mtp=500,key2=\"stringValue\"",
"CMCD-Session", "CMCD-Session",
"cid=\"mediaId\",sid=\"sessionId\",sf=d,st=l", "cid=\"mediaId\",sid=\"sessionId\",sf=d,st=l",
"CMCD-Status", "CMCD-Status",
......
...@@ -377,7 +377,7 @@ public class DefaultDashChunkSource implements DashChunkSource { ...@@ -377,7 +377,7 @@ public class DefaultDashChunkSource implements DashChunkSource {
playbackPositionUs, bufferedDurationUs, availableLiveDurationUs, queue, chunkIterators); playbackPositionUs, bufferedDurationUs, availableLiveDurationUs, queue, chunkIterators);
int selectedTrackIndex = trackSelection.getSelectedIndex(); int selectedTrackIndex = trackSelection.getSelectedIndex();
long chunkDurationUs = 0; long chunkDurationUs = C.TIME_UNSET;
if (selectedTrackIndex < chunkIterators.length && chunkIterators[selectedTrackIndex].next()) { if (selectedTrackIndex < chunkIterators.length && chunkIterators[selectedTrackIndex].next()) {
chunkDurationUs = chunkDurationUs =
chunkIterators[selectedTrackIndex].getChunkEndTimeUs() chunkIterators[selectedTrackIndex].getChunkEndTimeUs()
......
...@@ -316,7 +316,7 @@ public class DefaultDashChunkSourceTest { ...@@ -316,7 +316,7 @@ public class DefaultDashChunkSourceTest {
"CMCD-Object", "CMCD-Object",
"br=700,tb=1300,d=4000", "br=700,tb=1300,d=4000",
"CMCD-Request", "CMCD-Request",
"bl=0", "bl=0,mtp=1000",
"CMCD-Session", "CMCD-Session",
"cid=\"mediaId\",sid=\"" + cmcdConfiguration.sessionId + "\",sf=d,st=v"); "cid=\"mediaId\",sid=\"" + cmcdConfiguration.sessionId + "\",sf=d,st=v");
} }
...@@ -361,7 +361,7 @@ public class DefaultDashChunkSourceTest { ...@@ -361,7 +361,7 @@ public class DefaultDashChunkSourceTest {
"CMCD-Object", "CMCD-Object",
"br=700,tb=1300,d=4000", "br=700,tb=1300,d=4000",
"CMCD-Request", "CMCD-Request",
"bl=0", "bl=0,mtp=1000",
"CMCD-Session", "CMCD-Session",
"cid=\"mediaIdcontentIdSuffix\",sf=d,st=v", "cid=\"mediaIdcontentIdSuffix\",sf=d,st=v",
"CMCD-Status", "CMCD-Status",
...@@ -407,7 +407,7 @@ public class DefaultDashChunkSourceTest { ...@@ -407,7 +407,7 @@ public class DefaultDashChunkSourceTest {
"CMCD-Object", "CMCD-Object",
"br=700,tb=1300,d=4000,key1=value1", "br=700,tb=1300,d=4000,key1=value1",
"CMCD-Request", "CMCD-Request",
"bl=0,key2=\"stringValue\"", "bl=0,mtp=1000,key2=\"stringValue\"",
"CMCD-Session", "CMCD-Session",
"cid=\"mediaId\",sid=\"" + cmcdConfiguration.sessionId + "\",sf=d,st=v,key3=1", "cid=\"mediaId\",sid=\"" + cmcdConfiguration.sessionId + "\",sf=d,st=v,key3=1",
"CMCD-Status", "CMCD-Status",
......
...@@ -487,7 +487,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; ...@@ -487,7 +487,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
seenExpectedPlaylistError = false; seenExpectedPlaylistError = false;
expectedPlaylistUrl = null; expectedPlaylistUrl = null;
long chunkDurationUs = 0; long chunkDurationUs = C.TIME_UNSET;
if (selectedTrackIndex < mediaChunkIterators.length if (selectedTrackIndex < mediaChunkIterators.length
&& mediaChunkIterators[selectedTrackIndex].next()) { && mediaChunkIterators[selectedTrackIndex].next()) {
chunkDurationUs = chunkDurationUs =
......
...@@ -210,7 +210,7 @@ public class HlsChunkSourceTest { ...@@ -210,7 +210,7 @@ public class HlsChunkSourceTest {
assertThat(output.chunk.dataSpec.httpRequestHeaders) assertThat(output.chunk.dataSpec.httpRequestHeaders)
.containsExactly( .containsExactly(
"CMCD-Object", "CMCD-Object",
"br=800,tb=800,d=0", "br=800,tb=800",
"CMCD-Request", "CMCD-Request",
"bl=0", "bl=0",
"CMCD-Session", "CMCD-Session",
...@@ -256,7 +256,7 @@ public class HlsChunkSourceTest { ...@@ -256,7 +256,7 @@ public class HlsChunkSourceTest {
assertThat(output.chunk.dataSpec.httpRequestHeaders) assertThat(output.chunk.dataSpec.httpRequestHeaders)
.containsExactly( .containsExactly(
"CMCD-Object", "CMCD-Object",
"br=800,tb=800,d=0", "br=800,tb=800",
"CMCD-Request", "CMCD-Request",
"bl=0", "bl=0",
"CMCD-Session", "CMCD-Session",
...@@ -303,7 +303,7 @@ public class HlsChunkSourceTest { ...@@ -303,7 +303,7 @@ public class HlsChunkSourceTest {
assertThat(output.chunk.dataSpec.httpRequestHeaders) assertThat(output.chunk.dataSpec.httpRequestHeaders)
.containsExactly( .containsExactly(
"CMCD-Object", "CMCD-Object",
"br=800,tb=800,d=0,key1=value1", "br=800,tb=800,key1=value1",
"CMCD-Request", "CMCD-Request",
"bl=0,key2=\"stringValue\"", "bl=0,key2=\"stringValue\"",
"CMCD-Session", "CMCD-Session",
......
...@@ -286,7 +286,7 @@ public class DefaultSsChunkSource implements SsChunkSource { ...@@ -286,7 +286,7 @@ public class DefaultSsChunkSource implements SsChunkSource {
int manifestTrackIndex = trackSelection.getIndexInTrackGroup(trackSelectionIndex); int manifestTrackIndex = trackSelection.getIndexInTrackGroup(trackSelectionIndex);
Uri uri = streamElement.buildRequestUri(manifestTrackIndex, chunkIndex); Uri uri = streamElement.buildRequestUri(manifestTrackIndex, chunkIndex);
long chunkDurationUs = 0; long chunkDurationUs = C.TIME_UNSET;
if (trackSelectionIndex < chunkIterators.length && chunkIterators[trackSelectionIndex].next()) { if (trackSelectionIndex < chunkIterators.length && chunkIterators[trackSelectionIndex].next()) {
chunkDurationUs = chunkDurationUs =
chunkIterators[trackSelectionIndex].getChunkEndTimeUs() chunkIterators[trackSelectionIndex].getChunkEndTimeUs()
......
...@@ -66,7 +66,7 @@ public class DefaultSsChunkSourceTest { ...@@ -66,7 +66,7 @@ public class DefaultSsChunkSourceTest {
"CMCD-Object", "CMCD-Object",
"br=307,tb=1536,d=1968", "br=307,tb=1536,d=1968",
"CMCD-Request", "CMCD-Request",
"bl=0", "bl=0,mtp=1000",
"CMCD-Session", "CMCD-Session",
"cid=\"mediaId\",sid=\"" + cmcdConfiguration.sessionId + "\",sf=s,st=v"); "cid=\"mediaId\",sid=\"" + cmcdConfiguration.sessionId + "\",sf=s,st=v");
} }
...@@ -111,7 +111,7 @@ public class DefaultSsChunkSourceTest { ...@@ -111,7 +111,7 @@ public class DefaultSsChunkSourceTest {
"CMCD-Object", "CMCD-Object",
"br=307,tb=1536,d=1968", "br=307,tb=1536,d=1968",
"CMCD-Request", "CMCD-Request",
"bl=0", "bl=0,mtp=1000",
"CMCD-Session", "CMCD-Session",
"cid=\"mediaIdcontentIdSuffix\",sf=s,st=v", "cid=\"mediaIdcontentIdSuffix\",sf=s,st=v",
"CMCD-Status", "CMCD-Status",
...@@ -157,7 +157,7 @@ public class DefaultSsChunkSourceTest { ...@@ -157,7 +157,7 @@ public class DefaultSsChunkSourceTest {
"CMCD-Object", "CMCD-Object",
"br=307,tb=1536,d=1968,key1=value1", "br=307,tb=1536,d=1968,key1=value1",
"CMCD-Request", "CMCD-Request",
"bl=0,key2=\"stringValue\"", "bl=0,mtp=1000,key2=\"stringValue\"",
"CMCD-Session", "CMCD-Session",
"cid=\"mediaId\",sid=\"" + cmcdConfiguration.sessionId + "\",sf=s,st=v,key3=1", "cid=\"mediaId\",sid=\"" + cmcdConfiguration.sessionId + "\",sf=s,st=v,key3=1",
"CMCD-Status", "CMCD-Status",
......
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