From abdbe2b051bdd8c7365b76394dafae70a6442dbd Mon Sep 17 00:00:00 2001 From: Drew Thomas Date: Tue, 17 Dec 2024 15:13:58 -0800 Subject: [PATCH 1/3] Add PersistentStorage flag for ALLM The flag will call to the Media Settings Starboard Extension, if implemented and present. b/384568658 --- cobalt/browser/browser_module.cc | 2 + cobalt/h5vcc/h5vcc_settings.cc | 15 +++++++ cobalt/media/BUILD.gn | 1 + cobalt/media/media_module.cc | 39 +++++++++++++++++++ cobalt/media/media_module.h | 16 +++++--- .../java/dev/cobalt/coat/CobaltActivity.java | 14 +++++++ .../java/dev/cobalt/coat/StarboardBridge.java | 9 +++++ .../android/shared/media_settings_api.cc | 10 ++++- starboard/extension/media_settings.h | 4 ++ 9 files changed, 103 insertions(+), 7 deletions(-) diff --git a/cobalt/browser/browser_module.cc b/cobalt/browser/browser_module.cc index 75a27b117a44..5ff786a5e216 100644 --- a/cobalt/browser/browser_module.cc +++ b/cobalt/browser/browser_module.cc @@ -1671,6 +1671,8 @@ void BrowserModule::InitializeComponents() { } else { options_.media_module_options.allow_resume_after_suspend = SbSystemSupportsResume(); + options_.media_module_options.persistent_settings = + options_.persistent_settings; media_module_.reset(new media::MediaModule(system_window_.get(), GetResourceProvider(), options_.media_module_options)); diff --git a/cobalt/h5vcc/h5vcc_settings.cc b/cobalt/h5vcc/h5vcc_settings.cc index 165b86ca2426..71a342a4cc00 100644 --- a/cobalt/h5vcc/h5vcc_settings.cc +++ b/cobalt/h5vcc/h5vcc_settings.cc @@ -60,6 +60,8 @@ bool H5vccSettings::Set(const std::string& name, SetValueType value) const { const char kHTTP2[] = "HTTP2"; const char kHTTP3[] = "HTTP3"; const char kSkiaRasterizer[] = "SkiaRasterizer"; + const char kSetPreferMinimalPostProcessing[] = + "SetPreferMinimalPostProcessing"; #if SB_IS(EVERGREEN) const char kUpdaterMinFreeSpaceBytes[] = "Updater.MinFreeSpaceBytes"; @@ -78,6 +80,19 @@ bool H5vccSettings::Set(const std::string& name, SetValueType value) const { : false; } + if (name.compare(kSetPreferMinimalPostProcessing) == 0 && + value.IsType()) { + if (!persistent_settings_ || !media_module_) { + return false; + } else { + persistent_settings_->Set( + media::kPreferMinimalPostProcessingPersistentSettingsKey, + base::Value(value.AsType() != 0)); + media_module_->SetPreferMinimalPostProcessingFromPersistentSettings(); + return true; + } + } + if (name.compare(kNavigatorUAData) == 0 && value.IsType() && value.AsType() == 1) { global_environment_->BindTo("userAgentData", user_agent_data_, "navigator"); diff --git a/cobalt/media/BUILD.gn b/cobalt/media/BUILD.gn index 72aa18148ab4..62ef56a19a6e 100644 --- a/cobalt/media/BUILD.gn +++ b/cobalt/media/BUILD.gn @@ -106,6 +106,7 @@ component("media") { "//cobalt/loader:origin", "//cobalt/math", "//cobalt/network", + "//cobalt/persistent_storage:persistent_settings", "//cobalt/render_tree:render_tree", "//cobalt/system_window:system_window", "//media", diff --git a/cobalt/media/media_module.cc b/cobalt/media/media_module.cc index f245ac43a9e3..1f6b729a8cdc 100644 --- a/cobalt/media/media_module.cc +++ b/cobalt/media/media_module.cc @@ -185,6 +185,20 @@ class CanPlayTypeHandlerStarboard : public CanPlayTypeHandler { } // namespace +MediaModule::MediaModule(system_window::SystemWindow* system_window, + render_tree::ResourceProvider* resource_provider, + const Options& options) + : sbplayer_interface_(new DefaultSbPlayerInterface), + options_(options), + system_window_(system_window), + resource_provider_(resource_provider) { + Initialize(); +} + +void MediaModule::Initialize() { + SetPreferMinimalPostProcessingFromPersistentSettings(); +} + bool MediaModule::SetConfiguration(const std::string& name, int32 value) { if (name == "MaxAudioSamplesPerWrite" && value > 0) { max_audio_samples_per_write_ = value; @@ -252,6 +266,31 @@ bool MediaModule::SetConfiguration(const std::string& name, int32 value) { return false; } +void MediaModule::SetPreferMinimalPostProcessingFromPersistentSettings() { + // Called on initialization and when the persistent setting is changed. + if (options_.persistent_settings == nullptr) { + return; + } + + base::Value value; + options_.persistent_settings->Get( + kPreferMinimalPostProcessingPersistentSettingsKey, &value); + bool prefer_minimal_post_processing = value.GetIfBool().value_or(false); + + const StarboardExtensionMediaSettingsApi* media_settings_api = + static_cast( + SbSystemGetExtension(kStarboardExtensionMediaSettingsName)); + if (media_settings_api && + strcmp(media_settings_api->name, kStarboardExtensionMediaSettingsName) == + 0 && + media_settings_api->version >= 3) { + media_settings_api->SetPreferMinimalPostProcessing( + prefer_minimal_post_processing); + LOG(INFO) << "Set PreferMinimalPostProcessing to " + << (prefer_minimal_post_processing ? "true" : "false"); + } +} + std::unique_ptr MediaModule::CreateWebMediaPlayer( WebMediaPlayerClient* client) { SbWindow window = kSbWindowInvalid; diff --git a/cobalt/media/media_module.h b/cobalt/media/media_module.h index f29973a1f615..a01ab9ae8edf 100644 --- a/cobalt/media/media_module.h +++ b/cobalt/media/media_module.h @@ -33,6 +33,7 @@ #include "cobalt/media/player/web_media_player_delegate.h" #include "cobalt/media/player/web_media_player_impl.h" #include "cobalt/media/web_media_player_factory.h" +#include "cobalt/persistent_storage/persistent_settings.h" #include "cobalt/render_tree/image.h" #include "cobalt/render_tree/resource_provider.h" #include "cobalt/system_window/system_window.h" @@ -42,13 +43,17 @@ namespace cobalt { namespace media { +const char kPreferMinimalPostProcessingPersistentSettingsKey[] = + "PreferMinimalPostProcessing"; + class MediaModule : public WebMediaPlayerFactory, public WebMediaPlayerDelegate { public: struct Options { - Options() {} + Options() : persistent_settings(nullptr) {} bool allow_resume_after_suspend = true; + persistent_storage::PersistentSettings* persistent_settings; }; typedef render_tree::Image Image; @@ -59,16 +64,13 @@ class MediaModule : public WebMediaPlayerFactory, MediaModule(system_window::SystemWindow* system_window, render_tree::ResourceProvider* resource_provider, - const Options& options = Options()) - : sbplayer_interface_(new DefaultSbPlayerInterface), - options_(options), - system_window_(system_window), - resource_provider_(resource_provider) {} + const Options& options = Options()); // Returns true when the setting is set successfully or if the setting has // already been set to the expected value. Returns false when the setting is // invalid or not set to the expected value. bool SetConfiguration(const std::string& name, int32 value); + void SetPreferMinimalPostProcessingFromPersistentSettings(); const DecoderBufferAllocator* GetDecoderBufferAllocator() const { return &decoder_buffer_allocator_; @@ -98,6 +100,8 @@ class MediaModule : public WebMediaPlayerFactory, } private: + void Initialize(); + void RegisterDebugState(WebMediaPlayer* player); void DeregisterDebugState(); diff --git a/starboard/android/apk/app/src/main/java/dev/cobalt/coat/CobaltActivity.java b/starboard/android/apk/app/src/main/java/dev/cobalt/coat/CobaltActivity.java index d566fa98823f..14a596c81ff2 100644 --- a/starboard/android/apk/app/src/main/java/dev/cobalt/coat/CobaltActivity.java +++ b/starboard/android/apk/app/src/main/java/dev/cobalt/coat/CobaltActivity.java @@ -421,4 +421,18 @@ public void onLowMemory() { public long getAppStartTimestamp() { return timeInNanoseconds; } + + public void setPreferMinimalPostProcessing(boolean value) { + Runnable runnable = + new Runnable() { + @Override + public void run() { + if (getDisplay().isMinimalPostProcessingSupported()) { + getWindow().setPreferMinimalPostProcessing(value); + } + } + }; + + runOnUiThread(runnable); + } } diff --git a/starboard/android/apk/app/src/main/java/dev/cobalt/coat/StarboardBridge.java b/starboard/android/apk/app/src/main/java/dev/cobalt/coat/StarboardBridge.java index c0b7b209695b..e88c3112190e 100644 --- a/starboard/android/apk/app/src/main/java/dev/cobalt/coat/StarboardBridge.java +++ b/starboard/android/apk/app/src/main/java/dev/cobalt/coat/StarboardBridge.java @@ -827,4 +827,13 @@ protected long getPlayServicesVersion() { return 0; } } + + @SuppressWarnings("unused") + @UsedByNative + protected void setPreferMinimalPostProcessing(boolean value) { + Activity activity = activityHolder.get(); + if (activity instanceof CobaltActivity) { + ((CobaltActivity) activity).setPreferMinimalPostProcessing(value); + } + } } diff --git a/starboard/android/shared/media_settings_api.cc b/starboard/android/shared/media_settings_api.cc index 2a07bba1ff90..433ca358787a 100644 --- a/starboard/android/shared/media_settings_api.cc +++ b/starboard/android/shared/media_settings_api.cc @@ -13,6 +13,7 @@ // limitations under the License. #include "starboard/android/shared/media_settings_api.h" +#include "starboard/android/shared/jni_env_ext.h" #include "starboard/android/shared/media_codec_bridge_eradicator.h" #include "starboard/extension/media_settings.h" @@ -33,11 +34,18 @@ void SetAsyncReleaseMediaCodecBridgeTimeoutSeconds(int timeout_seconds) { MediaCodecBridgeEradicator::GetInstance()->SetTimeoutSeconds(timeout_seconds); } +void SetPreferMinimalPostProcessing(bool value) { + JniEnvExt* env = JniEnvExt::Get(); + env->CallStarboardVoidMethodOrAbort("setPreferMinimalPostProcessing", "(Z)V", + static_cast(value)); +} + const StarboardExtensionMediaSettingsApi kMediaSettingsApi = { kStarboardExtensionMediaSettingsName, - 2, // API version that's implemented. + 3, // API version that's implemented. &EnableAsyncReleaseMediaCodecBridge, &SetAsyncReleaseMediaCodecBridgeTimeoutSeconds, + &SetPreferMinimalPostProcessing, }; } // namespace diff --git a/starboard/extension/media_settings.h b/starboard/extension/media_settings.h index ae8b33bea086..09fb0cb9570e 100644 --- a/starboard/extension/media_settings.h +++ b/starboard/extension/media_settings.h @@ -40,6 +40,10 @@ typedef struct StarboardExtensionMediaSettingsApi { // Android TV. void (*SetAsyncReleaseMediaCodecBridgeTimeoutSeconds)(int timeout); + // This API passes the boolean through to + // Window.setPreferMinimalPostProcessing on Android TV. + // Added in extension version 3. + void (*SetPreferMinimalPostProcessing)(bool value); } StarboardExtensionMediaSettingsApi; #ifdef __cplusplus From e9f7cd4437d1cc89d2ae5c0f4835c2bba7de409b Mon Sep 17 00:00:00 2001 From: Drew Thomas Date: Fri, 20 Dec 2024 10:02:01 -0800 Subject: [PATCH 2/3] Address review comments --- cobalt/media/media_module.cc | 2 -- .../app/src/main/java/dev/cobalt/coat/CobaltActivity.java | 5 +++++ 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/cobalt/media/media_module.cc b/cobalt/media/media_module.cc index 1f6b729a8cdc..027bf7a86e60 100644 --- a/cobalt/media/media_module.cc +++ b/cobalt/media/media_module.cc @@ -286,8 +286,6 @@ void MediaModule::SetPreferMinimalPostProcessingFromPersistentSettings() { media_settings_api->version >= 3) { media_settings_api->SetPreferMinimalPostProcessing( prefer_minimal_post_processing); - LOG(INFO) << "Set PreferMinimalPostProcessing to " - << (prefer_minimal_post_processing ? "true" : "false"); } } diff --git a/starboard/android/apk/app/src/main/java/dev/cobalt/coat/CobaltActivity.java b/starboard/android/apk/app/src/main/java/dev/cobalt/coat/CobaltActivity.java index 14a596c81ff2..741a79acd4b1 100644 --- a/starboard/android/apk/app/src/main/java/dev/cobalt/coat/CobaltActivity.java +++ b/starboard/android/apk/app/src/main/java/dev/cobalt/coat/CobaltActivity.java @@ -23,6 +23,7 @@ import android.content.pm.PackageManager.NameNotFoundException; import android.media.AudioManager; import android.net.Uri; +import android.os.Build; import android.os.Bundle; import android.util.Pair; import android.view.View; @@ -423,6 +424,10 @@ public long getAppStartTimestamp() { } public void setPreferMinimalPostProcessing(boolean value) { + if (Build.VERSION.SDK_INT < 30) { + return; + } + Runnable runnable = new Runnable() { @Override From 218f7c19ca1059b10ac16ddf75d4c363a9e0c750 Mon Sep 17 00:00:00 2001 From: Drew Thomas Date: Mon, 6 Jan 2025 11:55:09 -0800 Subject: [PATCH 3/3] Address review comments --- cobalt/h5vcc/h5vcc_settings.cc | 2 +- cobalt/media/media_module.cc | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/cobalt/h5vcc/h5vcc_settings.cc b/cobalt/h5vcc/h5vcc_settings.cc index 67a3f233870b..a8e99e4478fb 100644 --- a/cobalt/h5vcc/h5vcc_settings.cc +++ b/cobalt/h5vcc/h5vcc_settings.cc @@ -90,7 +90,7 @@ bool H5vccSettings::Set(const std::string& name, SetValueType value) const { } else { persistent_settings_->Set( media::kPreferMinimalPostProcessingPersistentSettingsKey, - base::Value(value.AsType() != 0)); + base::Value(value.AsType() == 1)); media_module_->SetPreferMinimalPostProcessingFromPersistentSettings(); return true; } diff --git a/cobalt/media/media_module.cc b/cobalt/media/media_module.cc index 745ffefb6a4c..ab4544fed099 100644 --- a/cobalt/media/media_module.cc +++ b/cobalt/media/media_module.cc @@ -293,8 +293,8 @@ void MediaModule::SetPreferMinimalPostProcessingFromPersistentSettings() { static_cast( SbSystemGetExtension(kStarboardExtensionMediaSettingsName)); if (media_settings_api && - strcmp(media_settings_api->name, kStarboardExtensionMediaSettingsName) == - 0 && + std::string(media_settings_api->name) == + kStarboardExtensionMediaSettingsName && media_settings_api->version >= 3) { media_settings_api->SetPreferMinimalPostProcessing( prefer_minimal_post_processing);