blob: 253e0230fff9f979dc34aaac96795daabdb9637d [file] [log] [blame]
// Copyright 2025 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/starboard/media/renderer/chromium_starboard_conversions.h"
#include <cstring>
#include <optional>
#include <vector>
#include "chromecast/starboard/media/media/starboard_api_wrapper.h"
#include "chromecast/starboard/media/media/test_matchers.h"
#include "media/base/audio_codecs.h"
#include "media/base/audio_decoder_config.h"
#include "media/base/channel_layout.h"
#include "media/base/encryption_scheme.h"
#include "media/base/sample_format.h"
#include "media/base/video_codecs.h"
#include "media/base/video_color_space.h"
#include "media/base/video_decoder_config.h"
#include "media/base/video_transformation.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/geometry/size.h"
namespace chromecast {
namespace media {
namespace {
using ::media::AudioCodec;
using ::media::AudioDecoderConfig;
using ::media::ChannelLayout;
using ::media::EncryptionScheme;
using ::media::SampleFormat;
using ::media::VideoCodec;
using ::media::VideoCodecProfile;
using ::media::VideoColorSpace;
using ::media::VideoDecoderConfig;
using ::media::VideoTransformation;
using ::testing::Optional;
TEST(StarboardConversionsTest, ConvertsValidAudioConfigToStarboardConfig) {
EXPECT_THAT(
ToStarboardAudioSampleInfo(AudioDecoderConfig(
AudioCodec::kAAC, SampleFormat::kSampleFormatS32,
ChannelLayout::CHANNEL_LAYOUT_5_1, /*samples_per_second=*/48000,
/*extra_data=*/{}, EncryptionScheme::kCenc)),
Optional(MatchesAudioSampleInfo({
.codec = StarboardAudioCodec::kStarboardAudioCodecAac,
.mime = R"-(audio/mp4; codecs="mp4a.40.5")-",
.format_tag = 0,
.number_of_channels = 6,
.samples_per_second = 48000,
.average_bytes_per_second = 48000 * 4 * 6,
.block_alignment = 4,
.bits_per_sample = 32,
.audio_specific_config_size = 0,
.audio_specific_config = nullptr,
})));
}
TEST(StarboardConversionsTest, ReturnsNulloptForInvalidAudioConfig) {
// DTS is not supported in starboard.
EXPECT_EQ(ToStarboardAudioSampleInfo(AudioDecoderConfig(
AudioCodec::kDTS, SampleFormat::kSampleFormatS32,
ChannelLayout::CHANNEL_LAYOUT_5_1, /*samples_per_second=*/48000,
/*extra_data=*/{}, EncryptionScheme::kCenc)),
std::nullopt);
}
TEST(StarboardConversionsTest, ConvertsValidVideoConfigToStarboardConfig) {
EXPECT_THAT(
ToStarboardVideoSampleInfo(VideoDecoderConfig(
VideoCodec::kHEVC, VideoCodecProfile::HEVCPROFILE_MAIN10,
VideoDecoderConfig::AlphaMode::kIsOpaque,
VideoColorSpace(1, 1, 1, gfx::ColorSpace::RangeID::LIMITED),
VideoTransformation(), gfx::Size(1920, 1080), gfx::Rect(1920, 1080),
gfx::Size(1920, 1080), /*extra_data=*/{}, EncryptionScheme::kCenc)),
Optional(MatchesVideoSampleInfo({
.codec = StarboardVideoCodec::kStarboardVideoCodecH265,
.mime = R"-(video/mp4; codecs="hev1.2.6.L0.B0")-",
.max_video_capabilities = "",
.is_key_frame = false,
.frame_width = 1920,
.frame_height = 1080,
.color_metadata =
StarboardColorMetadata{
.bits_per_channel = 0, // unknown
.chroma_subsampling_horizontal = 0, // unknown
.chroma_subsampling_vertical = 0, // unknown
.cb_subsampling_horizontal = 0, // unknown
.cb_subsampling_vertical = 0, // unknown
.chroma_siting_horizontal = 0, // unknown
.chroma_siting_vertical = 0, // unknown
.mastering_metadata = {},
.max_cll = 0,
.max_fall = 0,
.primaries = 1,
.transfer = 1,
.matrix = 1,
.range = 1,
},
})));
}
TEST(StarboardConversionsTest,
ConvertsValidVideoConfigWithHdrMetadataToStarboardConfig) {
VideoDecoderConfig chromium_config(
VideoCodec::kHEVC, VideoCodecProfile::HEVCPROFILE_MAIN10,
VideoDecoderConfig::AlphaMode::kIsOpaque,
VideoColorSpace(9, 16, 9, gfx::ColorSpace::RangeID::LIMITED),
VideoTransformation(), gfx::Size(3840, 2160), gfx::Rect(3840, 2160),
gfx::Size(3840, 2160), /*extra_data=*/{}, EncryptionScheme::kUnencrypted);
gfx::HDRMetadata hdr_metadata;
gfx::HdrMetadataSmpteSt2086 smpte;
smpte.luminance_max = 0.9;
smpte.primaries.fRX = 0.1;
smpte.primaries.fRY = 0.2;
smpte.primaries.fGX = 0.3;
smpte.primaries.fGY = 0.4;
smpte.primaries.fBX = 0.5;
smpte.primaries.fBY = 0.6;
smpte.primaries.fWX = 0.7;
smpte.primaries.fWY = 0.8;
smpte.luminance_max = 1.1;
smpte.luminance_min = 0.01;
gfx::HdrMetadataCta861_3 cta;
cta.max_content_light_level = 100;
cta.max_frame_average_light_level = 1000;
hdr_metadata.smpte_st_2086 = smpte;
hdr_metadata.cta_861_3 = cta;
chromium_config.set_hdr_metadata(hdr_metadata);
EXPECT_THAT(ToStarboardVideoSampleInfo(chromium_config),
Optional(MatchesVideoSampleInfo({
.codec = StarboardVideoCodec::kStarboardVideoCodecH265,
.mime = R"-(video/mp4; codecs="hev1.2.6.L0.B0")-",
.max_video_capabilities = "",
.is_key_frame = false,
.frame_width = 3840,
.frame_height = 2160,
.color_metadata =
{
.bits_per_channel = 0, // unknown
.chroma_subsampling_horizontal = 0, // unknown
.chroma_subsampling_vertical = 0, // unknown
.cb_subsampling_horizontal = 0, // unknown
.cb_subsampling_vertical = 0, // unknown
.chroma_siting_horizontal = 0, // unknown
.chroma_siting_vertical = 0, // unknown
.mastering_metadata =
{
.primary_r_chromaticity_x = 0.1,
.primary_r_chromaticity_y = 0.2,
.primary_g_chromaticity_x = 0.3,
.primary_g_chromaticity_y = 0.4,
.primary_b_chromaticity_x = 0.5,
.primary_b_chromaticity_y = 0.6,
.white_point_chromaticity_x = 0.7,
.white_point_chromaticity_y = 0.8,
.luminance_max = 1.1,
.luminance_min = 0.01,
},
.max_cll = 100,
.max_fall = 1000,
.primaries = 9,
.transfer = 16,
.matrix = 9,
.range = 1,
},
})));
}
TEST(StarboardConversionsTest, ReturnsNulloptForInvalidVideoConfig) {
// Dolby Vision is paired with a bad profile.
EXPECT_EQ(
ToStarboardVideoSampleInfo(VideoDecoderConfig(
VideoCodec::kDolbyVision, VideoCodecProfile::VVCPROFILE_MAIN10,
VideoDecoderConfig::AlphaMode::kIsOpaque,
VideoColorSpace(1, 1, 1, gfx::ColorSpace::RangeID::LIMITED),
VideoTransformation(), gfx::Size(1920, 1080), gfx::Rect(1920, 1080),
gfx::Size(1920, 1080), /*extra_data=*/{}, EncryptionScheme::kCenc)),
std::nullopt);
}
} // namespace
} // namespace media
} // namespace chromecast