Commit 2c84f016 by olly Committed by Oliver Woodman

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
parent 1579b68c
......@@ -55,10 +55,12 @@ public final class FormatTest extends TestCase {
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);
byte[] projectionData = new byte[] {1, 2, 3};
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",
Format.OFFSET_SAMPLE_RELATIVE, INIT_DATA, drmInitData);
1024, 2048, 1920, 1080, 24, 90, 2, projectionData, C.STEREO_MODE_TOP_BOTTOM, 6, 44100,
C.ENCODING_PCM_24BIT, 1001, 1002, 0, "und", Format.OFFSET_SAMPLE_RELATIVE, INIT_DATA,
drmInitData);
Parcel parcel = Parcel.obtain();
formatToParcel.writeToParcel(parcel, 0);
......
......@@ -364,6 +364,21 @@ public final class C {
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
* {@link #TIME_UNSET} values.
*
......
......@@ -126,6 +126,9 @@ import java.util.List;
public static final int TYPE_mean = Util.getIntegerCodeForString("mean");
public static final int TYPE_name = Util.getIntegerCodeForString("name");
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_vp09 = Util.getIntegerCodeForString("vp09");
public static final int TYPE_vpcC = Util.getIntegerCodeForString("vpcC");
......
......@@ -29,6 +29,7 @@ import com.google.android.exoplayer2.util.ParsableByteArray;
import com.google.android.exoplayer2.util.Util;
import com.google.android.exoplayer2.video.AvcConfig;
import com.google.android.exoplayer2.video.HevcConfig;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
......@@ -663,6 +664,8 @@ import java.util.List;
List<byte[]> initializationData = null;
String mimeType = null;
byte[] projectionData = null;
int stereoMode = Format.NO_VALUE;
while (childPosition - position < size) {
parent.setPosition(childPosition);
int childStartPosition = parent.getPosition();
......@@ -705,6 +708,27 @@ import java.util.List;
} else if (childAtomType == Atom.TYPE_pasp) {
pixelWidthHeightRatio = parsePaspFromParent(parent, childStartPosition);
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;
}
......@@ -716,7 +740,7 @@ import java.util.List;
out.format = Format.createVideoSampleFormat(Integer.toString(trackId), mimeType, null,
Format.NO_VALUE, Format.NO_VALUE, width, height, Format.NO_VALUE, initializationData,
rotationDegrees, pixelWidthHeightRatio, drmInitData);
rotationDegrees, pixelWidthHeightRatio, projectionData, stereoMode, drmInitData);
}
/**
......@@ -1041,6 +1065,23 @@ import java.util.List;
}
/**
* 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.
*/
private static int parseExpandableClassSize(ParsableByteArray data) {
......
......@@ -373,6 +373,13 @@ public final class ParsableByteArray {
}
/**
* 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.
*/
public double readDouble() {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment