#include "media/cast/encoding/encoding_support.h"
#include <algorithm>
#include <bitset>
#include "base/command_line.h"
#include "build/build_config.h"
#include "media/base/media_switches.h"
#include "media/base/video_codecs.h"
#include "media/cast/encoding/external_video_encoder.h"
#include "media/media_buildflags.h"
namespace media::cast::encoding_support {
namespace {
using VideoCodecBitset =
std::bitset<static_cast<size_t>(VideoCodec::kMaxValue) + 1>;
static VideoCodecBitset& GetHardwareCodecDenyList() {
static VideoCodecBitset* const kInstance = new VideoCodecBitset();
return *kInstance;
}
bool IsCastStreamingAv1Enabled() {
#if BUILDFLAG(ENABLE_LIBAOM)
return base::FeatureList::IsEnabled(kCastStreamingAv1);
#else
return false;
#endif
}
bool IsHardwareEncodingEnabled(
const std::vector<VideoEncodeAccelerator::SupportedProfile>& profiles,
VideoCodecProfile min_profile,
VideoCodecProfile max_profile) {
for (const auto& vea_profile : profiles) {
if (vea_profile.profile >= min_profile &&
vea_profile.profile <= max_profile) {
return true;
}
}
return false;
}
bool IsHardwareH264EncodingEnabled(
const std::vector<VideoEncodeAccelerator::SupportedProfile>& profiles) {
const base::CommandLine& command_line =
*base::CommandLine::ForCurrentProcess();
if (command_line.HasSwitch(
switches::kCastStreamingForceDisableHardwareH264)) {
return false;
}
#if BUILDFLAG(IS_MAC)
if (!command_line.HasSwitch(
switches::kCastStreamingForceEnableHardwareH264) &&
!base::FeatureList::IsEnabled(kCastStreamingMacHardwareH264)) {
return false;
}
#endif
#if BUILDFLAG(IS_WIN)
if (!command_line.HasSwitch(
switches::kCastStreamingForceEnableHardwareH264) &&
!base::FeatureList::IsEnabled(kCastStreamingWinHardwareH264)) {
return false;
}
#endif
return IsHardwareEncodingEnabled(profiles, H264PROFILE_MIN, H264PROFILE_MAX);
}
bool IsHardwareHevcEncodingEnabled(
const std::vector<VideoEncodeAccelerator::SupportedProfile>& profiles) {
if (!base::FeatureList::IsEnabled(media::kCastStreamingMediaVideoEncoder)) {
return false;
}
if (!base::FeatureList::IsEnabled(media::kCastStreamingHardwareHevc)) {
return false;
}
return IsHardwareEncodingEnabled(profiles, HEVCPROFILE_MIN, HEVCPROFILE_MAX);
}
bool IsHardwareVP8EncodingEnabled(
const std::vector<VideoEncodeAccelerator::SupportedProfile>& profiles) {
if (!base::FeatureList::IsEnabled(kCastStreamingVp8)) {
return false;
}
if (base::CommandLine::ForCurrentProcess()->HasSwitch(
switches::kCastStreamingForceDisableHardwareVp8)) {
return false;
}
return IsHardwareEncodingEnabled(profiles, VP8PROFILE_MIN, VP8PROFILE_MAX);
}
bool IsHardwareVP9EncodingEnabled(
const std::vector<VideoEncodeAccelerator::SupportedProfile>& profiles) {
if (!base::FeatureList::IsEnabled(kCastStreamingVp9)) {
return false;
}
if (base::CommandLine::ForCurrentProcess()->HasSwitch(
switches::kCastStreamingForceDisableHardwareVp9)) {
return false;
}
return IsHardwareEncodingEnabled(profiles, VP9PROFILE_MIN, VP9PROFILE_MAX);
}
}
bool IsSoftwareEnabled(VideoCodec codec) {
switch (codec) {
case VideoCodec::kVP8:
return base::FeatureList::IsEnabled(kCastStreamingVp8);
case VideoCodec::kVP9:
return base::FeatureList::IsEnabled(kCastStreamingVp9);
case VideoCodec::kAV1:
return IsCastStreamingAv1Enabled();
case VideoCodec::kUnknown:
return true;
default:
return false;
}
}
bool IsHardwareEnabled(
VideoCodec codec,
const std::vector<VideoEncodeAccelerator::SupportedProfile>& profiles) {
if (IsHardwareDenyListed(codec)) {
return false;
}
switch (codec) {
case VideoCodec::kH264:
return IsHardwareH264EncodingEnabled(profiles);
case VideoCodec::kHEVC:
return IsHardwareHevcEncodingEnabled(profiles);
case VideoCodec::kVP8:
return IsHardwareVP8EncodingEnabled(profiles);
case VideoCodec::kVP9:
return IsHardwareVP9EncodingEnabled(profiles);
default:
return false;
}
}
bool IsHardwareDenyListed(VideoCodec codec) {
return GetHardwareCodecDenyList().test(static_cast<size_t>(codec));
}
void DenyListHardwareCodec(VideoCodec codec) {
CHECK(!IsHardwareDenyListed(codec));
GetHardwareCodecDenyList().set(static_cast<size_t>(codec));
}
void ClearHardwareCodecDenyListForTesting() {
GetHardwareCodecDenyList().reset();
}
}