mirror of
https://github.com/androidx/media.git
synced 2025-04-30 06:46:50 +08:00
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. PiperOrigin-RevId: 549369529 (cherry picked from commit cdb174c91a0a9e5387f9773ac24f015199a7999e)
This commit is contained in:
parent
6443614020
commit
7352a1be0a
@ -12,6 +12,9 @@
|
|||||||
Common Media Client Data (CMCD) logging.
|
Common Media Client Data (CMCD) logging.
|
||||||
* Add fields top birate (tb) and object duration (d) to Common Media
|
* Add fields top birate (tb) and object duration (d) to Common Media
|
||||||
Client Data (CMCD) logging.
|
Client Data (CMCD) logging.
|
||||||
|
* Add additional fields to Common Media Client Data (CMCD) logging:
|
||||||
|
streaming format (sf), stream type (st), version (v), top birate (tb),
|
||||||
|
object duration (d) and measured throughput (mtp).
|
||||||
* Audio Offload:
|
* Audio Offload:
|
||||||
* Prepend Ogg ID Header and Comment Header Pages to bitstream for
|
* Prepend Ogg ID Header and Comment Header Pages to bitstream for
|
||||||
offloaded Opus playback in accordance with RFC 7845.
|
offloaded Opus playback in accordance with RFC 7845.
|
||||||
|
@ -605,6 +605,11 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
|||||||
return trackSelection.isTrackExcluded(index, nowMs);
|
return trackSelection.isTrackExcluded(index, nowMs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getLatestBitrateEstimate() {
|
||||||
|
return trackSelection.getLatestBitrateEstimate();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(@Nullable Object o) {
|
public boolean equals(@Nullable Object o) {
|
||||||
if (this == o) {
|
if (this == o) {
|
||||||
|
@ -319,6 +319,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}.
|
||||||
@ -410,6 +411,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
|
||||||
@ -543,6 +545,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.
|
||||||
*
|
*
|
||||||
@ -681,8 +688,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);
|
||||||
|
@ -290,4 +290,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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -65,7 +65,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)
|
||||||
@ -88,6 +89,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.
|
||||||
@ -279,4 +281,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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -81,7 +81,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}
|
||||||
@ -112,7 +113,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);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -122,6 +123,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()
|
||||||
@ -212,12 +217,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;
|
||||||
}
|
}
|
||||||
@ -315,25 +319,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;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -356,6 +374,19 @@ public final class CmcdLog {
|
|||||||
* <p>This value MUST be rounded to the nearest 100 ms.
|
* <p>This value MUST be rounded to the nearest 100 ms.
|
||||||
*/
|
*/
|
||||||
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.
|
||||||
*
|
*
|
||||||
@ -366,6 +397,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;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -382,6 +414,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));
|
||||||
}
|
}
|
||||||
@ -576,7 +613,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) {
|
||||||
|
@ -107,6 +107,20 @@ public final class AdaptiveTrackSelectionTest {
|
|||||||
assertThat(adaptiveTrackSelection.getSelectionReason()).isEqualTo(C.SELECTION_REASON_INITIAL);
|
assertThat(adaptiveTrackSelection.getSelectionReason()).isEqualTo(C.SELECTION_REASON_INITIAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@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
|
@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);
|
||||||
|
@ -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 {
|
|||||||
"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",
|
||||||
|
@ -371,7 +371,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 {
|
|||||||
"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 {
|
|||||||
"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 {
|
|||||||
"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",
|
||||||
|
@ -479,7 +479,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 {
|
|||||||
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 {
|
|||||||
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 {
|
|||||||
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",
|
||||||
|
@ -280,7 +280,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 {
|
|||||||
"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 {
|
|||||||
"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 {
|
|||||||
"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",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user