diff --git a/library/core/src/main/java/com/google/android/exoplayer2/C.java b/library/core/src/main/java/com/google/android/exoplayer2/C.java index fac9818d9e..77d39fe866 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/C.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/C.java @@ -896,6 +896,26 @@ public final class C { */ public static final int COLOR_RANGE_FULL = MediaFormat.COLOR_RANGE_FULL; + /** Video projection types. */ + @Documented + @Retention(RetentionPolicy.SOURCE) + @IntDef({ + Format.NO_VALUE, + PROJECTION_RECTANGULAR, + PROJECTION_EQUIRECTANGULAR, + PROJECTION_CUBEMAP, + PROJECTION_MESH + }) + public @interface Projection {} + /** Conventional rectangular projection. */ + public static final int PROJECTION_RECTANGULAR = 0; + /** Equirectangular spherical projection. */ + public static final int PROJECTION_EQUIRECTANGULAR = 1; + /** Cube map projection. */ + public static final int PROJECTION_CUBEMAP = 2; + /** 3-D mesh projection. */ + public static final int PROJECTION_MESH = 3; + /** * Priority for media playback. * diff --git a/library/core/src/main/java/com/google/android/exoplayer2/extractor/mkv/MatroskaExtractor.java b/library/core/src/main/java/com/google/android/exoplayer2/extractor/mkv/MatroskaExtractor.java index 86b750e821..187b9ae443 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/extractor/mkv/MatroskaExtractor.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/extractor/mkv/MatroskaExtractor.java @@ -191,7 +191,11 @@ public final class MatroskaExtractor implements Extractor { private static final int ID_CUE_CLUSTER_POSITION = 0xF1; private static final int ID_LANGUAGE = 0x22B59C; private static final int ID_PROJECTION = 0x7670; + private static final int ID_PROJECTION_TYPE = 0x7671; private static final int ID_PROJECTION_PRIVATE = 0x7672; + private static final int ID_PROJECTION_POSE_YAW = 0x7673; + private static final int ID_PROJECTION_POSE_PITCH = 0x7674; + private static final int ID_PROJECTION_POSE_ROLL = 0x7675; private static final int ID_STEREO_MODE = 0x53B8; private static final int ID_COLOUR = 0x55B0; private static final int ID_COLOUR_RANGE = 0x55B9; @@ -760,6 +764,24 @@ public final class MatroskaExtractor implements Extractor { case ID_MAX_FALL: currentTrack.maxFrameAverageLuminance = (int) value; break; + case ID_PROJECTION_TYPE: + switch ((int) value) { + case 0: + currentTrack.projectionType = C.PROJECTION_RECTANGULAR; + break; + case 1: + currentTrack.projectionType = C.PROJECTION_EQUIRECTANGULAR; + break; + case 2: + currentTrack.projectionType = C.PROJECTION_CUBEMAP; + break; + case 3: + currentTrack.projectionType = C.PROJECTION_MESH; + break; + default: + break; + } + break; default: break; } @@ -803,6 +825,15 @@ public final class MatroskaExtractor implements Extractor { case ID_LUMNINANCE_MIN: currentTrack.minMasteringLuminance = (float) value; break; + case ID_PROJECTION_POSE_YAW: + currentTrack.projectionPoseYaw = (float) value; + break; + case ID_PROJECTION_POSE_PITCH: + currentTrack.projectionPosePitch = (float) value; + break; + case ID_PROJECTION_POSE_ROLL: + currentTrack.projectionPoseRoll = (float) value; + break; default: break; } @@ -1465,6 +1496,7 @@ public final class MatroskaExtractor implements Extractor { case ID_COLOUR_PRIMARIES: case ID_MAX_CLL: case ID_MAX_FALL: + case ID_PROJECTION_TYPE: return TYPE_UNSIGNED_INT; case ID_DOC_TYPE: case ID_NAME: @@ -1491,6 +1523,9 @@ public final class MatroskaExtractor implements Extractor { case ID_WHITE_POINT_CHROMATICITY_Y: case ID_LUMNINANCE_MAX: case ID_LUMNINANCE_MIN: + case ID_PROJECTION_POSE_YAW: + case ID_PROJECTION_POSE_PITCH: + case ID_PROJECTION_POSE_ROLL: return TYPE_FLOAT; default: return TYPE_UNKNOWN; @@ -1631,6 +1666,10 @@ public final class MatroskaExtractor implements Extractor { public int displayWidth = Format.NO_VALUE; public int displayHeight = Format.NO_VALUE; public int displayUnit = DISPLAY_UNIT_PIXELS; + @C.Projection public int projectionType = Format.NO_VALUE; + public float projectionPoseYaw = 0f; + public float projectionPosePitch = 0f; + public float projectionPoseRoll = 0f; public byte[] projectionData = null; @C.StereoMode public int stereoMode = Format.NO_VALUE; @@ -1850,6 +1889,21 @@ public final class MatroskaExtractor implements Extractor { } else if ("htc_video_rotA-270".equals(name)) { rotationDegrees = 270; } + if (projectionType == C.PROJECTION_RECTANGULAR + && Float.compare(projectionPoseYaw, 0f) == 0 + && Float.compare(projectionPosePitch, 0f) == 0) { + // The range of projectionPoseRoll is [-180, 180]. + if (Float.compare(projectionPoseRoll, 0f) == 0) { + rotationDegrees = 0; + } else if (Float.compare(projectionPosePitch, 90f) == 0) { + rotationDegrees = 90; + } else if (Float.compare(projectionPosePitch, -180f) == 0 + || Float.compare(projectionPosePitch, 180f) == 0) { + rotationDegrees = 180; + } else if (Float.compare(projectionPosePitch, -90f) == 0) { + rotationDegrees = 270; + } + } format = Format.createVideoSampleFormat( Integer.toString(trackId),