| // 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 "hdr_util.h" | |
| #include <cstddef> | |
| #include <new> | |
| #include "mkvparser/mkvparser.h" | |
| namespace libwebm { | |
| bool CopyPrimaryChromaticity(const mkvparser::PrimaryChromaticity& parser_pc, | |
| PrimaryChromaticityPtr* muxer_pc) { | |
| muxer_pc->reset(new (std::nothrow) | |
| mkvmuxer::PrimaryChromaticity(parser_pc.x, parser_pc.y)); | |
| if (!muxer_pc->get()) | |
| return false; | |
| return true; | |
| } | |
| bool MasteringMetadataValuePresent(double value) { | |
| return value != mkvparser::MasteringMetadata::kValueNotPresent; | |
| } | |
| bool CopyMasteringMetadata(const mkvparser::MasteringMetadata& parser_mm, | |
| mkvmuxer::MasteringMetadata* muxer_mm) { | |
| if (MasteringMetadataValuePresent(parser_mm.luminance_max)) | |
| muxer_mm->luminance_max = parser_mm.luminance_max; | |
| if (MasteringMetadataValuePresent(parser_mm.luminance_min)) | |
| muxer_mm->luminance_min = parser_mm.luminance_min; | |
| PrimaryChromaticityPtr r_ptr(NULL); | |
| PrimaryChromaticityPtr g_ptr(NULL); | |
| PrimaryChromaticityPtr b_ptr(NULL); | |
| PrimaryChromaticityPtr wp_ptr(NULL); | |
| if (parser_mm.r) { | |
| if (!CopyPrimaryChromaticity(*parser_mm.r, &r_ptr)) | |
| return false; | |
| } | |
| if (parser_mm.g) { | |
| if (!CopyPrimaryChromaticity(*parser_mm.g, &g_ptr)) | |
| return false; | |
| } | |
| if (parser_mm.b) { | |
| if (!CopyPrimaryChromaticity(*parser_mm.b, &b_ptr)) | |
| return false; | |
| } | |
| if (parser_mm.white_point) { | |
| if (!CopyPrimaryChromaticity(*parser_mm.white_point, &wp_ptr)) | |
| return false; | |
| } | |
| if (!muxer_mm->SetChromaticity(r_ptr.get(), g_ptr.get(), b_ptr.get(), | |
| wp_ptr.get())) { | |
| return false; | |
| } | |
| return true; | |
| } | |
| bool ColourValuePresent(long long value) { | |
| return value != mkvparser::Colour::kValueNotPresent; | |
| } | |
| bool CopyColour(const mkvparser::Colour& parser_colour, | |
| mkvmuxer::Colour* muxer_colour) { | |
| if (!muxer_colour) | |
| return false; | |
| if (ColourValuePresent(parser_colour.matrix_coefficients)) | |
| muxer_colour->matrix_coefficients = parser_colour.matrix_coefficients; | |
| if (ColourValuePresent(parser_colour.bits_per_channel)) | |
| muxer_colour->bits_per_channel = parser_colour.bits_per_channel; | |
| if (ColourValuePresent(parser_colour.chroma_subsampling_horz)) | |
| muxer_colour->chroma_subsampling_horz = | |
| parser_colour.chroma_subsampling_horz; | |
| if (ColourValuePresent(parser_colour.chroma_subsampling_vert)) | |
| muxer_colour->chroma_subsampling_vert = | |
| parser_colour.chroma_subsampling_vert; | |
| if (ColourValuePresent(parser_colour.cb_subsampling_horz)) | |
| muxer_colour->cb_subsampling_horz = parser_colour.cb_subsampling_horz; | |
| if (ColourValuePresent(parser_colour.cb_subsampling_vert)) | |
| muxer_colour->cb_subsampling_vert = parser_colour.cb_subsampling_vert; | |
| if (ColourValuePresent(parser_colour.chroma_siting_horz)) | |
| muxer_colour->chroma_siting_horz = parser_colour.chroma_siting_horz; | |
| if (ColourValuePresent(parser_colour.chroma_siting_vert)) | |
| muxer_colour->chroma_siting_vert = parser_colour.chroma_siting_vert; | |
| if (ColourValuePresent(parser_colour.range)) | |
| muxer_colour->range = parser_colour.range; | |
| if (ColourValuePresent(parser_colour.transfer_characteristics)) | |
| muxer_colour->transfer_characteristics = | |
| parser_colour.transfer_characteristics; | |
| if (ColourValuePresent(parser_colour.primaries)) | |
| muxer_colour->primaries = parser_colour.primaries; | |
| if (ColourValuePresent(parser_colour.max_cll)) | |
| muxer_colour->max_cll = parser_colour.max_cll; | |
| if (ColourValuePresent(parser_colour.max_fall)) | |
| muxer_colour->max_fall = parser_colour.max_fall; | |
| if (parser_colour.mastering_metadata) { | |
| mkvmuxer::MasteringMetadata muxer_mm; | |
| if (!CopyMasteringMetadata(*parser_colour.mastering_metadata, &muxer_mm)) | |
| return false; | |
| if (!muxer_colour->SetMasteringMetadata(muxer_mm)) | |
| return false; | |
| } | |
| return true; | |
| } | |
| // Format of VPx private data: | |
| // | |
| // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 | |
| // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |
| // | ID Byte | Length | | | |
| // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | | |
| // | | | |
| // : Bytes 1..Length of Codec Feature : | |
| // | | | |
| // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |
| // | |
| // ID Byte Format | |
| // ID byte is an unsigned byte. | |
| // 0 1 2 3 4 5 6 7 | |
| // +-+-+-+-+-+-+-+-+ | |
| // |X| ID | | |
| // +-+-+-+-+-+-+-+-+ | |
| // | |
| // The X bit is reserved. | |
| // | |
| // Currently only profile level is supported. ID byte must be set to 1, and | |
| // length must be 1. Supported values are: | |
| // | |
| // 10: Level 1 | |
| // 11: Level 1.1 | |
| // 20: Level 2 | |
| // 21: Level 2.1 | |
| // 30: Level 3 | |
| // 31: Level 3.1 | |
| // 40: Level 4 | |
| // 41: Level 4.1 | |
| // 50: Level 5 | |
| // 51: Level 5.1 | |
| // 52: Level 5.2 | |
| // 60: Level 6 | |
| // 61: Level 6.1 | |
| // 62: Level 6.2 | |
| // | |
| // See the following link for more information: | |
| // http://www.webmproject.org/vp9/profiles/ | |
| int ParseVpxCodecPrivate(const uint8_t* private_data, int32_t length) { | |
| const int kVpxCodecPrivateLength = 3; | |
| if (!private_data || length != kVpxCodecPrivateLength) | |
| return 0; | |
| const uint8_t id_byte = *private_data; | |
| if (id_byte != 1) | |
| return 0; | |
| const int kVpxProfileLength = 1; | |
| const uint8_t length_byte = private_data[1]; | |
| if (length_byte != kVpxProfileLength) | |
| return 0; | |
| const int level = static_cast<int>(private_data[2]); | |
| const int kNumLevels = 14; | |
| const int levels[kNumLevels] = {10, 11, 20, 21, 30, 31, 40, | |
| 41, 50, 51, 52, 60, 61, 62}; | |
| for (int i = 0; i < kNumLevels; ++i) { | |
| if (level == levels[i]) | |
| return level; | |
| } | |
| return 0; | |
| } | |
| } // namespace libwebm |