| // Copyright 2021 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "chromecast/shared/platform_info_serializer.h" |
| |
| #include <string_view> |
| |
| #include "base/check.h" |
| #include "base/functional/callback.h" |
| #include "base/logging.h" |
| #include "chromecast/bindings/shared/proto_serializer.h" |
| |
| namespace chromecast { |
| namespace { |
| bool IsOutOfRange(int value, int min, int max) { |
| return min > value || max < value; |
| } |
| } // namespace |
| |
| PlatformInfoSerializer::PlatformInfoSerializer() = default; |
| |
| PlatformInfoSerializer::PlatformInfoSerializer(PlatformInfoSerializer&& other) = |
| default; |
| |
| PlatformInfoSerializer::~PlatformInfoSerializer() = default; |
| |
| PlatformInfoSerializer& PlatformInfoSerializer::operator=( |
| PlatformInfoSerializer&& other) = default; |
| |
| // static |
| std::optional<PlatformInfoSerializer> PlatformInfoSerializer::Deserialize( |
| std::string_view base64) { |
| std::optional<cast::bindings::MediaCapabilitiesMessage> proto = |
| chromecast::bindings::ProtoSerializer< |
| cast::bindings::MediaCapabilitiesMessage>::Deserialize(base64); |
| if (!proto) { |
| return std::nullopt; |
| } |
| |
| PlatformInfoSerializer parser; |
| parser.platform_info_ = std::move(*proto); |
| return parser; |
| } |
| |
| std::string PlatformInfoSerializer::Serialize() const { |
| return chromecast::bindings::ProtoSerializer< |
| cast::bindings::MediaCapabilitiesMessage>::Serialize(platform_info_); |
| } |
| |
| void PlatformInfoSerializer::SetMaxWidth(int max_width) { |
| platform_info_.set_max_width(max_width); |
| } |
| |
| void PlatformInfoSerializer::SetMaxHeight(int max_height) { |
| platform_info_.set_max_height(max_height); |
| } |
| |
| void PlatformInfoSerializer::SetMaxFrameRate(int max_frame_rate) { |
| platform_info_.set_max_frame_rate(max_frame_rate); |
| } |
| |
| void PlatformInfoSerializer::SetSupportedCryptoBlockFormat( |
| const std::string& format) { |
| platform_info_.set_supported_cryptoblock_format(format); |
| } |
| |
| void PlatformInfoSerializer::SetMaxChannels(int max_channels) { |
| platform_info_.set_max_channels(max_channels); |
| } |
| |
| void PlatformInfoSerializer::SetPcmSurroundSoundSupported(bool is_supported) { |
| platform_info_.set_is_pcm_surround_sound_supported(is_supported); |
| } |
| |
| void PlatformInfoSerializer::SetPlatformDolbyVisionEnabled(bool is_enabled) { |
| platform_info_.set_is_platform_dolby_vision_enabled(is_enabled); |
| } |
| |
| void PlatformInfoSerializer::SetDolbyVisionSupported(bool is_supported) { |
| platform_info_.set_is_dolby_vision_supported(is_supported); |
| } |
| |
| void PlatformInfoSerializer::SetDolbyVision4kP60Supported(bool is_supported) { |
| platform_info_.set_is_dolby_vision4k_p60_supported(is_supported); |
| } |
| |
| void PlatformInfoSerializer::SetDolbyVisionSupportedByCurrentHdmiMode( |
| bool is_supported) { |
| platform_info_.set_is_dolby_vision_supported_by_current_hdmi_mode( |
| is_supported); |
| } |
| |
| void PlatformInfoSerializer::SetHdmiVideoModeSwitchEnabled(bool is_enabled) { |
| platform_info_.set_is_hdmi_video_mode_switch_enabled(is_enabled); |
| } |
| |
| void PlatformInfoSerializer::SetPlatformHevcEnabled(bool is_enabled) { |
| platform_info_.set_is_platform_hevc_enabled(is_enabled); |
| } |
| |
| void PlatformInfoSerializer::SetHdmiModeHdrCheckEnforced(bool is_enforced) { |
| platform_info_.set_is_hdmi_mode_hdr_check_enforced(is_enforced); |
| } |
| |
| void PlatformInfoSerializer::SetHdrSupportedByCurrentHdmiMode( |
| bool is_supported) { |
| platform_info_.set_is_hdr_supported_by_current_hdmi_mode(is_supported); |
| } |
| |
| void PlatformInfoSerializer::SetSmpteSt2084Supported(bool is_supported) { |
| platform_info_.set_is_smpte_st2084_supported(is_supported); |
| } |
| |
| void PlatformInfoSerializer::SetHlgSupported(bool is_supported) { |
| platform_info_.set_is_hlg_supported(is_supported); |
| } |
| |
| void PlatformInfoSerializer::SetHdrFeatureEnabled(bool is_enabled) { |
| platform_info_.set_is_hdr_feature_enabled(is_enabled); |
| } |
| |
| void PlatformInfoSerializer::SetSupportedLegacyVp9Levels( |
| std::vector<int> levels) { |
| platform_info_.clear_supported_legacy_vp9_levels(); |
| for (int level : levels) { |
| platform_info_.add_supported_legacy_vp9_levels(level); |
| } |
| } |
| |
| void PlatformInfoSerializer::SetHdcpVersion(int hdcp_version) { |
| platform_info_.set_hdcp_version(hdcp_version); |
| } |
| |
| void PlatformInfoSerializer::SetSpatialRenderingSupportMask(int mask) { |
| platform_info_.set_spatial_rendering_support_mask(mask); |
| } |
| |
| void PlatformInfoSerializer::SetMaxFillRate(int max_fill_rate) { |
| platform_info_.set_max_fill_rate(max_fill_rate); |
| } |
| |
| void PlatformInfoSerializer::SetSupportedAudioCodecs( |
| std::vector<AudioCodecInfo> codec_infos) { |
| platform_info_.clear_supported_audio_codecs(); |
| for (const auto& element : codec_infos) { |
| cast::bindings::AudioCodecInfo info; |
| DCHECK(cast::bindings::AudioCodecInfo::AudioCodec_IsValid(element.codec)); |
| DCHECK(cast::bindings::AudioCodecInfo::SampleFormat_IsValid( |
| element.sample_format)); |
| info.set_codec( |
| cast::bindings::AudioCodecInfo::AudioCodec_IsValid(element.codec) |
| ? static_cast<cast::bindings::AudioCodecInfo::AudioCodec>( |
| element.codec) |
| : cast::bindings::AudioCodecInfo::AUDIO_CODEC_UNKNOWN); |
| info.set_sample_format( |
| cast::bindings::AudioCodecInfo::SampleFormat_IsValid( |
| element.sample_format) |
| ? static_cast<cast::bindings::AudioCodecInfo::SampleFormat>( |
| element.sample_format) |
| : cast::bindings::AudioCodecInfo::SAMPLE_FORMAT_UNKNOWN); |
| info.set_max_samples_per_second(element.max_samples_per_second); |
| info.set_max_audio_channels(element.max_audio_channels); |
| *platform_info_.add_supported_audio_codecs() = std::move(info); |
| } |
| } |
| |
| void PlatformInfoSerializer::SetSupportedVideoCodecs( |
| std::vector<VideoCodecInfo> codec_infos) { |
| for (auto& element : codec_infos) { |
| cast::bindings::VideoCodecInfo info; |
| DCHECK(cast::bindings::VideoCodecInfo::VideoCodec_IsValid(element.codec)); |
| DCHECK( |
| cast::bindings::VideoCodecInfo::VideoProfile_IsValid(element.profile)); |
| info.set_codec( |
| cast::bindings::VideoCodecInfo::VideoCodec_IsValid(element.codec) |
| ? static_cast<cast::bindings::VideoCodecInfo::VideoCodec>( |
| element.codec) |
| : cast::bindings::VideoCodecInfo::VIDEO_CODEC_UNKNOWN); |
| info.set_profile( |
| cast::bindings::VideoCodecInfo::VideoProfile_IsValid(element.profile) |
| ? static_cast<cast::bindings::VideoCodecInfo::VideoProfile>( |
| element.profile) |
| : cast::bindings::VideoCodecInfo::VIDEO_PROFILE_UNKNOWN); |
| *platform_info_.add_supported_video_codecs() = std::move(info); |
| } |
| } |
| |
| std::optional<int> PlatformInfoSerializer::MaxWidth() const { |
| return platform_info_.max_width(); |
| } |
| |
| std::optional<int> PlatformInfoSerializer::MaxHeight() const { |
| return platform_info_.max_height(); |
| } |
| |
| std::optional<int> PlatformInfoSerializer::MaxFrameRate() const { |
| return platform_info_.max_frame_rate(); |
| } |
| |
| std::optional<std::string> PlatformInfoSerializer::SupportedCryptoBlockFormat() |
| const { |
| return platform_info_.supported_cryptoblock_format(); |
| } |
| |
| std::optional<int> PlatformInfoSerializer::MaxChannels() const { |
| return platform_info_.max_channels(); |
| } |
| |
| std::optional<bool> PlatformInfoSerializer::PcmSurroundSoundSupported() const { |
| return platform_info_.is_pcm_surround_sound_supported(); |
| } |
| |
| std::optional<bool> PlatformInfoSerializer::IsPlatformDolbyVisionEnabled() |
| const { |
| return platform_info_.is_platform_dolby_vision_enabled(); |
| } |
| |
| std::optional<bool> PlatformInfoSerializer::IsDolbyVisionSupported() const { |
| return platform_info_.is_dolby_vision_supported(); |
| } |
| |
| std::optional<bool> PlatformInfoSerializer::IsDolbyVision4kP60Supported() |
| const { |
| return platform_info_.is_dolby_vision4k_p60_supported(); |
| } |
| |
| std::optional<bool> |
| PlatformInfoSerializer::IsDolbyVisionSupportedByCurrentHdmiMode() const { |
| return platform_info_.is_dolby_vision_supported_by_current_hdmi_mode(); |
| } |
| |
| std::optional<bool> PlatformInfoSerializer::IsHdmiVideoModeSwitchEnabled() |
| const { |
| return platform_info_.is_hdmi_video_mode_switch_enabled(); |
| } |
| |
| std::optional<bool> PlatformInfoSerializer::IsPlatformHevcEnabled() const { |
| return platform_info_.is_platform_hevc_enabled(); |
| } |
| |
| std::optional<bool> PlatformInfoSerializer::IsHdmiModeHdrCheckEnforced() const { |
| return platform_info_.is_hdmi_mode_hdr_check_enforced(); |
| } |
| |
| std::optional<bool> PlatformInfoSerializer::IsHdrSupportedByCurrentHdmiMode() |
| const { |
| return platform_info_.is_hdr_supported_by_current_hdmi_mode(); |
| } |
| |
| std::optional<bool> PlatformInfoSerializer::IsSmpteSt2084Supported() const { |
| return platform_info_.is_smpte_st2084_supported(); |
| } |
| |
| std::optional<bool> PlatformInfoSerializer::IsHlgSupported() const { |
| return platform_info_.is_hlg_supported(); |
| } |
| |
| std::optional<bool> PlatformInfoSerializer::IsHdrFeatureEnabled() const { |
| return platform_info_.is_hdr_feature_enabled(); |
| } |
| |
| std::optional<std::vector<int>> |
| PlatformInfoSerializer::SupportedLegacyVp9Levels() const { |
| std::vector<int> levels; |
| levels.reserve(platform_info_.supported_legacy_vp9_levels_size()); |
| for (const auto& level : platform_info_.supported_legacy_vp9_levels()) { |
| levels.push_back(level); |
| } |
| |
| return levels; |
| } |
| |
| std::optional<int> PlatformInfoSerializer::HdcpVersion() const { |
| return platform_info_.hdcp_version(); |
| } |
| |
| std::optional<int> PlatformInfoSerializer::SpatialRenderingSupportMask() const { |
| return platform_info_.spatial_rendering_support_mask(); |
| } |
| |
| std::optional<int> PlatformInfoSerializer::MaxFillRate() const { |
| return platform_info_.max_fill_rate(); |
| } |
| |
| std::optional<std::vector<PlatformInfoSerializer::AudioCodecInfo>> |
| PlatformInfoSerializer::SupportedAudioCodecs() const { |
| std::vector<AudioCodecInfo> infos; |
| infos.reserve(platform_info_.supported_audio_codecs_size()); |
| for (const auto& info : platform_info_.supported_audio_codecs()) { |
| if (IsOutOfRange(info.codec(), media::AudioCodec::kAudioCodecMin, |
| media::AudioCodec::kAudioCodecMax)) { |
| LOG(WARNING) << "Unrecognized AudioCodec: " << info.codec(); |
| continue; |
| } |
| |
| if (IsOutOfRange(info.sample_format(), |
| media::SampleFormat::kSampleFormatMin, |
| media::SampleFormat::kSampleFormatMax)) { |
| LOG(WARNING) << "Unrecognized SampleFormat: " << info.sample_format(); |
| continue; |
| } |
| |
| AudioCodecInfo parsed; |
| parsed.codec = static_cast<media::AudioCodec>(info.codec()); |
| parsed.sample_format = |
| static_cast<media::SampleFormat>(info.sample_format()); |
| parsed.max_samples_per_second = info.max_samples_per_second(); |
| parsed.max_audio_channels = info.max_audio_channels(); |
| infos.push_back(std::move(parsed)); |
| } |
| |
| return infos.empty() |
| ? std::nullopt |
| : std::make_optional< |
| std::vector<PlatformInfoSerializer::AudioCodecInfo>>(infos); |
| } |
| |
| std::optional<std::vector<PlatformInfoSerializer::VideoCodecInfo>> |
| PlatformInfoSerializer::SupportedVideoCodecs() const { |
| std::vector<VideoCodecInfo> infos; |
| infos.reserve(platform_info_.supported_video_codecs_size()); |
| for (const auto& info : platform_info_.supported_video_codecs()) { |
| if (IsOutOfRange(info.codec(), media::VideoCodec::kVideoCodecMin, |
| media::VideoCodec::kVideoCodecMax)) { |
| LOG(WARNING) << "Unrecognized VideoCodec: " << info.codec(); |
| continue; |
| } |
| |
| if (IsOutOfRange(info.profile(), media::VideoProfile::kVideoProfileMin, |
| media::VideoProfile::kVideoProfileMax)) { |
| LOG(WARNING) << "Unrecognized VideoProfile: " << info.profile(); |
| continue; |
| } |
| |
| VideoCodecInfo parsed; |
| parsed.codec = static_cast<media::VideoCodec>(info.codec()); |
| parsed.profile = static_cast<media::VideoProfile>(info.profile()); |
| infos.push_back(std::move(parsed)); |
| } |
| |
| return infos.empty() |
| ? std::nullopt |
| : std::make_optional< |
| std::vector<PlatformInfoSerializer::VideoCodecInfo>>(infos); |
| } |
| |
| bool operator==(const PlatformInfoSerializer::AudioCodecInfo& first, |
| const PlatformInfoSerializer::AudioCodecInfo& second) { |
| return first.codec == second.codec && |
| first.sample_format == second.sample_format && |
| first.max_samples_per_second == second.max_samples_per_second && |
| first.max_audio_channels == second.max_audio_channels; |
| } |
| |
| bool operator==(const PlatformInfoSerializer::VideoCodecInfo& first, |
| const PlatformInfoSerializer::VideoCodecInfo& second) { |
| return first.codec == second.codec && first.profile == second.profile; |
| } |
| |
| } // namespace chromecast |