Commit e7a8283d by rohks Committed by Tianyi Feng

Add fields top bitrate(tb) and object duration(d)

Added these CMCD-Object fields to Common Media Client Data (CMCD) logging.

#minor-release

PiperOrigin-RevId: 548950296
(cherry picked from commit 43fc92167bc58070ff19dd39bb6b66f3d35b3b84)
parent 7feb2089
...@@ -69,7 +69,9 @@ public final class CmcdConfiguration { ...@@ -69,7 +69,9 @@ public final class CmcdConfiguration {
KEY_MAXIMUM_REQUESTED_BITRATE, KEY_MAXIMUM_REQUESTED_BITRATE,
KEY_STREAMING_FORMAT, KEY_STREAMING_FORMAT,
KEY_STREAM_TYPE, KEY_STREAM_TYPE,
KEY_VERSION KEY_VERSION,
KEY_TOP_BITRATE,
KEY_OBJECT_DURATION
}) })
@Documented @Documented
@Target(TYPE_USE) @Target(TYPE_USE)
...@@ -90,6 +92,8 @@ public final class CmcdConfiguration { ...@@ -90,6 +92,8 @@ public final class CmcdConfiguration {
public static final String KEY_STREAMING_FORMAT = "sf"; public static final String KEY_STREAMING_FORMAT = "sf";
public static final String KEY_STREAM_TYPE = "st"; public static final String KEY_STREAM_TYPE = "st";
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_OBJECT_DURATION = "d";
/** /**
* Factory for {@link CmcdConfiguration} instances. * Factory for {@link CmcdConfiguration} instances.
...@@ -265,4 +269,20 @@ public final class CmcdConfiguration { ...@@ -265,4 +269,20 @@ public final class CmcdConfiguration {
public boolean isStreamTypeLoggingAllowed() { public boolean isStreamTypeLoggingAllowed() {
return requestConfig.isKeyAllowed(KEY_STREAM_TYPE); return requestConfig.isKeyAllowed(KEY_STREAM_TYPE);
} }
/**
* Returns whether logging top bitrate is allowed based on the {@linkplain RequestConfig request
* configuration}.
*/
public boolean isTopBitrateLoggingAllowed() {
return requestConfig.isKeyAllowed(KEY_TOP_BITRATE);
}
/**
* Returns whether logging object duration is allowed based on the {@linkplain RequestConfig
* request configuration}.
*/
public boolean isObjectDurationLoggingAllowed() {
return requestConfig.isKeyAllowed(KEY_OBJECT_DURATION);
}
} }
...@@ -16,12 +16,14 @@ ...@@ -16,12 +16,14 @@
package com.google.android.exoplayer2.upstream; package com.google.android.exoplayer2.upstream;
import static com.google.android.exoplayer2.util.Assertions.checkArgument; import static com.google.android.exoplayer2.util.Assertions.checkArgument;
import static java.lang.Math.max;
import static java.lang.annotation.ElementType.TYPE_USE; import static java.lang.annotation.ElementType.TYPE_USE;
import android.text.TextUtils; import android.text.TextUtils;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.annotation.StringDef; import androidx.annotation.StringDef;
import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.source.TrackGroup;
import com.google.android.exoplayer2.trackselection.ExoTrackSelection; import com.google.android.exoplayer2.trackselection.ExoTrackSelection;
import com.google.android.exoplayer2.util.Util; import com.google.android.exoplayer2.util.Util;
import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMap;
...@@ -83,6 +85,7 @@ public final class CmcdLog { ...@@ -83,6 +85,7 @@ 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 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}
...@@ -92,6 +95,7 @@ public final class CmcdLog { ...@@ -92,6 +95,7 @@ public final class CmcdLog {
CmcdConfiguration cmcdConfiguration, CmcdConfiguration cmcdConfiguration,
ExoTrackSelection trackSelection, ExoTrackSelection trackSelection,
long bufferedDurationUs, long bufferedDurationUs,
long chunkDurationUs,
@StreamingFormat String streamingFormat, @StreamingFormat String streamingFormat,
boolean isLive) { boolean isLive) {
ImmutableMap<@CmcdConfiguration.HeaderKey String, String> customData = ImmutableMap<@CmcdConfiguration.HeaderKey String, String> customData =
...@@ -104,6 +108,17 @@ public final class CmcdLog { ...@@ -104,6 +108,17 @@ public final class CmcdLog {
if (cmcdConfiguration.isBitrateLoggingAllowed()) { if (cmcdConfiguration.isBitrateLoggingAllowed()) {
cmcdObject.setBitrateKbps(bitrateKbps); cmcdObject.setBitrateKbps(bitrateKbps);
} }
if (cmcdConfiguration.isTopBitrateLoggingAllowed()) {
TrackGroup trackGroup = trackSelection.getTrackGroup();
int topBitrate = trackSelection.getSelectedFormat().bitrate;
for (int i = 0; i < trackGroup.length; i++) {
topBitrate = max(topBitrate, trackGroup.getFormat(i).bitrate);
}
cmcdObject.setTopBitrateKbps(topBitrate / 1000);
}
if (cmcdConfiguration.isObjectDurationLoggingAllowed()) {
cmcdObject.setObjectDurationMs(chunkDurationUs / 1000);
}
CmcdLog.CmcdRequest.Builder cmcdRequest = CmcdLog.CmcdRequest.Builder cmcdRequest =
new CmcdLog.CmcdRequest.Builder() new CmcdLog.CmcdRequest.Builder()
...@@ -171,11 +186,15 @@ public final class CmcdLog { ...@@ -171,11 +186,15 @@ public final class CmcdLog {
/** Builder for {@link CmcdObject} instances. */ /** Builder for {@link CmcdObject} instances. */
public static final class Builder { public static final class Builder {
private int bitrateKbps; private int bitrateKbps;
private int topBitrateKbps;
private long objectDurationMs;
@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.bitrateKbps = C.RATE_UNSET_INT; this.bitrateKbps = C.RATE_UNSET_INT;
this.topBitrateKbps = C.RATE_UNSET_INT;
this.objectDurationMs = C.TIME_UNSET;
} }
/** Sets the {@link CmcdObject#bitrateKbps}. The default value is {@link C#RATE_UNSET_INT}. */ /** Sets the {@link CmcdObject#bitrateKbps}. The default value is {@link C#RATE_UNSET_INT}. */
...@@ -185,6 +204,28 @@ public final class CmcdLog { ...@@ -185,6 +204,28 @@ public final class CmcdLog {
return this; return this;
} }
/**
* Sets the {@link CmcdObject#topBitrateKbps}. The default value is {@link C#RATE_UNSET_INT}.
*/
@CanIgnoreReturnValue
public Builder setTopBitrateKbps(int topBitrateKbps) {
this.topBitrateKbps = topBitrateKbps;
return this;
}
/**
* Sets the {@link CmcdObject#objectDurationMs}. The default value is {@link C#TIME_UNSET}.
*
* @throws IllegalArgumentException If {@code objectDurationMs} is not equal to {@link
* C#TIME_UNSET} and is non-positive.
*/
@CanIgnoreReturnValue
public Builder setObjectDurationMs(long objectDurationMs) {
checkArgument(objectDurationMs == C.TIME_UNSET || objectDurationMs >= 0);
this.objectDurationMs = objectDurationMs;
return this;
}
/** Sets the {@link CmcdObject#customData}. The default value is {@code null}. */ /** Sets the {@link CmcdObject#customData}. The default value is {@code null}. */
@CanIgnoreReturnValue @CanIgnoreReturnValue
public Builder setCustomData(@Nullable String customData) { public Builder setCustomData(@Nullable String customData) {
...@@ -207,6 +248,21 @@ public final class CmcdLog { ...@@ -207,6 +248,21 @@ public final class CmcdLog {
*/ */
public final int bitrateKbps; public final int bitrateKbps;
/** /**
* The highest bitrate rendition, in kbps, in the manifest or playlist that the client is
* allowed to play, given current codec, licensing and sizing constraints. If unset, it is
* represented by the value {@link C#RATE_UNSET_INT}.
*/
public final int topBitrateKbps;
/**
* The playback duration in milliseconds of the object being requested, or {@link C#TIME_UNSET}
* if unset. If a partial segment is being requested, then this value MUST indicate the playback
* duration of that part and not that of its parent segment. This value can be an approximation
* of the estimated duration if the explicit value is not known.
*/
public final long objectDurationMs;
/**
* Custom data where the values of the keys vary with the object being requested, or {@code * Custom data where the values of the keys vary with the object being requested, or {@code
* null} if unset. * null} if unset.
* *
...@@ -217,6 +273,8 @@ public final class CmcdLog { ...@@ -217,6 +273,8 @@ public final class CmcdLog {
private CmcdObject(Builder builder) { private CmcdObject(Builder builder) {
this.bitrateKbps = builder.bitrateKbps; this.bitrateKbps = builder.bitrateKbps;
this.topBitrateKbps = builder.topBitrateKbps;
this.objectDurationMs = builder.objectDurationMs;
this.customData = builder.customData; this.customData = builder.customData;
} }
...@@ -233,6 +291,15 @@ public final class CmcdLog { ...@@ -233,6 +291,15 @@ public final class CmcdLog {
headerValue.append( headerValue.append(
Util.formatInvariant("%s=%d,", CmcdConfiguration.KEY_BITRATE, bitrateKbps)); Util.formatInvariant("%s=%d,", CmcdConfiguration.KEY_BITRATE, bitrateKbps));
} }
if (topBitrateKbps != C.RATE_UNSET_INT) {
headerValue.append(
Util.formatInvariant("%s=%d,", CmcdConfiguration.KEY_TOP_BITRATE, topBitrateKbps));
}
if (objectDurationMs != C.TIME_UNSET) {
headerValue.append(
Util.formatInvariant(
"%s=%d,", CmcdConfiguration.KEY_OBJECT_DURATION, objectDurationMs));
}
if (!TextUtils.isEmpty(customData)) { if (!TextUtils.isEmpty(customData)) {
headerValue.append(Util.formatInvariant("%s,", customData)); headerValue.append(Util.formatInvariant("%s,", customData));
} }
...@@ -262,6 +329,9 @@ public final class CmcdLog { ...@@ -262,6 +329,9 @@ public final class CmcdLog {
/** /**
* 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
* C#TIME_UNSET} and is non-positive.
*/ */
@CanIgnoreReturnValue @CanIgnoreReturnValue
public Builder setBufferLengthMs(long bufferLengthMs) { public Builder setBufferLengthMs(long bufferLengthMs) {
...@@ -273,7 +343,7 @@ public final class CmcdLog { ...@@ -273,7 +343,7 @@ public final class CmcdLog {
/** Sets the {@link CmcdRequest#customData}. The default value is {@code null}. */ /** Sets the {@link CmcdRequest#customData}. The default value is {@code null}. */
@CanIgnoreReturnValue @CanIgnoreReturnValue
public CmcdRequest.Builder setCustomData(@Nullable String customData) { public Builder setCustomData(@Nullable String customData) {
this.customData = customData; this.customData = customData;
return this; return this;
} }
...@@ -346,6 +416,9 @@ public final class CmcdLog { ...@@ -346,6 +416,9 @@ public final class CmcdLog {
/** /**
* Sets the {@link CmcdSession#contentId}. Maximum length allowed is 64 characters. The * Sets the {@link CmcdSession#contentId}. Maximum length allowed is 64 characters. The
* default value is {@code null}. * default value is {@code null}.
*
* @throws IllegalArgumentException If {@code contentId} is null or its length exceeds {@link
* CmcdConfiguration#MAX_ID_LENGTH}.
*/ */
@CanIgnoreReturnValue @CanIgnoreReturnValue
public Builder setContentId(@Nullable String contentId) { public Builder setContentId(@Nullable String contentId) {
...@@ -357,6 +430,9 @@ public final class CmcdLog { ...@@ -357,6 +430,9 @@ public final class CmcdLog {
/** /**
* Sets the {@link CmcdSession#sessionId}. Maximum length allowed is 64 characters. The * Sets the {@link CmcdSession#sessionId}. Maximum length allowed is 64 characters. The
* default value is {@code null}. * default value is {@code null}.
*
* @throws IllegalArgumentException If {@code sessionId} is null or its length exceeds {@link
* CmcdConfiguration#MAX_ID_LENGTH}.
*/ */
@CanIgnoreReturnValue @CanIgnoreReturnValue
public Builder setSessionId(@Nullable String sessionId) { public Builder setSessionId(@Nullable String sessionId) {
...@@ -502,6 +578,9 @@ public final class CmcdLog { ...@@ -502,6 +578,9 @@ public final class CmcdLog {
/** /**
* Sets the {@link CmcdStatus#maximumRequestedThroughputKbps}. Rounded to nearest 100 kbps. * Sets the {@link CmcdStatus#maximumRequestedThroughputKbps}. Rounded to nearest 100 kbps.
* 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
* {@link C#RATE_UNSET_INT} and is non-positive.
*/ */
@CanIgnoreReturnValue @CanIgnoreReturnValue
public Builder setMaximumRequestedThroughputKbps(int maximumRequestedThroughputKbps) { public Builder setMaximumRequestedThroughputKbps(int maximumRequestedThroughputKbps) {
......
...@@ -22,6 +22,7 @@ import static org.mockito.Mockito.when; ...@@ -22,6 +22,7 @@ import static org.mockito.Mockito.when;
import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.google.android.exoplayer2.Format; import com.google.android.exoplayer2.Format;
import com.google.android.exoplayer2.MediaItem; import com.google.android.exoplayer2.MediaItem;
import com.google.android.exoplayer2.source.TrackGroup;
import com.google.android.exoplayer2.trackselection.ExoTrackSelection; import com.google.android.exoplayer2.trackselection.ExoTrackSelection;
import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMap;
import org.junit.Test; import org.junit.Test;
...@@ -56,13 +57,16 @@ public class CmcdLogTest { ...@@ -56,13 +57,16 @@ public class CmcdLogTest {
CmcdConfiguration cmcdConfiguration = CmcdConfiguration cmcdConfiguration =
cmcdConfigurationFactory.createCmcdConfiguration(mediaItem); cmcdConfigurationFactory.createCmcdConfiguration(mediaItem);
ExoTrackSelection trackSelection = mock(ExoTrackSelection.class); ExoTrackSelection trackSelection = mock(ExoTrackSelection.class);
when(trackSelection.getSelectedFormat()) Format format = new Format.Builder().setPeakBitrate(840_000).build();
.thenReturn(new Format.Builder().setPeakBitrate(840_000).build()); when(trackSelection.getSelectedFormat()).thenReturn(format);
when(trackSelection.getTrackGroup())
.thenReturn(new TrackGroup(format, new Format.Builder().setPeakBitrate(1_000_000).build()));
CmcdLog cmcdLog = CmcdLog cmcdLog =
CmcdLog.createInstance( CmcdLog.createInstance(
cmcdConfiguration, cmcdConfiguration,
trackSelection, trackSelection,
/* bufferedDurationUs= */ 1_760_000, /* bufferedDurationUs= */ 1_760_000,
/* chunkDurationUs= */ 3_000_000,
CmcdLog.STREAMING_FORMAT_DASH, CmcdLog.STREAMING_FORMAT_DASH,
true); true);
...@@ -72,7 +76,7 @@ public class CmcdLogTest { ...@@ -72,7 +76,7 @@ public class CmcdLogTest {
assertThat(requestHeaders) assertThat(requestHeaders)
.containsExactly( .containsExactly(
"CMCD-Object", "CMCD-Object",
"br=840,key1=value1", "br=840,tb=1000,d=3000,key1=value1",
"CMCD-Request", "CMCD-Request",
"bl=1800,key2=\"stringValue\"", "bl=1800,key2=\"stringValue\"",
"CMCD-Session", "CMCD-Session",
......
...@@ -376,6 +376,13 @@ public class DefaultDashChunkSource implements DashChunkSource { ...@@ -376,6 +376,13 @@ public class DefaultDashChunkSource implements DashChunkSource {
trackSelection.updateSelectedTrack( trackSelection.updateSelectedTrack(
playbackPositionUs, bufferedDurationUs, availableLiveDurationUs, queue, chunkIterators); playbackPositionUs, bufferedDurationUs, availableLiveDurationUs, queue, chunkIterators);
int selectedTrackIndex = trackSelection.getSelectedIndex();
long chunkDurationUs = 0;
if (selectedTrackIndex < chunkIterators.length && chunkIterators[selectedTrackIndex].next()) {
chunkDurationUs =
chunkIterators[selectedTrackIndex].getChunkEndTimeUs()
- chunkIterators[selectedTrackIndex].getChunkStartTimeUs();
}
@Nullable @Nullable
CmcdLog cmcdLog = CmcdLog cmcdLog =
cmcdConfiguration == null cmcdConfiguration == null
...@@ -384,11 +391,11 @@ public class DefaultDashChunkSource implements DashChunkSource { ...@@ -384,11 +391,11 @@ public class DefaultDashChunkSource implements DashChunkSource {
cmcdConfiguration, cmcdConfiguration,
trackSelection, trackSelection,
bufferedDurationUs, bufferedDurationUs,
chunkDurationUs,
CmcdLog.STREAMING_FORMAT_DASH, CmcdLog.STREAMING_FORMAT_DASH,
manifest.dynamic); manifest.dynamic);
RepresentationHolder representationHolder = RepresentationHolder representationHolder = updateSelectedBaseUrl(selectedTrackIndex);
updateSelectedBaseUrl(trackSelection.getSelectedIndex());
if (representationHolder.chunkExtractor != null) { if (representationHolder.chunkExtractor != null) {
Representation selectedRepresentation = representationHolder.representation; Representation selectedRepresentation = representationHolder.representation;
@Nullable RangedUri pendingInitializationUri = null; @Nullable RangedUri pendingInitializationUri = null;
......
...@@ -314,7 +314,7 @@ public class DefaultDashChunkSourceTest { ...@@ -314,7 +314,7 @@ public class DefaultDashChunkSourceTest {
assertThat(output.chunk.dataSpec.httpRequestHeaders) assertThat(output.chunk.dataSpec.httpRequestHeaders)
.containsExactly( .containsExactly(
"CMCD-Object", "CMCD-Object",
"br=700", "br=700,tb=1300,d=4000",
"CMCD-Request", "CMCD-Request",
"bl=0", "bl=0",
"CMCD-Session", "CMCD-Session",
...@@ -359,7 +359,7 @@ public class DefaultDashChunkSourceTest { ...@@ -359,7 +359,7 @@ public class DefaultDashChunkSourceTest {
assertThat(output.chunk.dataSpec.httpRequestHeaders) assertThat(output.chunk.dataSpec.httpRequestHeaders)
.containsExactly( .containsExactly(
"CMCD-Object", "CMCD-Object",
"br=700", "br=700,tb=1300,d=4000",
"CMCD-Request", "CMCD-Request",
"bl=0", "bl=0",
"CMCD-Session", "CMCD-Session",
...@@ -405,7 +405,7 @@ public class DefaultDashChunkSourceTest { ...@@ -405,7 +405,7 @@ public class DefaultDashChunkSourceTest {
assertThat(output.chunk.dataSpec.httpRequestHeaders) assertThat(output.chunk.dataSpec.httpRequestHeaders)
.containsExactly( .containsExactly(
"CMCD-Object", "CMCD-Object",
"br=700,key1=value1", "br=700,tb=1300,d=4000,key1=value1",
"CMCD-Request", "CMCD-Request",
"bl=0,key2=\"stringValue\"", "bl=0,key2=\"stringValue\"",
"CMCD-Session", "CMCD-Session",
......
...@@ -487,6 +487,13 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; ...@@ -487,6 +487,13 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
seenExpectedPlaylistError = false; seenExpectedPlaylistError = false;
expectedPlaylistUrl = null; expectedPlaylistUrl = null;
long chunkDurationUs = 0;
if (selectedTrackIndex < mediaChunkIterators.length
&& mediaChunkIterators[selectedTrackIndex].next()) {
chunkDurationUs =
mediaChunkIterators[selectedTrackIndex].getChunkEndTimeUs()
- mediaChunkIterators[selectedTrackIndex].getChunkStartTimeUs();
}
@Nullable @Nullable
CmcdLog cmcdLog = CmcdLog cmcdLog =
cmcdConfiguration == null cmcdConfiguration == null
...@@ -495,6 +502,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; ...@@ -495,6 +502,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
cmcdConfiguration, cmcdConfiguration,
trackSelection, trackSelection,
bufferedDurationUs, bufferedDurationUs,
chunkDurationUs,
CmcdLog.STREAMING_FORMAT_HLS, CmcdLog.STREAMING_FORMAT_HLS,
!playlist.hasEndTag); !playlist.hasEndTag);
......
...@@ -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", "br=800,tb=800,d=0",
"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", "br=800,tb=800,d=0",
"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,key1=value1", "br=800,tb=800,d=0,key1=value1",
"CMCD-Request", "CMCD-Request",
"bl=0,key2=\"stringValue\"", "bl=0,key2=\"stringValue\"",
"CMCD-Session", "CMCD-Session",
......
...@@ -286,6 +286,12 @@ public class DefaultSsChunkSource implements SsChunkSource { ...@@ -286,6 +286,12 @@ 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;
if (trackSelectionIndex < chunkIterators.length && chunkIterators[trackSelectionIndex].next()) {
chunkDurationUs =
chunkIterators[trackSelectionIndex].getChunkEndTimeUs()
- chunkIterators[trackSelectionIndex].getChunkStartTimeUs();
}
@Nullable @Nullable
CmcdLog cmcdLog = CmcdLog cmcdLog =
cmcdConfiguration == null cmcdConfiguration == null
...@@ -294,6 +300,7 @@ public class DefaultSsChunkSource implements SsChunkSource { ...@@ -294,6 +300,7 @@ public class DefaultSsChunkSource implements SsChunkSource {
cmcdConfiguration, cmcdConfiguration,
trackSelection, trackSelection,
bufferedDurationUs, bufferedDurationUs,
chunkDurationUs,
CmcdLog.STREAMING_FORMAT_SS, CmcdLog.STREAMING_FORMAT_SS,
manifest.isLive); manifest.isLive);
......
...@@ -64,7 +64,7 @@ public class DefaultSsChunkSourceTest { ...@@ -64,7 +64,7 @@ public class DefaultSsChunkSourceTest {
assertThat(output.chunk.dataSpec.httpRequestHeaders) assertThat(output.chunk.dataSpec.httpRequestHeaders)
.containsExactly( .containsExactly(
"CMCD-Object", "CMCD-Object",
"br=307", "br=307,tb=1536,d=1968",
"CMCD-Request", "CMCD-Request",
"bl=0", "bl=0",
"CMCD-Session", "CMCD-Session",
...@@ -109,7 +109,7 @@ public class DefaultSsChunkSourceTest { ...@@ -109,7 +109,7 @@ public class DefaultSsChunkSourceTest {
assertThat(output.chunk.dataSpec.httpRequestHeaders) assertThat(output.chunk.dataSpec.httpRequestHeaders)
.containsExactly( .containsExactly(
"CMCD-Object", "CMCD-Object",
"br=307", "br=307,tb=1536,d=1968",
"CMCD-Request", "CMCD-Request",
"bl=0", "bl=0",
"CMCD-Session", "CMCD-Session",
...@@ -155,7 +155,7 @@ public class DefaultSsChunkSourceTest { ...@@ -155,7 +155,7 @@ public class DefaultSsChunkSourceTest {
assertThat(output.chunk.dataSpec.httpRequestHeaders) assertThat(output.chunk.dataSpec.httpRequestHeaders)
.containsExactly( .containsExactly(
"CMCD-Object", "CMCD-Object",
"br=307,key1=value1", "br=307,tb=1536,d=1968,key1=value1",
"CMCD-Request", "CMCD-Request",
"bl=0,key2=\"stringValue\"", "bl=0,key2=\"stringValue\"",
"CMCD-Session", "CMCD-Session",
......
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