Handle rectangular rotation projections in Matroska

See also https://github.com/Matroska-Org/matroska-specification/issues/269.

PiperOrigin-RevId: 226758584
This commit is contained in:
andrewlewis 2018-12-24 14:26:01 +00:00 committed by Oliver Woodman
parent 9728ac54ba
commit fc6a1ea522
2 changed files with 74 additions and 0 deletions

View File

@ -896,6 +896,26 @@ public final class C {
*/ */
public static final int COLOR_RANGE_FULL = MediaFormat.COLOR_RANGE_FULL; 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. * Priority for media playback.
* *

View File

@ -191,7 +191,11 @@ public final class MatroskaExtractor implements Extractor {
private static final int ID_CUE_CLUSTER_POSITION = 0xF1; private static final int ID_CUE_CLUSTER_POSITION = 0xF1;
private static final int ID_LANGUAGE = 0x22B59C; private static final int ID_LANGUAGE = 0x22B59C;
private static final int ID_PROJECTION = 0x7670; 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_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_STEREO_MODE = 0x53B8;
private static final int ID_COLOUR = 0x55B0; private static final int ID_COLOUR = 0x55B0;
private static final int ID_COLOUR_RANGE = 0x55B9; private static final int ID_COLOUR_RANGE = 0x55B9;
@ -760,6 +764,24 @@ public final class MatroskaExtractor implements Extractor {
case ID_MAX_FALL: case ID_MAX_FALL:
currentTrack.maxFrameAverageLuminance = (int) value; currentTrack.maxFrameAverageLuminance = (int) value;
break; 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: default:
break; break;
} }
@ -803,6 +825,15 @@ public final class MatroskaExtractor implements Extractor {
case ID_LUMNINANCE_MIN: case ID_LUMNINANCE_MIN:
currentTrack.minMasteringLuminance = (float) value; currentTrack.minMasteringLuminance = (float) value;
break; 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: default:
break; break;
} }
@ -1465,6 +1496,7 @@ public final class MatroskaExtractor implements Extractor {
case ID_COLOUR_PRIMARIES: case ID_COLOUR_PRIMARIES:
case ID_MAX_CLL: case ID_MAX_CLL:
case ID_MAX_FALL: case ID_MAX_FALL:
case ID_PROJECTION_TYPE:
return TYPE_UNSIGNED_INT; return TYPE_UNSIGNED_INT;
case ID_DOC_TYPE: case ID_DOC_TYPE:
case ID_NAME: case ID_NAME:
@ -1491,6 +1523,9 @@ public final class MatroskaExtractor implements Extractor {
case ID_WHITE_POINT_CHROMATICITY_Y: case ID_WHITE_POINT_CHROMATICITY_Y:
case ID_LUMNINANCE_MAX: case ID_LUMNINANCE_MAX:
case ID_LUMNINANCE_MIN: case ID_LUMNINANCE_MIN:
case ID_PROJECTION_POSE_YAW:
case ID_PROJECTION_POSE_PITCH:
case ID_PROJECTION_POSE_ROLL:
return TYPE_FLOAT; return TYPE_FLOAT;
default: default:
return TYPE_UNKNOWN; return TYPE_UNKNOWN;
@ -1631,6 +1666,10 @@ public final class MatroskaExtractor implements Extractor {
public int displayWidth = Format.NO_VALUE; public int displayWidth = Format.NO_VALUE;
public int displayHeight = Format.NO_VALUE; public int displayHeight = Format.NO_VALUE;
public int displayUnit = DISPLAY_UNIT_PIXELS; 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; public byte[] projectionData = null;
@C.StereoMode @C.StereoMode
public int stereoMode = Format.NO_VALUE; public int stereoMode = Format.NO_VALUE;
@ -1850,6 +1889,21 @@ public final class MatroskaExtractor implements Extractor {
} else if ("htc_video_rotA-270".equals(name)) { } else if ("htc_video_rotA-270".equals(name)) {
rotationDegrees = 270; 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 =
Format.createVideoSampleFormat( Format.createVideoSampleFormat(
Integer.toString(trackId), Integer.toString(trackId),