mkvmuxer: Add Projection element support.
Part of the Spherical Video V2 draft specification: https://github.com/google/spatial-media/blob/master/docs/spherical-video-v2-rfc.md Change-Id: Ia935ba975a0f01c1fb2919325ab7f70254c2ed10
This commit is contained in:
parent
725f36207e
commit
483a0ff800
@ -124,6 +124,14 @@ enum MkvId {
|
||||
kMkvLuminanceMin = 0x55DA,
|
||||
// end mastering metadata
|
||||
// end colour
|
||||
// projection
|
||||
kMkvProjection = 0x7670,
|
||||
kMkvProjectionType = 0x7671,
|
||||
kMkvProjectionPrivate = 0x7672,
|
||||
kMkvProjectionPoseYaw = 0x7673,
|
||||
kMkvProjectionPosePitch = 0x7674,
|
||||
kMkvProjectionPoseRoll = 0x7675,
|
||||
// end projection
|
||||
// audio
|
||||
kMkvAudio = 0xE1,
|
||||
kMkvSamplingFrequency = 0xB5,
|
||||
|
@ -1228,6 +1228,89 @@ uint64_t Colour::PayloadSize() const {
|
||||
return size;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Projection element
|
||||
|
||||
uint64_t Projection::ProjectionSize() const {
|
||||
uint64_t size = PayloadSize();
|
||||
|
||||
if (size > 0)
|
||||
size += EbmlMasterElementSize(libwebm::kMkvProjection, size);
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
bool Projection::Write(IMkvWriter* writer) const {
|
||||
const uint64_t size = PayloadSize();
|
||||
|
||||
// Don't write an empty element.
|
||||
if (size == 0)
|
||||
return true;
|
||||
|
||||
if (!WriteEbmlMasterElement(writer, libwebm::kMkvProjection, size))
|
||||
return false;
|
||||
|
||||
if (!WriteEbmlElement(writer, libwebm::kMkvProjectionType,
|
||||
static_cast<uint64>(type_))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (private_data_length_ > 0 && private_data_ != NULL &&
|
||||
!WriteEbmlElement(writer, libwebm::kMkvProjectionPrivate, private_data_,
|
||||
private_data_length_)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!WriteEbmlElement(writer, libwebm::kMkvProjectionPoseYaw, pose_yaw_))
|
||||
return false;
|
||||
|
||||
if (!WriteEbmlElement(writer, libwebm::kMkvProjectionPosePitch, pose_pitch_)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!WriteEbmlElement(writer, libwebm::kMkvProjectionPoseRoll, pose_roll_)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Projection::SetProjectionPrivate(const uint8_t* data,
|
||||
uint64_t data_length) {
|
||||
if (data == NULL || data_length == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
uint8_t* new_private_data = new (std::nothrow) uint8_t[data_length];
|
||||
if (new_private_data == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
delete[] private_data_;
|
||||
private_data_ = new_private_data;
|
||||
private_data_length_ = data_length;
|
||||
memcpy(private_data_, data, static_cast<size_t>(data_length));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
uint64_t Projection::PayloadSize() const {
|
||||
uint64_t size =
|
||||
EbmlElementSize(libwebm::kMkvProjection, static_cast<uint64>(type_));
|
||||
|
||||
if (private_data_length_ > 0 && private_data_ != NULL) {
|
||||
size += EbmlElementSize(libwebm::kMkvProjectionPrivate, private_data_,
|
||||
private_data_length_);
|
||||
}
|
||||
|
||||
size += EbmlElementSize(libwebm::kMkvProjectionPoseYaw, pose_yaw_);
|
||||
size += EbmlElementSize(libwebm::kMkvProjectionPosePitch, pose_pitch_);
|
||||
size += EbmlElementSize(libwebm::kMkvProjectionPoseRoll, pose_roll_);
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////
|
||||
//
|
||||
// VideoTrack Class
|
||||
@ -1245,9 +1328,13 @@ VideoTrack::VideoTrack(unsigned int* seed)
|
||||
stereo_mode_(0),
|
||||
alpha_mode_(0),
|
||||
width_(0),
|
||||
colour_(NULL) {}
|
||||
colour_(NULL),
|
||||
projection_(NULL) {}
|
||||
|
||||
VideoTrack::~VideoTrack() { delete colour_; }
|
||||
VideoTrack::~VideoTrack() {
|
||||
delete colour_;
|
||||
delete projection_;
|
||||
}
|
||||
|
||||
bool VideoTrack::SetStereoMode(uint64_t stereo_mode) {
|
||||
if (stereo_mode != kMono && stereo_mode != kSideBySideLeftIsFirst &&
|
||||
@ -1346,6 +1433,10 @@ bool VideoTrack::Write(IMkvWriter* writer) const {
|
||||
if (!colour_->Write(writer))
|
||||
return false;
|
||||
}
|
||||
if (projection_) {
|
||||
if (!projection_->Write(writer))
|
||||
return false;
|
||||
}
|
||||
|
||||
const int64_t stop_position = writer->Position();
|
||||
if (stop_position < 0 ||
|
||||
@ -1384,6 +1475,27 @@ bool VideoTrack::SetColour(const Colour& colour) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool VideoTrack::SetProjection(const Projection& projection) {
|
||||
std::auto_ptr<Projection> projection_ptr(new Projection());
|
||||
if (!projection_ptr.get())
|
||||
return false;
|
||||
|
||||
if (projection.private_data()) {
|
||||
if (!projection_ptr->SetProjectionPrivate(
|
||||
projection.private_data(), projection.private_data_length())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
projection_ptr->set_type(projection.type());
|
||||
projection_ptr->set_pose_yaw(projection.pose_yaw());
|
||||
projection_ptr->set_pose_pitch(projection.pose_pitch());
|
||||
projection_ptr->set_pose_roll(projection.pose_roll());
|
||||
delete projection_;
|
||||
projection_ = projection_ptr.release();
|
||||
return true;
|
||||
}
|
||||
|
||||
uint64_t VideoTrack::VideoPayloadSize() const {
|
||||
uint64_t size =
|
||||
EbmlElementSize(libwebm::kMkvPixelWidth, static_cast<uint64>(width_));
|
||||
@ -1419,6 +1531,9 @@ uint64_t VideoTrack::VideoPayloadSize() const {
|
||||
if (colour_)
|
||||
size += colour_->ColourSize();
|
||||
|
||||
if (projection_)
|
||||
size += projection_->ProjectionSize();
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
|
@ -464,6 +464,56 @@ class Colour {
|
||||
MasteringMetadata* mastering_metadata_;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////
|
||||
// Projection element.
|
||||
class Projection {
|
||||
public:
|
||||
enum ProjectionType {
|
||||
kTypeNotPresent = -1,
|
||||
kRectangular = 0,
|
||||
kEquirectangular = 1,
|
||||
kCubeMap = 2,
|
||||
kMesh = 3,
|
||||
};
|
||||
static const uint64_t kValueNotPresent;
|
||||
Projection()
|
||||
: type_(kRectangular),
|
||||
pose_yaw_(0.0),
|
||||
pose_pitch_(0.0),
|
||||
pose_roll_(0.0),
|
||||
private_data_(NULL),
|
||||
private_data_length_(0) {}
|
||||
~Projection() { delete[] private_data_; }
|
||||
|
||||
uint64_t ProjectionSize() const;
|
||||
bool Write(IMkvWriter* writer) const;
|
||||
|
||||
bool SetProjectionPrivate(const uint8_t* private_data,
|
||||
uint64_t private_data_length);
|
||||
|
||||
ProjectionType type() const { return type_; }
|
||||
void set_type(ProjectionType type) { type_ = type; }
|
||||
float pose_yaw() const { return pose_yaw_; }
|
||||
void set_pose_yaw(float pose_yaw) { pose_yaw_ = pose_yaw; }
|
||||
float pose_pitch() const { return pose_pitch_; }
|
||||
void set_pose_pitch(float pose_pitch) { pose_pitch_ = pose_pitch; }
|
||||
float pose_roll() const { return pose_roll_; }
|
||||
void set_pose_roll(float pose_roll) { pose_roll_ = pose_roll; }
|
||||
uint8_t* private_data() const { return private_data_; }
|
||||
uint64_t private_data_length() const { return private_data_length_; }
|
||||
|
||||
private:
|
||||
// Returns size of VideoProjection child elements.
|
||||
uint64_t PayloadSize() const;
|
||||
|
||||
ProjectionType type_;
|
||||
float pose_yaw_;
|
||||
float pose_pitch_;
|
||||
float pose_roll_;
|
||||
uint8_t* private_data_;
|
||||
uint64_t private_data_length_;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////
|
||||
// Track element.
|
||||
class Track {
|
||||
@ -611,6 +661,11 @@ class VideoTrack : public Track {
|
||||
// Deep copies |colour|.
|
||||
bool SetColour(const Colour& colour);
|
||||
|
||||
Projection* projection() { return projection_; };
|
||||
|
||||
// Deep copies |projection|.
|
||||
bool SetProjection(const Projection& projection);
|
||||
|
||||
private:
|
||||
// Returns the size in bytes of the Video element.
|
||||
uint64_t VideoPayloadSize() const;
|
||||
@ -629,6 +684,7 @@ class VideoTrack : public Track {
|
||||
uint64_t width_;
|
||||
|
||||
Colour* colour_;
|
||||
Projection* projection_;
|
||||
|
||||
LIBWEBM_DISALLOW_COPY_AND_ASSIGN(VideoTrack);
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user