mirror of
https://github.com/androidx/media.git
synced 2025-04-30 06:46:50 +08:00
Make Track selection objects Bundleable
Most of those objects needs to be sent to MediaControler. `TrackSelectior.Parameters` could have stayed Parcelable, but it needs to be `Bundleable` as it inherit from `TrackSelectionParameters` that is and needs to be serializable anyway for the demo app. As a result it has also been migrated to bundleable. PiperOrigin-RevId: 391353293
This commit is contained in:
parent
b689fbd44e
commit
cd297b048a
@ -98,7 +98,7 @@ public class PlayerActivity extends AppCompatActivity
|
||||
// Activity lifecycle.
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
public void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
dataSourceFactory = DemoUtil.getDataSourceFactory(/* context= */ this);
|
||||
|
||||
@ -114,7 +114,9 @@ public class PlayerActivity extends AppCompatActivity
|
||||
playerView.requestFocus();
|
||||
|
||||
if (savedInstanceState != null) {
|
||||
trackSelectorParameters = savedInstanceState.getParcelable(KEY_TRACK_SELECTOR_PARAMETERS);
|
||||
trackSelectorParameters =
|
||||
DefaultTrackSelector.Parameters.CREATOR.fromBundle(
|
||||
savedInstanceState.getBundle(KEY_TRACK_SELECTOR_PARAMETERS));
|
||||
startAutoPlay = savedInstanceState.getBoolean(KEY_AUTO_PLAY);
|
||||
startWindow = savedInstanceState.getInt(KEY_WINDOW);
|
||||
startPosition = savedInstanceState.getLong(KEY_POSITION);
|
||||
@ -207,7 +209,7 @@ public class PlayerActivity extends AppCompatActivity
|
||||
super.onSaveInstanceState(outState);
|
||||
updateTrackSelectorParameters();
|
||||
updateStartPosition();
|
||||
outState.putParcelable(KEY_TRACK_SELECTOR_PARAMETERS, trackSelectorParameters);
|
||||
outState.putBundle(KEY_TRACK_SELECTOR_PARAMETERS, trackSelectorParameters.toBundle());
|
||||
outState.putBoolean(KEY_AUTO_PLAY, startAutoPlay);
|
||||
outState.putInt(KEY_WINDOW, startWindow);
|
||||
outState.putLong(KEY_POSITION, startPosition);
|
||||
|
@ -15,19 +15,21 @@
|
||||
*/
|
||||
package com.google.android.exoplayer2;
|
||||
|
||||
import static com.google.android.exoplayer2.util.Assertions.checkNotNull;
|
||||
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
import android.os.Bundle;
|
||||
import androidx.annotation.IntDef;
|
||||
import androidx.annotation.Nullable;
|
||||
import com.google.android.exoplayer2.drm.DrmInitData;
|
||||
import com.google.android.exoplayer2.drm.ExoMediaCrypto;
|
||||
import com.google.android.exoplayer2.drm.UnsupportedMediaCrypto;
|
||||
import com.google.android.exoplayer2.metadata.Metadata;
|
||||
import com.google.android.exoplayer2.util.BundleableUtils;
|
||||
import com.google.android.exoplayer2.util.MimeTypes;
|
||||
import com.google.android.exoplayer2.util.Util;
|
||||
import com.google.android.exoplayer2.video.ColorInfo;
|
||||
import com.google.common.base.Joiner;
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
@ -112,7 +114,7 @@ import java.util.UUID;
|
||||
* <li>{@link #accessibilityChannel}
|
||||
* </ul>
|
||||
*/
|
||||
public final class Format implements Parcelable {
|
||||
public final class Format implements Bundleable {
|
||||
|
||||
/**
|
||||
* Builds {@link Format} instances.
|
||||
@ -610,6 +612,8 @@ public final class Format implements Parcelable {
|
||||
*/
|
||||
public static final long OFFSET_SAMPLE_RELATIVE = Long.MAX_VALUE;
|
||||
|
||||
private static final Format DEFAULT = new Builder().build();
|
||||
|
||||
/** An identifier for the format, or null if unknown or not applicable. */
|
||||
@Nullable public final String id;
|
||||
/** The human readable label, or null if unknown or not applicable. */
|
||||
@ -968,54 +972,6 @@ public final class Format implements Parcelable {
|
||||
}
|
||||
}
|
||||
|
||||
// Some fields are deprecated but they're still assigned below.
|
||||
@SuppressWarnings({"ResourceType"})
|
||||
/* package */ Format(Parcel in) {
|
||||
id = in.readString();
|
||||
label = in.readString();
|
||||
language = in.readString();
|
||||
selectionFlags = in.readInt();
|
||||
roleFlags = in.readInt();
|
||||
averageBitrate = in.readInt();
|
||||
peakBitrate = in.readInt();
|
||||
bitrate = peakBitrate != NO_VALUE ? peakBitrate : averageBitrate;
|
||||
codecs = in.readString();
|
||||
metadata = in.readParcelable(Metadata.class.getClassLoader());
|
||||
// Container specific.
|
||||
containerMimeType = in.readString();
|
||||
// Sample specific.
|
||||
sampleMimeType = in.readString();
|
||||
maxInputSize = in.readInt();
|
||||
int initializationDataSize = in.readInt();
|
||||
initializationData = new ArrayList<>(initializationDataSize);
|
||||
for (int i = 0; i < initializationDataSize; i++) {
|
||||
initializationData.add(checkNotNull(in.createByteArray()));
|
||||
}
|
||||
drmInitData = in.readParcelable(DrmInitData.class.getClassLoader());
|
||||
subsampleOffsetUs = in.readLong();
|
||||
// Video specific.
|
||||
width = in.readInt();
|
||||
height = in.readInt();
|
||||
frameRate = in.readFloat();
|
||||
rotationDegrees = in.readInt();
|
||||
pixelWidthHeightRatio = in.readFloat();
|
||||
boolean hasProjectionData = Util.readBoolean(in);
|
||||
projectionData = hasProjectionData ? in.createByteArray() : null;
|
||||
stereoMode = in.readInt();
|
||||
colorInfo = in.readParcelable(ColorInfo.class.getClassLoader());
|
||||
// Audio specific.
|
||||
channelCount = in.readInt();
|
||||
sampleRate = in.readInt();
|
||||
pcmEncoding = in.readInt();
|
||||
encoderDelay = in.readInt();
|
||||
encoderPadding = in.readInt();
|
||||
// Text specific.
|
||||
accessibilityChannel = in.readInt();
|
||||
// Provided by source.
|
||||
// Encrypted content must always have a non-null exoMediaCryptoType.
|
||||
exoMediaCryptoType = drmInitData != null ? UnsupportedMediaCrypto.class : null;
|
||||
}
|
||||
|
||||
/** Returns a {@link Format.Builder} initialized with the values of this instance. */
|
||||
public Builder buildUpon() {
|
||||
return new Builder(this);
|
||||
@ -1371,69 +1327,208 @@ public final class Format implements Parcelable {
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
// Parcelable implementation.
|
||||
// Bundleable implementation.
|
||||
@Documented
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
@IntDef({
|
||||
FIELD_ID,
|
||||
FIELD_LABEL,
|
||||
FIELD_LANGUAGE,
|
||||
FIELD_SELECTION_FLAGS,
|
||||
FIELD_ROLE_FLAGS,
|
||||
FIELD_AVERAGE_BITRATE,
|
||||
FIELD_PEAK_BITRATE,
|
||||
FIELD_CODECS,
|
||||
FIELD_METADATA,
|
||||
FIELD_CONTAINER_MIME_TYPE,
|
||||
FIELD_SAMPLE_MIME_TYPE,
|
||||
FIELD_MAX_INPUT_SIZE,
|
||||
FIELD_INITIALIZATION_DATA,
|
||||
FIELD_DRM_INIT_DATA,
|
||||
FIELD_SUBSAMPLE_OFFSET_US,
|
||||
FIELD_WIDTH,
|
||||
FIELD_HEIGHT,
|
||||
FIELD_FRAME_RATE,
|
||||
FIELD_ROTATION_DEGREES,
|
||||
FIELD_PIXEL_WIDTH_HEIGHT_RATIO,
|
||||
FIELD_PROJECTION_DATA,
|
||||
FIELD_STEREO_MODE,
|
||||
FIELD_COLOR_INFO,
|
||||
FIELD_CHANNEL_COUNT,
|
||||
FIELD_SAMPLE_RATE,
|
||||
FIELD_PCM_ENCODING,
|
||||
FIELD_ENCODER_DELAY,
|
||||
FIELD_ENCODER_PADDING,
|
||||
FIELD_ACCESSIBILITY_CHANNEL,
|
||||
})
|
||||
private @interface FieldNumber {}
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
private static final int FIELD_ID = 0;
|
||||
private static final int FIELD_LABEL = 1;
|
||||
private static final int FIELD_LANGUAGE = 2;
|
||||
private static final int FIELD_SELECTION_FLAGS = 3;
|
||||
private static final int FIELD_ROLE_FLAGS = 4;
|
||||
private static final int FIELD_AVERAGE_BITRATE = 5;
|
||||
private static final int FIELD_PEAK_BITRATE = 6;
|
||||
private static final int FIELD_CODECS = 7;
|
||||
private static final int FIELD_METADATA = 8;
|
||||
private static final int FIELD_CONTAINER_MIME_TYPE = 9;
|
||||
private static final int FIELD_SAMPLE_MIME_TYPE = 10;
|
||||
private static final int FIELD_MAX_INPUT_SIZE = 11;
|
||||
private static final int FIELD_INITIALIZATION_DATA = 12;
|
||||
private static final int FIELD_DRM_INIT_DATA = 13;
|
||||
private static final int FIELD_SUBSAMPLE_OFFSET_US = 14;
|
||||
private static final int FIELD_WIDTH = 15;
|
||||
private static final int FIELD_HEIGHT = 16;
|
||||
private static final int FIELD_FRAME_RATE = 17;
|
||||
private static final int FIELD_ROTATION_DEGREES = 18;
|
||||
private static final int FIELD_PIXEL_WIDTH_HEIGHT_RATIO = 19;
|
||||
private static final int FIELD_PROJECTION_DATA = 20;
|
||||
private static final int FIELD_STEREO_MODE = 21;
|
||||
private static final int FIELD_COLOR_INFO = 22;
|
||||
private static final int FIELD_CHANNEL_COUNT = 23;
|
||||
private static final int FIELD_SAMPLE_RATE = 24;
|
||||
private static final int FIELD_PCM_ENCODING = 25;
|
||||
private static final int FIELD_ENCODER_DELAY = 26;
|
||||
private static final int FIELD_ENCODER_PADDING = 27;
|
||||
private static final int FIELD_ACCESSIBILITY_CHANNEL = 28;
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>Omits the {@link #exoMediaCryptoType} field. The {@link #exoMediaCryptoType} of an instance
|
||||
* restored by {@link #CREATOR} will always be {@link UnsupportedMediaCrypto}.
|
||||
*/
|
||||
@Override
|
||||
public void writeToParcel(Parcel dest, int flags) {
|
||||
dest.writeString(id);
|
||||
dest.writeString(label);
|
||||
dest.writeString(language);
|
||||
dest.writeInt(selectionFlags);
|
||||
dest.writeInt(roleFlags);
|
||||
dest.writeInt(averageBitrate);
|
||||
dest.writeInt(peakBitrate);
|
||||
dest.writeString(codecs);
|
||||
dest.writeParcelable(metadata, 0);
|
||||
public Bundle toBundle() {
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putString(keyForField(FIELD_ID), id);
|
||||
bundle.putString(keyForField(FIELD_LABEL), label);
|
||||
bundle.putString(keyForField(FIELD_LANGUAGE), language);
|
||||
bundle.putInt(keyForField(FIELD_SELECTION_FLAGS), selectionFlags);
|
||||
bundle.putInt(keyForField(FIELD_ROLE_FLAGS), roleFlags);
|
||||
bundle.putInt(keyForField(FIELD_AVERAGE_BITRATE), averageBitrate);
|
||||
bundle.putInt(keyForField(FIELD_PEAK_BITRATE), peakBitrate);
|
||||
bundle.putString(keyForField(FIELD_CODECS), codecs);
|
||||
// Metadata is currently not Bundleable because Metadata.Entry is an Interface,
|
||||
// which would be difficult to unbundle in a backward compatible way.
|
||||
// The entries are additionally of limited usefulness to remote processes.
|
||||
bundle.putParcelable(keyForField(FIELD_METADATA), metadata);
|
||||
// Container specific.
|
||||
dest.writeString(containerMimeType);
|
||||
bundle.putString(keyForField(FIELD_CONTAINER_MIME_TYPE), containerMimeType);
|
||||
// Sample specific.
|
||||
dest.writeString(sampleMimeType);
|
||||
dest.writeInt(maxInputSize);
|
||||
int initializationDataSize = initializationData.size();
|
||||
dest.writeInt(initializationDataSize);
|
||||
for (int i = 0; i < initializationDataSize; i++) {
|
||||
dest.writeByteArray(initializationData.get(i));
|
||||
bundle.putString(keyForField(FIELD_SAMPLE_MIME_TYPE), sampleMimeType);
|
||||
bundle.putInt(keyForField(FIELD_MAX_INPUT_SIZE), maxInputSize);
|
||||
for (int i = 0; i < initializationData.size(); i++) {
|
||||
bundle.putByteArray(keyForInitializationData(i), initializationData.get(i));
|
||||
}
|
||||
dest.writeParcelable(drmInitData, 0);
|
||||
dest.writeLong(subsampleOffsetUs);
|
||||
// DrmInitData doesn't need to be Bundleable as it's only used in the playing process to
|
||||
// initialize the decoder.
|
||||
bundle.putParcelable(keyForField(FIELD_DRM_INIT_DATA), drmInitData);
|
||||
bundle.putLong(keyForField(FIELD_SUBSAMPLE_OFFSET_US), subsampleOffsetUs);
|
||||
// Video specific.
|
||||
dest.writeInt(width);
|
||||
dest.writeInt(height);
|
||||
dest.writeFloat(frameRate);
|
||||
dest.writeInt(rotationDegrees);
|
||||
dest.writeFloat(pixelWidthHeightRatio);
|
||||
Util.writeBoolean(dest, projectionData != null);
|
||||
if (projectionData != null) {
|
||||
dest.writeByteArray(projectionData);
|
||||
}
|
||||
dest.writeInt(stereoMode);
|
||||
dest.writeParcelable(colorInfo, flags);
|
||||
bundle.putInt(keyForField(FIELD_WIDTH), width);
|
||||
bundle.putInt(keyForField(FIELD_HEIGHT), height);
|
||||
bundle.putFloat(keyForField(FIELD_FRAME_RATE), frameRate);
|
||||
bundle.putInt(keyForField(FIELD_ROTATION_DEGREES), rotationDegrees);
|
||||
bundle.putFloat(keyForField(FIELD_PIXEL_WIDTH_HEIGHT_RATIO), pixelWidthHeightRatio);
|
||||
bundle.putByteArray(keyForField(FIELD_PROJECTION_DATA), projectionData);
|
||||
bundle.putInt(keyForField(FIELD_STEREO_MODE), stereoMode);
|
||||
bundle.putBundle(keyForField(FIELD_COLOR_INFO), BundleableUtils.toNullableBundle(colorInfo));
|
||||
// Audio specific.
|
||||
dest.writeInt(channelCount);
|
||||
dest.writeInt(sampleRate);
|
||||
dest.writeInt(pcmEncoding);
|
||||
dest.writeInt(encoderDelay);
|
||||
dest.writeInt(encoderPadding);
|
||||
bundle.putInt(keyForField(FIELD_CHANNEL_COUNT), channelCount);
|
||||
bundle.putInt(keyForField(FIELD_SAMPLE_RATE), sampleRate);
|
||||
bundle.putInt(keyForField(FIELD_PCM_ENCODING), pcmEncoding);
|
||||
bundle.putInt(keyForField(FIELD_ENCODER_DELAY), encoderDelay);
|
||||
bundle.putInt(keyForField(FIELD_ENCODER_PADDING), encoderPadding);
|
||||
// Text specific.
|
||||
dest.writeInt(accessibilityChannel);
|
||||
bundle.putInt(keyForField(FIELD_ACCESSIBILITY_CHANNEL), accessibilityChannel);
|
||||
return bundle;
|
||||
}
|
||||
|
||||
public static final Creator<Format> CREATOR =
|
||||
new Creator<Format>() {
|
||||
/** Object that can restore {@code Format} from a {@link Bundle}. */
|
||||
public static final Creator<Format> CREATOR = Format::fromBundle;
|
||||
|
||||
@Override
|
||||
public Format createFromParcel(Parcel in) {
|
||||
return new Format(in);
|
||||
}
|
||||
private static Format fromBundle(Bundle bundle) {
|
||||
Builder builder = new Builder();
|
||||
BundleableUtils.ensureClassLoader(bundle);
|
||||
builder
|
||||
.setId(defaultIfNull(bundle.getString(keyForField(FIELD_ID)), DEFAULT.id))
|
||||
.setLabel(defaultIfNull(bundle.getString(keyForField(FIELD_LABEL)), DEFAULT.label))
|
||||
.setLanguage(defaultIfNull(bundle.getString(keyForField(FIELD_LANGUAGE)), DEFAULT.language))
|
||||
.setSelectionFlags(
|
||||
bundle.getInt(keyForField(FIELD_SELECTION_FLAGS), DEFAULT.selectionFlags))
|
||||
.setRoleFlags(bundle.getInt(keyForField(FIELD_ROLE_FLAGS), DEFAULT.roleFlags))
|
||||
.setAverageBitrate(
|
||||
bundle.getInt(keyForField(FIELD_AVERAGE_BITRATE), DEFAULT.averageBitrate))
|
||||
.setPeakBitrate(bundle.getInt(keyForField(FIELD_PEAK_BITRATE), DEFAULT.peakBitrate))
|
||||
.setCodecs(defaultIfNull(bundle.getString(keyForField(FIELD_CODECS)), DEFAULT.codecs))
|
||||
.setMetadata(
|
||||
defaultIfNull(bundle.getParcelable(keyForField(FIELD_METADATA)), DEFAULT.metadata))
|
||||
// Container specific.
|
||||
.setContainerMimeType(
|
||||
defaultIfNull(
|
||||
bundle.getString(keyForField(FIELD_CONTAINER_MIME_TYPE)),
|
||||
DEFAULT.containerMimeType))
|
||||
// Sample specific.
|
||||
.setSampleMimeType(
|
||||
defaultIfNull(
|
||||
bundle.getString(keyForField(FIELD_SAMPLE_MIME_TYPE)), DEFAULT.sampleMimeType))
|
||||
.setMaxInputSize(bundle.getInt(keyForField(FIELD_MAX_INPUT_SIZE), DEFAULT.maxInputSize));
|
||||
|
||||
@Override
|
||||
public Format[] newArray(int size) {
|
||||
return new Format[size];
|
||||
}
|
||||
};
|
||||
List<byte[]> initializationData = new ArrayList<>();
|
||||
for (int i = 0; ; i++) {
|
||||
@Nullable byte[] data = bundle.getByteArray(keyForInitializationData(i));
|
||||
if (data == null) {
|
||||
break;
|
||||
}
|
||||
initializationData.add(data);
|
||||
}
|
||||
builder
|
||||
.setInitializationData(initializationData)
|
||||
.setDrmInitData(bundle.getParcelable(keyForField(FIELD_DRM_INIT_DATA)))
|
||||
.setSubsampleOffsetUs(
|
||||
bundle.getLong(keyForField(FIELD_SUBSAMPLE_OFFSET_US), DEFAULT.subsampleOffsetUs))
|
||||
// Video specific.
|
||||
.setWidth(bundle.getInt(keyForField(FIELD_WIDTH), DEFAULT.width))
|
||||
.setHeight(bundle.getInt(keyForField(FIELD_HEIGHT), DEFAULT.height))
|
||||
.setFrameRate(bundle.getFloat(keyForField(FIELD_FRAME_RATE), DEFAULT.frameRate))
|
||||
.setRotationDegrees(
|
||||
bundle.getInt(keyForField(FIELD_ROTATION_DEGREES), DEFAULT.rotationDegrees))
|
||||
.setPixelWidthHeightRatio(
|
||||
bundle.getFloat(
|
||||
keyForField(FIELD_PIXEL_WIDTH_HEIGHT_RATIO), DEFAULT.pixelWidthHeightRatio))
|
||||
.setProjectionData(bundle.getByteArray(keyForField(FIELD_PROJECTION_DATA)))
|
||||
.setStereoMode(bundle.getInt(keyForField(FIELD_STEREO_MODE), DEFAULT.stereoMode))
|
||||
.setColorInfo(
|
||||
BundleableUtils.fromNullableBundle(
|
||||
ColorInfo.CREATOR, bundle.getBundle(keyForField(FIELD_COLOR_INFO))))
|
||||
// Audio specific.
|
||||
.setChannelCount(bundle.getInt(keyForField(FIELD_CHANNEL_COUNT), DEFAULT.channelCount))
|
||||
.setSampleRate(bundle.getInt(keyForField(FIELD_SAMPLE_RATE), DEFAULT.sampleRate))
|
||||
.setPcmEncoding(bundle.getInt(keyForField(FIELD_PCM_ENCODING), DEFAULT.pcmEncoding))
|
||||
.setEncoderDelay(bundle.getInt(keyForField(FIELD_ENCODER_DELAY), DEFAULT.encoderDelay))
|
||||
.setEncoderPadding(
|
||||
bundle.getInt(keyForField(FIELD_ENCODER_PADDING), DEFAULT.encoderPadding))
|
||||
// Text specific.
|
||||
.setAccessibilityChannel(
|
||||
bundle.getInt(keyForField(FIELD_ACCESSIBILITY_CHANNEL), DEFAULT.accessibilityChannel));
|
||||
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
private static String keyForField(@FieldNumber int field) {
|
||||
return Integer.toString(field, Character.MAX_RADIX);
|
||||
}
|
||||
|
||||
private static String keyForInitializationData(int initialisationDataIndex) {
|
||||
return keyForField(FIELD_INITIALIZATION_DATA)
|
||||
+ "_"
|
||||
+ Integer.toString(initialisationDataIndex, Character.MAX_RADIX);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static <T> T defaultIfNull(@Nullable T value, @Nullable T defaultValue) {
|
||||
return value != null ? value : defaultValue;
|
||||
}
|
||||
}
|
||||
|
@ -15,17 +15,26 @@
|
||||
*/
|
||||
package com.google.android.exoplayer2.source;
|
||||
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
import static com.google.android.exoplayer2.util.Assertions.checkArgument;
|
||||
|
||||
import android.os.Bundle;
|
||||
import androidx.annotation.IntDef;
|
||||
import androidx.annotation.Nullable;
|
||||
import com.google.android.exoplayer2.Bundleable;
|
||||
import com.google.android.exoplayer2.C;
|
||||
import com.google.android.exoplayer2.Format;
|
||||
import com.google.android.exoplayer2.util.Assertions;
|
||||
import com.google.android.exoplayer2.util.BundleableUtils;
|
||||
import com.google.android.exoplayer2.util.Log;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.Lists;
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/** Defines an immutable group of tracks identified by their format identity. */
|
||||
public final class TrackGroup implements Parcelable {
|
||||
public final class TrackGroup implements Bundleable {
|
||||
|
||||
private static final String TAG = "TrackGroup";
|
||||
|
||||
@ -37,22 +46,18 @@ public final class TrackGroup implements Parcelable {
|
||||
// Lazily initialized hashcode.
|
||||
private int hashCode;
|
||||
|
||||
/** @param formats The track formats. At least one {@link Format} must be provided. */
|
||||
/**
|
||||
* Constructs an instance {@code TrackGroup} containing the provided {@code formats}.
|
||||
*
|
||||
* @param formats Non empty array of format.
|
||||
*/
|
||||
public TrackGroup(Format... formats) {
|
||||
Assertions.checkState(formats.length > 0);
|
||||
checkArgument(formats.length > 0);
|
||||
this.formats = formats;
|
||||
this.length = formats.length;
|
||||
verifyCorrectness();
|
||||
}
|
||||
|
||||
/* package */ TrackGroup(Parcel in) {
|
||||
length = in.readInt();
|
||||
formats = new Format[length];
|
||||
for (int i = 0; i < length; i++) {
|
||||
formats[i] = in.readParcelable(Format.class.getClassLoader());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the format of the track at a given index.
|
||||
*
|
||||
@ -103,35 +108,40 @@ public final class TrackGroup implements Parcelable {
|
||||
return length == other.length && Arrays.equals(formats, other.formats);
|
||||
}
|
||||
|
||||
// Parcelable implementation.
|
||||
// Bundleable implementation.
|
||||
|
||||
@Documented
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
@IntDef({
|
||||
FIELD_FORMATS,
|
||||
})
|
||||
private @interface FieldNumber {}
|
||||
|
||||
private static final int FIELD_FORMATS = 0;
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
public Bundle toBundle() {
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putParcelableArrayList(
|
||||
keyForField(FIELD_FORMATS), BundleableUtils.toBundleArrayList(Lists.newArrayList(formats)));
|
||||
return bundle;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(Parcel dest, int flags) {
|
||||
dest.writeInt(length);
|
||||
for (int i = 0; i < length; i++) {
|
||||
dest.writeParcelable(formats[i], 0);
|
||||
}
|
||||
}
|
||||
|
||||
public static final Parcelable.Creator<TrackGroup> CREATOR =
|
||||
new Parcelable.Creator<TrackGroup>() {
|
||||
|
||||
@Override
|
||||
public TrackGroup createFromParcel(Parcel in) {
|
||||
return new TrackGroup(in);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TrackGroup[] newArray(int size) {
|
||||
return new TrackGroup[size];
|
||||
}
|
||||
/** Object that can restore {@code TrackGroup} from a {@link Bundle}. */
|
||||
public static final Creator<TrackGroup> CREATOR =
|
||||
bundle -> {
|
||||
List<Format> formats =
|
||||
BundleableUtils.fromBundleNullableList(
|
||||
Format.CREATOR,
|
||||
bundle.getParcelableArrayList(keyForField(FIELD_FORMATS)),
|
||||
ImmutableList.of());
|
||||
return new TrackGroup(formats.toArray(new Format[0]));
|
||||
};
|
||||
|
||||
private static String keyForField(@FieldNumber int field) {
|
||||
return Integer.toString(field, Character.MAX_RADIX);
|
||||
}
|
||||
|
||||
private void verifyCorrectness() {
|
||||
// TrackGroups should only contain tracks with exactly the same content (but in different
|
||||
// qualities). We only log an error instead of throwing to not break backwards-compatibility for
|
||||
|
@ -15,14 +15,22 @@
|
||||
*/
|
||||
package com.google.android.exoplayer2.source;
|
||||
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
import android.os.Bundle;
|
||||
import androidx.annotation.IntDef;
|
||||
import androidx.annotation.Nullable;
|
||||
import com.google.android.exoplayer2.Bundleable;
|
||||
import com.google.android.exoplayer2.C;
|
||||
import com.google.android.exoplayer2.util.BundleableUtils;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.Lists;
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/** An immutable array of {@link TrackGroup}s. */
|
||||
public final class TrackGroupArray implements Parcelable {
|
||||
public final class TrackGroupArray implements Bundleable {
|
||||
|
||||
/** The empty array. */
|
||||
public static final TrackGroupArray EMPTY = new TrackGroupArray();
|
||||
@ -35,20 +43,12 @@ public final class TrackGroupArray implements Parcelable {
|
||||
// Lazily initialized hashcode.
|
||||
private int hashCode;
|
||||
|
||||
/** @param trackGroups The groups. May be empty. */
|
||||
/** Construct a {@code TrackGroupArray} from an array of (possibly empty) trackGroups. */
|
||||
public TrackGroupArray(TrackGroup... trackGroups) {
|
||||
this.trackGroups = trackGroups;
|
||||
this.length = trackGroups.length;
|
||||
}
|
||||
|
||||
/* package */ TrackGroupArray(Parcel in) {
|
||||
length = in.readInt();
|
||||
trackGroups = new TrackGroup[length];
|
||||
for (int i = 0; i < length; i++) {
|
||||
trackGroups[i] = in.readParcelable(TrackGroup.class.getClassLoader());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the group at a given index.
|
||||
*
|
||||
@ -102,32 +102,38 @@ public final class TrackGroupArray implements Parcelable {
|
||||
return length == other.length && Arrays.equals(trackGroups, other.trackGroups);
|
||||
}
|
||||
|
||||
// Parcelable implementation.
|
||||
// Bundleable implementation.
|
||||
|
||||
@Documented
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
@IntDef({
|
||||
FIELD_TRACK_GROUPS,
|
||||
})
|
||||
private @interface FieldNumber {}
|
||||
|
||||
private static final int FIELD_TRACK_GROUPS = 0;
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
public Bundle toBundle() {
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putParcelableArrayList(
|
||||
keyForField(FIELD_TRACK_GROUPS),
|
||||
BundleableUtils.toBundleArrayList(Lists.newArrayList(trackGroups)));
|
||||
return bundle;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(Parcel dest, int flags) {
|
||||
dest.writeInt(length);
|
||||
for (int i = 0; i < length; i++) {
|
||||
dest.writeParcelable(trackGroups[i], 0);
|
||||
}
|
||||
}
|
||||
|
||||
public static final Parcelable.Creator<TrackGroupArray> CREATOR =
|
||||
new Parcelable.Creator<TrackGroupArray>() {
|
||||
|
||||
@Override
|
||||
public TrackGroupArray createFromParcel(Parcel in) {
|
||||
return new TrackGroupArray(in);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TrackGroupArray[] newArray(int size) {
|
||||
return new TrackGroupArray[size];
|
||||
}
|
||||
/** Object that can restores a TrackGroupArray from a {@link Bundle}. */
|
||||
public static final Creator<TrackGroupArray> CREATOR =
|
||||
bundle -> {
|
||||
List<TrackGroup> trackGroups =
|
||||
BundleableUtils.fromBundleNullableList(
|
||||
TrackGroup.CREATOR,
|
||||
bundle.getParcelableArrayList(keyForField(FIELD_TRACK_GROUPS)),
|
||||
/* defaultValue= */ ImmutableList.of());
|
||||
return new TrackGroupArray(trackGroups.toArray(new TrackGroup[0]));
|
||||
};
|
||||
|
||||
private static String keyForField(@FieldNumber int field) {
|
||||
return Integer.toString(field, Character.MAX_RADIX);
|
||||
}
|
||||
}
|
||||
|
@ -16,23 +16,28 @@
|
||||
package com.google.android.exoplayer2.trackselection;
|
||||
|
||||
import static com.google.android.exoplayer2.util.Assertions.checkNotNull;
|
||||
import static com.google.common.base.MoreObjects.firstNonNull;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Point;
|
||||
import android.os.Bundle;
|
||||
import android.os.Looper;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
import android.view.accessibility.CaptioningManager;
|
||||
import androidx.annotation.CallSuper;
|
||||
import androidx.annotation.IntDef;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.RequiresApi;
|
||||
import com.google.android.exoplayer2.Bundleable;
|
||||
import com.google.android.exoplayer2.C;
|
||||
import com.google.android.exoplayer2.util.Util;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import java.util.ArrayList;
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.util.Locale;
|
||||
|
||||
/** Constraint parameters for track selection. */
|
||||
public class TrackSelectionParameters implements Parcelable {
|
||||
public class TrackSelectionParameters implements Bundleable {
|
||||
|
||||
/**
|
||||
* A builder for {@link TrackSelectionParameters}. See the {@link TrackSelectionParameters}
|
||||
@ -108,10 +113,7 @@ public class TrackSelectionParameters implements Parcelable {
|
||||
setViewportSizeToPhysicalDisplaySize(context, /* viewportOrientationMayChange= */ true);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param initialValues The {@link TrackSelectionParameters} from which the initial values of
|
||||
* the builder are obtained.
|
||||
*/
|
||||
/** Creates a builder with the initial values specified in {@code initialValues}. */
|
||||
protected Builder(TrackSelectionParameters initialValues) {
|
||||
// Video
|
||||
maxVideoWidth = initialValues.maxVideoWidth;
|
||||
@ -141,6 +143,89 @@ public class TrackSelectionParameters implements Parcelable {
|
||||
forceHighestSupportedBitrate = initialValues.forceHighestSupportedBitrate;
|
||||
}
|
||||
|
||||
/** Creates a builder with the initial values specified in {@code bundle}. */
|
||||
protected Builder(Bundle bundle) {
|
||||
// Video
|
||||
maxVideoWidth =
|
||||
bundle.getInt(keyForField(FIELD_MAX_VIDEO_WIDTH), DEFAULT_WITHOUT_CONTEXT.maxVideoWidth);
|
||||
maxVideoHeight =
|
||||
bundle.getInt(
|
||||
keyForField(FIELD_MAX_VIDEO_HEIGHT), DEFAULT_WITHOUT_CONTEXT.maxVideoHeight);
|
||||
maxVideoFrameRate =
|
||||
bundle.getInt(
|
||||
keyForField(FIELD_MAX_VIDEO_FRAMERATE), DEFAULT_WITHOUT_CONTEXT.maxVideoFrameRate);
|
||||
maxVideoBitrate =
|
||||
bundle.getInt(
|
||||
keyForField(FIELD_MAX_VIDEO_BITRATE), DEFAULT_WITHOUT_CONTEXT.maxVideoBitrate);
|
||||
minVideoWidth =
|
||||
bundle.getInt(keyForField(FIELD_MIN_VIDEO_WIDTH), DEFAULT_WITHOUT_CONTEXT.minVideoWidth);
|
||||
minVideoHeight =
|
||||
bundle.getInt(
|
||||
keyForField(FIELD_MIN_VIDEO_HEIGHT), DEFAULT_WITHOUT_CONTEXT.minVideoHeight);
|
||||
minVideoFrameRate =
|
||||
bundle.getInt(
|
||||
keyForField(FIELD_MIN_VIDEO_FRAMERATE), DEFAULT_WITHOUT_CONTEXT.minVideoFrameRate);
|
||||
minVideoBitrate =
|
||||
bundle.getInt(
|
||||
keyForField(FIELD_MIN_VIDEO_BITRATE), DEFAULT_WITHOUT_CONTEXT.minVideoBitrate);
|
||||
viewportWidth =
|
||||
bundle.getInt(keyForField(FIELD_VIEWPORT_WIDTH), DEFAULT_WITHOUT_CONTEXT.viewportWidth);
|
||||
viewportHeight =
|
||||
bundle.getInt(keyForField(FIELD_VIEWPORT_HEIGHT), DEFAULT_WITHOUT_CONTEXT.viewportHeight);
|
||||
viewportOrientationMayChange =
|
||||
bundle.getBoolean(
|
||||
keyForField(FIELD_VIEWPORT_ORIENTATION_MAY_CHANGE),
|
||||
DEFAULT_WITHOUT_CONTEXT.viewportOrientationMayChange);
|
||||
preferredVideoMimeTypes =
|
||||
ImmutableList.copyOf(
|
||||
firstNonNull(
|
||||
bundle.getStringArray(keyForField(FIELD_PREFERRED_VIDEO_MIMETYPES)),
|
||||
new String[0]));
|
||||
// Audio
|
||||
String[] preferredAudioLanguages1 =
|
||||
firstNonNull(
|
||||
bundle.getStringArray(keyForField(FIELD_PREFERRED_AUDIO_LANGUAGES)), new String[0]);
|
||||
preferredAudioLanguages = normalizeLanguageCodes(preferredAudioLanguages1);
|
||||
preferredAudioRoleFlags =
|
||||
bundle.getInt(
|
||||
keyForField(FIELD_PREFERRED_AUDIO_ROLE_FLAGS),
|
||||
DEFAULT_WITHOUT_CONTEXT.preferredAudioRoleFlags);
|
||||
maxAudioChannelCount =
|
||||
bundle.getInt(
|
||||
keyForField(FIELD_MAX_AUDIO_CHANNEL_COUNT),
|
||||
DEFAULT_WITHOUT_CONTEXT.maxAudioChannelCount);
|
||||
maxAudioBitrate =
|
||||
bundle.getInt(
|
||||
keyForField(FIELD_MAX_AUDIO_BITRATE), DEFAULT_WITHOUT_CONTEXT.maxAudioBitrate);
|
||||
preferredAudioMimeTypes =
|
||||
ImmutableList.copyOf(
|
||||
firstNonNull(
|
||||
bundle.getStringArray(keyForField(FIELD_PREFERRED_AUDIO_MIME_TYPES)),
|
||||
new String[0]));
|
||||
// Text
|
||||
preferredTextLanguages =
|
||||
normalizeLanguageCodes(
|
||||
firstNonNull(
|
||||
bundle.getStringArray(keyForField(FIELD_PREFERRED_TEXT_LANGUAGES)),
|
||||
new String[0]));
|
||||
preferredTextRoleFlags =
|
||||
bundle.getInt(
|
||||
keyForField(FIELD_PREFERRED_TEXT_ROLE_FLAGS),
|
||||
DEFAULT_WITHOUT_CONTEXT.preferredTextRoleFlags);
|
||||
selectUndeterminedTextLanguage =
|
||||
bundle.getBoolean(
|
||||
keyForField(FIELD_SELECT_UNDETERMINED_TEXT_LANGUAGE),
|
||||
DEFAULT_WITHOUT_CONTEXT.selectUndeterminedTextLanguage);
|
||||
// General
|
||||
forceLowestBitrate =
|
||||
bundle.getBoolean(
|
||||
keyForField(FIELD_FORCE_LOWEST_BITRATE), DEFAULT_WITHOUT_CONTEXT.forceLowestBitrate);
|
||||
forceHighestSupportedBitrate =
|
||||
bundle.getBoolean(
|
||||
keyForField(FIELD_FORCE_HIGHEST_SUPPORTED_BITRATE),
|
||||
DEFAULT_WITHOUT_CONTEXT.forceHighestSupportedBitrate);
|
||||
}
|
||||
|
||||
// Video
|
||||
|
||||
/**
|
||||
@ -322,11 +407,7 @@ public class TrackSelectionParameters implements Parcelable {
|
||||
* @return This builder.
|
||||
*/
|
||||
public Builder setPreferredAudioLanguages(String... preferredAudioLanguages) {
|
||||
ImmutableList.Builder<String> listBuilder = ImmutableList.builder();
|
||||
for (String language : checkNotNull(preferredAudioLanguages)) {
|
||||
listBuilder.add(Util.normalizeLanguageCode(checkNotNull(language)));
|
||||
}
|
||||
this.preferredAudioLanguages = listBuilder.build();
|
||||
this.preferredAudioLanguages = normalizeLanguageCodes(preferredAudioLanguages);
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -427,11 +508,7 @@ public class TrackSelectionParameters implements Parcelable {
|
||||
* @return This builder.
|
||||
*/
|
||||
public Builder setPreferredTextLanguages(String... preferredTextLanguages) {
|
||||
ImmutableList.Builder<String> listBuilder = ImmutableList.builder();
|
||||
for (String language : checkNotNull(preferredTextLanguages)) {
|
||||
listBuilder.add(Util.normalizeLanguageCode(checkNotNull(language)));
|
||||
}
|
||||
this.preferredTextLanguages = listBuilder.build();
|
||||
this.preferredTextLanguages = normalizeLanguageCodes(preferredTextLanguages);
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -512,6 +589,14 @@ public class TrackSelectionParameters implements Parcelable {
|
||||
preferredTextLanguages = ImmutableList.of(Util.getLocaleLanguageTag(preferredLocale));
|
||||
}
|
||||
}
|
||||
|
||||
private static ImmutableList<String> normalizeLanguageCodes(String[] preferredTextLanguages) {
|
||||
ImmutableList.Builder<String> listBuilder = ImmutableList.builder();
|
||||
for (String language : checkNotNull(preferredTextLanguages)) {
|
||||
listBuilder.add(Util.normalizeLanguageCode(checkNotNull(language)));
|
||||
}
|
||||
return listBuilder.build();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -537,20 +622,6 @@ public class TrackSelectionParameters implements Parcelable {
|
||||
*/
|
||||
@Deprecated public static final TrackSelectionParameters DEFAULT = DEFAULT_WITHOUT_CONTEXT;
|
||||
|
||||
public static final Creator<TrackSelectionParameters> CREATOR =
|
||||
new Creator<TrackSelectionParameters>() {
|
||||
|
||||
@Override
|
||||
public TrackSelectionParameters createFromParcel(Parcel in) {
|
||||
return new TrackSelectionParameters(in);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TrackSelectionParameters[] newArray(int size) {
|
||||
return new TrackSelectionParameters[size];
|
||||
}
|
||||
};
|
||||
|
||||
/** Returns an instance configured with default values. */
|
||||
public static TrackSelectionParameters getDefaults(Context context) {
|
||||
return new Builder(context).build();
|
||||
@ -707,42 +778,6 @@ public class TrackSelectionParameters implements Parcelable {
|
||||
this.forceHighestSupportedBitrate = builder.forceHighestSupportedBitrate;
|
||||
}
|
||||
|
||||
/* package */ TrackSelectionParameters(Parcel in) {
|
||||
ArrayList<String> preferredAudioLanguages = new ArrayList<>();
|
||||
in.readList(preferredAudioLanguages, /* loader= */ null);
|
||||
this.preferredAudioLanguages = ImmutableList.copyOf(preferredAudioLanguages);
|
||||
this.preferredAudioRoleFlags = in.readInt();
|
||||
ArrayList<String> preferredTextLanguages1 = new ArrayList<>();
|
||||
in.readList(preferredTextLanguages1, /* loader= */ null);
|
||||
this.preferredTextLanguages = ImmutableList.copyOf(preferredTextLanguages1);
|
||||
this.preferredTextRoleFlags = in.readInt();
|
||||
this.selectUndeterminedTextLanguage = Util.readBoolean(in);
|
||||
// Video
|
||||
this.maxVideoWidth = in.readInt();
|
||||
this.maxVideoHeight = in.readInt();
|
||||
this.maxVideoFrameRate = in.readInt();
|
||||
this.maxVideoBitrate = in.readInt();
|
||||
this.minVideoWidth = in.readInt();
|
||||
this.minVideoHeight = in.readInt();
|
||||
this.minVideoFrameRate = in.readInt();
|
||||
this.minVideoBitrate = in.readInt();
|
||||
this.viewportWidth = in.readInt();
|
||||
this.viewportHeight = in.readInt();
|
||||
this.viewportOrientationMayChange = Util.readBoolean(in);
|
||||
ArrayList<String> preferredVideoMimeTypes = new ArrayList<>();
|
||||
in.readList(preferredVideoMimeTypes, /* loader= */ null);
|
||||
this.preferredVideoMimeTypes = ImmutableList.copyOf(preferredVideoMimeTypes);
|
||||
// Audio
|
||||
this.maxAudioChannelCount = in.readInt();
|
||||
this.maxAudioBitrate = in.readInt();
|
||||
ArrayList<String> preferredAudioMimeTypes = new ArrayList<>();
|
||||
in.readList(preferredAudioMimeTypes, /* loader= */ null);
|
||||
this.preferredAudioMimeTypes = ImmutableList.copyOf(preferredAudioMimeTypes);
|
||||
// General
|
||||
this.forceLowestBitrate = Util.readBoolean(in);
|
||||
this.forceHighestSupportedBitrate = Util.readBoolean(in);
|
||||
}
|
||||
|
||||
/** Creates a new {@link Builder}, copying the initial values from this instance. */
|
||||
public Builder buildUpon() {
|
||||
return new Builder(this);
|
||||
@ -817,39 +852,109 @@ public class TrackSelectionParameters implements Parcelable {
|
||||
return result;
|
||||
}
|
||||
|
||||
// Parcelable implementation.
|
||||
// Bundleable implementation
|
||||
|
||||
@Documented
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
@IntDef({
|
||||
FIELD_PREFERRED_AUDIO_LANGUAGES,
|
||||
FIELD_PREFERRED_AUDIO_ROLE_FLAGS,
|
||||
FIELD_PREFERRED_TEXT_LANGUAGES,
|
||||
FIELD_PREFERRED_TEXT_ROLE_FLAGS,
|
||||
FIELD_SELECT_UNDETERMINED_TEXT_LANGUAGE,
|
||||
FIELD_MAX_VIDEO_WIDTH,
|
||||
FIELD_MAX_VIDEO_HEIGHT,
|
||||
FIELD_MAX_VIDEO_FRAMERATE,
|
||||
FIELD_MAX_VIDEO_BITRATE,
|
||||
FIELD_MIN_VIDEO_WIDTH,
|
||||
FIELD_MIN_VIDEO_HEIGHT,
|
||||
FIELD_MIN_VIDEO_FRAMERATE,
|
||||
FIELD_MIN_VIDEO_BITRATE,
|
||||
FIELD_VIEWPORT_WIDTH,
|
||||
FIELD_VIEWPORT_HEIGHT,
|
||||
FIELD_VIEWPORT_ORIENTATION_MAY_CHANGE,
|
||||
FIELD_PREFERRED_VIDEO_MIMETYPES,
|
||||
FIELD_MAX_AUDIO_CHANNEL_COUNT,
|
||||
FIELD_MAX_AUDIO_BITRATE,
|
||||
FIELD_PREFERRED_AUDIO_MIME_TYPES,
|
||||
FIELD_FORCE_LOWEST_BITRATE,
|
||||
FIELD_FORCE_HIGHEST_SUPPORTED_BITRATE,
|
||||
})
|
||||
private @interface FieldNumber {}
|
||||
|
||||
private static final int FIELD_PREFERRED_AUDIO_LANGUAGES = 1;
|
||||
private static final int FIELD_PREFERRED_AUDIO_ROLE_FLAGS = 2;
|
||||
private static final int FIELD_PREFERRED_TEXT_LANGUAGES = 3;
|
||||
private static final int FIELD_PREFERRED_TEXT_ROLE_FLAGS = 4;
|
||||
private static final int FIELD_SELECT_UNDETERMINED_TEXT_LANGUAGE = 5;
|
||||
private static final int FIELD_MAX_VIDEO_WIDTH = 6;
|
||||
private static final int FIELD_MAX_VIDEO_HEIGHT = 7;
|
||||
private static final int FIELD_MAX_VIDEO_FRAMERATE = 8;
|
||||
private static final int FIELD_MAX_VIDEO_BITRATE = 9;
|
||||
private static final int FIELD_MIN_VIDEO_WIDTH = 10;
|
||||
private static final int FIELD_MIN_VIDEO_HEIGHT = 11;
|
||||
private static final int FIELD_MIN_VIDEO_FRAMERATE = 12;
|
||||
private static final int FIELD_MIN_VIDEO_BITRATE = 13;
|
||||
private static final int FIELD_VIEWPORT_WIDTH = 14;
|
||||
private static final int FIELD_VIEWPORT_HEIGHT = 15;
|
||||
private static final int FIELD_VIEWPORT_ORIENTATION_MAY_CHANGE = 16;
|
||||
private static final int FIELD_PREFERRED_VIDEO_MIMETYPES = 17;
|
||||
private static final int FIELD_MAX_AUDIO_CHANNEL_COUNT = 18;
|
||||
private static final int FIELD_MAX_AUDIO_BITRATE = 19;
|
||||
private static final int FIELD_PREFERRED_AUDIO_MIME_TYPES = 20;
|
||||
private static final int FIELD_FORCE_LOWEST_BITRATE = 21;
|
||||
private static final int FIELD_FORCE_HIGHEST_SUPPORTED_BITRATE = 22;
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
@CallSuper
|
||||
public Bundle toBundle() {
|
||||
Bundle bundle = new Bundle();
|
||||
|
||||
// Video
|
||||
bundle.putInt(keyForField(FIELD_MAX_VIDEO_WIDTH), maxVideoWidth);
|
||||
bundle.putInt(keyForField(FIELD_MAX_VIDEO_HEIGHT), maxVideoHeight);
|
||||
bundle.putInt(keyForField(FIELD_MAX_VIDEO_FRAMERATE), maxVideoFrameRate);
|
||||
bundle.putInt(keyForField(FIELD_MAX_VIDEO_BITRATE), maxVideoBitrate);
|
||||
bundle.putInt(keyForField(FIELD_MIN_VIDEO_WIDTH), minVideoWidth);
|
||||
bundle.putInt(keyForField(FIELD_MIN_VIDEO_HEIGHT), minVideoHeight);
|
||||
bundle.putInt(keyForField(FIELD_MIN_VIDEO_FRAMERATE), minVideoFrameRate);
|
||||
bundle.putInt(keyForField(FIELD_MIN_VIDEO_BITRATE), minVideoBitrate);
|
||||
bundle.putInt(keyForField(FIELD_VIEWPORT_WIDTH), viewportWidth);
|
||||
bundle.putInt(keyForField(FIELD_VIEWPORT_HEIGHT), viewportHeight);
|
||||
bundle.putBoolean(
|
||||
keyForField(FIELD_VIEWPORT_ORIENTATION_MAY_CHANGE), viewportOrientationMayChange);
|
||||
bundle.putStringArray(
|
||||
keyForField(FIELD_PREFERRED_VIDEO_MIMETYPES),
|
||||
preferredVideoMimeTypes.toArray(new String[0]));
|
||||
// Audio
|
||||
bundle.putStringArray(
|
||||
keyForField(FIELD_PREFERRED_AUDIO_LANGUAGES),
|
||||
preferredAudioLanguages.toArray(new String[0]));
|
||||
bundle.putInt(keyForField(FIELD_PREFERRED_AUDIO_ROLE_FLAGS), preferredAudioRoleFlags);
|
||||
bundle.putInt(keyForField(FIELD_MAX_AUDIO_CHANNEL_COUNT), maxAudioChannelCount);
|
||||
bundle.putInt(keyForField(FIELD_MAX_AUDIO_BITRATE), maxAudioBitrate);
|
||||
bundle.putStringArray(
|
||||
keyForField(FIELD_PREFERRED_AUDIO_MIME_TYPES),
|
||||
preferredAudioMimeTypes.toArray(new String[0]));
|
||||
// Text
|
||||
bundle.putStringArray(
|
||||
keyForField(FIELD_PREFERRED_TEXT_LANGUAGES), preferredTextLanguages.toArray(new String[0]));
|
||||
bundle.putInt(keyForField(FIELD_PREFERRED_TEXT_ROLE_FLAGS), preferredTextRoleFlags);
|
||||
bundle.putBoolean(
|
||||
keyForField(FIELD_SELECT_UNDETERMINED_TEXT_LANGUAGE), selectUndeterminedTextLanguage);
|
||||
// General
|
||||
bundle.putBoolean(keyForField(FIELD_FORCE_LOWEST_BITRATE), forceLowestBitrate);
|
||||
bundle.putBoolean(
|
||||
keyForField(FIELD_FORCE_HIGHEST_SUPPORTED_BITRATE), forceHighestSupportedBitrate);
|
||||
|
||||
return bundle;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(Parcel dest, int flags) {
|
||||
dest.writeList(preferredAudioLanguages);
|
||||
dest.writeInt(preferredAudioRoleFlags);
|
||||
dest.writeList(preferredTextLanguages);
|
||||
dest.writeInt(preferredTextRoleFlags);
|
||||
Util.writeBoolean(dest, selectUndeterminedTextLanguage);
|
||||
// Video
|
||||
dest.writeInt(maxVideoWidth);
|
||||
dest.writeInt(maxVideoHeight);
|
||||
dest.writeInt(maxVideoFrameRate);
|
||||
dest.writeInt(maxVideoBitrate);
|
||||
dest.writeInt(minVideoWidth);
|
||||
dest.writeInt(minVideoHeight);
|
||||
dest.writeInt(minVideoFrameRate);
|
||||
dest.writeInt(minVideoBitrate);
|
||||
dest.writeInt(viewportWidth);
|
||||
dest.writeInt(viewportHeight);
|
||||
Util.writeBoolean(dest, viewportOrientationMayChange);
|
||||
dest.writeList(preferredVideoMimeTypes);
|
||||
// Audio
|
||||
dest.writeInt(maxAudioChannelCount);
|
||||
dest.writeInt(maxAudioBitrate);
|
||||
dest.writeList(preferredAudioMimeTypes);
|
||||
// General
|
||||
Util.writeBoolean(dest, forceLowestBitrate);
|
||||
Util.writeBoolean(dest, forceHighestSupportedBitrate);
|
||||
/** Object that can restore {@code TrackSelectionParameters} from a {@link Bundle}. */
|
||||
public static final Creator<TrackSelectionParameters> CREATOR =
|
||||
bundle -> new Builder(bundle).build();
|
||||
|
||||
private static String keyForField(@FieldNumber int field) {
|
||||
return Integer.toString(field, Character.MAX_RADIX);
|
||||
}
|
||||
}
|
||||
|
@ -15,7 +15,11 @@
|
||||
*/
|
||||
package com.google.android.exoplayer2.util;
|
||||
|
||||
import static com.google.android.exoplayer2.util.Assertions.checkNotNull;
|
||||
import static com.google.android.exoplayer2.util.Util.castNonNull;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.util.SparseArray;
|
||||
import androidx.annotation.Nullable;
|
||||
import com.google.android.exoplayer2.Bundleable;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
@ -68,13 +72,41 @@ public final class BundleableUtils {
|
||||
Bundleable.Creator<T> creator, List<Bundle> bundleList) {
|
||||
ImmutableList.Builder<T> builder = ImmutableList.builder();
|
||||
for (int i = 0; i < bundleList.size(); i++) {
|
||||
Bundle bundle = bundleList.get(i);
|
||||
Bundle bundle = checkNotNull(bundleList.get(i)); // Fail fast during parsing.
|
||||
T bundleable = creator.fromBundle(bundle);
|
||||
builder.add(bundleable);
|
||||
}
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a list of {@link Bundle} to a list of {@link Bundleable}. Returns {@code defaultValue}
|
||||
* if {@code bundleList} is null.
|
||||
*/
|
||||
public static <T extends Bundleable> List<T> fromBundleNullableList(
|
||||
Bundleable.Creator<T> creator, @Nullable List<Bundle> bundleList, List<T> defaultValue) {
|
||||
return (bundleList == null) ? defaultValue : fromBundleList(creator, bundleList);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a {@link SparseArray} of {@link Bundle} to a {@link SparseArray} of {@link
|
||||
* Bundleable}. Returns {@code defaultValue} if {@code bundleSparseArray} is null.
|
||||
*/
|
||||
public static <T extends Bundleable> SparseArray<T> fromBundleNullableSparseArray(
|
||||
Bundleable.Creator<T> creator,
|
||||
@Nullable SparseArray<Bundle> bundleSparseArray,
|
||||
SparseArray<T> defaultValue) {
|
||||
if (bundleSparseArray == null) {
|
||||
return defaultValue;
|
||||
}
|
||||
// Can't use ImmutableList as it doesn't support null elements.
|
||||
SparseArray<T> result = new SparseArray<>(bundleSparseArray.size());
|
||||
for (int i = 0; i < bundleSparseArray.size(); i++) {
|
||||
result.put(bundleSparseArray.keyAt(i), creator.fromBundle(bundleSparseArray.valueAt(i)));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a list of {@link Bundleable} to an {@link ArrayList} of {@link Bundle} so that the
|
||||
* returned list can be put to {@link Bundle} using {@link Bundle#putParcelableArrayList}
|
||||
@ -88,5 +120,31 @@ public final class BundleableUtils {
|
||||
return arrayList;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a {@link SparseArray} of {@link Bundleable} to an {@link SparseArray} of {@link
|
||||
* Bundle} so that the returned {@link SparseArray} can be put to {@link Bundle} using {@link
|
||||
* Bundle#putSparseParcelableArray} conveniently.
|
||||
*/
|
||||
public static <T extends Bundleable> SparseArray<Bundle> toBundleSparseArray(
|
||||
SparseArray<T> bundleableSparseArray) {
|
||||
SparseArray<Bundle> sparseArray = new SparseArray<>(bundleableSparseArray.size());
|
||||
for (int i = 0; i < bundleableSparseArray.size(); i++) {
|
||||
sparseArray.put(bundleableSparseArray.keyAt(i), bundleableSparseArray.valueAt(i).toBundle());
|
||||
}
|
||||
return sparseArray;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the application class loader to the given {@link Bundle} if no class loader is present.
|
||||
*
|
||||
* <p>This assumes that all classes unparceled from {@code bundle} are sharing the class loader of
|
||||
* {@code BundleableUtils}.
|
||||
*/
|
||||
public static void ensureClassLoader(@Nullable Bundle bundle) {
|
||||
if (bundle != null) {
|
||||
bundle.setClassLoader(castNonNull(BundleableUtils.class.getClassLoader()));
|
||||
}
|
||||
}
|
||||
|
||||
private BundleableUtils() {}
|
||||
}
|
||||
|
@ -15,17 +15,20 @@
|
||||
*/
|
||||
package com.google.android.exoplayer2.video;
|
||||
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
import android.os.Bundle;
|
||||
import androidx.annotation.IntDef;
|
||||
import androidx.annotation.Nullable;
|
||||
import com.google.android.exoplayer2.Bundleable;
|
||||
import com.google.android.exoplayer2.C;
|
||||
import com.google.android.exoplayer2.Format;
|
||||
import com.google.android.exoplayer2.util.Util;
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.util.Arrays;
|
||||
import org.checkerframework.dataflow.qual.Pure;
|
||||
|
||||
/** Stores color info. */
|
||||
public final class ColorInfo implements Parcelable {
|
||||
public final class ColorInfo implements Bundleable {
|
||||
|
||||
/**
|
||||
* Returns the {@link C.ColorSpace} corresponding to the given ISO color primary code, as per
|
||||
@ -116,16 +119,6 @@ public final class ColorInfo implements Parcelable {
|
||||
this.hdrStaticInfo = hdrStaticInfo;
|
||||
}
|
||||
|
||||
@SuppressWarnings("ResourceType")
|
||||
/* package */ ColorInfo(Parcel in) {
|
||||
colorSpace = in.readInt();
|
||||
colorRange = in.readInt();
|
||||
colorTransfer = in.readInt();
|
||||
boolean hasHdrStaticInfo = Util.readBoolean(in);
|
||||
hdrStaticInfo = hasHdrStaticInfo ? in.createByteArray() : null;
|
||||
}
|
||||
|
||||
// Parcelable implementation.
|
||||
@Override
|
||||
public boolean equals(@Nullable Object obj) {
|
||||
if (this == obj) {
|
||||
@ -167,32 +160,42 @@ public final class ColorInfo implements Parcelable {
|
||||
return hashCode;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
// Bundleable implementation
|
||||
|
||||
@Documented
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
@IntDef({
|
||||
FIELD_COLOR_SPACE,
|
||||
FIELD_COLOR_RANGE,
|
||||
FIELD_COLOR_TRANSFER,
|
||||
FIELD_HDR_STATIC_INFO,
|
||||
})
|
||||
private @interface FieldNumber {}
|
||||
|
||||
private static final int FIELD_COLOR_SPACE = 0;
|
||||
private static final int FIELD_COLOR_RANGE = 1;
|
||||
private static final int FIELD_COLOR_TRANSFER = 2;
|
||||
private static final int FIELD_HDR_STATIC_INFO = 3;
|
||||
|
||||
@Override
|
||||
public void writeToParcel(Parcel dest, int flags) {
|
||||
dest.writeInt(colorSpace);
|
||||
dest.writeInt(colorRange);
|
||||
dest.writeInt(colorTransfer);
|
||||
Util.writeBoolean(dest, hdrStaticInfo != null);
|
||||
if (hdrStaticInfo != null) {
|
||||
dest.writeByteArray(hdrStaticInfo);
|
||||
}
|
||||
public Bundle toBundle() {
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putInt(keyForField(FIELD_COLOR_SPACE), colorSpace);
|
||||
bundle.putInt(keyForField(FIELD_COLOR_RANGE), colorRange);
|
||||
bundle.putInt(keyForField(FIELD_COLOR_TRANSFER), colorTransfer);
|
||||
bundle.putByteArray(keyForField(FIELD_HDR_STATIC_INFO), hdrStaticInfo);
|
||||
return bundle;
|
||||
}
|
||||
|
||||
public static final Parcelable.Creator<ColorInfo> CREATOR =
|
||||
new Parcelable.Creator<ColorInfo>() {
|
||||
@Override
|
||||
public ColorInfo createFromParcel(Parcel in) {
|
||||
return new ColorInfo(in);
|
||||
}
|
||||
public static final Creator<ColorInfo> CREATOR =
|
||||
bundle ->
|
||||
new ColorInfo(
|
||||
bundle.getInt(keyForField(FIELD_COLOR_SPACE), Format.NO_VALUE),
|
||||
bundle.getInt(keyForField(FIELD_COLOR_RANGE), Format.NO_VALUE),
|
||||
bundle.getInt(keyForField(FIELD_COLOR_TRANSFER), Format.NO_VALUE),
|
||||
bundle.getByteArray(keyForField(FIELD_HDR_STATIC_INFO)));
|
||||
|
||||
@Override
|
||||
public ColorInfo[] newArray(int size) {
|
||||
return new ColorInfo[size];
|
||||
}
|
||||
};
|
||||
private static String keyForField(@FieldNumber int field) {
|
||||
return Integer.toString(field, Character.MAX_RADIX);
|
||||
}
|
||||
}
|
||||
|
@ -20,7 +20,6 @@ import static com.google.android.exoplayer2.util.MimeTypes.VIDEO_MP4;
|
||||
import static com.google.android.exoplayer2.util.MimeTypes.VIDEO_WEBM;
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import android.os.Parcel;
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||
import com.google.android.exoplayer2.drm.DrmInitData;
|
||||
import com.google.android.exoplayer2.drm.ExoMediaCrypto;
|
||||
@ -46,21 +45,15 @@ public final class FormatTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void parcelFormat_createsEqualFormat_exceptExoMediaCryptoType() {
|
||||
Format formatToParcel = createTestFormat();
|
||||
public void roundTripViaBundle_ofParameters_yieldsEqualInstanceExceptExoMediaCryptoType() {
|
||||
Format formatToBundle = createTestFormat();
|
||||
|
||||
Parcel parcel = Parcel.obtain();
|
||||
formatToParcel.writeToParcel(parcel, 0);
|
||||
parcel.setDataPosition(0);
|
||||
Format formatFromBundle = Format.CREATOR.fromBundle(formatToBundle.toBundle());
|
||||
|
||||
Format formatFromParcel = Format.CREATOR.createFromParcel(parcel);
|
||||
Format expectedFormat =
|
||||
formatToParcel.buildUpon().setExoMediaCryptoType(UnsupportedMediaCrypto.class).build();
|
||||
|
||||
assertThat(formatFromParcel.exoMediaCryptoType).isEqualTo(UnsupportedMediaCrypto.class);
|
||||
assertThat(formatFromParcel).isEqualTo(expectedFormat);
|
||||
|
||||
parcel.recycle();
|
||||
assertThat(formatFromBundle.exoMediaCryptoType).isEqualTo(UnsupportedMediaCrypto.class);
|
||||
assertThat(formatFromBundle)
|
||||
.isEqualTo(
|
||||
formatToBundle.buildUpon().setExoMediaCryptoType(UnsupportedMediaCrypto.class).build());
|
||||
}
|
||||
|
||||
private static Format createTestFormat() {
|
||||
|
@ -25,6 +25,7 @@ import com.google.android.exoplayer2.C.FormatSupport;
|
||||
import com.google.android.exoplayer2.source.MediaPeriodId;
|
||||
import com.google.android.exoplayer2.source.MediaSource;
|
||||
import com.google.android.exoplayer2.util.Assertions;
|
||||
import com.google.android.exoplayer2.util.BundleableUtils;
|
||||
import com.google.android.exoplayer2.util.Util;
|
||||
import java.io.IOException;
|
||||
import java.lang.annotation.Documented;
|
||||
@ -234,7 +235,9 @@ public final class ExoPlaybackException extends PlaybackException {
|
||||
rendererName = bundle.getString(keyForField(FIELD_RENDERER_NAME));
|
||||
rendererIndex =
|
||||
bundle.getInt(keyForField(FIELD_RENDERER_INDEX), /* defaultValue= */ C.INDEX_UNSET);
|
||||
rendererFormat = bundle.getParcelable(keyForField(FIELD_RENDERER_FORMAT));
|
||||
rendererFormat =
|
||||
BundleableUtils.fromNullableBundle(
|
||||
Format.CREATOR, bundle.getBundle(keyForField(FIELD_RENDERER_FORMAT)));
|
||||
rendererFormatSupport =
|
||||
bundle.getInt(
|
||||
keyForField(FIELD_RENDERER_FORMAT_SUPPORT), /* defaultValue= */ C.FORMAT_HANDLED);
|
||||
@ -396,7 +399,8 @@ public final class ExoPlaybackException extends PlaybackException {
|
||||
bundle.putInt(keyForField(FIELD_TYPE), type);
|
||||
bundle.putString(keyForField(FIELD_RENDERER_NAME), rendererName);
|
||||
bundle.putInt(keyForField(FIELD_RENDERER_INDEX), rendererIndex);
|
||||
bundle.putParcelable(keyForField(FIELD_RENDERER_FORMAT), rendererFormat);
|
||||
bundle.putBundle(
|
||||
keyForField(FIELD_RENDERER_FORMAT), BundleableUtils.toNullableBundle(rendererFormat));
|
||||
bundle.putInt(keyForField(FIELD_RENDERER_FORMAT_SUPPORT), rendererFormatSupport);
|
||||
bundle.putBoolean(keyForField(FIELD_IS_RECOVERABLE), isRecoverable);
|
||||
return bundle;
|
||||
|
@ -17,13 +17,14 @@ package com.google.android.exoplayer2.trackselection;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Point;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
import android.os.Bundle;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Pair;
|
||||
import android.util.SparseArray;
|
||||
import android.util.SparseBooleanArray;
|
||||
import androidx.annotation.IntDef;
|
||||
import androidx.annotation.Nullable;
|
||||
import com.google.android.exoplayer2.Bundleable;
|
||||
import com.google.android.exoplayer2.C;
|
||||
import com.google.android.exoplayer2.C.FormatSupport;
|
||||
import com.google.android.exoplayer2.ExoPlaybackException;
|
||||
@ -39,11 +40,15 @@ import com.google.android.exoplayer2.source.MediaSource.MediaPeriodId;
|
||||
import com.google.android.exoplayer2.source.TrackGroup;
|
||||
import com.google.android.exoplayer2.source.TrackGroupArray;
|
||||
import com.google.android.exoplayer2.util.Assertions;
|
||||
import com.google.android.exoplayer2.util.BundleableUtils;
|
||||
import com.google.android.exoplayer2.util.Util;
|
||||
import com.google.common.collect.ComparisonChain;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.Ordering;
|
||||
import com.google.common.primitives.Ints;
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
@ -239,6 +244,66 @@ public class DefaultTrackSelector extends MappingTrackSelector {
|
||||
rendererDisabledFlags = initialValues.rendererDisabledFlags.clone();
|
||||
}
|
||||
|
||||
@SuppressWarnings("method.invocation") // Only setter are invoked.
|
||||
private ParametersBuilder(Bundle bundle) {
|
||||
super(bundle);
|
||||
Parameters defaultValue = Parameters.DEFAULT_WITHOUT_CONTEXT;
|
||||
// Video
|
||||
setExceedVideoConstraintsIfNecessary(
|
||||
bundle.getBoolean(
|
||||
Parameters.keyForField(Parameters.FIELD_EXCEED_VIDEO_CONSTRAINTS_IF_NECESSARY),
|
||||
defaultValue.exceedVideoConstraintsIfNecessary));
|
||||
setAllowVideoMixedMimeTypeAdaptiveness(
|
||||
bundle.getBoolean(
|
||||
Parameters.keyForField(Parameters.FIELD_ALLOW_VIDEO_MIXED_MIME_TYPE_ADAPTIVENESS),
|
||||
defaultValue.allowVideoMixedMimeTypeAdaptiveness));
|
||||
setAllowVideoNonSeamlessAdaptiveness(
|
||||
bundle.getBoolean(
|
||||
Parameters.keyForField(Parameters.FIELD_ALLOW_VIDEO_NON_SEAMLESS_ADAPTIVENESS),
|
||||
defaultValue.allowVideoNonSeamlessAdaptiveness));
|
||||
// Audio
|
||||
setExceedAudioConstraintsIfNecessary(
|
||||
bundle.getBoolean(
|
||||
Parameters.keyForField(Parameters.FIELD_EXCEED_AUDIO_CONSTRAINTS_IF_NCESSARY),
|
||||
defaultValue.exceedAudioConstraintsIfNecessary));
|
||||
setAllowAudioMixedMimeTypeAdaptiveness(
|
||||
bundle.getBoolean(
|
||||
Parameters.keyForField(Parameters.FIELD_ALLOW_AUDIO_MIXED_MIME_TYPE_ADAPTIVENESS),
|
||||
defaultValue.allowAudioMixedMimeTypeAdaptiveness));
|
||||
setAllowAudioMixedSampleRateAdaptiveness(
|
||||
bundle.getBoolean(
|
||||
Parameters.keyForField(Parameters.FIELD_ALLOW_AUDIO_MIXED_SAMPLE_RATE_ADAPTIVENESS),
|
||||
defaultValue.allowAudioMixedSampleRateAdaptiveness));
|
||||
setAllowAudioMixedChannelCountAdaptiveness(
|
||||
bundle.getBoolean(
|
||||
Parameters.keyForField(Parameters.FIELD_ALLOW_AUDIO_MIXED_CHANNEL_COUNT_ADAPTIVENESS),
|
||||
defaultValue.allowAudioMixedChannelCountAdaptiveness));
|
||||
// Text
|
||||
setDisabledTextTrackSelectionFlags(
|
||||
bundle.getInt(
|
||||
Parameters.keyForField(Parameters.FIELD_DISABLED_TEXT_TRACK_SELECTION_FLAGS),
|
||||
defaultValue.disabledTextTrackSelectionFlags));
|
||||
// General
|
||||
setExceedRendererCapabilitiesIfNecessary(
|
||||
bundle.getBoolean(
|
||||
Parameters.keyForField(Parameters.FIELD_EXCEED_RENDERER_CAPABILITIES_IF_NECESSARY),
|
||||
defaultValue.exceedRendererCapabilitiesIfNecessary));
|
||||
setTunnelingEnabled(
|
||||
bundle.getBoolean(
|
||||
Parameters.keyForField(Parameters.FIELD_TUNNELING_ENABLED),
|
||||
defaultValue.tunnelingEnabled));
|
||||
setAllowMultipleAdaptiveSelections(
|
||||
bundle.getBoolean(
|
||||
Parameters.keyForField(Parameters.FIELD_ALLOW_MULTIPLE_ADAPTIVE_SELECTIONS),
|
||||
defaultValue.allowMultipleAdaptiveSelections));
|
||||
|
||||
selectionOverrides = new SparseArray<>();
|
||||
setSelectionOverridesFromBundle(bundle);
|
||||
|
||||
rendererDisabledFlags = new SparseBooleanArray();
|
||||
setRendererDisableFlagsFromBundle(bundle);
|
||||
}
|
||||
|
||||
// Video
|
||||
|
||||
@Override
|
||||
@ -724,12 +789,52 @@ public class DefaultTrackSelector extends MappingTrackSelector {
|
||||
}
|
||||
return clone;
|
||||
}
|
||||
|
||||
private void setSelectionOverridesFromBundle(Bundle bundle) {
|
||||
@Nullable
|
||||
int[] rendererIndexes =
|
||||
bundle.getIntArray(
|
||||
Parameters.keyForField(Parameters.FIELD_SELECTION_OVERRIDES_RENDERER_INDEXES));
|
||||
List<TrackGroupArray> trackGroupArrays =
|
||||
BundleableUtils.fromBundleNullableList(
|
||||
TrackGroupArray.CREATOR,
|
||||
bundle.getParcelableArrayList(
|
||||
Parameters.keyForField(Parameters.FIELD_SELECTION_OVERRIDES_TRACK_GROUP_ARRAYS)),
|
||||
/* defaultValue= */ ImmutableList.of());
|
||||
SparseArray<SelectionOverride> selectionOverrides =
|
||||
BundleableUtils.fromBundleNullableSparseArray(
|
||||
SelectionOverride.CREATOR,
|
||||
bundle.getSparseParcelableArray(
|
||||
Parameters.keyForField(Parameters.FIELD_SELECTION_OVERRIDES)),
|
||||
/* defaultValue= */ new SparseArray<>());
|
||||
|
||||
if (rendererIndexes == null || rendererIndexes.length != trackGroupArrays.size()) {
|
||||
return; // Incorrect format, ignore all overrides.
|
||||
}
|
||||
for (int i = 0; i < rendererIndexes.length; i++) {
|
||||
int rendererIndex = rendererIndexes[i];
|
||||
TrackGroupArray groups = trackGroupArrays.get(i);
|
||||
@Nullable SelectionOverride selectionOverride = selectionOverrides.get(i);
|
||||
setSelectionOverride(rendererIndex, groups, selectionOverride);
|
||||
}
|
||||
}
|
||||
|
||||
private void setRendererDisableFlagsFromBundle(Bundle bundle) {
|
||||
int[] rendererIndexes =
|
||||
bundle.getIntArray(Parameters.keyForField(Parameters.FIELD_RENDERER_DISABLED_INDEXES));
|
||||
if (rendererIndexes == null) {
|
||||
return;
|
||||
}
|
||||
for (int rendererIndex : rendererIndexes) {
|
||||
setRendererDisabled(rendererIndex, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Extends {@link Parameters} by adding fields that are specific to {@link DefaultTrackSelector}.
|
||||
*/
|
||||
public static final class Parameters extends TrackSelectionParameters implements Parcelable {
|
||||
public static final class Parameters extends TrackSelectionParameters implements Bundleable {
|
||||
|
||||
/**
|
||||
* An instance with default values, except those obtained from the {@link Context}.
|
||||
@ -755,19 +860,6 @@ public class DefaultTrackSelector extends MappingTrackSelector {
|
||||
*/
|
||||
@Deprecated public static final Parameters DEFAULT = DEFAULT_WITHOUT_CONTEXT;
|
||||
|
||||
public static final Creator<Parameters> CREATOR =
|
||||
new Creator<Parameters>() {
|
||||
|
||||
@Override
|
||||
public Parameters createFromParcel(Parcel in) {
|
||||
return new Parameters(in);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Parameters[] newArray(int size) {
|
||||
return new Parameters[size];
|
||||
}
|
||||
};
|
||||
/**
|
||||
* Bitmask of selection flags that are disabled for text track selections. See {@link
|
||||
* C.SelectionFlags}. The default value is {@code 0} (i.e. no flags).
|
||||
@ -868,28 +960,6 @@ public class DefaultTrackSelector extends MappingTrackSelector {
|
||||
rendererDisabledFlags = builder.rendererDisabledFlags;
|
||||
}
|
||||
|
||||
/* package */ Parameters(Parcel in) {
|
||||
super(in);
|
||||
// Video
|
||||
this.exceedVideoConstraintsIfNecessary = Util.readBoolean(in);
|
||||
this.allowVideoMixedMimeTypeAdaptiveness = Util.readBoolean(in);
|
||||
this.allowVideoNonSeamlessAdaptiveness = Util.readBoolean(in);
|
||||
// Audio
|
||||
this.exceedAudioConstraintsIfNecessary = Util.readBoolean(in);
|
||||
this.allowAudioMixedMimeTypeAdaptiveness = Util.readBoolean(in);
|
||||
this.allowAudioMixedSampleRateAdaptiveness = Util.readBoolean(in);
|
||||
this.allowAudioMixedChannelCountAdaptiveness = Util.readBoolean(in);
|
||||
// Text
|
||||
this.disabledTextTrackSelectionFlags = in.readInt();
|
||||
// General
|
||||
this.exceedRendererCapabilitiesIfNecessary = Util.readBoolean(in);
|
||||
this.tunnelingEnabled = Util.readBoolean(in);
|
||||
this.allowMultipleAdaptiveSelections = Util.readBoolean(in);
|
||||
// Overrides
|
||||
this.selectionOverrides = readSelectionOverrides(in);
|
||||
this.rendererDisabledFlags = Util.castNonNull(in.readSparseBooleanArray());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the renderer is disabled.
|
||||
*
|
||||
@ -928,6 +998,7 @@ public class DefaultTrackSelector extends MappingTrackSelector {
|
||||
}
|
||||
|
||||
/** Creates a new {@link ParametersBuilder}, copying the initial values from this instance. */
|
||||
@Override
|
||||
public ParametersBuilder buildUpon() {
|
||||
return new ParametersBuilder(this);
|
||||
}
|
||||
@ -987,80 +1058,141 @@ public class DefaultTrackSelector extends MappingTrackSelector {
|
||||
return result;
|
||||
}
|
||||
|
||||
// Parcelable implementation.
|
||||
// Bundleable implementation.
|
||||
|
||||
@Documented
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
@IntDef({
|
||||
FIELD_EXCEED_VIDEO_CONSTRAINTS_IF_NECESSARY,
|
||||
FIELD_ALLOW_VIDEO_MIXED_MIME_TYPE_ADAPTIVENESS,
|
||||
FIELD_ALLOW_VIDEO_NON_SEAMLESS_ADAPTIVENESS,
|
||||
FIELD_EXCEED_AUDIO_CONSTRAINTS_IF_NCESSARY,
|
||||
FIELD_ALLOW_AUDIO_MIXED_MIME_TYPE_ADAPTIVENESS,
|
||||
FIELD_ALLOW_AUDIO_MIXED_SAMPLE_RATE_ADAPTIVENESS,
|
||||
FIELD_ALLOW_AUDIO_MIXED_CHANNEL_COUNT_ADAPTIVENESS,
|
||||
FIELD_DISABLED_TEXT_TRACK_SELECTION_FLAGS,
|
||||
FIELD_EXCEED_RENDERER_CAPABILITIES_IF_NECESSARY,
|
||||
FIELD_TUNNELING_ENABLED,
|
||||
FIELD_ALLOW_MULTIPLE_ADAPTIVE_SELECTIONS,
|
||||
FIELD_SELECTION_OVERRIDES_RENDERER_INDEXES,
|
||||
FIELD_SELECTION_OVERRIDES_TRACK_GROUP_ARRAYS,
|
||||
FIELD_SELECTION_OVERRIDES,
|
||||
FIELD_RENDERER_DISABLED_INDEXES,
|
||||
})
|
||||
private @interface FieldNumber {}
|
||||
|
||||
// Start at 1000 to avoid conflict with the base class fields.
|
||||
private static final int FIELD_EXCEED_VIDEO_CONSTRAINTS_IF_NECESSARY = 1000;
|
||||
private static final int FIELD_ALLOW_VIDEO_MIXED_MIME_TYPE_ADAPTIVENESS = 1001;
|
||||
private static final int FIELD_ALLOW_VIDEO_NON_SEAMLESS_ADAPTIVENESS = 1002;
|
||||
private static final int FIELD_EXCEED_AUDIO_CONSTRAINTS_IF_NCESSARY = 1003;
|
||||
private static final int FIELD_ALLOW_AUDIO_MIXED_MIME_TYPE_ADAPTIVENESS = 1004;
|
||||
private static final int FIELD_ALLOW_AUDIO_MIXED_SAMPLE_RATE_ADAPTIVENESS = 1005;
|
||||
private static final int FIELD_ALLOW_AUDIO_MIXED_CHANNEL_COUNT_ADAPTIVENESS = 1006;
|
||||
private static final int FIELD_DISABLED_TEXT_TRACK_SELECTION_FLAGS = 1007;
|
||||
private static final int FIELD_EXCEED_RENDERER_CAPABILITIES_IF_NECESSARY = 1008;
|
||||
private static final int FIELD_TUNNELING_ENABLED = 1009;
|
||||
private static final int FIELD_ALLOW_MULTIPLE_ADAPTIVE_SELECTIONS = 1010;
|
||||
private static final int FIELD_SELECTION_OVERRIDES_RENDERER_INDEXES = 1011;
|
||||
private static final int FIELD_SELECTION_OVERRIDES_TRACK_GROUP_ARRAYS = 1012;
|
||||
private static final int FIELD_SELECTION_OVERRIDES = 1013;
|
||||
private static final int FIELD_RENDERER_DISABLED_INDEXES = 1014;
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
public Bundle toBundle() {
|
||||
Bundle bundle = super.toBundle();
|
||||
|
||||
@Override
|
||||
public void writeToParcel(Parcel dest, int flags) {
|
||||
super.writeToParcel(dest, flags);
|
||||
// Video
|
||||
Util.writeBoolean(dest, exceedVideoConstraintsIfNecessary);
|
||||
Util.writeBoolean(dest, allowVideoMixedMimeTypeAdaptiveness);
|
||||
Util.writeBoolean(dest, allowVideoNonSeamlessAdaptiveness);
|
||||
bundle.putBoolean(
|
||||
keyForField(FIELD_EXCEED_VIDEO_CONSTRAINTS_IF_NECESSARY),
|
||||
exceedVideoConstraintsIfNecessary);
|
||||
bundle.putBoolean(
|
||||
keyForField(FIELD_ALLOW_VIDEO_MIXED_MIME_TYPE_ADAPTIVENESS),
|
||||
allowVideoMixedMimeTypeAdaptiveness);
|
||||
bundle.putBoolean(
|
||||
keyForField(FIELD_ALLOW_VIDEO_NON_SEAMLESS_ADAPTIVENESS),
|
||||
allowVideoNonSeamlessAdaptiveness);
|
||||
// Audio
|
||||
Util.writeBoolean(dest, exceedAudioConstraintsIfNecessary);
|
||||
Util.writeBoolean(dest, allowAudioMixedMimeTypeAdaptiveness);
|
||||
Util.writeBoolean(dest, allowAudioMixedSampleRateAdaptiveness);
|
||||
Util.writeBoolean(dest, allowAudioMixedChannelCountAdaptiveness);
|
||||
bundle.putBoolean(
|
||||
keyForField(FIELD_EXCEED_AUDIO_CONSTRAINTS_IF_NCESSARY),
|
||||
exceedAudioConstraintsIfNecessary);
|
||||
bundle.putBoolean(
|
||||
keyForField(FIELD_ALLOW_AUDIO_MIXED_MIME_TYPE_ADAPTIVENESS),
|
||||
allowAudioMixedMimeTypeAdaptiveness);
|
||||
bundle.putBoolean(
|
||||
keyForField(FIELD_ALLOW_AUDIO_MIXED_SAMPLE_RATE_ADAPTIVENESS),
|
||||
allowAudioMixedSampleRateAdaptiveness);
|
||||
bundle.putBoolean(
|
||||
keyForField(FIELD_ALLOW_AUDIO_MIXED_CHANNEL_COUNT_ADAPTIVENESS),
|
||||
allowAudioMixedChannelCountAdaptiveness);
|
||||
// Text
|
||||
dest.writeInt(disabledTextTrackSelectionFlags);
|
||||
bundle.putInt(
|
||||
keyForField(FIELD_DISABLED_TEXT_TRACK_SELECTION_FLAGS), disabledTextTrackSelectionFlags);
|
||||
// General
|
||||
Util.writeBoolean(dest, exceedRendererCapabilitiesIfNecessary);
|
||||
Util.writeBoolean(dest, tunnelingEnabled);
|
||||
Util.writeBoolean(dest, allowMultipleAdaptiveSelections);
|
||||
// Overrides
|
||||
writeSelectionOverridesToParcel(dest, selectionOverrides);
|
||||
dest.writeSparseBooleanArray(rendererDisabledFlags);
|
||||
bundle.putBoolean(
|
||||
keyForField(FIELD_EXCEED_RENDERER_CAPABILITIES_IF_NECESSARY),
|
||||
exceedRendererCapabilitiesIfNecessary);
|
||||
bundle.putBoolean(keyForField(FIELD_TUNNELING_ENABLED), tunnelingEnabled);
|
||||
bundle.putBoolean(
|
||||
keyForField(FIELD_ALLOW_MULTIPLE_ADAPTIVE_SELECTIONS), allowMultipleAdaptiveSelections);
|
||||
|
||||
putSelectionOverridesToBundle(bundle, selectionOverrides);
|
||||
putRendererDisabledFlagsToBundle(bundle, rendererDisabledFlags);
|
||||
|
||||
return bundle;
|
||||
}
|
||||
|
||||
// Static utility methods.
|
||||
/** Object that can restore {@code Parameters} from a {@link Bundle}. */
|
||||
public static final Creator<Parameters> CREATOR =
|
||||
bundle -> new ParametersBuilder(bundle).build();
|
||||
|
||||
private static SparseArray<Map<TrackGroupArray, @NullableType SelectionOverride>>
|
||||
readSelectionOverrides(Parcel in) {
|
||||
int renderersWithOverridesCount = in.readInt();
|
||||
SparseArray<Map<TrackGroupArray, @NullableType SelectionOverride>> selectionOverrides =
|
||||
new SparseArray<>(renderersWithOverridesCount);
|
||||
for (int i = 0; i < renderersWithOverridesCount; i++) {
|
||||
int rendererIndex = in.readInt();
|
||||
int overrideCount = in.readInt();
|
||||
Map<TrackGroupArray, @NullableType SelectionOverride> overrides =
|
||||
new HashMap<>(overrideCount);
|
||||
for (int j = 0; j < overrideCount; j++) {
|
||||
TrackGroupArray trackGroups =
|
||||
Assertions.checkNotNull(in.readParcelable(TrackGroupArray.class.getClassLoader()));
|
||||
@Nullable
|
||||
SelectionOverride override = in.readParcelable(SelectionOverride.class.getClassLoader());
|
||||
overrides.put(trackGroups, override);
|
||||
}
|
||||
selectionOverrides.put(rendererIndex, overrides);
|
||||
}
|
||||
return selectionOverrides;
|
||||
private static String keyForField(@FieldNumber int field) {
|
||||
return Integer.toString(field, Character.MAX_RADIX);
|
||||
}
|
||||
|
||||
private static void writeSelectionOverridesToParcel(
|
||||
Parcel dest,
|
||||
/**
|
||||
* Bundles selection overrides in 3 arrays of equal length. Each triplet of matching index is -
|
||||
* the selection override (stored in a sparse array as they can be null) - the trackGroupArray
|
||||
* of that override - the rendererIndex of that override
|
||||
*/
|
||||
private static void putSelectionOverridesToBundle(
|
||||
Bundle bundle,
|
||||
SparseArray<Map<TrackGroupArray, @NullableType SelectionOverride>> selectionOverrides) {
|
||||
int renderersWithOverridesCount = selectionOverrides.size();
|
||||
dest.writeInt(renderersWithOverridesCount);
|
||||
for (int i = 0; i < renderersWithOverridesCount; i++) {
|
||||
ArrayList<Integer> rendererIndexes = new ArrayList<>();
|
||||
ArrayList<TrackGroupArray> trackGroupArrays = new ArrayList<>();
|
||||
SparseArray<SelectionOverride> selections = new SparseArray<>();
|
||||
|
||||
for (int i = 0; i < selectionOverrides.size(); i++) {
|
||||
int rendererIndex = selectionOverrides.keyAt(i);
|
||||
Map<TrackGroupArray, @NullableType SelectionOverride> overrides =
|
||||
selectionOverrides.valueAt(i);
|
||||
int overrideCount = overrides.size();
|
||||
dest.writeInt(rendererIndex);
|
||||
dest.writeInt(overrideCount);
|
||||
for (Map.Entry<TrackGroupArray, @NullableType SelectionOverride> override :
|
||||
overrides.entrySet()) {
|
||||
dest.writeParcelable(override.getKey(), /* parcelableFlags= */ 0);
|
||||
dest.writeParcelable(override.getValue(), /* parcelableFlags= */ 0);
|
||||
selectionOverrides.valueAt(i).entrySet()) {
|
||||
@Nullable SelectionOverride selection = override.getValue();
|
||||
if (selection != null) {
|
||||
selections.put(trackGroupArrays.size(), selection);
|
||||
}
|
||||
trackGroupArrays.add(override.getKey());
|
||||
rendererIndexes.add(rendererIndex);
|
||||
}
|
||||
bundle.putIntArray(
|
||||
keyForField(FIELD_SELECTION_OVERRIDES_RENDERER_INDEXES), Ints.toArray(rendererIndexes));
|
||||
bundle.putParcelableArrayList(
|
||||
keyForField(FIELD_SELECTION_OVERRIDES_TRACK_GROUP_ARRAYS),
|
||||
BundleableUtils.toBundleArrayList(trackGroupArrays));
|
||||
bundle.putSparseParcelableArray(
|
||||
keyForField(FIELD_SELECTION_OVERRIDES),
|
||||
BundleableUtils.toBundleSparseArray(selections));
|
||||
}
|
||||
}
|
||||
|
||||
private static void putRendererDisabledFlagsToBundle(
|
||||
Bundle bundle, SparseBooleanArray rendererDisabledFlags) {
|
||||
int[] rendererIndexes = new int[rendererDisabledFlags.size()];
|
||||
for (int i = 0; i < rendererDisabledFlags.size(); i++) {
|
||||
rendererIndexes[i] = rendererDisabledFlags.keyAt(i);
|
||||
}
|
||||
bundle.putIntArray(keyForField(FIELD_RENDERER_DISABLED_INDEXES), rendererIndexes);
|
||||
}
|
||||
|
||||
private static boolean areRendererDisabledFlagsEqual(
|
||||
SparseBooleanArray first, SparseBooleanArray second) {
|
||||
int firstSize = first.size();
|
||||
@ -1113,7 +1245,7 @@ public class DefaultTrackSelector extends MappingTrackSelector {
|
||||
}
|
||||
|
||||
/** A track selection override. */
|
||||
public static final class SelectionOverride implements Parcelable {
|
||||
public static final class SelectionOverride implements Bundleable {
|
||||
|
||||
public final int groupIndex;
|
||||
public final int[] tracks;
|
||||
@ -1121,6 +1253,8 @@ public class DefaultTrackSelector extends MappingTrackSelector {
|
||||
public final int type;
|
||||
|
||||
/**
|
||||
* Constructs a {@code SelectionOverride} to override tracks of a group.
|
||||
*
|
||||
* @param groupIndex The overriding track group index.
|
||||
* @param tracks The overriding track indices within the track group.
|
||||
*/
|
||||
@ -1129,6 +1263,8 @@ public class DefaultTrackSelector extends MappingTrackSelector {
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a {@code SelectionOverride} of the given type to override tracks of a group.
|
||||
*
|
||||
* @param groupIndex The overriding track group index.
|
||||
* @param tracks The overriding track indices within the track group.
|
||||
* @param type The type that will be returned from {@link TrackSelection#getType()}.
|
||||
@ -1141,14 +1277,6 @@ public class DefaultTrackSelector extends MappingTrackSelector {
|
||||
Arrays.sort(this.tracks);
|
||||
}
|
||||
|
||||
/* package */ SelectionOverride(Parcel in) {
|
||||
groupIndex = in.readInt();
|
||||
length = in.readByte();
|
||||
tracks = new int[length];
|
||||
in.readIntArray(tracks);
|
||||
type = in.readInt();
|
||||
}
|
||||
|
||||
/** Returns whether this override contains the specified track index. */
|
||||
public boolean containsTrack(int track) {
|
||||
for (int overrideTrack : tracks) {
|
||||
@ -1179,34 +1307,44 @@ public class DefaultTrackSelector extends MappingTrackSelector {
|
||||
&& type == other.type;
|
||||
}
|
||||
|
||||
// Parcelable implementation.
|
||||
// Bundleable implementation.
|
||||
|
||||
@Documented
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
@IntDef({
|
||||
FIELD_GROUP_INDEX,
|
||||
FIELD_TRACKS,
|
||||
FIELD_TRACK_TYPE,
|
||||
})
|
||||
private @interface FieldNumber {}
|
||||
|
||||
private static final int FIELD_GROUP_INDEX = 0;
|
||||
private static final int FIELD_TRACKS = 1;
|
||||
private static final int FIELD_TRACK_TYPE = 2;
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
public Bundle toBundle() {
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putInt(keyForField(FIELD_GROUP_INDEX), groupIndex);
|
||||
bundle.putIntArray(keyForField(FIELD_TRACKS), tracks);
|
||||
bundle.putInt(keyForField(FIELD_TRACK_TYPE), type);
|
||||
return bundle;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(Parcel dest, int flags) {
|
||||
dest.writeInt(groupIndex);
|
||||
dest.writeInt(tracks.length);
|
||||
dest.writeIntArray(tracks);
|
||||
dest.writeInt(type);
|
||||
}
|
||||
|
||||
public static final Parcelable.Creator<SelectionOverride> CREATOR =
|
||||
new Parcelable.Creator<SelectionOverride>() {
|
||||
|
||||
@Override
|
||||
public SelectionOverride createFromParcel(Parcel in) {
|
||||
return new SelectionOverride(in);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SelectionOverride[] newArray(int size) {
|
||||
return new SelectionOverride[size];
|
||||
}
|
||||
/** Object that can restore {@code SelectionOverride} from a {@link Bundle}. */
|
||||
public static final Creator<SelectionOverride> CREATOR =
|
||||
bundle -> {
|
||||
int groupIndex = bundle.getInt(keyForField(FIELD_GROUP_INDEX), -1);
|
||||
@Nullable int[] tracks = bundle.getIntArray(keyForField(FIELD_TRACKS));
|
||||
int trackType = bundle.getInt(keyForField(FIELD_TRACK_TYPE), -1);
|
||||
Assertions.checkArgument(groupIndex >= 0 && trackType >= 0);
|
||||
Assertions.checkNotNull(tracks);
|
||||
return new SelectionOverride(groupIndex, tracks, trackType);
|
||||
};
|
||||
|
||||
private static String keyForField(@FieldNumber int field) {
|
||||
return Integer.toString(field, Character.MAX_RADIX);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -17,7 +17,6 @@ package com.google.android.exoplayer2.source;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import android.os.Parcel;
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||
import com.google.android.exoplayer2.Format;
|
||||
import com.google.android.exoplayer2.util.MimeTypes;
|
||||
@ -29,7 +28,7 @@ import org.junit.runner.RunWith;
|
||||
public final class TrackGroupArrayTest {
|
||||
|
||||
@Test
|
||||
public void parcelable() {
|
||||
public void roundTripViaBundle_ofTrackGroupArray_yieldsEqualInstance() {
|
||||
Format.Builder formatBuilder = new Format.Builder();
|
||||
Format format1 = formatBuilder.setSampleMimeType(MimeTypes.VIDEO_H264).build();
|
||||
Format format2 = formatBuilder.setSampleMimeType(MimeTypes.AUDIO_AAC).build();
|
||||
@ -38,15 +37,11 @@ public final class TrackGroupArrayTest {
|
||||
TrackGroup trackGroup1 = new TrackGroup(format1, format2);
|
||||
TrackGroup trackGroup2 = new TrackGroup(format3);
|
||||
|
||||
TrackGroupArray trackGroupArrayToParcel = new TrackGroupArray(trackGroup1, trackGroup2);
|
||||
TrackGroupArray trackGroupArrayToBundle = new TrackGroupArray(trackGroup1, trackGroup2);
|
||||
|
||||
Parcel parcel = Parcel.obtain();
|
||||
trackGroupArrayToParcel.writeToParcel(parcel, 0);
|
||||
parcel.setDataPosition(0);
|
||||
TrackGroupArray trackGroupArrayFromBundle =
|
||||
TrackGroupArray.CREATOR.fromBundle(trackGroupArrayToBundle.toBundle());
|
||||
|
||||
TrackGroupArray trackGroupArrayFromParcel = TrackGroupArray.CREATOR.createFromParcel(parcel);
|
||||
assertThat(trackGroupArrayFromParcel).isEqualTo(trackGroupArrayToParcel);
|
||||
|
||||
parcel.recycle();
|
||||
assertThat(trackGroupArrayFromBundle).isEqualTo(trackGroupArrayToBundle);
|
||||
}
|
||||
}
|
||||
|
@ -17,7 +17,6 @@ package com.google.android.exoplayer2.source;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import android.os.Parcel;
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||
import com.google.android.exoplayer2.Format;
|
||||
import com.google.android.exoplayer2.util.MimeTypes;
|
||||
@ -29,20 +28,15 @@ import org.junit.runner.RunWith;
|
||||
public final class TrackGroupTest {
|
||||
|
||||
@Test
|
||||
public void parcelable() {
|
||||
public void roundTripViaBundle_ofTrackGroup_yieldsEqualInstance() {
|
||||
Format.Builder formatBuilder = new Format.Builder();
|
||||
Format format1 = formatBuilder.setSampleMimeType(MimeTypes.VIDEO_H264).build();
|
||||
Format format2 = formatBuilder.setSampleMimeType(MimeTypes.AUDIO_AAC).build();
|
||||
|
||||
TrackGroup trackGroupToParcel = new TrackGroup(format1, format2);
|
||||
TrackGroup trackGroupToBundle = new TrackGroup(format1, format2);
|
||||
|
||||
Parcel parcel = Parcel.obtain();
|
||||
trackGroupToParcel.writeToParcel(parcel, 0);
|
||||
parcel.setDataPosition(0);
|
||||
TrackGroup trackGroupFromBundle = TrackGroup.CREATOR.fromBundle(trackGroupToBundle.toBundle());
|
||||
|
||||
TrackGroup trackGroupFromParcel = TrackGroup.CREATOR.createFromParcel(parcel);
|
||||
assertThat(trackGroupFromParcel).isEqualTo(trackGroupToParcel);
|
||||
|
||||
parcel.recycle();
|
||||
assertThat(trackGroupFromBundle).isEqualTo(trackGroupToBundle);
|
||||
}
|
||||
}
|
||||
|
@ -29,9 +29,9 @@ import static org.mockito.Mockito.when;
|
||||
import static org.mockito.MockitoAnnotations.initMocks;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Parcel;
|
||||
import androidx.test.core.app.ApplicationProvider;
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||
import com.google.android.exoplayer2.Bundleable;
|
||||
import com.google.android.exoplayer2.C;
|
||||
import com.google.android.exoplayer2.ExoPlaybackException;
|
||||
import com.google.android.exoplayer2.Format;
|
||||
@ -139,37 +139,26 @@ public final class DefaultTrackSelectorTest {
|
||||
assertThat(parameters.buildUpon().build()).isEqualTo(parameters);
|
||||
}
|
||||
|
||||
/** Tests {@link Parameters} {@link android.os.Parcelable} implementation. */
|
||||
/** Tests {@link Parameters} {@link Bundleable} implementation. */
|
||||
@Test
|
||||
public void parameters_parcelAndUnParcelable() {
|
||||
Parameters parametersToParcel = buildParametersForEqualsTest();
|
||||
public void roundTripViaBundle_ofParameters_yieldsEqualInstance() {
|
||||
Parameters parametersToBundle = buildParametersForEqualsTest();
|
||||
|
||||
Parcel parcel = Parcel.obtain();
|
||||
parametersToParcel.writeToParcel(parcel, 0);
|
||||
parcel.setDataPosition(0);
|
||||
Parameters parametersFromBundle = Parameters.CREATOR.fromBundle(parametersToBundle.toBundle());
|
||||
|
||||
Parameters parametersFromParcel = Parameters.CREATOR.createFromParcel(parcel);
|
||||
assertThat(parametersFromParcel).isEqualTo(parametersToParcel);
|
||||
|
||||
parcel.recycle();
|
||||
assertThat(parametersFromBundle).isEqualTo(parametersToBundle);
|
||||
}
|
||||
|
||||
/** Tests {@link SelectionOverride}'s {@link android.os.Parcelable} implementation. */
|
||||
/** Tests {@link SelectionOverride}'s {@link Bundleable} implementation. */
|
||||
@Test
|
||||
public void selectionOverrideParcelable() {
|
||||
int[] tracks = new int[] {2, 3};
|
||||
SelectionOverride selectionOverrideToParcel =
|
||||
new SelectionOverride(/* groupIndex= */ 1, tracks);
|
||||
public void roundTripViaBundle_ofSelectionOverride_yieldsEqualInstance() {
|
||||
SelectionOverride selectionOverrideToBundle =
|
||||
new SelectionOverride(/* groupIndex= */ 1, /* tracks...= */ 2, 3);
|
||||
|
||||
Parcel parcel = Parcel.obtain();
|
||||
selectionOverrideToParcel.writeToParcel(parcel, 0);
|
||||
parcel.setDataPosition(0);
|
||||
SelectionOverride selectionOverrideFromBundle =
|
||||
SelectionOverride.CREATOR.fromBundle(selectionOverrideToBundle.toBundle());
|
||||
|
||||
SelectionOverride selectionOverrideFromParcel =
|
||||
SelectionOverride.CREATOR.createFromParcel(parcel);
|
||||
assertThat(selectionOverrideFromParcel).isEqualTo(selectionOverrideToParcel);
|
||||
|
||||
parcel.recycle();
|
||||
assertThat(selectionOverrideFromBundle).isEqualTo(selectionOverrideToBundle);
|
||||
}
|
||||
|
||||
/** Tests that a null override clears a track selection. */
|
||||
@ -1764,7 +1753,13 @@ public final class DefaultTrackSelectorTest {
|
||||
/* rendererIndex= */ 2,
|
||||
new TrackGroupArray(VIDEO_TRACK_GROUP),
|
||||
new SelectionOverride(0, 1))
|
||||
.setSelectionOverride(
|
||||
/* rendererIndex= */ 2, new TrackGroupArray(AUDIO_TRACK_GROUP), /* override= */ null)
|
||||
.setSelectionOverride(
|
||||
/* rendererIndex= */ 5, new TrackGroupArray(VIDEO_TRACK_GROUP), /* override= */ null)
|
||||
.setRendererDisabled(1, true)
|
||||
.setRendererDisabled(3, true)
|
||||
.setRendererDisabled(5, false)
|
||||
.build();
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user