Chromium Code Reviews| Index: media/formats/webm/webm_colour_parser.cc |
| diff --git a/media/formats/webm/webm_colour_parser.cc b/media/formats/webm/webm_colour_parser.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..c058b55d04e6e7a3980be64b7ddb413006532399 |
| --- /dev/null |
| +++ b/media/formats/webm/webm_colour_parser.cc |
| @@ -0,0 +1,563 @@ |
| +// Copyright 2016 The Chromium Authors. All rights reserved. |
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +#include "media/formats/webm/webm_colour_parser.h" |
| + |
| +#include "base/logging.h" |
| +#include "media/formats/webm/webm_constants.h" |
| + |
| +namespace media { |
| + |
| +// The definitions below are copied from the current libwebm top-of-tree. |
| +// Chromium's third_party/libwebm doesn't have these yet. We can probably just |
| +// include libwebm header directly in the future. |
| +// ---- Begin copy/paste from libwebm/webm_parser/include/webm/dom_types.h ---- |
| + |
| +/** |
| + A parsed \WebMID{MatrixCoefficients} element. |
| + |
| + Matroska/WebM adopted these values from Table 4 of ISO/IEC 23001-8:2013/DCOR1. |
| + See that document for further details. |
| + */ |
| +enum class MatrixCoefficients : std::uint64_t { |
| + /** |
| + The identity matrix. |
| + |
| + Typically used for GBR (often referred to as RGB); however, may also be used |
| + for YZX (often referred to as XYZ). |
| + */ |
| + kRgb = 0, |
| + |
| + /** |
| + Rec. ITU-R BT.709-5. |
| + */ |
| + kBt709 = 1, |
| + |
| + /** |
| + Image characteristics are unknown or are determined by the application. |
| + */ |
| + kUnspecified = 2, |
| + |
| + /** |
| + United States Federal Communications Commission Title 47 Code of Federal |
| + Regulations (2003) 73.682 (a) (20). |
| + */ |
| + kFcc = 4, |
| + |
| + /** |
| + Rec. ITU-R BT.470‑6 System B, G (historical). |
| + */ |
| + kBt470Bg = 5, |
| + |
| + /** |
| + Society of Motion Picture and Television Engineers 170M (2004). |
| + */ |
| + kSmpte170M = 6, |
| + |
| + /** |
| + Society of Motion Picture and Television Engineers 240M (1999). |
| + */ |
| + kSmpte240M = 7, |
| + |
| + /** |
| + YCgCo. |
| + */ |
| + kYCgCo = 8, |
| + |
| + /** |
| + Rec. ITU-R BT.2020 (non-constant luminance). |
| + */ |
| + kBt2020NonconstantLuminance = 9, |
| + |
| + /** |
| + Rec. ITU-R BT.2020 (constant luminance). |
| + */ |
| + kBt2020ConstantLuminance = 10, |
| +}; |
| + |
| +/** |
| + A parsed \WebMID{Range} element. |
| + */ |
| +enum class Range : std::uint64_t { |
| + /** |
| + Unspecified. |
| + */ |
| + kUnspecified = 0, |
| + |
| + /** |
| + Broadcast range. |
| + */ |
| + kBroadcast = 1, |
| + |
| + /** |
| + Full range (no clipping). |
| + */ |
| + kFull = 2, |
| + |
| + /** |
| + Defined by MatrixCoefficients/TransferCharacteristics. |
| + */ |
| + kDerived = 3, |
| +}; |
| + |
| +/** |
| + A parsed \WebMID{TransferCharacteristics} element. |
| + |
| + Matroska/WebM adopted these values from Table 3 of ISO/IEC 23001-8:2013/DCOR1. |
| + See that document for further details. |
| + */ |
| +enum class TransferCharacteristics : std::uint64_t { |
| + /** |
| + Rec. ITU-R BT.709-6. |
| + */ |
| + kBt709 = 1, |
| + |
| + /** |
| + Image characteristics are unknown or are determined by the application. |
| + */ |
| + kUnspecified = 2, |
| + |
| + /** |
| + Rec. ITU‑R BT.470‑6 System M (historical) with assumed display gamma 2.2. |
| + */ |
| + kGamma22curve = 4, |
| + |
| + /** |
| + Rec. ITU‑R BT.470-6 System B, G (historical) with assumed display gamma 2.8. |
| + */ |
| + kGamma28curve = 5, |
| + |
| + /** |
| + Society of Motion Picture and Television Engineers 170M (2004). |
| + */ |
| + kSmpte170M = 6, |
| + |
| + /** |
| + Society of Motion Picture and Television Engineers 240M (1999). |
| + */ |
| + kSmpte240M = 7, |
| + |
| + /** |
| + Linear transfer characteristics. |
| + */ |
| + kLinear = 8, |
| + |
| + /** |
| + Logarithmic transfer characteristic (100:1 range). |
| + */ |
| + kLog = 9, |
| + |
| + /** |
| + Logarithmic transfer characteristic (100 * Sqrt(10) : 1 range). |
| + */ |
| + kLogSqrt = 10, |
| + |
| + /** |
| + IEC 61966-2-4. |
| + */ |
| + kIec6196624 = 11, |
| + |
| + /** |
| + Rec. ITU‑R BT.1361-0 extended colour gamut system (historical). |
| + */ |
| + kBt1361ExtendedColourGamut = 12, |
| + |
| + /** |
| + IEC 61966-2-1 sRGB or sYCC. |
| + */ |
| + kIec6196621 = 13, |
| + |
| + /** |
| + Rec. ITU-R BT.2020-2 (10-bit system). |
| + */ |
| + k10BitBt2020 = 14, |
| + |
| + /** |
| + Rec. ITU-R BT.2020-2 (12-bit system). |
| + */ |
| + k12BitBt2020 = 15, |
| + |
| + /** |
| + Society of Motion Picture and Television Engineers ST 2084. |
| + */ |
| + kSmpteSt2084 = 16, |
| + |
| + /** |
| + Society of Motion Picture and Television Engineers ST 428-1. |
| + */ |
| + kSmpteSt4281 = 17, |
| + |
| + /** |
| + Association of Radio Industries and Businesses (ARIB) STD-B67. |
| + */ |
| + kAribStdB67Hlg = 18, |
| +}; |
| + |
| +/** |
| + A parsed \WebMID{Primaries} element. |
| + |
| + Matroska/WebM adopted these values from Table 2 of ISO/IEC 23001-8:2013/DCOR1. |
| + See that document for further details. |
| + */ |
| +enum class Primaries : std::uint64_t { |
| + /** |
| + Rec. ITU‑R BT.709-6. |
| + */ |
| + kBt709 = 1, |
| + |
| + /** |
| + Image characteristics are unknown or are determined by the application. |
| + */ |
| + kUnspecified = 2, |
| + |
| + /** |
| + Rec. ITU‑R BT.470‑6 System M (historical). |
| + */ |
| + kBt470M = 4, |
| + |
| + /** |
| + Rec. ITU‑R BT.470‑6 System B, G (historical). |
| + */ |
| + kBt470Bg = 5, |
| + |
| + /** |
| + Society of Motion Picture and Television Engineers 170M (2004). |
| + */ |
| + kSmpte170M = 6, |
| + |
| + /** |
| + Society of Motion Picture and Television Engineers 240M (1999). |
| + */ |
| + kSmpte240M = 7, |
| + |
| + /** |
| + Generic film. |
| + */ |
| + kFilm = 8, |
| + |
| + /** |
| + Rec. ITU-R BT.2020-2. |
| + */ |
| + kBt2020 = 9, |
| + |
| + /** |
| + Society of Motion Picture and Television Engineers ST 428-1. |
| + */ |
| + kSmpteSt4281 = 10, |
| + |
| + /** |
| + JEDEC P22 phosphors/EBU Tech. 3213-E (1975). |
| + */ |
| + kJedecP22Phosphors = 22, |
| +}; |
| + |
| +// ---- End copy/paste from libwebm/webm_parser/include/webm/dom_types.h ---- |
| + |
| +gfx::ColorSpace::MatrixID FromWebMMatrixCoefficients(MatrixCoefficients c) { |
| + switch (c) { |
| + case MatrixCoefficients::kRgb: |
| + return gfx::ColorSpace::MatrixID::RGB; |
| + case MatrixCoefficients::kBt709: |
| + return gfx::ColorSpace::MatrixID::BT709; |
| + case MatrixCoefficients::kUnspecified: |
| + return gfx::ColorSpace::MatrixID::UNSPECIFIED; |
| + case MatrixCoefficients::kFcc: |
| + return gfx::ColorSpace::MatrixID::FCC; |
| + case MatrixCoefficients::kBt470Bg: |
| + return gfx::ColorSpace::MatrixID::BT470BG; |
| + case MatrixCoefficients::kSmpte170M: |
| + return gfx::ColorSpace::MatrixID::SMPTE170M; |
| + case MatrixCoefficients::kSmpte240M: |
| + return gfx::ColorSpace::MatrixID::SMPTE240M; |
| + case MatrixCoefficients::kYCgCo: |
| + return gfx::ColorSpace::MatrixID::YCOCG; |
| + case MatrixCoefficients::kBt2020NonconstantLuminance: |
| + return gfx::ColorSpace::MatrixID::BT2020_NCL; |
| + case MatrixCoefficients::kBt2020ConstantLuminance: |
| + return gfx::ColorSpace::MatrixID::BT2020_CL; |
| + } |
| + NOTREACHED(); |
| + return gfx::ColorSpace::MatrixID::UNSPECIFIED; |
| +} |
| + |
| +gfx::ColorSpace::RangeID FromWebMRange(Range range) { |
| + switch (range) { |
| + case Range::kUnspecified: |
| + return gfx::ColorSpace::RangeID::UNSPECIFIED; |
| + case Range::kBroadcast: |
| + return gfx::ColorSpace::RangeID::LIMITED; |
| + case Range::kFull: |
| + return gfx::ColorSpace::RangeID::FULL; |
| + case Range::kDerived: |
| + return gfx::ColorSpace::RangeID::DERIVED; |
| + } |
| + NOTREACHED(); |
| + return gfx::ColorSpace::RangeID::UNSPECIFIED; |
| +} |
| + |
|
hubbe
2016/09/21 20:25:44
Since these should line up exactly in all cases, i
servolk
2016/09/21 20:53:22
Yeah, I was thinking about whether it's better to
servolk
2016/09/21 21:11:27
Yup, sorry, I meant static_assert. I'll convert th
servolk
2016/09/21 22:05:06
Done.
|
| +gfx::ColorSpace::TransferID FromWebMTransferCharacteristics( |
| + TransferCharacteristics tc) { |
| + switch (tc) { |
| + case TransferCharacteristics::kBt709: |
| + return gfx::ColorSpace::TransferID::BT709; |
| + case TransferCharacteristics::kUnspecified: |
| + return gfx::ColorSpace::TransferID::UNSPECIFIED; |
| + case TransferCharacteristics::kGamma22curve: |
| + return gfx::ColorSpace::TransferID::GAMMA22; |
| + case TransferCharacteristics::kGamma28curve: |
| + return gfx::ColorSpace::TransferID::GAMMA28; |
| + case TransferCharacteristics::kSmpte170M: |
| + return gfx::ColorSpace::TransferID::SMPTE170M; |
| + case TransferCharacteristics::kSmpte240M: |
| + return gfx::ColorSpace::TransferID::SMPTE240M; |
| + case TransferCharacteristics::kLinear: |
| + return gfx::ColorSpace::TransferID::LINEAR; |
| + case TransferCharacteristics::kLog: |
| + return gfx::ColorSpace::TransferID::LOG; |
| + case TransferCharacteristics::kLogSqrt: |
| + return gfx::ColorSpace::TransferID::LOG_SQRT; |
| + case TransferCharacteristics::kIec6196624: |
| + return gfx::ColorSpace::TransferID::IEC61966_2_4; |
| + case TransferCharacteristics::kBt1361ExtendedColourGamut: |
| + return gfx::ColorSpace::TransferID::BT1361_ECG; |
| + case TransferCharacteristics::kIec6196621: |
| + return gfx::ColorSpace::TransferID::IEC61966_2_1; |
| + case TransferCharacteristics::k10BitBt2020: |
| + return gfx::ColorSpace::TransferID::BT2020_10; |
| + case TransferCharacteristics::k12BitBt2020: |
| + return gfx::ColorSpace::TransferID::BT2020_12; |
| + case TransferCharacteristics::kSmpteSt2084: |
| + return gfx::ColorSpace::TransferID::SMPTEST2084; |
| + case TransferCharacteristics::kSmpteSt4281: |
| + return gfx::ColorSpace::TransferID::SMPTEST428_1; |
| + case TransferCharacteristics::kAribStdB67Hlg: |
| + return gfx::ColorSpace::TransferID::ARIB_STD_B67; |
| + } |
| + NOTREACHED(); |
| + return gfx::ColorSpace::TransferID::UNSPECIFIED; |
| +} |
| + |
| +gfx::ColorSpace::PrimaryID FromWebMPrimaries(Primaries primaries) { |
| + switch (primaries) { |
| + case Primaries::kBt709: |
| + return gfx::ColorSpace::PrimaryID::BT709; |
| + case Primaries::kUnspecified: |
| + return gfx::ColorSpace::PrimaryID::UNSPECIFIED; |
| + case Primaries::kBt470M: |
| + return gfx::ColorSpace::PrimaryID::BT470M; |
| + case Primaries::kBt470Bg: |
| + return gfx::ColorSpace::PrimaryID::BT470BG; |
| + case Primaries::kSmpte170M: |
| + return gfx::ColorSpace::PrimaryID::SMPTE170M; |
| + case Primaries::kSmpte240M: |
| + return gfx::ColorSpace::PrimaryID::SMPTE240M; |
| + case Primaries::kFilm: |
| + return gfx::ColorSpace::PrimaryID::FILM; |
| + case Primaries::kBt2020: |
| + return gfx::ColorSpace::PrimaryID::BT2020; |
| + case Primaries::kSmpteSt4281: |
| + return gfx::ColorSpace::PrimaryID::SMPTEST428_1; |
| + case Primaries::kJedecP22Phosphors: |
| + return gfx::ColorSpace::PrimaryID::UNSPECIFIED; |
| + } |
| + NOTREACHED(); |
| + return gfx::ColorSpace::PrimaryID::UNSPECIFIED; |
| +} |
| + |
| +WebMColorMetadata::WebMColorMetadata() {} |
| +WebMColorMetadata::WebMColorMetadata(const WebMColorMetadata& rhs) = default; |
| + |
| +WebMMasteringMetadataParser::WebMMasteringMetadataParser() {} |
| +WebMMasteringMetadataParser::~WebMMasteringMetadataParser() {} |
| + |
| +bool WebMMasteringMetadataParser::OnFloat(int id, double val) { |
| + switch (id) { |
| + case kWebMIdPrimaryRChromaticityX: |
| + mastering_metadata_.primary_r_chromaticity_x = val; |
| + break; |
| + case kWebMIdPrimaryRChromaticityY: |
| + mastering_metadata_.primary_r_chromaticity_y = val; |
| + break; |
| + case kWebMIdPrimaryGChromaticityX: |
| + mastering_metadata_.primary_g_chromaticity_x = val; |
| + break; |
| + case kWebMIdPrimaryGChromaticityY: |
| + mastering_metadata_.primary_g_chromaticity_y = val; |
| + break; |
| + case kWebMIdPrimaryBChromaticityX: |
| + mastering_metadata_.primary_b_chromaticity_x = val; |
| + break; |
| + case kWebMIdPrimaryBChromaticityY: |
| + mastering_metadata_.primary_b_chromaticity_y = val; |
| + break; |
| + case kWebMIdWhitePointChromaticityX: |
| + mastering_metadata_.white_point_chromaticity_x = val; |
| + break; |
| + case kWebMIdWhitePointChromaticityY: |
| + mastering_metadata_.white_point_chromaticity_y = val; |
| + break; |
| + case kWebMIdLuminanceMax: |
| + mastering_metadata_.luminance_max = val; |
| + break; |
| + case kWebMIdLuminanceMin: |
| + mastering_metadata_.luminance_min = val; |
| + break; |
| + default: |
| + DVLOG(1) << "Unexpected id in MasteringMetadata: 0x" << std::hex << id; |
| + return false; |
| + } |
| + return true; |
| +} |
| + |
| +WebMColourParser::WebMColourParser() { |
| + Reset(); |
| +} |
| + |
| +WebMColourParser::~WebMColourParser() {} |
| + |
| +void WebMColourParser::Reset() { |
| + matrix_coefficients_ = -1; |
| + bits_per_channel_ = -1; |
| + chroma_subsampling_horz_ = -1; |
| + chroma_subsampling_vert_ = -1; |
| + cb_subsampling_horz_ = -1; |
| + cb_subsampling_vert_ = -1; |
| + chroma_siting_horz_ = -1; |
| + chroma_siting_vert_ = -1; |
| + range_ = -1; |
| + transfer_characteristics_ = -1; |
| + primaries_ = -1; |
| + max_cll_ = -1; |
| + max_fall_ = -1; |
| +} |
| + |
| +WebMParserClient* WebMColourParser::OnListStart(int id) { |
| + if (id == kWebMIdMasteringMetadata) { |
| + mastering_metadata_parsed_ = false; |
| + return &mastering_metadata_parser_; |
| + } |
| + |
| + return this; |
| +} |
| + |
| +bool WebMColourParser::OnListEnd(int id) { |
| + if (id == kWebMIdMasteringMetadata) |
| + mastering_metadata_parsed_ = true; |
| + return true; |
| +} |
| + |
| +bool WebMColourParser::OnUInt(int id, int64_t val) { |
| + int64_t* dst = nullptr; |
| + |
| + switch (id) { |
| + case kWebMIdMatrixCoefficients: |
| + dst = &matrix_coefficients_; |
| + break; |
| + case kWebMIdBitsPerChannel: |
| + dst = &bits_per_channel_; |
| + break; |
| + case kWebMIdChromaSubsamplingHorz: |
| + dst = &chroma_subsampling_horz_; |
| + break; |
| + case kWebMIdChromaSubsamplingVert: |
| + dst = &chroma_subsampling_vert_; |
| + break; |
| + case kWebMIdCbSubsamplingHorz: |
| + dst = &cb_subsampling_horz_; |
| + break; |
| + case kWebMIdCbSubsamplingVert: |
| + dst = &cb_subsampling_vert_; |
| + break; |
| + case kWebMIdChromaSitingHorz: |
| + dst = &chroma_siting_horz_; |
| + break; |
| + case kWebMIdChromaSitingVert: |
| + dst = &chroma_siting_vert_; |
| + break; |
| + case kWebMIdRange: |
| + dst = &range_; |
| + break; |
| + case kWebMIdTransferCharacteristics: |
| + dst = &transfer_characteristics_; |
| + break; |
| + case kWebMIdPrimaries: |
| + dst = &primaries_; |
| + break; |
| + case kWebMIdMaxCLL: |
| + dst = &max_cll_; |
| + break; |
| + case kWebMIdMaxFALL: |
| + dst = &max_fall_; |
| + break; |
| + default: |
| + return true; |
| + } |
| + |
| + DCHECK(dst); |
| + if (*dst != -1) { |
| + LOG(ERROR) << "Multiple values for id " << std::hex << id << " specified (" |
| + << *dst << " and " << val << ")"; |
| + return false; |
| + } |
| + |
| + *dst = val; |
| + return true; |
| +} |
| + |
| +WebMColorMetadata WebMColourParser::GetWebMColorMetadata() const { |
| + WebMColorMetadata color_metadata; |
| + |
| + if (bits_per_channel_ != -1) |
| + color_metadata.BitsPerChannel = bits_per_channel_; |
| + |
| + if (chroma_subsampling_horz_ != -1) |
| + color_metadata.ChromaSubsamplingHorz = chroma_subsampling_horz_; |
| + if (chroma_subsampling_vert_ != -1) |
| + color_metadata.ChromaSubsamplingVert = chroma_subsampling_vert_; |
| + if (cb_subsampling_horz_ != -1) |
| + color_metadata.CbSubsamplingHorz = cb_subsampling_horz_; |
| + if (cb_subsampling_vert_ != -1) |
| + color_metadata.CbSubsamplingVert = cb_subsampling_vert_; |
| + if (chroma_siting_horz_ != -1) |
| + color_metadata.ChromaSitingHorz = chroma_siting_horz_; |
| + if (chroma_siting_vert_ != -1) |
| + color_metadata.ChromaSitingVert = chroma_siting_vert_; |
| + |
| + gfx::ColorSpace::MatrixID matrix_id = gfx::ColorSpace::MatrixID::UNSPECIFIED; |
| + if (matrix_coefficients_ != -1) |
| + matrix_id = FromWebMMatrixCoefficients( |
| + static_cast<MatrixCoefficients>(matrix_coefficients_)); |
| + |
| + gfx::ColorSpace::RangeID range_id = gfx::ColorSpace::RangeID::UNSPECIFIED; |
| + if (range_ != -1) |
| + range_id = FromWebMRange(static_cast<Range>(range_)); |
| + |
| + gfx::ColorSpace::TransferID transfer_id = |
| + gfx::ColorSpace::TransferID::UNSPECIFIED; |
| + if (transfer_characteristics_ != -1) |
| + transfer_id = FromWebMTransferCharacteristics( |
| + static_cast<TransferCharacteristics>(transfer_characteristics_)); |
| + |
| + gfx::ColorSpace::PrimaryID primary_id = |
| + gfx::ColorSpace::PrimaryID::UNSPECIFIED; |
| + if (primaries_ != -1) |
| + primary_id = FromWebMPrimaries(static_cast<Primaries>(primaries_)); |
| + |
| + color_metadata.color_space = |
| + gfx::ColorSpace(primary_id, transfer_id, matrix_id, range_id); |
| + |
| + if (max_cll_ != -1) |
| + color_metadata.hdr_metadata.max_cll = max_cll_; |
| + |
| + if (max_fall_ != -1) |
| + color_metadata.hdr_metadata.max_fall = max_fall_; |
| + |
| + if (mastering_metadata_parsed_) |
| + color_metadata.hdr_metadata.mastering_metadata = |
| + mastering_metadata_parser_.GetMasteringMetadata(); |
| + |
| + return color_metadata; |
| +} |
| + |
| +} // namespace media |