diff --git a/library/src/androidTest/java/com/google/android/exoplayer/FormatTest.java b/library/src/androidTest/java/com/google/android/exoplayer/FormatTest.java index ec9df17934..ab0b2874a0 100644 --- a/library/src/androidTest/java/com/google/android/exoplayer/FormatTest.java +++ b/library/src/androidTest/java/com/google/android/exoplayer/FormatTest.java @@ -15,17 +15,26 @@ */ package com.google.android.exoplayer; +import static com.google.android.exoplayer.drm.StreamingDrmSessionManager.WIDEVINE_UUID; +import static com.google.android.exoplayer.util.MimeTypes.VIDEO_MP4; +import static com.google.android.exoplayer.util.MimeTypes.VIDEO_WEBM; + +import com.google.android.exoplayer.drm.DrmInitData; +import com.google.android.exoplayer.testutil.TestUtil; +import com.google.android.exoplayer.util.MimeTypes; import com.google.android.exoplayer.util.Util; import android.annotation.SuppressLint; import android.annotation.TargetApi; import android.media.MediaFormat; +import android.os.Parcel; import junit.framework.TestCase; import java.nio.ByteBuffer; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; import java.util.List; /** @@ -33,30 +42,55 @@ import java.util.List; */ public final class FormatTest extends TestCase { + private static final List INIT_DATA; + static { + byte[] initData1 = new byte[] {1, 2, 3}; + byte[] initData2 = new byte[] {4, 5, 6}; + List initData = new ArrayList<>(); + initData.add(initData1); + initData.add(initData2); + INIT_DATA = Collections.unmodifiableList(initData); + } + + public void testParcelable() { + DrmInitData.SchemeData DRM_DATA_1 = new DrmInitData.SchemeData(WIDEVINE_UUID, VIDEO_MP4, + TestUtil.buildTestData(128, 1 /* data seed */)); + DrmInitData.SchemeData DRM_DATA_2 = new DrmInitData.SchemeData(C.UUID_NIL, VIDEO_WEBM, + TestUtil.buildTestData(128, 1 /* data seed */)); + DrmInitData drmInitData = new DrmInitData(DRM_DATA_1, DRM_DATA_2); + + Format formatToParcel = new Format("id", MimeTypes.VIDEO_MP4, MimeTypes.VIDEO_H264, 1024, 2048, + 1920, 1080, 24, 90, 2, 6, 44100, C.ENCODING_PCM_24BIT, 1001, 1002, "und", + Format.OFFSET_SAMPLE_RELATIVE, INIT_DATA, drmInitData, false); + + Parcel parcel = Parcel.obtain(); + formatToParcel.writeToParcel(parcel, 0); + parcel.setDataPosition(0); + + Format formatFromParcel = Format.CREATOR.createFromParcel(parcel); + assertEquals(formatToParcel, formatFromParcel); + + parcel.recycle(); + } + public void testConversionToFrameworkMediaFormat() { if (Util.SDK_INT < 16) { // Test doesn't apply. return; } - byte[] initData1 = new byte[] {1, 2, 3}; - byte[] initData2 = new byte[] {4, 5, 6}; - List initData = new ArrayList<>(); - initData.add(initData1); - initData.add(initData2); - - testConversionToFrameworkMediaFormatV16(Format.createVideoSampleFormat( - null, "video/xyz", 5000, 102400, 1280, 720, 30, initData, null)); - testConversionToFrameworkMediaFormatV16(Format.createVideoSampleFormat( - null, "video/xyz", 5000, Format.NO_VALUE, 1280, 720, 30, null, null)); - testConversionToFrameworkMediaFormatV16(Format.createAudioSampleFormat( - null, "audio/xyz", 500, 128, 5, 44100, initData, null, null)); - testConversionToFrameworkMediaFormatV16(Format.createAudioSampleFormat( - null, "audio/xyz", 500, Format.NO_VALUE, 5, 44100, null, null, null)); - testConversionToFrameworkMediaFormatV16( - Format.createTextSampleFormat(null, "text/xyz", Format.NO_VALUE, "eng", null)); - testConversionToFrameworkMediaFormatV16( - Format.createTextSampleFormat(null, "text/xyz", Format.NO_VALUE, null, null)); + testConversionToFrameworkMediaFormatV16(Format.createVideoSampleFormat(null, "video/xyz", 5000, + 102400, 1280, 720, 30, INIT_DATA, null)); + testConversionToFrameworkMediaFormatV16(Format.createVideoSampleFormat(null, "video/xyz", 5000, + Format.NO_VALUE, 1280, 720, 30, null, null)); + testConversionToFrameworkMediaFormatV16(Format.createAudioSampleFormat(null, "audio/xyz", 500, + 128, 5, 44100, INIT_DATA, null, null)); + testConversionToFrameworkMediaFormatV16(Format.createAudioSampleFormat(null, "audio/xyz", 500, + Format.NO_VALUE, 5, 44100, null, null, null)); + testConversionToFrameworkMediaFormatV16(Format.createTextSampleFormat(null, "text/xyz", + Format.NO_VALUE, "eng", null)); + testConversionToFrameworkMediaFormatV16(Format.createTextSampleFormat(null, "text/xyz", + Format.NO_VALUE, null, null)); } @SuppressLint("InlinedApi") diff --git a/library/src/androidTest/java/com/google/android/exoplayer/drm/DrmInitDataTest.java b/library/src/androidTest/java/com/google/android/exoplayer/drm/DrmInitDataTest.java index 20146ecb9d..611d3dec3c 100644 --- a/library/src/androidTest/java/com/google/android/exoplayer/drm/DrmInitDataTest.java +++ b/library/src/androidTest/java/com/google/android/exoplayer/drm/DrmInitDataTest.java @@ -23,6 +23,7 @@ import com.google.android.exoplayer.C; import com.google.android.exoplayer.drm.DrmInitData.SchemeData; import com.google.android.exoplayer.testutil.TestUtil; +import android.os.Parcel; import android.test.MoreAsserts; import junit.framework.TestCase; @@ -43,6 +44,19 @@ public class DrmInitDataTest extends TestCase { private static final SchemeData DATA_UNIVERSAL = new SchemeData(C.UUID_NIL, VIDEO_MP4, TestUtil.buildTestData(128, 3 /* data seed */)); + public void testParcelable() { + DrmInitData drmInitDataToParcel = new DrmInitData(DATA_1, DATA_2); + + Parcel parcel = Parcel.obtain(); + drmInitDataToParcel.writeToParcel(parcel, 0); + parcel.setDataPosition(0); + + DrmInitData drmInitDataFromParcel = DrmInitData.CREATOR.createFromParcel(parcel); + assertEquals(drmInitDataToParcel, drmInitDataFromParcel); + + parcel.recycle(); + } + public void testEquals() { DrmInitData drmInitData = new DrmInitData(DATA_1, DATA_2); diff --git a/library/src/main/java/com/google/android/exoplayer/Format.java b/library/src/main/java/com/google/android/exoplayer/Format.java index eae856660f..61c4917c89 100644 --- a/library/src/main/java/com/google/android/exoplayer/Format.java +++ b/library/src/main/java/com/google/android/exoplayer/Format.java @@ -22,8 +22,11 @@ import com.google.android.exoplayer.util.Util; import android.annotation.SuppressLint; import android.annotation.TargetApi; import android.media.MediaFormat; +import android.os.Parcel; +import android.os.Parcelable; import java.nio.ByteBuffer; +import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.Comparator; @@ -32,7 +35,7 @@ import java.util.List; /** * Representation of a media format. */ -public final class Format { +public final class Format implements Parcelable { /** * Sorts {@link Format} objects in order of decreasing bandwidth. @@ -302,6 +305,33 @@ public final class Format { this.requiresSecureDecryption = requiresSecureDecryption; } + /* package */ Format(Parcel in) { + id = in.readString(); + containerMimeType = in.readString(); + sampleMimeType = in.readString(); + bitrate = in.readInt(); + maxInputSize = in.readInt(); + width = in.readInt(); + height = in.readInt(); + frameRate = in.readFloat(); + rotationDegrees = in.readInt(); + pixelWidthHeightRatio = in.readFloat(); + channelCount = in.readInt(); + sampleRate = in.readInt(); + pcmEncoding = in.readInt(); + encoderDelay = in.readInt(); + encoderPadding = in.readInt(); + language = in.readString(); + subsampleOffsetUs = in.readLong(); + int initializationDataSize = in.readInt(); + initializationData = new ArrayList<>(initializationDataSize); + for (int i = 0; i < initializationDataSize; i++) { + initializationData.add(in.createByteArray()); + } + drmInitData = in.readParcelable(DrmInitData.class.getClassLoader()); + requiresSecureDecryption = in.readInt() == 1; + } + public Format copyWithMaxInputSize(int maxInputSize) { return new Format(id, containerMimeType, sampleMimeType, bitrate, maxInputSize, width, height, frameRate, rotationDegrees, pixelWidthHeightRatio, channelCount, sampleRate, @@ -456,4 +486,53 @@ public final class Format { } } + // Parcelable implementation. + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + dest.writeString(id); + dest.writeString(containerMimeType); + dest.writeString(sampleMimeType); + dest.writeInt(bitrate); + dest.writeInt(maxInputSize); + dest.writeInt(width); + dest.writeInt(height); + dest.writeFloat(frameRate); + dest.writeInt(rotationDegrees); + dest.writeFloat(pixelWidthHeightRatio); + dest.writeInt(channelCount); + dest.writeInt(sampleRate); + dest.writeInt(pcmEncoding); + dest.writeInt(encoderDelay); + dest.writeInt(encoderPadding); + dest.writeString(language); + dest.writeLong(subsampleOffsetUs); + int initializationDataSize = initializationData.size(); + dest.writeInt(initializationDataSize); + for (int i = 0; i < initializationDataSize; i++) { + dest.writeByteArray(initializationData.get(i)); + } + dest.writeParcelable(drmInitData, 0); + dest.writeInt(requiresSecureDecryption ? 1 : 0); + } + + public static final Creator CREATOR = new Creator() { + + @Override + public Format createFromParcel(Parcel in) { + return new Format(in); + } + + @Override + public Format[] newArray(int size) { + return new Format[size]; + } + + }; + } diff --git a/library/src/main/java/com/google/android/exoplayer/drm/DrmInitData.java b/library/src/main/java/com/google/android/exoplayer/drm/DrmInitData.java index 5c3cf9061a..8a03b90b9c 100644 --- a/library/src/main/java/com/google/android/exoplayer/drm/DrmInitData.java +++ b/library/src/main/java/com/google/android/exoplayer/drm/DrmInitData.java @@ -20,6 +20,9 @@ import com.google.android.exoplayer.drm.DrmInitData.SchemeData; import com.google.android.exoplayer.util.Assertions; import com.google.android.exoplayer.util.Util; +import android.os.Parcel; +import android.os.Parcelable; + import java.util.Arrays; import java.util.Comparator; import java.util.List; @@ -28,7 +31,7 @@ import java.util.UUID; /** * Encapsulates DRM initialization data for possibly multiple DRM schemes. */ -public final class DrmInitData implements Comparator { +public final class DrmInitData implements Comparator, Parcelable { private final SchemeData[] schemeDatas; @@ -59,6 +62,10 @@ public final class DrmInitData implements Comparator { this.schemeDatas = schemeDatas; } + /* package */ DrmInitData(Parcel in) { + schemeDatas = in.createTypedArray(SchemeData.CREATOR); + } + /** * Retrieves data for a given DRM scheme, specified by its UUID. * @@ -99,10 +106,37 @@ public final class DrmInitData implements Comparator { : first.uuid.compareTo(second.uuid); } + // Parcelable implementation. + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + dest.writeTypedArray(schemeDatas, 0); + } + + public static final Parcelable.Creator CREATOR = + new Parcelable.Creator() { + + @Override + public DrmInitData createFromParcel(Parcel in) { + return new DrmInitData(in); + } + + @Override + public DrmInitData[] newArray(int size) { + return new DrmInitData[size]; + } + + }; + /** * Scheme initialization data. */ - public static final class SchemeData { + public static final class SchemeData implements Parcelable { // Lazily initialized hashcode. private int hashCode; @@ -133,6 +167,12 @@ public final class DrmInitData implements Comparator { this.data = Assertions.checkNotNull(data); } + /* package */ SchemeData(Parcel in) { + uuid = new UUID(in.readLong(), in.readLong()); + mimeType = in.readString(); + data = in.createByteArray(); + } + /** * Returns whether this initialization data applies to the specified scheme. * @@ -159,7 +199,7 @@ public final class DrmInitData implements Comparator { @Override public int hashCode() { if (hashCode == 0) { - int result = ((uuid == null) ? 0 : uuid.hashCode()); + int result = uuid.hashCode(); result = 31 * result + mimeType.hashCode(); result = 31 * result + Arrays.hashCode(data); hashCode = result; @@ -167,6 +207,36 @@ public final class DrmInitData implements Comparator { return hashCode; } + // Parcelable implementation. + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + dest.writeLong(uuid.getMostSignificantBits()); + dest.writeLong(uuid.getLeastSignificantBits()); + dest.writeString(mimeType); + dest.writeByteArray(data); + } + + public static final Parcelable.Creator CREATOR = + new Parcelable.Creator() { + + @Override + public SchemeData createFromParcel(Parcel in) { + return new SchemeData(in); + } + + @Override + public SchemeData[] newArray(int size) { + return new SchemeData[size]; + } + + }; + } }