Add setters to ColorSpace class
Color space information will be transmitted as uint8_t. It's therefore necessary to convert from uint8_t to the corresponding enums. Bug: webrtc:8651 Change-Id: Ib7e7f9f6b4d7e0c291d283822180144944f3ea1e Reviewed-on: https://webrtc-review.googlesource.com/c/111757 Commit-Queue: Johannes Kron <kron@webrtc.org> Reviewed-by: Karl Wiberg <kwiberg@webrtc.org> Reviewed-by: Niels Moller <nisse@webrtc.org> Cr-Commit-Position: refs/heads/master@{#25797}
This commit is contained in:
parent
196c5ba045
commit
65c921cb4f
@ -10,6 +10,48 @@
|
||||
|
||||
#include "api/video/color_space.h"
|
||||
|
||||
namespace {
|
||||
// Try to convert |enum_value| into the enum class T. |enum_bitmask| is created
|
||||
// by the funciton below. Returns true if conversion was successful, false
|
||||
// otherwise.
|
||||
template <typename T>
|
||||
bool SetFromUint8(uint8_t enum_value, uint64_t enum_bitmask, T* out) {
|
||||
if ((enum_value < 64) && ((enum_bitmask >> enum_value) & 1)) {
|
||||
*out = static_cast<T>(enum_value);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// This function serves as an assert for the constexpr function below. It's on
|
||||
// purpose not declared as constexpr so that it causes a build problem if enum
|
||||
// values of 64 or above are used. The bitmask and the code generating it would
|
||||
// have to be extended if the standard is updated to include enum values >= 64.
|
||||
int EnumMustBeLessThan64() {
|
||||
return -1;
|
||||
}
|
||||
|
||||
template <typename T, size_t N>
|
||||
constexpr int MakeMask(const int index, const int length, T (&values)[N]) {
|
||||
return length > 1
|
||||
? (MakeMask(index, 1, values) +
|
||||
MakeMask(index + 1, length - 1, values))
|
||||
: (static_cast<uint8_t>(values[index]) < 64
|
||||
? (uint64_t{1} << static_cast<uint8_t>(values[index]))
|
||||
: EnumMustBeLessThan64());
|
||||
}
|
||||
|
||||
// Create a bitmask where each bit corresponds to one potential enum value.
|
||||
// |values| should be an array listing all possible enum values. The bit is set
|
||||
// to one if the corresponding enum exists. Only works for enums with values
|
||||
// less than 64.
|
||||
template <typename T, size_t N>
|
||||
constexpr uint64_t CreateEnumBitmask(T (&values)[N]) {
|
||||
return MakeMask(0, N, values);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
ColorSpace::ColorSpace() = default;
|
||||
@ -55,4 +97,57 @@ const HdrMetadata* ColorSpace::hdr_metadata() const {
|
||||
return hdr_metadata_ ? &*hdr_metadata_ : nullptr;
|
||||
}
|
||||
|
||||
bool ColorSpace::set_primaries_from_uint8(uint8_t enum_value) {
|
||||
constexpr PrimaryID kPrimaryIds[] = {
|
||||
PrimaryID::kInvalid, PrimaryID::kBT709, PrimaryID::kUNSPECIFIED,
|
||||
PrimaryID::kBT470M, PrimaryID::kBT470BG, PrimaryID::kSMPTE170M,
|
||||
PrimaryID::kSMPTE240M, PrimaryID::kFILM, PrimaryID::kBT2020,
|
||||
PrimaryID::kSMPTEST428, PrimaryID::kSMPTEST431, PrimaryID::kSMPTEST432,
|
||||
PrimaryID::kJEDECP22};
|
||||
constexpr uint64_t enum_bitmask = CreateEnumBitmask(kPrimaryIds);
|
||||
|
||||
return SetFromUint8(enum_value, enum_bitmask, &primaries_);
|
||||
}
|
||||
|
||||
bool ColorSpace::set_transfer_from_uint8(uint8_t enum_value) {
|
||||
constexpr TransferID kTransferIds[] = {
|
||||
TransferID::kInvalid, TransferID::kBT709,
|
||||
TransferID::kUNSPECIFIED, TransferID::kGAMMA22,
|
||||
TransferID::kGAMMA28, TransferID::kSMPTE170M,
|
||||
TransferID::kSMPTE240M, TransferID::kLINEAR,
|
||||
TransferID::kLOG, TransferID::kLOG_SQRT,
|
||||
TransferID::kIEC61966_2_4, TransferID::kBT1361_ECG,
|
||||
TransferID::kIEC61966_2_1, TransferID::kBT2020_10,
|
||||
TransferID::kBT2020_12, TransferID::kSMPTEST2084,
|
||||
TransferID::kSMPTEST428, TransferID::kARIB_STD_B67};
|
||||
constexpr uint64_t enum_bitmask = CreateEnumBitmask(kTransferIds);
|
||||
|
||||
return SetFromUint8(enum_value, enum_bitmask, &transfer_);
|
||||
}
|
||||
|
||||
bool ColorSpace::set_matrix_from_uint8(uint8_t enum_value) {
|
||||
constexpr MatrixID kMatrixIds[] = {
|
||||
MatrixID::kRGB, MatrixID::kBT709, MatrixID::kUNSPECIFIED,
|
||||
MatrixID::kFCC, MatrixID::kBT470BG, MatrixID::kSMPTE170M,
|
||||
MatrixID::kSMPTE240M, MatrixID::kYCOCG, MatrixID::kBT2020_NCL,
|
||||
MatrixID::kBT2020_CL, MatrixID::kSMPTE2085, MatrixID::kCDNCLS,
|
||||
MatrixID::kCDCLS, MatrixID::kBT2100_ICTCP, MatrixID::kInvalid};
|
||||
constexpr uint64_t enum_bitmask = CreateEnumBitmask(kMatrixIds);
|
||||
|
||||
return SetFromUint8(enum_value, enum_bitmask, &matrix_);
|
||||
}
|
||||
|
||||
bool ColorSpace::set_range_from_uint8(uint8_t enum_value) {
|
||||
constexpr RangeID kRangeIds[] = {RangeID::kInvalid, RangeID::kLimited,
|
||||
RangeID::kFull, RangeID::kDerived};
|
||||
constexpr uint64_t enum_bitmask = CreateEnumBitmask(kRangeIds);
|
||||
|
||||
return SetFromUint8(enum_value, enum_bitmask, &range_);
|
||||
}
|
||||
|
||||
void ColorSpace::set_hdr_metadata(const HdrMetadata* hdr_metadata) {
|
||||
hdr_metadata_ =
|
||||
hdr_metadata ? absl::make_optional(*hdr_metadata) : absl::nullopt;
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
@ -48,6 +48,8 @@ class ColorSpace {
|
||||
kSMPTEST431 = 11,
|
||||
kSMPTEST432 = 12,
|
||||
kJEDECP22 = 22, // Identical to EBU3213-E
|
||||
// When adding/removing entries here, please make sure to do the
|
||||
// corresponding change to kPrimaryIds.
|
||||
};
|
||||
|
||||
enum class TransferID : uint8_t {
|
||||
@ -70,6 +72,8 @@ class ColorSpace {
|
||||
kSMPTEST2084 = 16,
|
||||
kSMPTEST428 = 17,
|
||||
kARIB_STD_B67 = 18,
|
||||
// When adding/removing entries here, please make sure to do the
|
||||
// corresponding change to kTransferIds.
|
||||
};
|
||||
|
||||
enum class MatrixID : uint8_t {
|
||||
@ -88,7 +92,9 @@ class ColorSpace {
|
||||
kCDNCLS = 12,
|
||||
kCDCLS = 13,
|
||||
kBT2100_ICTCP = 14,
|
||||
kInvalid = 255
|
||||
kInvalid = 63,
|
||||
// When adding/removing entries here, please make sure to do the
|
||||
// corresponding change to kMatrixIds.
|
||||
};
|
||||
|
||||
enum class RangeID {
|
||||
@ -100,7 +106,9 @@ class ColorSpace {
|
||||
// Full RGB color range with RGB valees from 0 to 255.
|
||||
kFull = 2,
|
||||
// Range is defined by MatrixCoefficients/TransferCharacteristics.
|
||||
kDerived = 3
|
||||
kDerived = 3,
|
||||
// When adding/removing entries here, please make sure to do the
|
||||
// corresponding change to kRangeIds.
|
||||
};
|
||||
|
||||
ColorSpace();
|
||||
@ -130,6 +138,12 @@ class ColorSpace {
|
||||
RangeID range() const;
|
||||
const HdrMetadata* hdr_metadata() const;
|
||||
|
||||
bool set_primaries_from_uint8(uint8_t enum_value);
|
||||
bool set_transfer_from_uint8(uint8_t enum_value);
|
||||
bool set_matrix_from_uint8(uint8_t enum_value);
|
||||
bool set_range_from_uint8(uint8_t enum_value);
|
||||
void set_hdr_metadata(const HdrMetadata* hdr_metadata);
|
||||
|
||||
private:
|
||||
PrimaryID primaries_ = PrimaryID::kInvalid;
|
||||
TransferID transfer_ = TransferID::kInvalid;
|
||||
|
||||
@ -11,10 +11,12 @@ import("../../../webrtc.gni")
|
||||
rtc_source_set("rtc_api_video_unittests") {
|
||||
testonly = true
|
||||
sources = [
|
||||
"color_space_unittest.cc",
|
||||
"video_bitrate_allocation_unittest.cc",
|
||||
]
|
||||
deps = [
|
||||
"..:video_bitrate_allocation",
|
||||
"..:video_frame",
|
||||
"../../../test:test_support",
|
||||
]
|
||||
}
|
||||
|
||||
55
api/video/test/color_space_unittest.cc
Normal file
55
api/video/test/color_space_unittest.cc
Normal file
@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright (c) 2018 The WebRTC 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 <stdint.h>
|
||||
|
||||
#include "api/video/color_space.h"
|
||||
#include "test/gtest.h"
|
||||
|
||||
namespace webrtc {
|
||||
TEST(ColorSpace, TestSettingPrimariesFromUint8) {
|
||||
ColorSpace color_space;
|
||||
EXPECT_TRUE(color_space.set_primaries_from_uint8(
|
||||
static_cast<uint8_t>(ColorSpace::PrimaryID::kBT470BG)));
|
||||
EXPECT_EQ(ColorSpace::PrimaryID::kBT470BG, color_space.primaries());
|
||||
EXPECT_FALSE(color_space.set_primaries_from_uint8(3));
|
||||
EXPECT_FALSE(color_space.set_primaries_from_uint8(23));
|
||||
EXPECT_FALSE(color_space.set_primaries_from_uint8(64));
|
||||
}
|
||||
|
||||
TEST(ColorSpace, TestSettingTransferFromUint8) {
|
||||
ColorSpace color_space;
|
||||
EXPECT_TRUE(color_space.set_transfer_from_uint8(
|
||||
static_cast<uint8_t>(ColorSpace::TransferID::kBT2020_10)));
|
||||
EXPECT_EQ(ColorSpace::TransferID::kBT2020_10, color_space.transfer());
|
||||
EXPECT_FALSE(color_space.set_transfer_from_uint8(3));
|
||||
EXPECT_FALSE(color_space.set_transfer_from_uint8(19));
|
||||
EXPECT_FALSE(color_space.set_transfer_from_uint8(128));
|
||||
}
|
||||
|
||||
TEST(ColorSpace, TestSettingMatrixFromUint8) {
|
||||
ColorSpace color_space;
|
||||
EXPECT_TRUE(color_space.set_matrix_from_uint8(
|
||||
static_cast<uint8_t>(ColorSpace::MatrixID::kCDNCLS)));
|
||||
EXPECT_EQ(ColorSpace::MatrixID::kCDNCLS, color_space.matrix());
|
||||
EXPECT_FALSE(color_space.set_matrix_from_uint8(3));
|
||||
EXPECT_FALSE(color_space.set_matrix_from_uint8(15));
|
||||
EXPECT_FALSE(color_space.set_matrix_from_uint8(255));
|
||||
}
|
||||
|
||||
TEST(ColorSpace, TestSettingRangeFromUint8) {
|
||||
ColorSpace color_space;
|
||||
EXPECT_TRUE(color_space.set_range_from_uint8(
|
||||
static_cast<uint8_t>(ColorSpace::RangeID::kFull)));
|
||||
EXPECT_EQ(ColorSpace::RangeID::kFull, color_space.range());
|
||||
EXPECT_FALSE(color_space.set_range_from_uint8(4));
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
||||
Loading…
x
Reference in New Issue
Block a user