From 676a7135d19d9b212f45203f8d041cf896f0c9fb Mon Sep 17 00:00:00 2001 From: Michael Bradshaw Date: Thu, 25 Aug 2016 12:00:05 -0700 Subject: [PATCH] Add support for the Projection element It's a part of the Google Spatial Media V2 spec: https://github.com/google/spatial-media/blob/master/docs/spherical-video-v2-rfc.md Change-Id: I52f05e34b19239af09774da2f88eb584a0bfa628 --- CMakeLists.txt | 2 + webm_parser/demo/demo.cc | 34 ++++++ webm_parser/include/webm/dom_types.h | 68 ++++++++++- webm_parser/include/webm/id.h | 42 +++++++ webm_parser/src/projection_parser.h | 40 ++++++ webm_parser/src/video_parser.h | 4 +- webm_parser/tests/projection_parser_test.cc | 129 ++++++++++++++++++++ webm_parser/tests/video_parser_test.cc | 22 ++++ 8 files changed, 339 insertions(+), 2 deletions(-) create mode 100644 webm_parser/src/projection_parser.h create mode 100644 webm_parser/tests/projection_parser_test.cc diff --git a/CMakeLists.txt b/CMakeLists.txt index 75fcef4..ad7bea4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -132,6 +132,7 @@ add_library(webm_parser STATIC "${LIBWEBM_SRC_DIR}/webm_parser/src/parser.h" "${LIBWEBM_SRC_DIR}/webm_parser/src/parser_utils.cc" "${LIBWEBM_SRC_DIR}/webm_parser/src/parser_utils.h" + "${LIBWEBM_SRC_DIR}/webm_parser/src/projection_parser.h" "${LIBWEBM_SRC_DIR}/webm_parser/src/recursive_parser.h" "${LIBWEBM_SRC_DIR}/webm_parser/src/seek_head_parser.h" "${LIBWEBM_SRC_DIR}/webm_parser/src/seek_parser.h" @@ -347,6 +348,7 @@ if (ENABLE_TESTS) "${LIBWEBM_SRC_DIR}/webm_parser/tests/master_value_parser_test.cc" "${LIBWEBM_SRC_DIR}/webm_parser/tests/mastering_metadata_parser_test.cc" "${LIBWEBM_SRC_DIR}/webm_parser/tests/parser_utils_test.cc" + "${LIBWEBM_SRC_DIR}/webm_parser/tests/projection_parser_test.cc" "${LIBWEBM_SRC_DIR}/webm_parser/tests/recursive_parser_test.cc" "${LIBWEBM_SRC_DIR}/webm_parser/tests/seek_head_parser_test.cc" "${LIBWEBM_SRC_DIR}/webm_parser/tests/seek_parser_test.cc" diff --git a/webm_parser/demo/demo.cc b/webm_parser/demo/demo.cc index d00adc3..b6a112c 100644 --- a/webm_parser/demo/demo.cc +++ b/webm_parser/demo/demo.cc @@ -217,6 +217,18 @@ std::ostream& operator<<(std::ostream& os, Id id) { return os << "LuminanceMax"; case Id::kLuminanceMin: return os << "LuminanceMin"; + case Id::kProjection: + return os << "Projection"; + case Id::kProjectionType: + return os << "kProjectionType"; + case Id::kProjectionPrivate: + return os << "kProjectionPrivate"; + case Id::kProjectionPoseYaw: + return os << "kProjectionPoseYaw"; + case Id::kProjectionPosePitch: + return os << "kProjectionPosePitch"; + case Id::kProjectionPoseRoll: + return os << "ProjectionPoseRoll"; case Id::kAudio: return os << "Audio"; case Id::kSamplingFrequency: @@ -441,6 +453,19 @@ std::ostream& operator<<(std::ostream& os, Primaries value) { } } +std::ostream& operator<<(std::ostream& os, ProjectionType value) { + switch (value) { + case ProjectionType::kRectangular: + return os << "0 (rectangular)"; + case ProjectionType::kEquirectangular: + return os << "1 (equirectangular)"; + case ProjectionType::kCubeMap: + return os << "2 (cube map)"; + default: + return PrintUnknownEnumValue(os, value); + } +} + std::ostream& operator<<(std::ostream& os, FlagInterlaced value) { switch (value) { case FlagInterlaced::kUnspecified: @@ -684,6 +709,7 @@ class DemoCallback : public Callback { PrintOptionalElement("AspectRatioType", video.aspect_ratio_type); PrintOptionalElement("FrameRate", video.frame_rate); PrintMasterElement("Colour", video.colour); + PrintMasterElement("Projection", video.projection); } void PrintMasterElement(const Colour& colour) { @@ -725,6 +751,14 @@ class DemoCallback : public Callback { PrintOptionalElement("LuminanceMin", mastering_metadata.luminance_min); } + void PrintMasterElement(const Projection& projection) { + PrintMandatoryElement("ProjectionType", projection.type); + PrintOptionalElement("ProjectionPrivate", projection.projection_private); + PrintMandatoryElement("ProjectionPoseYaw", projection.pose_yaw); + PrintMandatoryElement("ProjectionPosePitch", projection.pose_pitch); + PrintMandatoryElement("ProjectionPoseRoll", projection.pose_roll); + } + void PrintMasterElement(const Audio& audio) { PrintMandatoryElement("SamplingFrequency", audio.sampling_frequency); PrintOptionalElement("OutputSamplingFrequency", audio.output_frequency); diff --git a/webm_parser/include/webm/dom_types.h b/webm_parser/include/webm/dom_types.h index a5c99eb..93927e2 100644 --- a/webm_parser/include/webm/dom_types.h +++ b/webm_parser/include/webm/dom_types.h @@ -883,6 +883,66 @@ struct Colour { } }; +/** + A parsed \WebMID{ProjectionType} element. + */ +enum class ProjectionType : std::uint64_t { + /** + Rectangular. + */ + kRectangular = 0, + + /** + Equirectangular. + */ + kEquirectangular = 1, + + /** + Cube map. + */ + kCubeMap = 2, +}; + +/** + A parsed \WebMID{Projection} element. + */ +struct Projection { + /** + A parsed \WebMID{ProjectionType} element. + */ + Element type; + + /** + A parsed \WebMID{ProjectionPrivate} element. + */ + Element> projection_private; + + /** + A parsed \WebMID{ProjectionPoseYaw} element. + */ + Element pose_yaw; + + /** + A parsed \WebMID{ProjectionPosePitch} element. + */ + Element pose_pitch; + + /** + A parsed \WebMID{ProjectionPoseRoll} element. + */ + Element pose_roll; + + /** + Returns true if every member within the two objects are equal. + */ + bool operator==(const Projection& other) const { + return type == other.type && + projection_private == other.projection_private && + pose_yaw == other.pose_yaw && pose_pitch == other.pose_pitch && + pose_roll == other.pose_roll; + } +}; + /** A parsed \WebMID{FlagInterlaced} element. */ @@ -1113,6 +1173,11 @@ struct Video { */ Element colour; + /** + A parsed \WebMID{Projection} element. + */ + Element projection; + /** Returns true if every member within the two objects are equal. */ @@ -1128,7 +1193,8 @@ struct Video { display_height == other.display_height && display_unit == other.display_unit && aspect_ratio_type == other.aspect_ratio_type && - frame_rate == other.frame_rate && colour == other.colour; + frame_rate == other.frame_rate && colour == other.colour && + projection == other.projection; } }; diff --git a/webm_parser/include/webm/id.h b/webm_parser/include/webm/id.h index 3d63afb..0f761db 100644 --- a/webm_parser/include/webm/id.h +++ b/webm_parser/include/webm/id.h @@ -704,6 +704,48 @@ enum class Id : std::uint32_t { */ kLuminanceMin = 0x55DA, + /** + \WebMID{Projection} element ID. + + \WebMTable{Master, 5, No, No, No, , } + */ + kProjection = 0x7670, + + /** + \WebMID{ProjectionType} element ID. + + \WebMTable{Unsigned integer, 6, Yes, No, No, , 0} + */ + kProjectionType = 0x7671, + + /** + \WebMID{ProjectionPrivate} element ID. + + \WebMTable{Binary, 6, No, No, No, , } + */ + kProjectionPrivate = 0x7672, + + /** + \WebMID{ProjectionPoseYaw} element ID. + + \WebMTable{Float, 6, Yes, No, No, , 0} + */ + kProjectionPoseYaw = 0x7673, + + /** + \WebMID{ProjectionPosePitch} element ID. + + \WebMTable{Float, 6, Yes, No, No, , 0} + */ + kProjectionPosePitch = 0x7674, + + /** + \WebMID{ProjectionPoseRoll} element ID. + + \WebMTable{Float, 6, Yes, No, No, , 0} + */ + kProjectionPoseRoll = 0x7675, + /** \MatroskaID{Audio} element ID. diff --git a/webm_parser/src/projection_parser.h b/webm_parser/src/projection_parser.h new file mode 100644 index 0000000..a851eb6 --- /dev/null +++ b/webm_parser/src/projection_parser.h @@ -0,0 +1,40 @@ +// Copyright (c) 2016 The WebM project authors. All Rights Reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. An additional intellectual property rights grant can be found +// in the file PATENTS. All contributing project authors may +// be found in the AUTHORS file in the root of the source tree. +#ifndef SRC_PROJECTION_PARSER_H_ +#define SRC_PROJECTION_PARSER_H_ + +#include "src/byte_parser.h" +#include "src/float_parser.h" +#include "src/int_parser.h" +#include "src/master_value_parser.h" +#include "webm/dom_types.h" +#include "webm/id.h" + +namespace webm { + +// Spec reference: +// https://github.com/google/spatial-media/blob/master/docs/spherical-video-v2-rfc.md#projection-master-element +class ProjectionParser : public MasterValueParser { + public: + ProjectionParser() + : MasterValueParser( + MakeChild>(Id::kProjectionType, + &Projection::type), + MakeChild(Id::kProjectionPrivate, + &Projection::projection_private), + MakeChild(Id::kProjectionPoseYaw, + &Projection::pose_yaw), + MakeChild(Id::kProjectionPosePitch, + &Projection::pose_pitch), + MakeChild(Id::kProjectionPoseRoll, + &Projection::pose_roll)) {} +}; + +} // namespace webm + +#endif // SRC_PROJECTION_PARSER_H_ diff --git a/webm_parser/src/video_parser.h b/webm_parser/src/video_parser.h index 33f3722..20c12e2 100644 --- a/webm_parser/src/video_parser.h +++ b/webm_parser/src/video_parser.h @@ -16,6 +16,7 @@ #include "src/float_parser.h" #include "src/int_parser.h" #include "src/master_value_parser.h" +#include "src/projection_parser.h" #include "webm/callback.h" #include "webm/dom_types.h" #include "webm/id.h" @@ -58,7 +59,8 @@ class VideoParser : public MasterValueParser