// 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 #include #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(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