Merge "Add support for the Projection element"
This commit is contained in:
commit
ff667d5fb4
@ -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"
|
||||
|
@ -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);
|
||||
|
@ -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<ProjectionType> type;
|
||||
|
||||
/**
|
||||
A parsed \WebMID{ProjectionPrivate} element.
|
||||
*/
|
||||
Element<std::vector<std::uint8_t>> projection_private;
|
||||
|
||||
/**
|
||||
A parsed \WebMID{ProjectionPoseYaw} element.
|
||||
*/
|
||||
Element<double> pose_yaw;
|
||||
|
||||
/**
|
||||
A parsed \WebMID{ProjectionPosePitch} element.
|
||||
*/
|
||||
Element<double> pose_pitch;
|
||||
|
||||
/**
|
||||
A parsed \WebMID{ProjectionPoseRoll} element.
|
||||
*/
|
||||
Element<double> 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> colour;
|
||||
|
||||
/**
|
||||
A parsed \WebMID{Projection} element.
|
||||
*/
|
||||
Element<Projection> 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;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -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.
|
||||
|
||||
|
40
webm_parser/src/projection_parser.h
Normal file
40
webm_parser/src/projection_parser.h
Normal file
@ -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<Projection> {
|
||||
public:
|
||||
ProjectionParser()
|
||||
: MasterValueParser(
|
||||
MakeChild<IntParser<ProjectionType>>(Id::kProjectionType,
|
||||
&Projection::type),
|
||||
MakeChild<BinaryParser>(Id::kProjectionPrivate,
|
||||
&Projection::projection_private),
|
||||
MakeChild<FloatParser>(Id::kProjectionPoseYaw,
|
||||
&Projection::pose_yaw),
|
||||
MakeChild<FloatParser>(Id::kProjectionPosePitch,
|
||||
&Projection::pose_pitch),
|
||||
MakeChild<FloatParser>(Id::kProjectionPoseRoll,
|
||||
&Projection::pose_roll)) {}
|
||||
};
|
||||
|
||||
} // namespace webm
|
||||
|
||||
#endif // SRC_PROJECTION_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<Video> {
|
||||
MakeChild<IntParser<AspectRatioType>>(Id::kAspectRatioType,
|
||||
&Video::aspect_ratio_type),
|
||||
MakeChild<FloatParser>(Id::kFrameRate, &Video::frame_rate),
|
||||
MakeChild<ColourParser>(Id::kColour, &Video::colour)) {}
|
||||
MakeChild<ColourParser>(Id::kColour, &Video::colour),
|
||||
MakeChild<ProjectionParser>(Id::kProjection, &Video::projection)) {}
|
||||
|
||||
Status Init(const ElementMetadata& metadata,
|
||||
std::uint64_t max_size) override {
|
||||
|
129
webm_parser/tests/projection_parser_test.cc
Normal file
129
webm_parser/tests/projection_parser_test.cc
Normal file
@ -0,0 +1,129 @@
|
||||
// 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.
|
||||
#include "src/projection_parser.h"
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#include "test_utils/element_parser_test.h"
|
||||
#include "webm/id.h"
|
||||
|
||||
using webm::ElementParserTest;
|
||||
using webm::Id;
|
||||
using webm::Projection;
|
||||
using webm::ProjectionType;
|
||||
using webm::ProjectionParser;
|
||||
|
||||
namespace {
|
||||
|
||||
class ProjectionParserTest
|
||||
: public ElementParserTest<ProjectionParser, Id::kProjection> {};
|
||||
|
||||
TEST_F(ProjectionParserTest, DefaultParse) {
|
||||
ParseAndVerify();
|
||||
|
||||
const Projection projection = parser_.value();
|
||||
|
||||
EXPECT_FALSE(projection.type.is_present());
|
||||
EXPECT_EQ(ProjectionType::kRectangular, projection.type.value());
|
||||
|
||||
EXPECT_FALSE(projection.projection_private.is_present());
|
||||
EXPECT_EQ(std::vector<std::uint8_t>{}, projection.projection_private.value());
|
||||
|
||||
EXPECT_FALSE(projection.pose_yaw.is_present());
|
||||
EXPECT_EQ(0.0, projection.pose_yaw.value());
|
||||
|
||||
EXPECT_FALSE(projection.pose_pitch.is_present());
|
||||
EXPECT_EQ(0.0, projection.pose_pitch.value());
|
||||
|
||||
EXPECT_FALSE(projection.pose_roll.is_present());
|
||||
EXPECT_EQ(0.0, projection.pose_roll.value());
|
||||
}
|
||||
|
||||
TEST_F(ProjectionParserTest, DefaultValues) {
|
||||
SetReaderData({
|
||||
0x76, 0x71, // ID = 0x7671 (ProjectionType).
|
||||
0x80, // Size = 0.
|
||||
|
||||
0x76, 0x72, // ID = 0x7672 (ProjectionPrivate).
|
||||
0x80, // Size = 0.
|
||||
|
||||
0x76, 0x73, // ID = 0x7673 (ProjectionPoseYaw).
|
||||
0x80, // Size = 0.
|
||||
|
||||
0x76, 0x74, // ID = 0x7674 (ProjectionPosePitch).
|
||||
0x80, // Size = 0.
|
||||
|
||||
0x76, 0x75, // ID = 0x7675 (ProjectionPoseRoll).
|
||||
0x80, // Size = 0.
|
||||
});
|
||||
|
||||
ParseAndVerify();
|
||||
|
||||
const Projection projection = parser_.value();
|
||||
|
||||
EXPECT_TRUE(projection.type.is_present());
|
||||
EXPECT_EQ(ProjectionType::kRectangular, projection.type.value());
|
||||
|
||||
EXPECT_TRUE(projection.projection_private.is_present());
|
||||
EXPECT_EQ(std::vector<std::uint8_t>{}, projection.projection_private.value());
|
||||
|
||||
EXPECT_TRUE(projection.pose_yaw.is_present());
|
||||
EXPECT_EQ(0.0, projection.pose_yaw.value());
|
||||
|
||||
EXPECT_TRUE(projection.pose_pitch.is_present());
|
||||
EXPECT_EQ(0.0, projection.pose_pitch.value());
|
||||
|
||||
EXPECT_TRUE(projection.pose_roll.is_present());
|
||||
EXPECT_EQ(0.0, projection.pose_roll.value());
|
||||
}
|
||||
|
||||
TEST_F(ProjectionParserTest, CustomValues) {
|
||||
SetReaderData({
|
||||
0x76, 0x71, // ID = 0x7671 (ProjectionType).
|
||||
0x10, 0x00, 0x00, 0x01, // Size = 1.
|
||||
0x01, // Body (value = equirectangular).
|
||||
|
||||
0x76, 0x72, // ID = 0x7672 (ProjectionPrivate).
|
||||
0x10, 0x00, 0x00, 0x01, // Size = 1.
|
||||
0x00, // Body.
|
||||
|
||||
0x76, 0x73, // ID = 0x7673 (ProjectionPoseYaw).
|
||||
0x10, 0x00, 0x00, 0x04, // Size = 4.
|
||||
0x3f, 0x80, 0x00, 0x00, // Body (value = 1.0).
|
||||
|
||||
0x76, 0x74, // ID = 0x7674 (ProjectionPosePitch).
|
||||
0x10, 0x00, 0x00, 0x04, // Size = 4.
|
||||
0x40, 0x00, 0x00, 0x00, // Body (value = 2.0).
|
||||
|
||||
0x76, 0x75, // ID = 0x7675 (ProjectionPoseRoll).
|
||||
0x10, 0x00, 0x00, 0x04, // Size = 4.
|
||||
0x40, 0x80, 0x00, 0x00, // Body (value = 4.0).
|
||||
});
|
||||
|
||||
ParseAndVerify();
|
||||
|
||||
const Projection projection = parser_.value();
|
||||
|
||||
EXPECT_TRUE(projection.type.is_present());
|
||||
EXPECT_EQ(ProjectionType::kEquirectangular, projection.type.value());
|
||||
|
||||
EXPECT_TRUE(projection.projection_private.is_present());
|
||||
EXPECT_EQ(std::vector<std::uint8_t>{0x00},
|
||||
projection.projection_private.value());
|
||||
|
||||
EXPECT_TRUE(projection.pose_yaw.is_present());
|
||||
EXPECT_EQ(1.0, projection.pose_yaw.value());
|
||||
|
||||
EXPECT_TRUE(projection.pose_pitch.is_present());
|
||||
EXPECT_EQ(2.0, projection.pose_pitch.value());
|
||||
|
||||
EXPECT_TRUE(projection.pose_roll.is_present());
|
||||
EXPECT_EQ(4.0, projection.pose_roll.value());
|
||||
}
|
||||
|
||||
} // namespace
|
@ -18,6 +18,8 @@ using webm::DisplayUnit;
|
||||
using webm::ElementParserTest;
|
||||
using webm::FlagInterlaced;
|
||||
using webm::Id;
|
||||
using webm::Projection;
|
||||
using webm::ProjectionType;
|
||||
using webm::StereoMode;
|
||||
using webm::Video;
|
||||
using webm::VideoParser;
|
||||
@ -75,6 +77,9 @@ TEST_F(VideoParserTest, DefaultParse) {
|
||||
|
||||
EXPECT_FALSE(video.colour.is_present());
|
||||
EXPECT_EQ(Colour{}, video.colour.value());
|
||||
|
||||
EXPECT_FALSE(video.projection.is_present());
|
||||
EXPECT_EQ(Projection{}, video.projection.value());
|
||||
}
|
||||
|
||||
TEST_F(VideoParserTest, DefaultValues) {
|
||||
@ -123,6 +128,9 @@ TEST_F(VideoParserTest, DefaultValues) {
|
||||
|
||||
0x55, 0xB0, // ID = 0x55B0 (Colour).
|
||||
0x20, 0x00, 0x00, // Size = 0.
|
||||
|
||||
0x76, 0x70, // ID = 0x7670 (Projection).
|
||||
0x20, 0x00, 0x00, // Size = 0.
|
||||
});
|
||||
|
||||
ParseAndVerify();
|
||||
@ -173,6 +181,9 @@ TEST_F(VideoParserTest, DefaultValues) {
|
||||
|
||||
EXPECT_TRUE(video.colour.is_present());
|
||||
EXPECT_EQ(Colour{}, video.colour.value());
|
||||
|
||||
EXPECT_TRUE(video.projection.is_present());
|
||||
EXPECT_EQ(Projection{}, video.projection.value());
|
||||
}
|
||||
|
||||
TEST_F(VideoParserTest, CustomValues) {
|
||||
@ -239,6 +250,13 @@ TEST_F(VideoParserTest, CustomValues) {
|
||||
0x55, 0xB2, // ID = 0x55B2 (BitsPerChannel).
|
||||
0x10, 0x00, 0x00, 0x01, // Size = 1.
|
||||
0x01, // Body (value = 1).
|
||||
|
||||
0x76, 0x70, // ID = 0x7670 (Projection).
|
||||
0x10, 0x00, 0x00, 0x07, // Size = 7.
|
||||
|
||||
0x76, 0x71, // ID = 0x7671 (ProjectionType).
|
||||
0x10, 0x00, 0x00, 0x01, // Size = 1.
|
||||
0x02, // Body (value = cube map).
|
||||
});
|
||||
|
||||
ParseAndVerify();
|
||||
@ -291,6 +309,10 @@ TEST_F(VideoParserTest, CustomValues) {
|
||||
EXPECT_TRUE(video.colour.value().bits_per_channel.is_present());
|
||||
EXPECT_EQ(static_cast<std::uint64_t>(1),
|
||||
video.colour.value().bits_per_channel.value());
|
||||
|
||||
EXPECT_TRUE(video.projection.is_present());
|
||||
EXPECT_TRUE(video.projection.value().type.is_present());
|
||||
EXPECT_EQ(ProjectionType::kCubeMap, video.projection.value().type.value());
|
||||
}
|
||||
|
||||
TEST_F(VideoParserTest, AbsentDisplaySize) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user