Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
{
"comment": "TODO: b/450568428 - Investigate these failing tests",
"failing_tests": [
"MediaCapabilitiesCache*",
"MimeUtilTest.ChecksSupportedFlacContainers",
"MimeUtilTest.ChecksSupportedMp3Containers",
"MimeUtilTest.ChecksSupportedPcmContainers",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
{
"comment": "TODO: b/450568428 - Investigate these failing tests",
"failing_tests": [
"MediaCapabilitiesCache*",
"MimeUtilTest.ChecksSupportedFlacContainers",
"MimeUtilTest.ChecksSupportedMp3Containers",
"MimeUtilTest.ChecksSupportedPcmContainers",
Expand Down
33 changes: 33 additions & 0 deletions starboard/android/shared/media_capabilities_cache.cc
Original file line number Diff line number Diff line change
Expand Up @@ -397,6 +397,14 @@ bool MediaCapabilitiesCache::IsPassthroughSupported(SbMediaAudioCodec codec) {
return supported;
}

bool MediaCapabilitiesCache::IsAv18kCappedAt30() {
if (!is_enabled_) {
// When the cache is not enabled, always checks video fps.
return true;
}
return is_av1_8k_capped_at_30_;
}

bool MediaCapabilitiesCache::GetAudioConfiguration(
int index,
SbMediaAudioConfiguration* configuration) {
Expand Down Expand Up @@ -562,6 +570,7 @@ void MediaCapabilitiesCache::UpdateMediaCapabilities_Locked() {
media_capabilities_provider_->GetCodecCapabilities(
audio_codec_capabilities_map_, video_codec_capabilities_map_);
LoadAudioConfigurations_Locked();
LoadIsAv18kCappedAt30_Locked();
}

void MediaCapabilitiesCache::LoadAudioConfigurations_Locked() {
Expand All @@ -579,4 +588,28 @@ void MediaCapabilitiesCache::LoadAudioConfigurations_Locked() {
}
}

void MediaCapabilitiesCache::LoadIsAv18kCappedAt30_Locked() {
const bool enable_av1_startup_optimization =
starboard::features::FeatureList::IsEnabled(
starboard::features::kEnableAv1StartupOptimization);
if (!enable_av1_startup_optimization) {
return;
}

is_av1_8k_capped_at_30_ = false;
for (const auto& video_capability :
video_codec_capabilities_map_[SupportedVideoCodecToMimeType(
kSbMediaVideoCodecAv1)]) {
constexpr int kWidth8K = 7680;
constexpr int kHeight8K = 4320;
if (video_capability->AreResolutionAndRateSupported(kWidth8K, kHeight8K,
/*fps=*/0) &&
!video_capability->AreResolutionAndRateSupported(kWidth8K, kHeight8K,
/*fps=*/60)) {
is_av1_8k_capped_at_30_ = true;
break;
}
}
}

} // namespace starboard
9 changes: 9 additions & 0 deletions starboard/android/shared/media_capabilities_cache.h
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,13 @@ class MediaCapabilitiesCache {

bool IsPassthroughSupported(SbMediaAudioCodec codec);

// Some android devices support av1 up to 8k30 and 4k60. In that case, we
// cannot ask it to always use max supported width and height, which would
// lead 8k60 being used and exceed system resource limit. See b/173575800.
// When IsAv18kCappedAt30() returns true, the device needs extra check of
// video fps to prevent 8k60 is used unexpectedly.
bool IsAv18kCappedAt30();

bool GetAudioConfiguration(int index,
SbMediaAudioConfiguration* configuration);

Expand Down Expand Up @@ -219,6 +226,7 @@ class MediaCapabilitiesCache {

void UpdateMediaCapabilities_Locked();
void LoadAudioConfigurations_Locked();
void LoadIsAv18kCappedAt30_Locked();

std::mutex mutex_;

Expand All @@ -238,6 +246,7 @@ class MediaCapabilitiesCache {
std::vector<SbMediaAudioConfiguration> audio_configurations_;
bool is_widevine_supported_ = false;
bool is_cbcs_supported_ = false;
bool is_av1_8k_capped_at_30_ = true;

std::atomic_bool is_enabled_{true};
std::atomic_bool capabilities_is_dirty_{true};
Expand Down
20 changes: 12 additions & 8 deletions starboard/android/shared/video_decoder.cc
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@

#include "base/android/jni_android.h"
#include "build/build_config.h"
#include "starboard/android/shared/media_capabilities_cache.h"
#include "starboard/android/shared/media_common.h"
#include "starboard/android/shared/video_render_algorithm.h"
#include "starboard/android/shared/video_surface_texture_bridge.h"
Expand Down Expand Up @@ -416,6 +417,9 @@ MediaCodecVideoDecoder::MediaCodecVideoDecoder(
flush_delay_usec_(android_get_device_api_level() < 34 ? flush_delay_usec
: 0),
force_reset_surface_(force_reset_surface),
needs_fps_to_initialize_codec_(
video_codec_ == kSbMediaVideoCodecAv1 &&
MediaCapabilitiesCache::GetInstance()->IsAv18kCappedAt30()),
is_video_frame_tracker_enabled_(IsFrameRenderedCallbackEnabled() ||
tunnel_mode_audio_session_id != -1),
has_new_texture_available_(false),
Expand Down Expand Up @@ -447,7 +451,7 @@ MediaCodecVideoDecoder::MediaCodecVideoDecoder(
SB_DCHECK_EQ(output_mode_, kSbPlayerOutputModeDecodeToTexture);
}

if (video_codec_ != kSbMediaVideoCodecAv1) {
if (!needs_fps_to_initialize_codec_) {
auto result = InitializeCodec(video_stream_info);
if (!result) {
*error_message =
Expand Down Expand Up @@ -560,7 +564,7 @@ void MediaCodecVideoDecoder::WriteInputBuffers(

// Re-initialize the codec now if it was torn down either in |Reset| or
// because we need to change the color metadata.
if (video_codec_ != kSbMediaVideoCodecAv1 && media_decoder_ == NULL) {
if (!needs_fps_to_initialize_codec_ && media_decoder_ == NULL) {
auto result = InitializeCodec(input_buffers.front()->video_stream_info());
if (!result) {
std::string error_message =
Expand All @@ -581,7 +585,7 @@ void MediaCodecVideoDecoder::WriteInputBuffers(

input_buffer_written_ += input_buffers.size();

if (video_codec_ == kSbMediaVideoCodecAv1 && video_fps_ == 0) {
if (needs_fps_to_initialize_codec_ && video_fps_ == 0) {
SB_DCHECK(!media_decoder_);

pending_input_buffers_.insert(pending_input_buffers_.end(),
Expand Down Expand Up @@ -625,7 +629,7 @@ void MediaCodecVideoDecoder::WriteEndOfStream() {
return;
}

if (video_codec_ == kSbMediaVideoCodecAv1 && video_fps_ == 0) {
if (needs_fps_to_initialize_codec_ && video_fps_ == 0) {
SB_DCHECK(!media_decoder_);
SB_DCHECK_EQ(pending_input_buffers_.size(),
static_cast<size_t>(input_buffer_written_));
Expand Down Expand Up @@ -660,7 +664,7 @@ void MediaCodecVideoDecoder::Reset() {
SB_CHECK(BelongsToCurrentThread());

// If fail to flush |media_decoder_| or |media_decoder_| is null, then
// re-create |media_decoder_|. If the codec is kSbMediaVideoCodecAv1,
// re-create |media_decoder_|. If |needs_fps_to_initialize_codec_| is true,
// set video_fps_ to 0 will call InitializeCodec(),
// which we do not need if flush the codec.
if (!enable_flush_during_seek_ || !media_decoder_ ||
Expand Down Expand Up @@ -701,7 +705,7 @@ Result<void> MediaCodecVideoDecoder::InitializeCodec(
const VideoStreamInfo& video_stream_info) {
SB_CHECK(BelongsToCurrentThread());

if (video_stream_info.codec == kSbMediaVideoCodecAv1) {
if (needs_fps_to_initialize_codec_) {
SB_DCHECK_GT(pending_input_buffers_.size(), 0u);

// Guesstimate the video fps.
Expand Down Expand Up @@ -779,7 +783,7 @@ Result<void> MediaCodecVideoDecoder::InitializeCodec(
return Failure("Video surface does not exist.");
}

if (video_stream_info.codec == kSbMediaVideoCodecAv1) {
if (needs_fps_to_initialize_codec_) {
SB_DCHECK_GT(video_fps_, 0);
} else {
SB_DCHECK_EQ(video_fps_, 0);
Expand Down Expand Up @@ -809,7 +813,7 @@ Result<void> MediaCodecVideoDecoder::InitializeCodec(
}
media_decoder_->SetPlaybackRate(playback_rate_);

if (video_stream_info.codec == kSbMediaVideoCodecAv1) {
if (needs_fps_to_initialize_codec_) {
SB_DCHECK(!pending_input_buffers_.empty());
} else {
SB_DCHECK(pending_input_buffers_.empty());
Expand Down
4 changes: 4 additions & 0 deletions starboard/android/shared/video_decoder.h
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,10 @@ class MediaCodecVideoDecoder : public VideoDecoder,
// Force resetting the video surface after every playback.
const bool force_reset_surface_;

// Codec initialization will be delayed until the decoder receives enough
// inputs to estimate video fps when |needs_fps_to_initialize_codec_| is true.
const bool needs_fps_to_initialize_codec_;

// On some platforms tunnel mode is only supported in the secure pipeline. So
// we create a dummy drm system to force the video playing in secure pipeline
// to enable tunnel mode.
Expand Down
5 changes: 5 additions & 0 deletions starboard/extension/feature_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,11 @@ STARBOARD_FEATURE(kVideoDecoderDelayUsecOverride,
STARBOARD_FEATURE(kRejectLowPerformanceSoftwareDecoder,
"RejectLowPerformanceSoftwareDecoder",
false)

// Set the following variable to true to enable av1 startup optimization.
STARBOARD_FEATURE(kEnableAv1StartupOptimization,
"EnableAv1StartupOptimization",
false)
#endif // BUILDFLAG(IS_ANDROID) && (SB_API_VERSION >= 17)
FEATURE_LIST_END

Expand Down
Loading