Parse and expose proj and st3d/stereo_mode

As described in:
https://github.com/google/spatial-media/blob/master/docs/spherical-video-v2-rfc.md.

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=130776689
This commit is contained in:
olly 2016-08-19 11:57:46 -07:00 committed by Oliver Woodman
parent 1579b68cf6
commit 2c84f016fe
6 changed files with 145 additions and 44 deletions

View File

@ -55,10 +55,12 @@ public final class FormatTest extends TestCase {
DrmInitData.SchemeData DRM_DATA_2 = new DrmInitData.SchemeData(C.UUID_NIL, VIDEO_WEBM, DrmInitData.SchemeData DRM_DATA_2 = new DrmInitData.SchemeData(C.UUID_NIL, VIDEO_WEBM,
TestUtil.buildTestData(128, 1 /* data seed */)); TestUtil.buildTestData(128, 1 /* data seed */));
DrmInitData drmInitData = new DrmInitData(DRM_DATA_1, DRM_DATA_2); DrmInitData drmInitData = new DrmInitData(DRM_DATA_1, DRM_DATA_2);
byte[] projectionData = new byte[] {1, 2, 3};
Format formatToParcel = new Format("id", MimeTypes.VIDEO_MP4, MimeTypes.VIDEO_H264, null, Format formatToParcel = new Format("id", MimeTypes.VIDEO_MP4, MimeTypes.VIDEO_H264, null,
1024, 2048, 1920, 1080, 24, 90, 2, 6, 44100, C.ENCODING_PCM_24BIT, 1001, 1002, 0, "und", 1024, 2048, 1920, 1080, 24, 90, 2, projectionData, C.STEREO_MODE_TOP_BOTTOM, 6, 44100,
Format.OFFSET_SAMPLE_RELATIVE, INIT_DATA, drmInitData); C.ENCODING_PCM_24BIT, 1001, 1002, 0, "und", Format.OFFSET_SAMPLE_RELATIVE, INIT_DATA,
drmInitData);
Parcel parcel = Parcel.obtain(); Parcel parcel = Parcel.obtain();
formatToParcel.writeToParcel(parcel, 0); formatToParcel.writeToParcel(parcel, 0);

View File

@ -363,6 +363,21 @@ public final class C {
*/ */
public static final int MSG_CUSTOM_BASE = 10000; public static final int MSG_CUSTOM_BASE = 10000;
/**
* Indicates Monoscopic stereo layout, used with 360/3D/VR videos.
*/
public static final int STEREO_MODE_MONO = 0;
/**
* Indicates Top-Bottom stereo layout, used with 360/3D/VR videos.
*/
public static final int STEREO_MODE_TOP_BOTTOM = 1;
/**
* Indicates Left-Right stereo layout, used with 360/3D/VR videos.
*/
public static final int STEREO_MODE_LEFT_RIGHT = 2;
/** /**
* Converts a time in microseconds to the corresponding time in milliseconds, preserving * Converts a time in microseconds to the corresponding time in milliseconds, preserving
* {@link #TIME_UNSET} values. * {@link #TIME_UNSET} values.

View File

@ -137,6 +137,16 @@ public final class Format implements Parcelable {
* applicable. * applicable.
*/ */
public final float pixelWidthHeightRatio; public final float pixelWidthHeightRatio;
/**
* The stereo layout for 360/3D/VR video, or {@link #NO_VALUE} if not applicable. Valid stereo
* modes are {@link C#STEREO_MODE_MONO}, {@link C#STEREO_MODE_TOP_BOTTOM}, {@link
* C#STEREO_MODE_LEFT_RIGHT}.
*/
public final int stereoMode;
/**
* The projection data for 360/VR video, or null if not applicable.
*/
public final byte[] projectionData;
// Audio specific. // Audio specific.
@ -196,8 +206,8 @@ public final class Format implements Parcelable {
String sampleMimeType, String codecs, int bitrate, int width, int height, String sampleMimeType, String codecs, int bitrate, int width, int height,
float frameRate, List<byte[]> initializationData) { float frameRate, List<byte[]> initializationData) {
return new Format(id, containerMimeType, sampleMimeType, codecs, bitrate, NO_VALUE, width, return new Format(id, containerMimeType, sampleMimeType, codecs, bitrate, NO_VALUE, width,
height, frameRate, NO_VALUE, NO_VALUE, NO_VALUE, NO_VALUE, NO_VALUE, NO_VALUE, NO_VALUE, 0, height, frameRate, NO_VALUE, NO_VALUE, null, NO_VALUE, NO_VALUE, NO_VALUE, NO_VALUE,
null, OFFSET_SAMPLE_RELATIVE, initializationData, null); NO_VALUE, NO_VALUE, 0, null, OFFSET_SAMPLE_RELATIVE, initializationData, null);
} }
public static Format createVideoSampleFormat(String id, String sampleMimeType, String codecs, public static Format createVideoSampleFormat(String id, String sampleMimeType, String codecs,
@ -211,9 +221,19 @@ public final class Format implements Parcelable {
int bitrate, int maxInputSize, int width, int height, float frameRate, int bitrate, int maxInputSize, int width, int height, float frameRate,
List<byte[]> initializationData, int rotationDegrees, float pixelWidthHeightRatio, List<byte[]> initializationData, int rotationDegrees, float pixelWidthHeightRatio,
DrmInitData drmInitData) { DrmInitData drmInitData) {
return createVideoSampleFormat(id, sampleMimeType, codecs, bitrate, maxInputSize, width,
height, frameRate, initializationData, rotationDegrees, pixelWidthHeightRatio, null,
NO_VALUE, drmInitData);
}
public static Format createVideoSampleFormat(String id, String sampleMimeType, String codecs,
int bitrate, int maxInputSize, int width, int height, float frameRate,
List<byte[]> initializationData, int rotationDegrees, float pixelWidthHeightRatio,
byte[] projectionData, int stereoMode, DrmInitData drmInitData) {
return new Format(id, null, sampleMimeType, codecs, bitrate, maxInputSize, width, height, return new Format(id, null, sampleMimeType, codecs, bitrate, maxInputSize, width, height,
frameRate, rotationDegrees, pixelWidthHeightRatio, NO_VALUE, NO_VALUE, NO_VALUE, NO_VALUE, frameRate, rotationDegrees, pixelWidthHeightRatio, projectionData, stereoMode, NO_VALUE,
NO_VALUE, 0, null, OFFSET_SAMPLE_RELATIVE, initializationData, drmInitData); NO_VALUE, NO_VALUE, NO_VALUE, NO_VALUE, 0, null, OFFSET_SAMPLE_RELATIVE, initializationData,
drmInitData);
} }
// Audio. // Audio.
@ -222,8 +242,9 @@ public final class Format implements Parcelable {
String sampleMimeType, String codecs, int bitrate, int channelCount, int sampleRate, String sampleMimeType, String codecs, int bitrate, int channelCount, int sampleRate,
List<byte[]> initializationData, int selectionFlags, String language) { List<byte[]> initializationData, int selectionFlags, String language) {
return new Format(id, containerMimeType, sampleMimeType, codecs, bitrate, NO_VALUE, NO_VALUE, return new Format(id, containerMimeType, sampleMimeType, codecs, bitrate, NO_VALUE, NO_VALUE,
NO_VALUE, NO_VALUE, NO_VALUE, NO_VALUE, channelCount, sampleRate, NO_VALUE, NO_VALUE, NO_VALUE, NO_VALUE, NO_VALUE, NO_VALUE, null, NO_VALUE, channelCount, sampleRate, NO_VALUE,
NO_VALUE, selectionFlags, language, OFFSET_SAMPLE_RELATIVE, initializationData, null); NO_VALUE, NO_VALUE, selectionFlags, language, OFFSET_SAMPLE_RELATIVE, initializationData,
null);
} }
public static Format createAudioSampleFormat(String id, String sampleMimeType, String codecs, public static Format createAudioSampleFormat(String id, String sampleMimeType, String codecs,
@ -248,9 +269,9 @@ public final class Format implements Parcelable {
int encoderDelay, int encoderPadding, List<byte[]> initializationData, int encoderDelay, int encoderPadding, List<byte[]> initializationData,
DrmInitData drmInitData, int selectionFlags, String language) { DrmInitData drmInitData, int selectionFlags, String language) {
return new Format(id, null, sampleMimeType, codecs, bitrate, maxInputSize, NO_VALUE, NO_VALUE, return new Format(id, null, sampleMimeType, codecs, bitrate, maxInputSize, NO_VALUE, NO_VALUE,
NO_VALUE, NO_VALUE, NO_VALUE, channelCount, sampleRate, pcmEncoding, encoderDelay, NO_VALUE, NO_VALUE, NO_VALUE, null, NO_VALUE, channelCount, sampleRate, pcmEncoding,
encoderPadding, selectionFlags, language, OFFSET_SAMPLE_RELATIVE, initializationData, encoderDelay, encoderPadding, selectionFlags, language, OFFSET_SAMPLE_RELATIVE,
drmInitData); initializationData, drmInitData);
} }
// Text. // Text.
@ -258,8 +279,8 @@ public final class Format implements Parcelable {
public static Format createTextContainerFormat(String id, String containerMimeType, public static Format createTextContainerFormat(String id, String containerMimeType,
String sampleMimeType, String codecs, int bitrate, int selectionFlags, String language) { String sampleMimeType, String codecs, int bitrate, int selectionFlags, String language) {
return new Format(id, containerMimeType, sampleMimeType, codecs, bitrate, NO_VALUE, NO_VALUE, return new Format(id, containerMimeType, sampleMimeType, codecs, bitrate, NO_VALUE, NO_VALUE,
NO_VALUE, NO_VALUE, NO_VALUE, NO_VALUE, NO_VALUE, NO_VALUE, NO_VALUE, NO_VALUE, NO_VALUE, NO_VALUE, NO_VALUE, NO_VALUE, NO_VALUE, null, NO_VALUE, NO_VALUE, NO_VALUE, NO_VALUE,
selectionFlags, language, OFFSET_SAMPLE_RELATIVE, null, null); NO_VALUE, NO_VALUE, selectionFlags, language, OFFSET_SAMPLE_RELATIVE, null, null);
} }
public static Format createTextSampleFormat(String id, String sampleMimeType, String codecs, public static Format createTextSampleFormat(String id, String sampleMimeType, String codecs,
@ -272,8 +293,8 @@ public final class Format implements Parcelable {
int bitrate, int selectionFlags, String language, DrmInitData drmInitData, int bitrate, int selectionFlags, String language, DrmInitData drmInitData,
long subsampleOffsetUs) { long subsampleOffsetUs) {
return new Format(id, null, sampleMimeType, codecs, bitrate, NO_VALUE, NO_VALUE, NO_VALUE, return new Format(id, null, sampleMimeType, codecs, bitrate, NO_VALUE, NO_VALUE, NO_VALUE,
NO_VALUE, NO_VALUE, NO_VALUE, NO_VALUE, NO_VALUE, NO_VALUE, NO_VALUE, NO_VALUE, NO_VALUE, NO_VALUE, NO_VALUE, null, NO_VALUE, NO_VALUE, NO_VALUE, NO_VALUE, NO_VALUE,
selectionFlags, language, subsampleOffsetUs, null, drmInitData); NO_VALUE, selectionFlags, language, subsampleOffsetUs, null, drmInitData);
} }
// Image. // Image.
@ -281,8 +302,8 @@ public final class Format implements Parcelable {
public static Format createImageSampleFormat(String id, String sampleMimeType, String codecs, public static Format createImageSampleFormat(String id, String sampleMimeType, String codecs,
int bitrate, List<byte[]> initializationData, String language, DrmInitData drmInitData) { int bitrate, List<byte[]> initializationData, String language, DrmInitData drmInitData) {
return new Format(id, null, sampleMimeType, codecs, bitrate, NO_VALUE, NO_VALUE, NO_VALUE, return new Format(id, null, sampleMimeType, codecs, bitrate, NO_VALUE, NO_VALUE, NO_VALUE,
NO_VALUE, NO_VALUE, NO_VALUE, NO_VALUE, NO_VALUE, NO_VALUE, NO_VALUE, NO_VALUE, 0, language, NO_VALUE, NO_VALUE, NO_VALUE, null, NO_VALUE, NO_VALUE, NO_VALUE, NO_VALUE, NO_VALUE,
OFFSET_SAMPLE_RELATIVE, initializationData, drmInitData); NO_VALUE, 0, language, OFFSET_SAMPLE_RELATIVE, initializationData, drmInitData);
} }
// Generic. // Generic.
@ -290,22 +311,23 @@ public final class Format implements Parcelable {
public static Format createContainerFormat(String id, String containerMimeType, public static Format createContainerFormat(String id, String containerMimeType,
String sampleMimeType, int bitrate) { String sampleMimeType, int bitrate) {
return new Format(id, containerMimeType, sampleMimeType, null, bitrate, NO_VALUE, NO_VALUE, return new Format(id, containerMimeType, sampleMimeType, null, bitrate, NO_VALUE, NO_VALUE,
NO_VALUE, NO_VALUE, NO_VALUE, NO_VALUE, NO_VALUE, NO_VALUE, NO_VALUE, NO_VALUE, NO_VALUE, NO_VALUE, NO_VALUE, NO_VALUE, NO_VALUE, null, NO_VALUE, NO_VALUE, NO_VALUE, NO_VALUE,
0, null, OFFSET_SAMPLE_RELATIVE, null, null); NO_VALUE, NO_VALUE, 0, null, OFFSET_SAMPLE_RELATIVE, null, null);
} }
public static Format createSampleFormat(String id, String sampleMimeType, String codecs, public static Format createSampleFormat(String id, String sampleMimeType, String codecs,
int bitrate, DrmInitData drmInitData) { int bitrate, DrmInitData drmInitData) {
return new Format(id, null, sampleMimeType, codecs, bitrate, NO_VALUE, NO_VALUE, NO_VALUE, return new Format(id, null, sampleMimeType, codecs, bitrate, NO_VALUE, NO_VALUE, NO_VALUE,
NO_VALUE, NO_VALUE, NO_VALUE, NO_VALUE, NO_VALUE, NO_VALUE, NO_VALUE, NO_VALUE, 0, null, NO_VALUE, NO_VALUE, NO_VALUE, null, NO_VALUE, NO_VALUE, NO_VALUE, NO_VALUE, NO_VALUE,
OFFSET_SAMPLE_RELATIVE, null, drmInitData); NO_VALUE, 0, null, OFFSET_SAMPLE_RELATIVE, null, drmInitData);
} }
/* package */ Format(String id, String containerMimeType, String sampleMimeType, String codecs, /* package */ Format(String id, String containerMimeType, String sampleMimeType, String codecs,
int bitrate, int maxInputSize, int width, int height, float frameRate, int rotationDegrees, int bitrate, int maxInputSize, int width, int height, float frameRate, int rotationDegrees,
float pixelWidthHeightRatio, int channelCount, int sampleRate, int pcmEncoding, float pixelWidthHeightRatio, byte[] projectionData, int stereoMode, int channelCount,
int encoderDelay, int encoderPadding, int selectionFlags, String language, int sampleRate, int pcmEncoding, int encoderDelay, int encoderPadding, int selectionFlags,
long subsampleOffsetUs, List<byte[]> initializationData, DrmInitData drmInitData) { String language, long subsampleOffsetUs, List<byte[]> initializationData,
DrmInitData drmInitData) {
this.id = id; this.id = id;
this.containerMimeType = containerMimeType; this.containerMimeType = containerMimeType;
this.sampleMimeType = sampleMimeType; this.sampleMimeType = sampleMimeType;
@ -317,6 +339,8 @@ public final class Format implements Parcelable {
this.frameRate = frameRate; this.frameRate = frameRate;
this.rotationDegrees = rotationDegrees; this.rotationDegrees = rotationDegrees;
this.pixelWidthHeightRatio = pixelWidthHeightRatio; this.pixelWidthHeightRatio = pixelWidthHeightRatio;
this.projectionData = projectionData;
this.stereoMode = stereoMode;
this.channelCount = channelCount; this.channelCount = channelCount;
this.sampleRate = sampleRate; this.sampleRate = sampleRate;
this.pcmEncoding = pcmEncoding; this.pcmEncoding = pcmEncoding;
@ -342,6 +366,9 @@ public final class Format implements Parcelable {
frameRate = in.readFloat(); frameRate = in.readFloat();
rotationDegrees = in.readInt(); rotationDegrees = in.readInt();
pixelWidthHeightRatio = in.readFloat(); pixelWidthHeightRatio = in.readFloat();
boolean hasProjectionData = in.readInt() != 0;
projectionData = hasProjectionData ? in.createByteArray() : null;
stereoMode = in.readInt();
channelCount = in.readInt(); channelCount = in.readInt();
sampleRate = in.readInt(); sampleRate = in.readInt();
pcmEncoding = in.readInt(); pcmEncoding = in.readInt();
@ -360,24 +387,24 @@ public final class Format implements Parcelable {
public Format copyWithMaxInputSize(int maxInputSize) { public Format copyWithMaxInputSize(int maxInputSize) {
return new Format(id, containerMimeType, sampleMimeType, codecs, bitrate, maxInputSize, return new Format(id, containerMimeType, sampleMimeType, codecs, bitrate, maxInputSize,
width, height, frameRate, rotationDegrees, pixelWidthHeightRatio, channelCount, sampleRate, width, height, frameRate, rotationDegrees, pixelWidthHeightRatio, projectionData,
pcmEncoding, encoderDelay, encoderPadding, selectionFlags, language, subsampleOffsetUs, stereoMode, channelCount, sampleRate, pcmEncoding, encoderDelay, encoderPadding,
initializationData, drmInitData); selectionFlags, language, subsampleOffsetUs, initializationData, drmInitData);
} }
public Format copyWithSubsampleOffsetUs(long subsampleOffsetUs) { public Format copyWithSubsampleOffsetUs(long subsampleOffsetUs) {
return new Format(id, containerMimeType, sampleMimeType, codecs, bitrate, maxInputSize, return new Format(id, containerMimeType, sampleMimeType, codecs, bitrate, maxInputSize,
width, height, frameRate, rotationDegrees, pixelWidthHeightRatio, channelCount, sampleRate, width, height, frameRate, rotationDegrees, pixelWidthHeightRatio, projectionData,
pcmEncoding, encoderDelay, encoderPadding, selectionFlags, language, subsampleOffsetUs, stereoMode, channelCount, sampleRate, pcmEncoding, encoderDelay, encoderPadding,
initializationData, drmInitData); selectionFlags, language, subsampleOffsetUs, initializationData, drmInitData);
} }
public Format copyWithContainerInfo(String id, int bitrate, int width, int height, public Format copyWithContainerInfo(String id, int bitrate, int width, int height,
int selectionFlags, String language) { int selectionFlags, String language) {
return new Format(id, containerMimeType, sampleMimeType, codecs, bitrate, maxInputSize, return new Format(id, containerMimeType, sampleMimeType, codecs, bitrate, maxInputSize,
width, height, frameRate, rotationDegrees, pixelWidthHeightRatio, channelCount, sampleRate, width, height, frameRate, rotationDegrees, pixelWidthHeightRatio, projectionData,
pcmEncoding, encoderDelay, encoderPadding, selectionFlags, language, subsampleOffsetUs, stereoMode, channelCount, sampleRate, pcmEncoding, encoderDelay, encoderPadding,
initializationData, drmInitData); selectionFlags, language, subsampleOffsetUs, initializationData, drmInitData);
} }
public Format copyWithManifestFormatInfo(Format manifestFormat, public Format copyWithManifestFormatInfo(Format manifestFormat,
@ -391,23 +418,23 @@ public final class Format implements Parcelable {
DrmInitData drmInitData = (preferManifestDrmInitData && manifestFormat.drmInitData != null) DrmInitData drmInitData = (preferManifestDrmInitData && manifestFormat.drmInitData != null)
|| this.drmInitData == null ? manifestFormat.drmInitData : this.drmInitData; || this.drmInitData == null ? manifestFormat.drmInitData : this.drmInitData;
return new Format(id, containerMimeType, sampleMimeType, codecs, bitrate, maxInputSize, width, return new Format(id, containerMimeType, sampleMimeType, codecs, bitrate, maxInputSize, width,
height, frameRate, rotationDegrees, pixelWidthHeightRatio, channelCount, sampleRate, height, frameRate, rotationDegrees, pixelWidthHeightRatio, projectionData, stereoMode,
pcmEncoding, encoderDelay, encoderPadding, selectionFlags, language, subsampleOffsetUs, channelCount, sampleRate, pcmEncoding, encoderDelay, encoderPadding, selectionFlags,
initializationData, drmInitData); language, subsampleOffsetUs, initializationData, drmInitData);
} }
public Format copyWithGaplessInfo(int encoderDelay, int encoderPadding) { public Format copyWithGaplessInfo(int encoderDelay, int encoderPadding) {
return new Format(id, containerMimeType, sampleMimeType, codecs, bitrate, maxInputSize, return new Format(id, containerMimeType, sampleMimeType, codecs, bitrate, maxInputSize,
width, height, frameRate, rotationDegrees, pixelWidthHeightRatio, channelCount, sampleRate, width, height, frameRate, rotationDegrees, pixelWidthHeightRatio, projectionData,
pcmEncoding, encoderDelay, encoderPadding, selectionFlags, language, subsampleOffsetUs, stereoMode, channelCount, sampleRate, pcmEncoding, encoderDelay, encoderPadding,
initializationData, drmInitData); selectionFlags, language, subsampleOffsetUs, initializationData, drmInitData);
} }
public Format copyWithDrmInitData(DrmInitData drmInitData) { public Format copyWithDrmInitData(DrmInitData drmInitData) {
return new Format(id, containerMimeType, sampleMimeType, codecs, bitrate, maxInputSize, return new Format(id, containerMimeType, sampleMimeType, codecs, bitrate, maxInputSize,
width, height, frameRate, rotationDegrees, pixelWidthHeightRatio, channelCount, sampleRate, width, height, frameRate, rotationDegrees, pixelWidthHeightRatio, projectionData,
pcmEncoding, encoderDelay, encoderPadding, selectionFlags, language, subsampleOffsetUs, stereoMode, channelCount, sampleRate, pcmEncoding, encoderDelay, encoderPadding,
initializationData, drmInitData); selectionFlags, language, subsampleOffsetUs, initializationData, drmInitData);
} }
/** /**
@ -484,7 +511,7 @@ public final class Format implements Parcelable {
if (bitrate != other.bitrate || maxInputSize != other.maxInputSize if (bitrate != other.bitrate || maxInputSize != other.maxInputSize
|| width != other.width || height != other.height || frameRate != other.frameRate || width != other.width || height != other.height || frameRate != other.frameRate
|| rotationDegrees != other.rotationDegrees || rotationDegrees != other.rotationDegrees
|| pixelWidthHeightRatio != other.pixelWidthHeightRatio || pixelWidthHeightRatio != other.pixelWidthHeightRatio || stereoMode != other.stereoMode
|| channelCount != other.channelCount || sampleRate != other.sampleRate || channelCount != other.channelCount || sampleRate != other.sampleRate
|| pcmEncoding != other.pcmEncoding || encoderDelay != other.encoderDelay || pcmEncoding != other.pcmEncoding || encoderDelay != other.encoderDelay
|| encoderPadding != other.encoderPadding || subsampleOffsetUs != other.subsampleOffsetUs || encoderPadding != other.encoderPadding || subsampleOffsetUs != other.subsampleOffsetUs
@ -494,6 +521,7 @@ public final class Format implements Parcelable {
|| !Util.areEqual(sampleMimeType, other.sampleMimeType) || !Util.areEqual(sampleMimeType, other.sampleMimeType)
|| !Util.areEqual(codecs, other.codecs) || !Util.areEqual(codecs, other.codecs)
|| !Util.areEqual(drmInitData, other.drmInitData) || !Util.areEqual(drmInitData, other.drmInitData)
|| !Arrays.equals(projectionData, other.projectionData)
|| initializationData.size() != other.initializationData.size()) { || initializationData.size() != other.initializationData.size()) {
return false; return false;
} }
@ -546,6 +574,11 @@ public final class Format implements Parcelable {
dest.writeFloat(frameRate); dest.writeFloat(frameRate);
dest.writeInt(rotationDegrees); dest.writeInt(rotationDegrees);
dest.writeFloat(pixelWidthHeightRatio); dest.writeFloat(pixelWidthHeightRatio);
dest.writeInt(projectionData != null ? 1 : 0);
if (projectionData != null) {
dest.writeByteArray(projectionData);
}
dest.writeInt(stereoMode);
dest.writeInt(channelCount); dest.writeInt(channelCount);
dest.writeInt(sampleRate); dest.writeInt(sampleRate);
dest.writeInt(pcmEncoding); dest.writeInt(pcmEncoding);

View File

@ -126,6 +126,9 @@ import java.util.List;
public static final int TYPE_mean = Util.getIntegerCodeForString("mean"); public static final int TYPE_mean = Util.getIntegerCodeForString("mean");
public static final int TYPE_name = Util.getIntegerCodeForString("name"); public static final int TYPE_name = Util.getIntegerCodeForString("name");
public static final int TYPE_data = Util.getIntegerCodeForString("data"); public static final int TYPE_data = Util.getIntegerCodeForString("data");
public static final int TYPE_st3d = Util.getIntegerCodeForString("st3d");
public static final int TYPE_sv3d = Util.getIntegerCodeForString("sv3d");
public static final int TYPE_proj = Util.getIntegerCodeForString("proj");
public static final int TYPE_vp08 = Util.getIntegerCodeForString("vp08"); public static final int TYPE_vp08 = Util.getIntegerCodeForString("vp08");
public static final int TYPE_vp09 = Util.getIntegerCodeForString("vp09"); public static final int TYPE_vp09 = Util.getIntegerCodeForString("vp09");
public static final int TYPE_vpcC = Util.getIntegerCodeForString("vpcC"); public static final int TYPE_vpcC = Util.getIntegerCodeForString("vpcC");

View File

@ -29,6 +29,7 @@ import com.google.android.exoplayer2.util.ParsableByteArray;
import com.google.android.exoplayer2.util.Util; import com.google.android.exoplayer2.util.Util;
import com.google.android.exoplayer2.video.AvcConfig; import com.google.android.exoplayer2.video.AvcConfig;
import com.google.android.exoplayer2.video.HevcConfig; import com.google.android.exoplayer2.video.HevcConfig;
import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
@ -663,6 +664,8 @@ import java.util.List;
List<byte[]> initializationData = null; List<byte[]> initializationData = null;
String mimeType = null; String mimeType = null;
byte[] projectionData = null;
int stereoMode = Format.NO_VALUE;
while (childPosition - position < size) { while (childPosition - position < size) {
parent.setPosition(childPosition); parent.setPosition(childPosition);
int childStartPosition = parent.getPosition(); int childStartPosition = parent.getPosition();
@ -705,6 +708,27 @@ import java.util.List;
} else if (childAtomType == Atom.TYPE_pasp) { } else if (childAtomType == Atom.TYPE_pasp) {
pixelWidthHeightRatio = parsePaspFromParent(parent, childStartPosition); pixelWidthHeightRatio = parsePaspFromParent(parent, childStartPosition);
pixelWidthHeightRatioFromPasp = true; pixelWidthHeightRatioFromPasp = true;
} else if (childAtomType == Atom.TYPE_sv3d) {
projectionData = parseProjFromParent(parent, childStartPosition, childAtomSize);
} else if (childAtomType == Atom.TYPE_st3d) {
int version = parent.readUnsignedByte();
parent.skipBytes(3); // Flags.
if (version == 0) {
int layout = parent.readUnsignedByte();
switch (layout) {
case 0:
stereoMode = C.STEREO_MODE_MONO;
break;
case 1:
stereoMode = C.STEREO_MODE_TOP_BOTTOM;
break;
case 2:
stereoMode = C.STEREO_MODE_LEFT_RIGHT;
break;
default:
break;
}
}
} }
childPosition += childAtomSize; childPosition += childAtomSize;
} }
@ -716,7 +740,7 @@ import java.util.List;
out.format = Format.createVideoSampleFormat(Integer.toString(trackId), mimeType, null, out.format = Format.createVideoSampleFormat(Integer.toString(trackId), mimeType, null,
Format.NO_VALUE, Format.NO_VALUE, width, height, Format.NO_VALUE, initializationData, Format.NO_VALUE, Format.NO_VALUE, width, height, Format.NO_VALUE, initializationData,
rotationDegrees, pixelWidthHeightRatio, drmInitData); rotationDegrees, pixelWidthHeightRatio, projectionData, stereoMode, drmInitData);
} }
/** /**
@ -1040,6 +1064,23 @@ import java.util.List;
return null; return null;
} }
/**
* Parses the proj box from sv3d box, as specified by https://github.com/google/spatial-media
*/
private static byte[] parseProjFromParent(ParsableByteArray parent, int position, int size) {
int childPosition = position + Atom.HEADER_SIZE;
while (childPosition - position < size) {
parent.setPosition(childPosition);
int childAtomSize = parent.readInt();
int childAtomType = parent.readInt();
if (childAtomType == Atom.TYPE_proj) {
return Arrays.copyOfRange(parent.data, childPosition, childPosition + childAtomSize);
}
childPosition += childAtomSize;
}
return null;
}
/** /**
* Parses the size of an expandable class, as specified by ISO 14496-1 subsection 8.3.3. * Parses the size of an expandable class, as specified by ISO 14496-1 subsection 8.3.3.
*/ */

View File

@ -372,6 +372,13 @@ public final class ParsableByteArray {
return result; return result;
} }
/**
* Reads the next four bytes as a 32-bit floating point value.
*/
public float readFloat() {
return Float.intBitsToFloat(readInt());
}
/** /**
* Reads the next eight bytes as a 64-bit floating point value. * Reads the next eight bytes as a 64-bit floating point value.
*/ */