mkvmuxer: Fix Colour element support.

Colour and MasteringMetadata were treating payload size and total
size as equal:

- Internally both must use actual payload size (sum of child elements).
- External users need sum of child elements and the size of the
  respective ID.

Change-Id: Idefb193b9de394bfc6a0044f1673a62be61c6b12
This commit is contained in:
Tom Finegan
2016-02-11 18:34:37 -08:00
parent eaeca3415d
commit 375e416336
2 changed files with 75 additions and 52 deletions

View File

@@ -875,30 +875,8 @@ bool PrimaryChromaticity::Write(IMkvWriter* writer, MkvId x_id,
return WriteEbmlElement(writer, x_id, x) && WriteEbmlElement(writer, y_id, y); return WriteEbmlElement(writer, x_id, x) && WriteEbmlElement(writer, y_id, y);
} }
uint64 MasteringMetadata::MasteringMetadataPayloadSize() const { uint64 MasteringMetadata::MasteringMetadataSize() const {
uint64 size = 0; uint64 size = PayloadSize();
if (luminance_max != kUnspecifiedMmValue)
size += EbmlElementSize(kMkvLuminanceMax, luminance_max);
if (luminance_min != kUnspecifiedMmValue)
size += EbmlElementSize(kMkvLuminanceMin, luminance_min);
if (r_) {
size += r_->PrimaryChromaticityPayloadSize(kMkvPrimaryRChromaticityX,
kMkvPrimaryRChromaticityY);
}
if (g_) {
size += g_->PrimaryChromaticityPayloadSize(kMkvPrimaryGChromaticityX,
kMkvPrimaryGChromaticityY);
}
if (b_) {
size += b_->PrimaryChromaticityPayloadSize(kMkvPrimaryBChromaticityX,
kMkvPrimaryBChromaticityY);
}
if (white_point_) {
size += white_point_->PrimaryChromaticityPayloadSize(
kMkvWhitePointChromaticityX, kMkvWhitePointChromaticityY);
}
if (size > 0) if (size > 0)
size += EbmlMasterElementSize(kMkvMasteringMetadata, size); size += EbmlMasterElementSize(kMkvMasteringMetadata, size);
@@ -907,7 +885,7 @@ uint64 MasteringMetadata::MasteringMetadataPayloadSize() const {
} }
bool MasteringMetadata::Write(IMkvWriter* writer) const { bool MasteringMetadata::Write(IMkvWriter* writer) const {
const uint64 size = MasteringMetadataPayloadSize(); const uint64 size = PayloadSize();
// Don't write an empty element. // Don't write an empty element.
if (size == 0) if (size == 0)
@@ -978,32 +956,36 @@ bool MasteringMetadata::SetChromaticity(
return true; return true;
} }
uint64 Colour::ColourPayloadSize() const { uint64 MasteringMetadata::PayloadSize() const {
uint64 size = 0; uint64 size = 0;
if (matrix != kUnspecifiedColourValue) if (luminance_max != kUnspecifiedMmValue)
size += EbmlElementSize(kMkvMatrix, matrix); size += EbmlElementSize(kMkvLuminanceMax, luminance_max);
if (bits_per_channel != kUnspecifiedColourValue) if (luminance_min != kUnspecifiedMmValue)
size += EbmlElementSize(kMkvBitsPerChannel, bits_per_channel); size += EbmlElementSize(kMkvLuminanceMin, luminance_min);
if (chroma_subsampling != kUnspecifiedColourValue)
size += EbmlElementSize(kMkvChromaSubsampling, chroma_subsampling);
if (chroma_siting_horz != kUnspecifiedColourValue)
size += EbmlElementSize(kMkvChromaSitingHorz, chroma_siting_horz);
if (chroma_siting_vert != kUnspecifiedColourValue)
size += EbmlElementSize(kMkvChromaSitingVert, chroma_siting_vert);
if (range != kUnspecifiedColourValue)
size += EbmlElementSize(kMkvRange, range);
if (transfer_function != kUnspecifiedColourValue)
size += EbmlElementSize(kMkvTransferFunction, transfer_function);
if (primaries != kUnspecifiedColourValue)
size += EbmlElementSize(kMkvPrimaries, primaries);
if (max_cll != kUnspecifiedColourValue)
size += EbmlElementSize(kMkvMaxCLL, max_cll);
if (max_fall != kUnspecifiedColourValue)
size += EbmlElementSize(kMkvMaxFALL, max_fall);
if (mastering_metadata_) if (r_) {
size += mastering_metadata_->MasteringMetadataPayloadSize(); size += r_->PrimaryChromaticityPayloadSize(kMkvPrimaryRChromaticityX,
kMkvPrimaryRChromaticityY);
}
if (g_) {
size += g_->PrimaryChromaticityPayloadSize(kMkvPrimaryGChromaticityX,
kMkvPrimaryGChromaticityY);
}
if (b_) {
size += b_->PrimaryChromaticityPayloadSize(kMkvPrimaryBChromaticityX,
kMkvPrimaryBChromaticityY);
}
if (white_point_) {
size += white_point_->PrimaryChromaticityPayloadSize(
kMkvWhitePointChromaticityX, kMkvWhitePointChromaticityY);
}
return size;
}
uint64 Colour::ColourSize() const {
uint64 size = PayloadSize();
if (size > 0) if (size > 0)
size += EbmlMasterElementSize(kMkvColour, size); size += EbmlMasterElementSize(kMkvColour, size);
@@ -1012,7 +994,7 @@ uint64 Colour::ColourPayloadSize() const {
} }
bool Colour::Write(IMkvWriter* writer) const { bool Colour::Write(IMkvWriter* writer) const {
const uint64 size = ColourPayloadSize(); const uint64 size = PayloadSize();
// Don't write an empty element. // Don't write an empty element.
if (size == 0) if (size == 0)
@@ -1086,6 +1068,37 @@ bool Colour::SetMasteringMetadata(const MasteringMetadata& mastering_metadata) {
mastering_metadata_ = mm_ptr.release(); mastering_metadata_ = mm_ptr.release();
return true; return true;
} }
uint64 Colour::PayloadSize() const {
uint64 size = 0;
if (matrix != kUnspecifiedColourValue)
size += EbmlElementSize(kMkvMatrix, matrix);
if (bits_per_channel != kUnspecifiedColourValue)
size += EbmlElementSize(kMkvBitsPerChannel, bits_per_channel);
if (chroma_subsampling != kUnspecifiedColourValue)
size += EbmlElementSize(kMkvChromaSubsampling, chroma_subsampling);
if (chroma_siting_horz != kUnspecifiedColourValue)
size += EbmlElementSize(kMkvChromaSitingHorz, chroma_siting_horz);
if (chroma_siting_vert != kUnspecifiedColourValue)
size += EbmlElementSize(kMkvChromaSitingVert, chroma_siting_vert);
if (range != kUnspecifiedColourValue)
size += EbmlElementSize(kMkvRange, range);
if (transfer_function != kUnspecifiedColourValue)
size += EbmlElementSize(kMkvTransferFunction, transfer_function);
if (primaries != kUnspecifiedColourValue)
size += EbmlElementSize(kMkvPrimaries, primaries);
if (max_cll != kUnspecifiedColourValue)
size += EbmlElementSize(kMkvMaxCLL, max_cll);
if (max_fall != kUnspecifiedColourValue)
size += EbmlElementSize(kMkvMaxFALL, max_fall);
if (mastering_metadata_)
size += mastering_metadata_->MasteringMetadataSize();
return size;
}
/////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////
// //
// VideoTrack Class // VideoTrack Class
@@ -1250,7 +1263,7 @@ uint64 VideoTrack::VideoPayloadSize() const {
if (frame_rate_ > 0.0) if (frame_rate_ > 0.0)
size += EbmlElementSize(kMkvFrameRate, static_cast<float>(frame_rate_)); size += EbmlElementSize(kMkvFrameRate, static_cast<float>(frame_rate_));
if (colour_) if (colour_)
size += colour_->ColourPayloadSize(); size += colour_->ColourSize();
return size; return size;
} }

View File

@@ -362,7 +362,9 @@ class MasteringMetadata {
delete b_; delete b_;
delete white_point_; delete white_point_;
} }
uint64 MasteringMetadataPayloadSize() const;
// Returns total size of the MasteringMetadata element.
uint64 MasteringMetadataSize() const;
bool Write(IMkvWriter* writer) const; bool Write(IMkvWriter* writer) const;
// Copies non-null chromaticity. // Copies non-null chromaticity.
@@ -379,6 +381,9 @@ class MasteringMetadata {
float luminance_min; float luminance_min;
private: private:
// Returns size of MasteringMetadata child elements.
uint64 PayloadSize() const;
PrimaryChromaticity* r_; PrimaryChromaticity* r_;
PrimaryChromaticity* g_; PrimaryChromaticity* g_;
PrimaryChromaticity* b_; PrimaryChromaticity* b_;
@@ -401,7 +406,9 @@ class Colour {
max_fall(kUnspecifiedColourValue), max_fall(kUnspecifiedColourValue),
mastering_metadata_(NULL) {} mastering_metadata_(NULL) {}
~Colour() { delete mastering_metadata_; } ~Colour() { delete mastering_metadata_; }
uint64 ColourPayloadSize() const;
// Returns total size of the Colour element.
uint64 ColourSize() const;
bool Write(IMkvWriter* writer) const; bool Write(IMkvWriter* writer) const;
// Deep copies |mastering_metadata|. // Deep copies |mastering_metadata|.
@@ -423,6 +430,9 @@ class Colour {
uint64 max_fall; uint64 max_fall;
private: private:
// Returns size of Colour child elements.
uint64 PayloadSize() const;
MasteringMetadata* mastering_metadata_; MasteringMetadata* mastering_metadata_;
}; };