From 713f5de588573c562e995947e18a212ecb690dfc Mon Sep 17 00:00:00 2001 From: =?utf8?q?Aleksander=20=C5=9Awiniarski?= Date: Mon, 18 Mar 2024 09:23:31 +0100 Subject: [PATCH 01/16] Fix for building with Tizen X Repo MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Currently for building with Tizen X repo we are using directory of form out.tz_v9.0* to store object files, which is the same format of directory, as when creating with standard repositories. Due to this object files from these builds get mixed in the same directory. This patch fixes this by use of conditional in .spec file. When the Tizen X is detected, the directory of form out.tz_X* will be used instead Change-Id: Ia57797b5e1d8cfb865ecc72887877abd8d0c9a7b Signed-off-by: Aleksander Świniarski --- packaging/chromium-efl.spec | 10 ++++++++++ tizen_src/build/common.sh | 1 + 2 files changed, 11 insertions(+) diff --git a/packaging/chromium-efl.spec b/packaging/chromium-efl.spec index a2934b7..f6624ae 100644 --- a/packaging/chromium-efl.spec +++ b/packaging/chromium-efl.spec @@ -46,6 +46,12 @@ Source1: content_shell.in %define tizen_version %{tizen_version_major}%{tizen_version_minor} +%if "%{?_is_tizen_x}" == "1" +%define __is_tizen_x 1 +%else +%define __is_tizen_x 0 +%endif + %if "%{?_build_chrome}" == "1" %define __build_chrome 1 %else @@ -481,8 +487,12 @@ Chromium gcov objects %if %{__build_chrome} == 1 %define OUTPUT_BASE_FOLDER out.chrome.tz_v%{tizen_version_major}.%{tizen_version_minor}.%{repo_name}.%{ARCHITECTURE} %else +%if %{__is_tizen_x} == 1 +%define OUTPUT_BASE_FOLDER out.tz_X.%{repo_name}.%{ARCHITECTURE} +%else %define OUTPUT_BASE_FOLDER out.tz_v%{tizen_version_major}.%{tizen_version_minor}.%{repo_name}.%{ARCHITECTURE} %endif +%endif export GN_GENERATOR_OUTPUT=$PWD/%{OUTPUT_BASE_FOLDER} diff --git a/tizen_src/build/common.sh b/tizen_src/build/common.sh index 7ed7887..3fcf1eb 100755 --- a/tizen_src/build/common.sh +++ b/tizen_src/build/common.sh @@ -363,6 +363,7 @@ function setupAndExecuteTargetBuild() { PROFILE=tzwr_5.5_arm-spin elif [[ $platform == "Base-X" ]]; then PROFILE=tz_X + ARGS+=(--define "_is_tizen_x 1") else echo "Cannot set default PROFILE for platform=${platform}" exit 1 -- 2.7.4 From 4973ea732b37891f7e057f3cf91f2a69031533c7 Mon Sep 17 00:00:00 2001 From: uzair Date: Wed, 3 Apr 2024 10:42:41 +0530 Subject: [PATCH 02/16] [M120 Migration][HOTFIX][EMULATOR] Fix for output surface creation failure The emulator platform DDK api glGetInternalformativ is returning incorrect GL_SAMPLES count which results in black screen. Ideally it needs to checked as to why emulator DDK returns GL_SAMPLES as 0 whereas all other profiles DDK return correct GL_SAMPLES count. Referece: https://review.tizen.org/gerrit/c/290611 Change-Id: I1e1c5e6fe2a0c438f60a22c307cd23394dbbdd60 Signed-off-by: uzair --- third_party/skia/src/gpu/ganesh/gl/GrGLCaps.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/third_party/skia/src/gpu/ganesh/gl/GrGLCaps.cpp b/third_party/skia/src/gpu/ganesh/gl/GrGLCaps.cpp index 0c4a07d..46e5964 100644 --- a/third_party/skia/src/gpu/ganesh/gl/GrGLCaps.cpp +++ b/third_party/skia/src/gpu/ganesh/gl/GrGLCaps.cpp @@ -52,6 +52,8 @@ class SkJSONWriter; #include #endif +#include "build/build_config.h" + GrGLCaps::GrGLCaps(const GrContextOptions& contextOptions, const GrGLContextInfo& ctxInfo, const GrGLInterface* glInterface) : INHERITED(contextOptions) { @@ -3442,11 +3444,17 @@ void GrGLCaps::setupSampleCounts(const GrGLContextInfo& ctxInfo, const GrGLInter GrGLenum glFormat = this->getRenderbufferInternalFormat(grGLFormat); GR_GL_GetInternalformativ(gli, GR_GL_RENDERBUFFER, glFormat, GR_GL_NUM_SAMPLE_COUNTS, 1, &count); +#if BUILDFLAG(IS_TIZEN_EMULATOR) + count = 1; +#endif if (count) { std::unique_ptr temp(new int[count]); GR_GL_GetInternalformativ(gli, GR_GL_RENDERBUFFER, glFormat, GR_GL_SAMPLES, count, temp.get()); // GL has a concept of MSAA rasterization with a single sample but we do not. +#if BUILDFLAG(IS_TIZEN_EMULATOR) + temp[0] = 1; +#endif if (count && temp[count - 1] == 1) { --count; SkASSERT(!count || temp[count -1] > 1); -- 2.7.4 From 406a40ddf1570440ccc836ad4862941eb9265864 Mon Sep 17 00:00:00 2001 From: zhaosy Date: Mon, 25 Mar 2024 10:52:30 +0800 Subject: [PATCH 03/16] [M120 Migration][WRTjs][VD] set screen solution for ultra width screen products For ultra width screen products(21:9 or 32:9), if app has "base_screen_resolution" metadata, when app is launched, window system will change window to 2580*1080 or 3840*1080. But view is not updated, so app still is displayed as 1920*1080. So when app is launched, set screen solution again. Reference: https://review.tizen.org/gerrit/#/c/platform/framework/web/chromium-efl/+/308471/ Change-Id: I9de89e1a3aed79a0c1d91ada401f53e4b64a6aed Signed-off-by: zhaosy Signed-off-by: DongHyun Song (cherry picked from commit ba2b872240f3148c4f4d00fe7849b1538aac7750) --- tizen_src/chromium_impl/ui/ozone/platform/efl/efl_screen.cc | 5 +++++ tizen_src/chromium_impl/ui/ozone/platform/efl/efl_screen.h | 1 + wrt/src/browser/tv/wrt_native_window_tv.cc | 11 +++++++++++ 3 files changed, 17 insertions(+) diff --git a/tizen_src/chromium_impl/ui/ozone/platform/efl/efl_screen.cc b/tizen_src/chromium_impl/ui/ozone/platform/efl/efl_screen.cc index 5df11cb..840af03 100644 --- a/tizen_src/chromium_impl/ui/ozone/platform/efl/efl_screen.cc +++ b/tizen_src/chromium_impl/ui/ozone/platform/efl/efl_screen.cc @@ -30,6 +30,11 @@ std::vector screen_list; } // namespace // static +void EflScreen::ClearCachedDisplaySize() { + screen_width = screen_height = 0; +} + +// static gfx::Rect EflScreen::GetDisplaySize() { if (!screen_width || !screen_height) { #if defined(USE_WAYLAND) diff --git a/tizen_src/chromium_impl/ui/ozone/platform/efl/efl_screen.h b/tizen_src/chromium_impl/ui/ozone/platform/efl/efl_screen.h index ba37c4b..c5ce65d 100644 --- a/tizen_src/chromium_impl/ui/ozone/platform/efl/efl_screen.h +++ b/tizen_src/chromium_impl/ui/ozone/platform/efl/efl_screen.h @@ -21,6 +21,7 @@ namespace ui { class EflScreen : public PlatformScreen { public: static gfx::Rect GetDisplaySize(); + static void ClearCachedDisplaySize(); EflScreen(); diff --git a/wrt/src/browser/tv/wrt_native_window_tv.cc b/wrt/src/browser/tv/wrt_native_window_tv.cc index 5684d27..27b07cf 100644 --- a/wrt/src/browser/tv/wrt_native_window_tv.cc +++ b/wrt/src/browser/tv/wrt_native_window_tv.cc @@ -81,6 +81,8 @@ const char* kProxyVconfKey = "memory/dnet/proxy"; const char* kWebAppProxyVconfKey = "db/webapp/proxy"; // metadata +const char* kBaseScreenResolution = + "http://tizen.org/metadata/app_ui_type/base_screen_resolution"; const char* kDualDecodingWebRTC = "http://samsung.com/tv/metadata/dual.decoding.support"; const char* kContentZoomFill = @@ -844,6 +846,15 @@ void WRTNativeWindowTV::SetAppMetaDataInfo() { LOG(INFO) << "zoom fill is " << zoom_fill; menu_zoom_fill_ = meta_data_info.GetValue(kContentZoomFill); } + + auto base_screen_resolution = meta_data_info.GetValue(kBaseScreenResolution); + if (!base_screen_resolution.empty()) { + LOG(INFO) << "base screen resolution is " << base_screen_resolution; + int width = 1920, height = 1080; + ui::EflScreen::ClearCachedDisplaySize(); + GetScreenResolution(width, height); + SetScreenResolution(width, height); + } } void WRTNativeWindowTV::SetAppMetaDataInfoRelatedWindow() { -- 2.7.4 From 716d4a834eba54bab3ca01b90fc410dc213893c4 Mon Sep 17 00:00:00 2001 From: DongHyun Song Date: Thu, 4 Apr 2024 09:34:43 +0000 Subject: [PATCH 04/16] Revert "[M120 Migration][WRTjs][VD] set screen solution for ultra width screen products" merged by mistake This reverts commit 406a40ddf1570440ccc836ad4862941eb9265864. Change-Id: Id72e75f0c9bb6b32b49800fea9f0a2f02ea74136 --- tizen_src/chromium_impl/ui/ozone/platform/efl/efl_screen.cc | 5 ----- tizen_src/chromium_impl/ui/ozone/platform/efl/efl_screen.h | 1 - wrt/src/browser/tv/wrt_native_window_tv.cc | 11 ----------- 3 files changed, 17 deletions(-) diff --git a/tizen_src/chromium_impl/ui/ozone/platform/efl/efl_screen.cc b/tizen_src/chromium_impl/ui/ozone/platform/efl/efl_screen.cc index 840af03..5df11cb 100644 --- a/tizen_src/chromium_impl/ui/ozone/platform/efl/efl_screen.cc +++ b/tizen_src/chromium_impl/ui/ozone/platform/efl/efl_screen.cc @@ -30,11 +30,6 @@ std::vector screen_list; } // namespace // static -void EflScreen::ClearCachedDisplaySize() { - screen_width = screen_height = 0; -} - -// static gfx::Rect EflScreen::GetDisplaySize() { if (!screen_width || !screen_height) { #if defined(USE_WAYLAND) diff --git a/tizen_src/chromium_impl/ui/ozone/platform/efl/efl_screen.h b/tizen_src/chromium_impl/ui/ozone/platform/efl/efl_screen.h index c5ce65d..ba37c4b 100644 --- a/tizen_src/chromium_impl/ui/ozone/platform/efl/efl_screen.h +++ b/tizen_src/chromium_impl/ui/ozone/platform/efl/efl_screen.h @@ -21,7 +21,6 @@ namespace ui { class EflScreen : public PlatformScreen { public: static gfx::Rect GetDisplaySize(); - static void ClearCachedDisplaySize(); EflScreen(); diff --git a/wrt/src/browser/tv/wrt_native_window_tv.cc b/wrt/src/browser/tv/wrt_native_window_tv.cc index 27b07cf..5684d27 100644 --- a/wrt/src/browser/tv/wrt_native_window_tv.cc +++ b/wrt/src/browser/tv/wrt_native_window_tv.cc @@ -81,8 +81,6 @@ const char* kProxyVconfKey = "memory/dnet/proxy"; const char* kWebAppProxyVconfKey = "db/webapp/proxy"; // metadata -const char* kBaseScreenResolution = - "http://tizen.org/metadata/app_ui_type/base_screen_resolution"; const char* kDualDecodingWebRTC = "http://samsung.com/tv/metadata/dual.decoding.support"; const char* kContentZoomFill = @@ -846,15 +844,6 @@ void WRTNativeWindowTV::SetAppMetaDataInfo() { LOG(INFO) << "zoom fill is " << zoom_fill; menu_zoom_fill_ = meta_data_info.GetValue(kContentZoomFill); } - - auto base_screen_resolution = meta_data_info.GetValue(kBaseScreenResolution); - if (!base_screen_resolution.empty()) { - LOG(INFO) << "base screen resolution is " << base_screen_resolution; - int width = 1920, height = 1080; - ui::EflScreen::ClearCachedDisplaySize(); - GetScreenResolution(width, height); - SetScreenResolution(width, height); - } } void WRTNativeWindowTV::SetAppMetaDataInfoRelatedWindow() { -- 2.7.4 From bb345c85101b7e8f78f03c2f39c2d9de79dd60e8 Mon Sep 17 00:00:00 2001 From: saurabh-2 Date: Fri, 5 Apr 2024 10:23:41 +0530 Subject: [PATCH 05/16] Fixing COVERITY Issue This patch fixes the COVERITY issues of following types: AUTO_CAUSES_COPY Change-Id: Ie6a7814070590a64fd03f2005ccec6aa9f39fd3f Signed-off-by: saurabh-2 --- .../chromium_impl/media/capture/video/tizen/camera_device_tizen.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tizen_src/chromium_impl/media/capture/video/tizen/camera_device_tizen.cc b/tizen_src/chromium_impl/media/capture/video/tizen/camera_device_tizen.cc index 2fab2f0..39fdd16 100644 --- a/tizen_src/chromium_impl/media/capture/video/tizen/camera_device_tizen.cc +++ b/tizen_src/chromium_impl/media/capture/video/tizen/camera_device_tizen.cc @@ -181,8 +181,8 @@ void GenerateChromiumVideoCaptureFormat( std::vector& capabilities, const std::vector& formats, std::vector& outSupportedFormats) { - for (auto supportedFrameInfo : capabilities) { - for (auto supportedFormat : formats) { + for (const auto& supportedFrameInfo : capabilities) { + for (const auto& supportedFormat : formats) { media::VideoCaptureFormat format; format.frame_size = supportedFrameInfo.resolution; format.frame_rate = supportedFrameInfo.fps; -- 2.7.4 From 3953af1cef55131bb676a8df272fba5b1ee8254d Mon Sep 17 00:00:00 2001 From: DongHyun Song Date: Wed, 3 Apr 2024 09:54:38 +0900 Subject: [PATCH 06/16] [XWalkExtension] Fix dangling issue of GetMetadataValue It cannot return local std::string's c_str() value as a return value. It can be a dangling pointer. Change-Id: I6e00b594e267433b17f56998886fd9344c9d0a80 Signed-off-by: DongHyun Song --- .../components/xwalk_extensions/browser/xwalk_extension.cc | 9 ++++++--- .../components/xwalk_extensions/public/XW_Extension_Runtime.h | 2 +- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/tizen_src/chromium_impl/components/xwalk_extensions/browser/xwalk_extension.cc b/tizen_src/chromium_impl/components/xwalk_extensions/browser/xwalk_extension.cc index b4df023..247f283 100644 --- a/tizen_src/chromium_impl/components/xwalk_extensions/browser/xwalk_extension.cc +++ b/tizen_src/chromium_impl/components/xwalk_extensions/browser/xwalk_extension.cc @@ -165,10 +165,13 @@ class XWalkExtension::Interface { extension_manager->SendMouseEvent(event, btn, x, y); } - static const char* RuntimeGetMetadataValue(const char* key) { + static void RuntimeGetMetadataValue(const char* key, + char* value, + unsigned int len) { auto* extension_manager = XWalkExtensionManager::GetInstance(); - auto value = extension_manager->GetMetadataValue(key); - return strdup(value.c_str()); + auto metadata_value = extension_manager->GetMetadataValue(key); + if (!metadata_value.empty()) + std::snprintf(value, len, "%s", metadata_value.c_str()); } static int PermissionsCheckAPIAccessControl( diff --git a/tizen_src/chromium_impl/components/xwalk_extensions/public/XW_Extension_Runtime.h b/tizen_src/chromium_impl/components/xwalk_extensions/public/XW_Extension_Runtime.h index d7b3cea..7d284a7 100644 --- a/tizen_src/chromium_impl/components/xwalk_extensions/public/XW_Extension_Runtime.h +++ b/tizen_src/chromium_impl/components/xwalk_extensions/public/XW_Extension_Runtime.h @@ -45,7 +45,7 @@ typedef struct XW_Internal_WindowInterface_ { void (*RemoveWindowEventListener)(XW_Instance instance); void (*SendKeyEvent)(const char* event, const char* key_code); void (*SendMouseEvent)(const char* event, int button, int x, int y); - const char* (*GetMetadataValue)(const char* key); + void (*GetMetadataValue)(const char* key, char* value, unsigned int len); } XW_Internal_WindowInterface; #ifdef __cplusplus -- 2.7.4 From 3e0816ba6e10505268902b3146e9e3cb86a9a888 Mon Sep 17 00:00:00 2001 From: jiangyuwei Date: Sun, 7 Apr 2024 14:46:19 +0800 Subject: [PATCH 07/16] [M120 Migration] Add guard code to avoid crash during webview clean In low memory case, browser will clean webview and create new one, driver will release and cause autofill crash. References: - https://review.tizen.org/gerrit/300788/ Change-Id: Iedd4a8a2a7005fc472ee00bb4e26599c8507e642 Signed-off-by: jiangyuwei --- components/password_manager/core/browser/password_form_filling.cc | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/components/password_manager/core/browser/password_form_filling.cc b/components/password_manager/core/browser/password_form_filling.cc index ca45a25..16a62c3 100644 --- a/components/password_manager/core/browser/password_form_filling.cc +++ b/components/password_manager/core/browser/password_form_filling.cc @@ -129,7 +129,10 @@ LikelyFormFilling SendFillInformationToRenderer( bool webauthn_suggestions_available) { DCHECK(driver); DCHECK_EQ(PasswordForm::Scheme::kHtml, observed_form.scheme); - + if (!driver) { + LOG(ERROR) << "driver already released, fill will not work"; + return LikelyFormFilling::kNoFilling; + } if (autofill::IsShowAutofillSignaturesEnabled()) { driver->AnnotateFieldsWithParsingResult( {.username_renderer_id = observed_form.username_element_renderer_id, -- 2.7.4 From 29ad5a946f64ca23da19e716089adf5659f49505 Mon Sep 17 00:00:00 2001 From: jiangyuwei Date: Sun, 7 Apr 2024 14:04:59 +0800 Subject: [PATCH 08/16] [M120 Migration][VD][Accessibility] Add smart callbacks for spatial navigation This patch is for changing focus from web view in Tizen TV to browser when cannot move focus any more by press arrow keys in spatial navigation. References: - https://review.tizen.org/gerrit/291208/ Change-Id: I3c7d860b9f42e6f863c0174ce918490b6fcf0202 Signed-off-by: jiangyuwei --- components/plugins/renderer/webview_plugin.h | 1 + .../renderer_host/render_widget_host_impl.cc | 7 +++++ .../renderer_host/render_widget_host_impl.h | 1 + .../renderer_host/render_widget_host_view_aura.cc | 6 ++++ .../renderer_host/render_widget_host_view_aura.h | 1 + .../renderer_host/render_widget_host_view_base.h | 2 ++ content/public/browser/web_contents_delegate.h | 1 + .../public/mojom/widget/platform_widget.mojom | 3 ++ .../renderer/core/frame/web_frame_widget_impl.cc | 4 +++ .../renderer/core/frame/web_frame_widget_impl.h | 1 + .../blink/renderer/core/page/spatial_navigation.h | 12 ++++++++ .../core/page/spatial_navigation_controller.cc | 32 ++++++++++++++++++++++ .../core/page/spatial_navigation_controller.h | 1 + .../blink/renderer/platform/widget/widget_base.cc | 4 +++ .../blink/renderer/platform/widget/widget_base.h | 1 + .../renderer_host/rwhv_aura_common_helper_efl.cc | 5 ++++ .../renderer_host/rwhv_aura_common_helper_efl.h | 1 + .../ewk/efl_integration/eweb_view_callbacks.h | 4 +++ .../efl_integration/web_contents_delegate_efl.cc | 7 +++++ .../efl_integration/web_contents_delegate_efl.h | 1 + 20 files changed, 95 insertions(+) diff --git a/components/plugins/renderer/webview_plugin.h b/components/plugins/renderer/webview_plugin.h index 4d9c310..1ce8690 100644 --- a/components/plugins/renderer/webview_plugin.h +++ b/components/plugins/renderer/webview_plugin.h @@ -197,6 +197,7 @@ class WebViewPlugin : public blink::WebPlugin, public blink::WebViewObserver { void SetCursor(const ui::Cursor& cursor) override; #if BUILDFLAG(IS_TIZEN_TV) void DidEdgeScrollBy(const gfx::Point& point, bool handled) override {} + void MoveFocusToBrowser(int direction) override {} void NotifyTrackInfoToBrowser(int active_track_id, const std::string& url, const std::string& lang) override {} diff --git a/content/browser/renderer_host/render_widget_host_impl.cc b/content/browser/renderer_host/render_widget_host_impl.cc index 474dd2d..e19024b 100644 --- a/content/browser/renderer_host/render_widget_host_impl.cc +++ b/content/browser/renderer_host/render_widget_host_impl.cc @@ -2902,6 +2902,13 @@ void RenderWidgetHostImpl::DidEdgeScrollBy(const gfx::Point& offset, bool handle view_->DidEdgeScrollBy(offset, handled); } +void RenderWidgetHostImpl::MoveFocusToBrowser(int direction) { + if (!GetView()) + return; + + view_->MoveFocusToBrowser(direction); +} + void RenderWidgetHostImpl::SetTranslatedURL(const std::string& url) { if (!blink_widget_) return; diff --git a/content/browser/renderer_host/render_widget_host_impl.h b/content/browser/renderer_host/render_widget_host_impl.h index d9abcd9..c542a51 100644 --- a/content/browser/renderer_host/render_widget_host_impl.h +++ b/content/browser/renderer_host/render_widget_host_impl.h @@ -322,6 +322,7 @@ class CONTENT_EXPORT RenderWidgetHostImpl #if BUILDFLAG(IS_TIZEN_TV) //Browser edge scroll void DidEdgeScrollBy(const gfx::Point& point, bool handled) override; + void MoveFocusToBrowser(int direction) override; void NotifyTrackInfoToBrowser(int active_track_id, const std::string& url, const std::string& lang) override; diff --git a/content/browser/renderer_host/render_widget_host_view_aura.cc b/content/browser/renderer_host/render_widget_host_view_aura.cc index a3d24c3..8dc88b6 100644 --- a/content/browser/renderer_host/render_widget_host_view_aura.cc +++ b/content/browser/renderer_host/render_widget_host_view_aura.cc @@ -2364,6 +2364,12 @@ void RenderWidgetHostViewAura::DidEdgeScrollBy(const gfx::Point& offset, efl_helper_->DidEdgeScrollBy(offset, handled); } +void RenderWidgetHostViewAura::MoveFocusToBrowser(int direction) { + if (aura_efl_helper()) { + aura_efl_helper()->MoveFocusToBrowser(direction); + } +} + void RenderWidgetHostViewAura::NotifyTrackInfoToBrowser( int active_track_id, const std::string& url, diff --git a/content/browser/renderer_host/render_widget_host_view_aura.h b/content/browser/renderer_host/render_widget_host_view_aura.h index 80bb89f..fa133fa 100644 --- a/content/browser/renderer_host/render_widget_host_view_aura.h +++ b/content/browser/renderer_host/render_widget_host_view_aura.h @@ -235,6 +235,7 @@ class CONTENT_EXPORT RenderWidgetHostViewAura #if BUILDFLAG(IS_TIZEN_TV) //Browser edge scroll void DidEdgeScrollBy(const gfx::Point& offset, bool handled) override ; + void MoveFocusToBrowser(int direction) override; void NotifyTrackInfoToBrowser(int active_track_id, const std::string& url, const std::string& lang) override; diff --git a/content/browser/renderer_host/render_widget_host_view_base.h b/content/browser/renderer_host/render_widget_host_view_base.h index 2b55acf..5076dde 100644 --- a/content/browser/renderer_host/render_widget_host_view_base.h +++ b/content/browser/renderer_host/render_widget_host_view_base.h @@ -507,6 +507,8 @@ class CONTENT_EXPORT RenderWidgetHostViewBase : public RenderWidgetHostView { #if BUILDFLAG(IS_TIZEN_TV) //Browser edge scroll virtual void DidEdgeScrollBy(const gfx::Point& offset, bool handled) {} + virtual void MoveFocusToBrowser(int direction) {} + // notify web browser video playing status virtual void VideoPlayingStatusReceived(bool is_playing, int callback_id) {} diff --git a/content/public/browser/web_contents_delegate.h b/content/public/browser/web_contents_delegate.h index d2d66ab..57d3318 100644 --- a/content/public/browser/web_contents_delegate.h +++ b/content/public/browser/web_contents_delegate.h @@ -409,6 +409,7 @@ class CONTENT_EXPORT WebContentsDelegate { #if BUILDFLAG(IS_TIZEN_TV) virtual void DidEdgeScrollBy(const gfx::Point& offset, bool handled) {} + virtual void MoveFocusToBrowser(int direction) {} virtual void ShowMicOpenedNotification(bool show) {} #endif diff --git a/third_party/blink/public/mojom/widget/platform_widget.mojom b/third_party/blink/public/mojom/widget/platform_widget.mojom index 0f8367e..9c2cd90c 100644 --- a/third_party/blink/public/mojom/widget/platform_widget.mojom +++ b/third_party/blink/public/mojom/widget/platform_widget.mojom @@ -41,6 +41,9 @@ interface WidgetHost { //Browser edge scroll DidEdgeScrollBy(gfx.mojom.Point offset, bool handled); + [EnableIf=is_tizen_tv] + MoveFocusToBrowser(int32 direction); + // Sent by a widget to the browser to set the tooltip text for the current // cursor position. An empty |tooltip_text| will hide the tooltip view. UpdateTooltipUnderCursor(mojo_base.mojom.String16 tooltip_text, diff --git a/third_party/blink/renderer/core/frame/web_frame_widget_impl.cc b/third_party/blink/renderer/core/frame/web_frame_widget_impl.cc index beb29d0..153089a 100644 --- a/third_party/blink/renderer/core/frame/web_frame_widget_impl.cc +++ b/third_party/blink/renderer/core/frame/web_frame_widget_impl.cc @@ -5189,6 +5189,10 @@ void WebFrameWidgetImpl::NotifyTrackInfoToBrowser(int active_track_id, << " url:" << url << " lang:" << lang; widget_base_->NotifyTrackInfoToBrowser(active_track_id, url, lang); } + +void WebFrameWidgetImpl::MoveFocusToBrowser(int direction) { + widget_base_->MoveFocusToBrowser(direction); +} #endif #if BUILDFLAG(IS_TIZEN) diff --git a/third_party/blink/renderer/core/frame/web_frame_widget_impl.h b/third_party/blink/renderer/core/frame/web_frame_widget_impl.h index c327506..64d8a9b 100644 --- a/third_party/blink/renderer/core/frame/web_frame_widget_impl.h +++ b/third_party/blink/renderer/core/frame/web_frame_widget_impl.h @@ -713,6 +713,7 @@ class CORE_EXPORT WebFrameWidgetImpl void NotifyTrackInfoToBrowser(int active_track_id, const std::string& url, const std::string& lang); + void MoveFocusToBrowser(int direction); #endif protected: diff --git a/third_party/blink/renderer/core/page/spatial_navigation.h b/third_party/blink/renderer/core/page/spatial_navigation.h index 5963970..c7de3c5 100644 --- a/third_party/blink/renderer/core/page/spatial_navigation.h +++ b/third_party/blink/renderer/core/page/spatial_navigation.h @@ -35,6 +35,18 @@ class HTMLFrameOwnerElement; enum class SpatialNavigationDirection { kNone, kUp, kRight, kDown, kLeft }; +// The direction value in WebFocusType (before Tizen 5.5) is different from +// SpatialNavigationDirection. While ewk callback is using the int value of +// them, if can not change ewk interface then we need compatible adaptation +enum CompatibilityFocusType { + kFocusTypeNone = 0, + // Spatial navigation. + kFocusTypeUp = 3, + kFocusTypeDown, + kFocusTypeLeft, + kFocusTypeRight +}; + constexpr double kMaxDistance = std::numeric_limits::max(); CORE_EXPORT bool IsSpatialNavigationEnabled(const LocalFrame*); diff --git a/third_party/blink/renderer/core/page/spatial_navigation_controller.cc b/third_party/blink/renderer/core/page/spatial_navigation_controller.cc index 47f16c4..fb654f4 100644 --- a/third_party/blink/renderer/core/page/spatial_navigation_controller.cc +++ b/third_party/blink/renderer/core/page/spatial_navigation_controller.cc @@ -37,6 +37,7 @@ #include "third_party/blink/renderer/core/css/style_change_reason.h" #if BUILDFLAG(IS_TIZEN_TV) +#include "third_party/blink/renderer/core/frame/web_frame_widget_impl.h" #include "third_party/blink/renderer/platform/keyboard_codes.h" #endif @@ -309,6 +310,25 @@ void SpatialNavigationController::Trace(Visitor* visitor) const { visitor->Trace(page_); } +int SpatialNavigationController::ToCompatibilityFocusType( + SpatialNavigationDirection direction) { + switch (direction) { + case SpatialNavigationDirection::kUp: + return CompatibilityFocusType::kFocusTypeUp; + case SpatialNavigationDirection::kDown: + return CompatibilityFocusType::kFocusTypeDown; + case SpatialNavigationDirection::kLeft: + return CompatibilityFocusType::kFocusTypeLeft; + case SpatialNavigationDirection::kRight: + return CompatibilityFocusType::kFocusTypeRight; + case SpatialNavigationDirection::kNone: + return CompatibilityFocusType::kFocusTypeNone; + default: + NOTREACHED(); + return CompatibilityFocusType::kFocusTypeNone; + } +} + bool SpatialNavigationController::Advance( SpatialNavigationDirection direction) { Node* interest_node = StartingNode(); @@ -357,6 +377,18 @@ bool SpatialNavigationController::Advance( document->UpdateStyleAndLayout(DocumentUpdateReason::kSpatialNavigation); } +#if BUILDFLAG(IS_TIZEN_TV) + Frame* frame = page_->GetFocusController().FocusedOrMainFrame(); + auto* local_frame = DynamicTo(frame); + if (!local_frame) + return false; + WebFrameWidgetImpl* wfwgt = + static_cast(local_frame->GetWidgetForLocalRoot()); + if (!wfwgt) + return false; + wfwgt->MoveFocusToBrowser(ToCompatibilityFocusType(direction)); +#endif + return false; } diff --git a/third_party/blink/renderer/core/page/spatial_navigation_controller.h b/third_party/blink/renderer/core/page/spatial_navigation_controller.h index 5ec3087..922c340 100644 --- a/third_party/blink/renderer/core/page/spatial_navigation_controller.h +++ b/third_party/blink/renderer/core/page/spatial_navigation_controller.h @@ -55,6 +55,7 @@ class CORE_EXPORT SpatialNavigationController final #endif private: + int ToCompatibilityFocusType(SpatialNavigationDirection direction); // Entry-point into SpatialNavigation advancement. Will return true if an // action (moving interest or scrolling), false otherwise. bool Advance(SpatialNavigationDirection direction); diff --git a/third_party/blink/renderer/platform/widget/widget_base.cc b/third_party/blink/renderer/platform/widget/widget_base.cc index 5cd531a..d1446fe 100644 --- a/third_party/blink/renderer/platform/widget/widget_base.cc +++ b/third_party/blink/renderer/platform/widget/widget_base.cc @@ -1169,6 +1169,10 @@ void WidgetBase::DidEdgeScrollBy(const gfx::Point& offset, bool handled) { widget_host_->DidEdgeScrollBy(offset, handled); } +void WidgetBase::MoveFocusToBrowser(int direction) { + widget_host_->MoveFocusToBrowser(direction); +} + void WidgetBase::NotifyTrackInfoToBrowser(int active_track_id, const std::string& url, const std::string& lang) { diff --git a/third_party/blink/renderer/platform/widget/widget_base.h b/third_party/blink/renderer/platform/widget/widget_base.h index d385fc7..b260337 100644 --- a/third_party/blink/renderer/platform/widget/widget_base.h +++ b/third_party/blink/renderer/platform/widget/widget_base.h @@ -266,6 +266,7 @@ class PLATFORM_EXPORT WidgetBase : public mojom::blink::Widget, #if BUILDFLAG(IS_TIZEN_TV) //Browser edge scroll void DidEdgeScrollBy(const gfx::Point& offset, bool handled); + void MoveFocusToBrowser(int direction); void NotifyTrackInfoToBrowser(int active_track_id, const std::string& url, const std::string& lang); diff --git a/tizen_src/chromium_impl/content/browser/renderer_host/rwhv_aura_common_helper_efl.cc b/tizen_src/chromium_impl/content/browser/renderer_host/rwhv_aura_common_helper_efl.cc index c9ad3a8..e9192bc 100644 --- a/tizen_src/chromium_impl/content/browser/renderer_host/rwhv_aura_common_helper_efl.cc +++ b/tizen_src/chromium_impl/content/browser/renderer_host/rwhv_aura_common_helper_efl.cc @@ -451,6 +451,11 @@ void RWHVAuraCommonHelperEfl::DidEdgeScrollBy(const gfx::Point& offset, web_contents_->GetDelegate()->DidEdgeScrollBy(offset, handled); } +void RWHVAuraCommonHelperEfl::MoveFocusToBrowser(int direction) { + if (web_contents_) + web_contents_->GetDelegate()->MoveFocusToBrowser(direction); +} + void RWHVAuraCommonHelperEfl::SetParentalRatingResult(const std::string& url, bool is_pass) { if (rwhv_aura_) diff --git a/tizen_src/chromium_impl/content/browser/renderer_host/rwhv_aura_common_helper_efl.h b/tizen_src/chromium_impl/content/browser/renderer_host/rwhv_aura_common_helper_efl.h index d79c7c2..1c1ad6b 100644 --- a/tizen_src/chromium_impl/content/browser/renderer_host/rwhv_aura_common_helper_efl.h +++ b/tizen_src/chromium_impl/content/browser/renderer_host/rwhv_aura_common_helper_efl.h @@ -137,6 +137,7 @@ class CONTENT_EXPORT RWHVAuraCommonHelperEfl { #if BUILDFLAG(IS_TIZEN_TV) //Browser edge scroll void DidEdgeScrollBy(const gfx::Point& offset, bool handled); + void MoveFocusToBrowser(int direction); void SetPopupMenuVisible(const bool visible); void SetPopupMenuBounds(const gfx::Rect& popup_bounds); void SetCursorByClient(bool enable) { cursor_set_by_client_ = enable; } diff --git a/tizen_src/ewk/efl_integration/eweb_view_callbacks.h b/tizen_src/ewk/efl_integration/eweb_view_callbacks.h index 9a0ac17..06ed6a5 100644 --- a/tizen_src/ewk/efl_integration/eweb_view_callbacks.h +++ b/tizen_src/ewk/efl_integration/eweb_view_callbacks.h @@ -170,6 +170,7 @@ enum CallbackType { NewWindowNavigationPolicyDecision, #endif // IS_TIZEN #if BUILDFLAG(IS_TIZEN_TV) + AtkKeyEventNotHandled, HoverOverLink, HoverOutLink, ParentalRatingInfo, @@ -369,6 +370,9 @@ DECLARE_EWK_VIEW_CALLBACK(NewWindowNavigationPolicyDecision, "policy,decision,ne #if BUILDFLAG(IS_TIZEN_TV) DECLARE_EWK_VIEW_CALLBACK(ParentalRatingInfo, "on,parentalrating,info", void*); +DECLARE_EWK_VIEW_CALLBACK(AtkKeyEventNotHandled, + "atk,keyevent,nothandled", + int*); DECLARE_EWK_VIEW_CALLBACK(HoverOverLink, "hover,over,link", const char*); DECLARE_EWK_VIEW_CALLBACK(HoverOutLink, "hover,out,link", const char*); DECLARE_EWK_VIEW_CALLBACK(LoginFormSubmitted, diff --git a/tizen_src/ewk/efl_integration/web_contents_delegate_efl.cc b/tizen_src/ewk/efl_integration/web_contents_delegate_efl.cc index 6c4c6e3..7eb7f0f 100644 --- a/tizen_src/ewk/efl_integration/web_contents_delegate_efl.cc +++ b/tizen_src/ewk/efl_integration/web_contents_delegate_efl.cc @@ -823,6 +823,13 @@ void WebContentsDelegateEfl::DidEdgeScrollBy(const gfx::Point& offset, web_view_->InvokeEdgeScrollByCallback(offset, handled); } +void WebContentsDelegateEfl::MoveFocusToBrowser(int direction) { + if (web_view_) { + web_view_->SmartCallback().call( + &direction); + } +} + void WebContentsDelegateEfl::WillDraw(int new_rotation, gfx::Size frame_data_output_size) { if (web_view_) { diff --git a/tizen_src/ewk/efl_integration/web_contents_delegate_efl.h b/tizen_src/ewk/efl_integration/web_contents_delegate_efl.h index 5dc1bd5..4e1b834 100644 --- a/tizen_src/ewk/efl_integration/web_contents_delegate_efl.h +++ b/tizen_src/ewk/efl_integration/web_contents_delegate_efl.h @@ -77,6 +77,7 @@ class WebContentsDelegateEfl : public WebContentsDelegate { #if BUILDFLAG(IS_TIZEN_TV) //Browser edge scroll void DidEdgeScrollBy(const gfx::Point& offset, bool handled) override; + void MoveFocusToBrowser(int direction) override; void NotifyDownloadableFontInfo(const std::string& scheme_id_uri, const std::string& value, const std::string& data, -- 2.7.4 From da3845600fe150c21eb1a53399b3fd7e324a3dfa Mon Sep 17 00:00:00 2001 From: "peng.yin" Date: Thu, 13 Oct 2022 13:58:23 +0800 Subject: [PATCH 09/16] [M120 Migration][MM][WebRTC] Base implementation for webrtc video hole stream migrate the TizenEsPlusPlayerRenderer class from M108 who roles same as MmVideodecoder before, but it creates a self owned EsPlusPlayer by mojo renderer, and update the latest geometry change info to EsPlusPlayer. refer to: https://review.tizen.org/gerrit/#/c/291285/ Change-Id: I0743eb1202dfa261501a9fdf12b2d5d73c34fa39 Signed-off-by: peng.yin --- cc/layers/layer_impl.h | 4 + cc/layers/video_layer.cc | 36 +- cc/layers/video_layer.h | 21 +- cc/layers/video_layer_impl.cc | 41 +- cc/layers/video_layer_impl.h | 21 +- .../playback_command_forwarding_renderer.cc | 8 + media/base/pipeline_impl.cc | 2 +- media/base/renderer.h | 18 +- media/base/video_decoder_config.h | 22 +- media/base/video_frame.cc | 13 +- media/base/video_frame.h | 3 +- media/base/video_frame_metadata.cc | 3 + media/base/video_frame_metadata.h | 4 + media/filters/chunk_demuxer.cc | 2 + media/mojo/clients/mojo_demuxer_stream_impl.cc | 10 +- media/mojo/clients/mojo_renderer.cc | 44 +- media/mojo/clients/mojo_renderer.h | 10 +- media/mojo/clients/mojo_renderer_wrapper.cc | 10 +- media/mojo/clients/mojo_renderer_wrapper.h | 5 +- media/mojo/mojom/media_types.mojom | 1 + media/mojo/mojom/renderer.mojom | 29 +- media/mojo/mojom/renderer_extensions.mojom | 6 + .../mojom/video_decoder_config_mojom_traits.cc | 2 + .../mojo/mojom/video_decoder_config_mojom_traits.h | 4 + media/mojo/services/mojo_renderer_service.cc | 36 +- media/mojo/services/mojo_renderer_service.h | 11 +- .../modules/mediastream/web_media_stream_sink.h | 1 + .../web/modules/mediastream/webmediaplayer_ms.h | 7 + .../mediastream/local_video_capturer_source.cc | 14 +- .../modules/mediastream/webmediaplayer_ms.cc | 96 ++- .../mediastream/webmediaplayer_ms_compositor.cc | 36 + .../mediastream/webmediaplayer_ms_compositor.h | 2 +- third_party/blink/renderer/platform/media/BUILD.gn | 9 + .../platform/media/web_media_player_impl.cc | 7 +- .../peerconnection/webrtc_video_track_source.cc | 21 + .../platform/video_capture/video_capture_impl.cc | 65 ++ .../platform/video_capture/video_capture_impl.h | 15 + .../webrtc/convert_to_webrtc_video_frame_buffer.cc | 5 +- .../content/browser/media/tizen_renderer_impl.cc | 141 +++- .../content/browser/media/tizen_renderer_impl.h | 26 +- .../media/tizen/media_player_renderer_client.cc | 6 +- .../media/tizen/media_player_renderer_client.h | 3 +- .../audio/tizen/capi_usb_audio_input_stream.cc | 2 +- .../blink/renderer/tizen_esplusplayer_renderer.cc | 883 +++++++++++++++++++++ .../blink/renderer/tizen_esplusplayer_renderer.h | 304 +++++++ .../video/tizen/video_capture_device_tizen.cc | 7 +- .../media/filters/esplusplayer_util.cc | 5 + .../media/filters/media_player_esplusplayer_tv.cc | 170 +++- .../media/filters/media_player_esplusplayer_tv.h | 22 +- .../media/filters/media_player_tizen.h | 5 + tizen_src/chromium_impl/media/media_efl.gni | 12 + 51 files changed, 2162 insertions(+), 68 deletions(-) create mode 100644 tizen_src/chromium_impl/media/blink/renderer/tizen_esplusplayer_renderer.cc create mode 100644 tizen_src/chromium_impl/media/blink/renderer/tizen_esplusplayer_renderer.h diff --git a/cc/layers/layer_impl.h b/cc/layers/layer_impl.h index 20c3639..ff4af40 100644 --- a/cc/layers/layer_impl.h +++ b/cc/layers/layer_impl.h @@ -472,6 +472,10 @@ class CC_EXPORT LayerImpl { // TODO(sunxd): Remove this function and replace it with visitor pattern. virtual bool is_surface_layer() const; +#if defined(TIZEN_VIDEO_HOLE) && BUILDFLAG(IS_TIZEN_TV) + virtual absl::optional GetVideoId() const { return absl::nullopt; } +#endif + int CalculateJitter(); std::string DebugName() const; diff --git a/cc/layers/video_layer.cc b/cc/layers/video_layer.cc index 21b6d7d..9fb763f 100644 --- a/cc/layers/video_layer.cc +++ b/cc/layers/video_layer.cc @@ -10,13 +10,34 @@ namespace cc { scoped_refptr VideoLayer::Create( VideoFrameProvider* provider, - media::VideoTransformation transform) { - return base::WrapRefCounted(new VideoLayer(provider, transform)); + media::VideoTransformation transform +#if defined(TIZEN_VIDEO_HOLE) && BUILDFLAG(IS_TIZEN_TV) + , + absl::optional player_id +#endif +) { + return base::WrapRefCounted(new VideoLayer(provider, transform +#if defined(TIZEN_VIDEO_HOLE) && BUILDFLAG(IS_TIZEN_TV) + , + player_id +#endif + )); } VideoLayer::VideoLayer(VideoFrameProvider* provider, - media::VideoTransformation transform) - : provider_(provider), transform_(transform) { + media::VideoTransformation transform +#if defined(TIZEN_VIDEO_HOLE) && BUILDFLAG(IS_TIZEN_TV) + , + absl::optional player_id +#endif + ) + : provider_(provider), + transform_(transform) +#if defined(TIZEN_VIDEO_HOLE) && BUILDFLAG(IS_TIZEN_TV) + , + player_id_(player_id) +#endif +{ SetMayContainVideo(true); DCHECK(provider_.Read(*this)); } @@ -26,7 +47,12 @@ VideoLayer::~VideoLayer() = default; std::unique_ptr VideoLayer::CreateLayerImpl( LayerTreeImpl* tree_impl) const { return VideoLayerImpl::Create(tree_impl, id(), provider_.Read(*this), - transform_); + transform_ +#if defined(TIZEN_VIDEO_HOLE) && BUILDFLAG(IS_TIZEN_TV) + , + player_id_ +#endif + ); } bool VideoLayer::RequiresSetNeedsDisplayOnHdrHeadroomChange() const { diff --git a/cc/layers/video_layer.h b/cc/layers/video_layer.h index c8f3ea4..9db97e9 100644 --- a/cc/layers/video_layer.h +++ b/cc/layers/video_layer.h @@ -24,7 +24,12 @@ class VideoLayerImpl; class CC_EXPORT VideoLayer : public Layer { public: static scoped_refptr Create(VideoFrameProvider* provider, - media::VideoTransformation transform); + media::VideoTransformation transform +#if defined(TIZEN_VIDEO_HOLE) && BUILDFLAG(IS_TIZEN_TV) + , + absl::optional player_id +#endif + ); VideoLayer(const VideoLayer&) = delete; VideoLayer& operator=(const VideoLayer&) = delete; @@ -37,9 +42,17 @@ class CC_EXPORT VideoLayer : public Layer { // Clears |provider_| to ensure it is not used after destruction. void StopUsingProvider(); + media::VideoTransformation GetTransform() const { return transform_; } + private: VideoLayer(VideoFrameProvider* provider, - media::VideoTransformation transform); + media::VideoTransformation transform +#if defined(TIZEN_VIDEO_HOLE) && BUILDFLAG(IS_TIZEN_TV) + , + absl::optional player_id +#endif + ); + ~VideoLayer() override; // This pointer is only for passing to VideoLayerImpl's constructor. It should @@ -47,6 +60,10 @@ class CC_EXPORT VideoLayer : public Layer { ProtectedSequenceReadable> provider_; const media::VideoTransformation transform_; + +#if defined(TIZEN_VIDEO_HOLE) && BUILDFLAG(IS_TIZEN_TV) + absl::optional player_id_; +#endif }; } // namespace cc diff --git a/cc/layers/video_layer_impl.cc b/cc/layers/video_layer_impl.cc index b51b823..01a9ade 100644 --- a/cc/layers/video_layer_impl.cc +++ b/cc/layers/video_layer_impl.cc @@ -38,7 +38,12 @@ std::unique_ptr VideoLayerImpl::Create( LayerTreeImpl* tree_impl, int id, VideoFrameProvider* provider, - const media::VideoTransformation& video_transform) { + const media::VideoTransformation& video_transform +#if defined(TIZEN_VIDEO_HOLE) && BUILDFLAG(IS_TIZEN_TV) + , + absl::optional player_id +#endif +) { DCHECK(tree_impl->task_runner_provider()->IsMainThreadBlocked() || base::FeatureList::IsEnabled(features::kNonBlockingCommit)); DCHECK(tree_impl->task_runner_provider()->IsImplThread()); @@ -48,17 +53,32 @@ std::unique_ptr VideoLayerImpl::Create( provider, tree_impl->GetVideoFrameControllerClient()); return base::WrapUnique(new VideoLayerImpl( - tree_impl, id, std::move(provider_client_impl), video_transform)); + tree_impl, id, std::move(provider_client_impl), video_transform +#if defined(TIZEN_VIDEO_HOLE) && BUILDFLAG(IS_TIZEN_TV) + , + player_id +#endif + )); } VideoLayerImpl::VideoLayerImpl( LayerTreeImpl* tree_impl, int id, scoped_refptr provider_client_impl, - const media::VideoTransformation& video_transform) + const media::VideoTransformation& video_transform +#if defined(TIZEN_VIDEO_HOLE) && BUILDFLAG(IS_TIZEN_TV) + , + absl::optional player_id +#endif + ) : LayerImpl(tree_impl, id), provider_client_impl_(std::move(provider_client_impl)), - video_transform_(video_transform) { + video_transform_(video_transform) +#if defined(TIZEN_VIDEO_HOLE) && BUILDFLAG(IS_TIZEN_TV) + , + player_id_(player_id) +#endif +{ set_may_contain_video(true); } @@ -82,7 +102,12 @@ VideoLayerImpl::~VideoLayerImpl() { std::unique_ptr VideoLayerImpl::CreateLayerImpl( LayerTreeImpl* tree_impl) const { return base::WrapUnique(new VideoLayerImpl( - tree_impl, id(), provider_client_impl_, video_transform_)); + tree_impl, id(), provider_client_impl_, video_transform_ +#if defined(TIZEN_VIDEO_HOLE) && BUILDFLAG(IS_TIZEN_TV) + , + player_id_ +#endif + )); } void VideoLayerImpl::DidBecomeActive() { @@ -348,6 +373,12 @@ int VideoLayerImpl::render_target_effect_tree_index() const { } return LayerImpl::render_target_effect_tree_index(); } + +#if BUILDFLAG(IS_TIZEN_TV) +absl::optional VideoLayerImpl::GetVideoId() const { + return player_id_; +} +#endif // BUILDFLAG(IS_TIZEN_TV) #endif void VideoLayerImpl::SetNeedsRedraw() { diff --git a/cc/layers/video_layer_impl.h b/cc/layers/video_layer_impl.h index 4aac591..237fc8c 100644 --- a/cc/layers/video_layer_impl.h +++ b/cc/layers/video_layer_impl.h @@ -37,7 +37,12 @@ class CC_EXPORT VideoLayerImpl : public LayerImpl { LayerTreeImpl* tree_impl, int id, VideoFrameProvider* provider, - const media::VideoTransformation& video_transform); + const media::VideoTransformation& video_transform +#if defined(TIZEN_VIDEO_HOLE) && BUILDFLAG(IS_TIZEN_TV) + , + absl::optional player_id +#endif + ); VideoLayerImpl(const VideoLayerImpl&) = delete; ~VideoLayerImpl() override; @@ -57,6 +62,9 @@ class CC_EXPORT VideoLayerImpl : public LayerImpl { gfx::ContentColorUsage GetContentColorUsage() const override; #if defined(TIZEN_VIDEO_HOLE) int render_target_effect_tree_index() const override; +#if BUILDFLAG(IS_TIZEN_TV) + absl::optional GetVideoId() const override; +#endif // BUILDFLAG(IS_TIZEN_TV) #endif void SetNeedsRedraw(); @@ -74,7 +82,12 @@ class CC_EXPORT VideoLayerImpl : public LayerImpl { LayerTreeImpl* tree_impl, int id, scoped_refptr provider_client_impl, - const media::VideoTransformation& video_transform); + const media::VideoTransformation& video_transform +#if defined(TIZEN_VIDEO_HOLE) && BUILDFLAG(IS_TIZEN_TV) + , + absl::optional player_id +#endif + ); const char* LayerTypeAsString() const override; @@ -94,6 +107,10 @@ class CC_EXPORT VideoLayerImpl : public LayerImpl { media::VideoTransformation video_transform_; +#if defined(TIZEN_VIDEO_HOLE) && BUILDFLAG(IS_TIZEN_TV) + absl::optional player_id_; +#endif + #if defined(TIZEN_TBM_SUPPORT) scoped_refptr context_provider_; viz::ResourceId resource_id_; diff --git a/components/cast_streaming/renderer/control/playback_command_forwarding_renderer.cc b/components/cast_streaming/renderer/control/playback_command_forwarding_renderer.cc index ccf00d8..4255a37 100644 --- a/components/cast_streaming/renderer/control/playback_command_forwarding_renderer.cc +++ b/components/cast_streaming/renderer/control/playback_command_forwarding_renderer.cc @@ -43,6 +43,14 @@ class RendererCommandForwarder : public media::mojom::Renderer { ~RendererCommandForwarder() override = default; // media::mojom::Renderer overrides. +#if defined(TIZEN_MULTIMEDIA) + void EnableLowLatencyMode() override {} + void SetHardwareResource( + media::mojom::HardwareResourceConfig config, + media::mojom::Renderer::SetHardwareResourceCallback) override {} + void RequestVideoDecodedBuffer( + media::mojom::Renderer::RequestVideoDecodedBufferCallback cb) override {} +#endif void Initialize( ::mojo::PendingAssociatedRemote client, absl::optional< diff --git a/media/base/pipeline_impl.cc b/media/base/pipeline_impl.cc index b33eec4..a026dd0 100644 --- a/media/base/pipeline_impl.cc +++ b/media/base/pipeline_impl.cc @@ -712,7 +712,7 @@ void PipelineImpl::RendererWrapper::SetCdm(CdmContext* cdm_context, void PipelineImpl::RendererWrapper::SetMediaGeometry(const gfx::RectF rect_f) { LOG(INFO) << __func__; if (shared_state_.renderer) - shared_state_.renderer->SetMediaGeometry(rect_f); + shared_state_.renderer->SetMediaGeometry(rect_f, media::VIDEO_ROTATION_0); } #endif diff --git a/media/base/renderer.h b/media/base/renderer.h index 133476d..e32caab 100644 --- a/media/base/renderer.h +++ b/media/base/renderer.h @@ -22,6 +22,11 @@ namespace media { class CdmContext; class MediaResource; class RendererClient; +#if defined(TIZEN_MULTIMEDIA) +namespace mojom { +enum class HardwareResourceConfig; +} +#endif // Types of media::Renderer. // WARNING: These values are reported to metrics. Entries should not be @@ -97,18 +102,29 @@ class MEDIA_EXPORT Renderer { #if defined(TIZEN_MULTIMEDIA) virtual void Seek(base::TimeDelta time, base::OnceClosure seek_cb) {} virtual void Suspend() {} + virtual void EnableLowLatencyMode() {} + using SetHardwareResourceCB = base::OnceCallback; + virtual void SetHardwareResource(media::mojom::HardwareResourceConfig config, + SetHardwareResourceCB cb) {} + using RequestVideoDecodedBufferCB = base::OnceCallback; + virtual void RequestVideoDecodedBuffer(RequestVideoDecodedBufferCB cb) {} using ToggledFullscreenCB = base::OnceCallback; virtual void ToggleFullscreenMode(bool is_fullscreen, ToggledFullscreenCB cb) {} #endif #if defined(TIZEN_VIDEO_HOLE) + virtual void SetPlayerVideoAbove(int32_t other_id) {} + virtual void UseSubsurfaceController() {} virtual void SetVideoHole(bool is_video_hole) {} - virtual void SetMediaGeometry(const gfx::RectF& rect) {} + virtual void SetMediaGeometry(const gfx::RectF& rect, + media::VideoRotation rotation) {} #endif using StartDateCB = base::OnceCallback; #if BUILDFLAG(IS_TIZEN_TV) + using GetVideoIdCB = base::OnceCallback; + virtual void GetVideoId(GetVideoIdCB cb) {} virtual void SetContentMimeType(const std::string& mime_type) {} virtual void SetParentalRatingResult(bool is_pass) {} virtual void SetActiveTextTrack(int id, bool is_in_band) {} diff --git a/media/base/video_decoder_config.h b/media/base/video_decoder_config.h index 436cfc0..c288349 100644 --- a/media/base/video_decoder_config.h +++ b/media/base/video_decoder_config.h @@ -24,6 +24,13 @@ namespace media { +#if defined(TIZEN_MULTIMEDIA) +constexpr auto kFHDVideoMaxWidth = 1920; +constexpr auto kFHDVideoMaxHeight = 1080; +constexpr auto k8KVideoMaxWidth = 7680; +constexpr auto k8KVideoMaxHeight = 4320; +#endif + // Describes the content of a video stream, as described by the media container // (or otherwise determined by the demuxer). class MEDIA_EXPORT VideoDecoderConfig { @@ -167,10 +174,16 @@ class MEDIA_EXPORT VideoDecoderConfig { #if BUILDFLAG(IS_TIZEN_TV) void set_hdr_info(const std::string& hdr_info) { hdr_info_ = hdr_info; } const std::string& hdr_info() const { return hdr_info_; } - void set_framerate_num(const int num) { framerate_num_ = num; } - void set_framerate_den(const int den) { framerate_den_ = den; } + void set_framerate_num(int num) { framerate_num_ = num; } + void set_framerate_den(int den) { framerate_den_ = den; } + void set_enable_manual_copy(bool enable) { enable_manual_copy_ = enable; } int framerate_num() const { return framerate_num_; } int framerate_den() const { return framerate_den_; } + bool enable_manual_copy() const { return enable_manual_copy_; } +#endif +#if defined(TIZEN_MULTIMEDIA) + void set_max_coded_size(gfx::Size size) { max_coded_size_ = size; } + const gfx::Size& max_coded_size() const { return max_coded_size_; } #endif private: @@ -201,9 +214,14 @@ class MEDIA_EXPORT VideoDecoderConfig { bool is_rtc_ = false; #if BUILDFLAG(IS_TIZEN_TV) + bool needs_raw_access_ = false; int framerate_num_ = 0; int framerate_den_ = 0; std::string hdr_info_; + bool enable_manual_copy_{false}; +#endif +#if defined(TIZEN_MULTIMEDIA) + gfx::Size max_coded_size_{k8KVideoMaxWidth, k8KVideoMaxHeight}; #endif // Not using DISALLOW_COPY_AND_ASSIGN here intentionally to allow the compiler diff --git a/media/base/video_frame.cc b/media/base/video_frame.cc index e7f03f7..87d60b3 100644 --- a/media/base/video_frame.cc +++ b/media/base/video_frame.cc @@ -521,8 +521,17 @@ scoped_refptr VideoFrame::WrapExternalData( const gfx::Size& natural_size, const uint8_t* data, size_t data_size, - base::TimeDelta timestamp) { - auto layout = GetDefaultLayout(format, coded_size); + base::TimeDelta timestamp, + size_t encoded_data_size) { + absl::optional layout; + if (format == PIXEL_FORMAT_ENCODED) { + auto plane = media::ColorPlaneLayout(encoded_data_size, 0, data_size); + layout = media::VideoFrameLayout::CreateWithPlanes(format, coded_size, + {std::move(plane)}); + } else { + layout = GetDefaultLayout(format, coded_size); + } + if (!layout) return nullptr; return WrapExternalDataWithLayout(*layout, visible_rect, natural_size, data, diff --git a/media/base/video_frame.h b/media/base/video_frame.h index 3ed6fec..f31ae5b 100644 --- a/media/base/video_frame.h +++ b/media/base/video_frame.h @@ -262,7 +262,8 @@ class MEDIA_EXPORT VideoFrame : public base::RefCountedThreadSafe { const gfx::Size& natural_size, const uint8_t* data, size_t data_size, - base::TimeDelta timestamp); + base::TimeDelta timestamp, + size_t encoded_data_size = 0); static scoped_refptr WrapExternalDataWithLayout( const VideoFrameLayout& layout, diff --git a/media/base/video_frame_metadata.cc b/media/base/video_frame_metadata.cc index 24d2844..3a64c017 100644 --- a/media/base/video_frame_metadata.cc +++ b/media/base/video_frame_metadata.cc @@ -70,6 +70,9 @@ void VideoFrameMetadata::MergeMetadataFrom( MERGE_OPTIONAL_FIELD(receive_time, metadata_source); MERGE_OPTIONAL_FIELD(wallclock_frame_duration, metadata_source); MERGE_OPTIONAL_FIELD(maximum_composition_delay_in_frames, metadata_source); +#if BUILDFLAG(IS_TIZEN_TV) + MERGE_OPTIONAL_FIELD(player_id, metadata_source); +#endif #undef MERGE_VALUE_FIELD #undef MERGE_OPTIONAL_FIELD diff --git a/media/base/video_frame_metadata.h b/media/base/video_frame_metadata.h index b14a94a..82a2b0a 100644 --- a/media/base/video_frame_metadata.h +++ b/media/base/video_frame_metadata.h @@ -216,6 +216,10 @@ struct MEDIA_EXPORT VideoFrameMetadata { // This is an experimental feature, see crbug.com/1138888 for more // information. absl::optional maximum_composition_delay_in_frames; + +#if BUILDFLAG(IS_TIZEN_TV) + absl::optional player_id; +#endif }; } // namespace media diff --git a/media/filters/chunk_demuxer.cc b/media/filters/chunk_demuxer.cc index df72051..8daa31a 100644 --- a/media/filters/chunk_demuxer.cc +++ b/media/filters/chunk_demuxer.cc @@ -375,6 +375,8 @@ void ChunkDemuxerStream::CompletePendingReadIfPossible_Locked() { switch (state_) { case UNINITIALIZED: + if (stream_->GetCurrentVideoDecoderConfig().is_rtc()) + return; NOTREACHED_NORETURN(); case RETURNING_ABORT_FOR_READS: // Null buffers should be returned in this state since we are waiting diff --git a/media/mojo/clients/mojo_demuxer_stream_impl.cc b/media/mojo/clients/mojo_demuxer_stream_impl.cc index f4b26f7..7afeabe 100644 --- a/media/mojo/clients/mojo_demuxer_stream_impl.cc +++ b/media/mojo/clients/mojo_demuxer_stream_impl.cc @@ -96,8 +96,14 @@ void MojoDemuxerStreamImpl::OnBufferReady( #if defined(TIZEN_MULTIMEDIA) if (status == Status::kNeedBuffer) { - LOG(INFO) << __func__ << " (" << media::DemuxerStream::GetTypeName(stream_->type()) - << ") kNeedBuffer!"; + static int64_t log_second = -1; + int64_t log_second_now = + (base::TimeTicks::Now() - base::TimeTicks()).InSeconds(); + bool log_on = (log_second != log_second_now); + log_second = log_second_now; + LOG_IF(INFO, log_on) << __func__ << " (" + << media::DemuxerStream::GetTypeName(stream_->type()) + << ") kNeedBuffer!"; std::move(callback).Run(Status::kNeedBuffer, {}, audio_config, video_config); return; diff --git a/media/mojo/clients/mojo_renderer.cc b/media/mojo/clients/mojo_renderer.cc index 148a8b3..8c7ff42 100644 --- a/media/mojo/clients/mojo_renderer.cc +++ b/media/mojo/clients/mojo_renderer.cc @@ -256,14 +256,27 @@ base::TimeDelta MojoRenderer::GetMediaTime() { } #if defined(TIZEN_VIDEO_HOLE) +void MojoRenderer::SetPlayerVideoAbove(int32_t other_id) { + DVLOG(2) << __func__; + BindRemoteRendererIfNeeded(); + remote_renderer_->SetPlayerVideoAbove(other_id); +} + +void MojoRenderer::UseSubsurfaceController() { + DVLOG(2) << __func__; + BindRemoteRendererIfNeeded(); + remote_renderer_->UseSubsurfaceController(); +} + void MojoRenderer::SetVideoHole(bool is_video_hole) { BindRemoteRendererIfNeeded(); remote_renderer_->SetVideoHole(is_video_hole); } -void MojoRenderer::SetMediaGeometry(const gfx::RectF& rect) { +void MojoRenderer::SetMediaGeometry(const gfx::RectF& rect, + VideoRotation rotation) { if (remote_renderer_.is_bound()) - remote_renderer_->SetMediaGeometry(rect); + remote_renderer_->SetMediaGeometry(rect, rotation); } #endif @@ -271,6 +284,26 @@ RendererType MojoRenderer::GetRendererType() { return RendererType::kMojo; } +#if defined(TIZEN_MULTIMEDIA) +void MojoRenderer::EnableLowLatencyMode() { + LOG(INFO) << __func__; + if (remote_renderer_.is_bound()) + remote_renderer_->EnableLowLatencyMode(); +} + +void MojoRenderer::SetHardwareResource(mojom::HardwareResourceConfig config, + SetHardwareResourceCB cb) { + LOG(INFO) << __func__; + if (remote_renderer_.is_bound()) + remote_renderer_->SetHardwareResource(config, std::move(cb)); +} + +void MojoRenderer::RequestVideoDecodedBuffer(RequestVideoDecodedBufferCB cb) { + if (remote_renderer_.is_bound()) + remote_renderer_->RequestVideoDecodedBuffer(std::move(cb)); +} +#endif + void MojoRenderer::OnTimeUpdate(base::TimeDelta time, base::TimeDelta max_time, base::TimeTicks capture_time) { @@ -344,6 +377,13 @@ void MojoRenderer::OnStatisticsUpdate(const PipelineStatistics& stats) { } #if BUILDFLAG(IS_TIZEN_TV) +void MojoRenderer::GetVideoId(GetVideoIdCB cb) { + DCHECK(task_runner_->RunsTasksInCurrentSequence()); + + if (remote_renderer_.is_bound()) + remote_renderer_->GetVideoId(std::move(cb)); +} + void MojoRenderer::SetContentMimeType(const std::string& mime_type) { DVLOG(2) << __func__ << " mime_type : " << mime_type; DCHECK(task_runner_->RunsTasksInCurrentSequence()); diff --git a/media/mojo/clients/mojo_renderer.h b/media/mojo/clients/mojo_renderer.h index 8ae441e..5bf3a50 100644 --- a/media/mojo/clients/mojo_renderer.h +++ b/media/mojo/clients/mojo_renderer.h @@ -62,6 +62,10 @@ class MojoRenderer : public Renderer, public mojom::RendererClient { #if defined(TIZEN_MULTIMEDIA) void Seek(base::TimeDelta time, base::OnceClosure seek_cb) override; void Suspend() override; + void EnableLowLatencyMode() override; + void SetHardwareResource(mojom::HardwareResourceConfig config, + SetHardwareResourceCB cb) override; + void RequestVideoDecodedBuffer(RequestVideoDecodedBufferCB cb) override; void ToggleFullscreenMode(bool is_fullscreen, ToggledFullscreenCB cb) override; #endif @@ -72,11 +76,15 @@ class MojoRenderer : public Renderer, public mojom::RendererClient { RendererType GetRendererType() override; #if defined(TIZEN_VIDEO_HOLE) + void SetPlayerVideoAbove(int32_t other_id) override; + void UseSubsurfaceController() override; void SetVideoHole(bool is_video_hole) override; - void SetMediaGeometry(const gfx::RectF& rect) override; + void SetMediaGeometry(const gfx::RectF& rect, + VideoRotation rotation) override; #endif #if BUILDFLAG(IS_TIZEN_TV) + void GetVideoId(GetVideoIdCB cb) override; void SetContentMimeType(const std::string& mime_type) override; void SetParentalRatingResult(bool is_pass) override; void SetActiveTextTrack(int id, bool is_in_band) override; diff --git a/media/mojo/clients/mojo_renderer_wrapper.cc b/media/mojo/clients/mojo_renderer_wrapper.cc index f5dee67..bff94b6 100644 --- a/media/mojo/clients/mojo_renderer_wrapper.cc +++ b/media/mojo/clients/mojo_renderer_wrapper.cc @@ -67,8 +67,9 @@ void MojoRendererWrapper::SetVideoHole(bool is_video_hole) { mojo_renderer_->SetVideoHole(is_video_hole); } -void MojoRendererWrapper::SetMediaGeometry(const gfx::RectF& rect) { - mojo_renderer_->SetMediaGeometry(rect); +void MojoRendererWrapper::SetMediaGeometry(const gfx::RectF& rect, + VideoRotation rotation) { + mojo_renderer_->SetMediaGeometry(rect, rotation); } #endif @@ -77,6 +78,11 @@ base::TimeDelta MojoRendererWrapper::GetMediaTime() { } #if BUILDFLAG(IS_TIZEN_TV) +void MojoRendererWrapper::GetVideoId(GetVideoIdCB cb) { + if (mojo_renderer_) + mojo_renderer_->GetVideoId(std::move(cb)); +} + void MojoRendererWrapper::SetContentMimeType(const std::string& mime_type) { if (mojo_renderer_) mojo_renderer_->SetContentMimeType(mime_type); diff --git a/media/mojo/clients/mojo_renderer_wrapper.h b/media/mojo/clients/mojo_renderer_wrapper.h index 4bf07fe..1dc7c14 100644 --- a/media/mojo/clients/mojo_renderer_wrapper.h +++ b/media/mojo/clients/mojo_renderer_wrapper.h @@ -45,11 +45,14 @@ class MojoRendererWrapper : public Renderer { #if defined(TIZEN_VIDEO_HOLE) void SetVideoHole(bool is_video_hole) override; - void SetMediaGeometry(const gfx::RectF& rect) override; + void SetMediaGeometry(const gfx::RectF& rect, + VideoRotation rotation) override; #endif #if BUILDFLAG(IS_TIZEN_TV) using StartDateCB = base::OnceCallback; + using GetVideoIdCB = base::OnceCallback; + void GetVideoId(GetVideoIdCB cb) override; void SetContentMimeType(const std::string& mime_type) override; void SetParentalRatingResult(bool is_pass) override; void SetActiveTextTrack(int id, bool is_in_band) override; diff --git a/media/mojo/mojom/media_types.mojom b/media/mojo/mojom/media_types.mojom index d86cdf8..7ea0505 100644 --- a/media/mojo/mojom/media_types.mojom +++ b/media/mojo/mojom/media_types.mojom @@ -196,6 +196,7 @@ struct VideoDecoderConfig { EncryptionScheme encryption_scheme; VideoColorSpace color_space_info; gfx.mojom.HDRMetadata? hdr_metadata; + bool is_rtc; [EnableIf=is_tizen_tv] string hdr_info; [EnableIf=is_tizen_tv] diff --git a/media/mojo/mojom/renderer.mojom b/media/mojo/mojom/renderer.mojom index b6aaaf0..79a0f93 100644 --- a/media/mojo/mojom/renderer.mojom +++ b/media/mojo/mojom/renderer.mojom @@ -23,6 +23,15 @@ struct MediaUrlParams { bool is_hls; }; +[EnableIf=tizen_multimedia] +enum HardwareResourceConfig { + kMainDecoderMainScaler = 0, + kSubDecoderSubScaler, + kSubDecoderMainScaler, + kMainDecoderSubScaler, + kNone, +}; + // A Mojo equivalent of media::Renderer. Used when audio and video decoding // happens outside of the sandboxed render process. // See media/mojo/README.md @@ -60,10 +69,25 @@ interface Renderer { SetCdm(mojo_base.mojom.UnguessableToken? cdm_id) => (bool success); [EnableIf=tizen_video_hole] + SetPlayerVideoAbove(int32 other_id); + + [EnableIf=tizen_video_hole] + UseSubsurfaceController(); + + [EnableIf=tizen_video_hole] SetVideoHole(bool is_video_hole); [EnableIf=tizen_video_hole] - SetMediaGeometry(gfx.mojom.RectF rect); + SetMediaGeometry(gfx.mojom.RectF rect, VideoRotation rotation); + + [EnableIf=tizen_multimedia] + EnableLowLatencyMode(); + + [EnableIf=tizen_multimedia] + SetHardwareResource(HardwareResourceConfig config) => (bool success); + + [EnableIf=tizen_multimedia] + RequestVideoDecodedBuffer() => (bool success); [EnableIf=tizen_multimedia] ToggleFullscreenMode(bool is_fullscreen) => (); @@ -72,6 +96,9 @@ interface Renderer { SetContentMimeType(string mime_type); [EnableIf=is_tizen_tv] + GetVideoId()=> (int32 player_id); + + [EnableIf=is_tizen_tv] SetParentalRatingResult(bool is_pass); [EnableIf=is_tizen_tv] diff --git a/media/mojo/mojom/renderer_extensions.mojom b/media/mojo/mojom/renderer_extensions.mojom index 966f077..b4a775c 100644 --- a/media/mojo/mojom/renderer_extensions.mojom +++ b/media/mojo/mojom/renderer_extensions.mojom @@ -102,6 +102,12 @@ interface MediaPlayerRendererExtension { [EnableIf=tizen_tbm_support] OnTbmBufferExhausted(gfx.mojom.TbmBufferHandle tbm_buffer_handle); + + [EnableIf=is_tizen_tv] + EnableTbmBufferCallback(bool enabled); + + [EnableIf=is_tizen_tv] + SetCallBackFrameSize(gfx.mojom.Size size); }; // Extension of the mojo::RendererClient communication layer for media flinging, diff --git a/media/mojo/mojom/video_decoder_config_mojom_traits.cc b/media/mojo/mojom/video_decoder_config_mojom_traits.cc index ed74736..dcf30fa 100644 --- a/media/mojo/mojom/video_decoder_config_mojom_traits.cc +++ b/media/mojo/mojom/video_decoder_config_mojom_traits.cc @@ -63,6 +63,8 @@ bool StructTraitsset_level(input.level()); + output->set_is_rtc(input.is_rtc()); + #if BUILDFLAG(IS_TIZEN_TV) std::string hdr; if (!input.ReadHdrInfo(&hdr)) diff --git a/media/mojo/mojom/video_decoder_config_mojom_traits.h b/media/mojo/mojom/video_decoder_config_mojom_traits.h index 5dff94d..204c0ab 100644 --- a/media/mojo/mojom/video_decoder_config_mojom_traits.h +++ b/media/mojo/mojom/video_decoder_config_mojom_traits.h @@ -74,6 +74,10 @@ struct StructTraitsSuspend(); } +void MojoRendererService::EnableLowLatencyMode() { + DVLOG(2) << __func__; + renderer_->EnableLowLatencyMode(); +} + +void MojoRendererService::SetHardwareResource( + media::mojom::HardwareResourceConfig config, + mojom::Renderer::SetHardwareResourceCallback cb) { + DVLOG(2) << __func__; + renderer_->SetHardwareResource(config, std::move(cb)); +} + +void MojoRendererService::RequestVideoDecodedBuffer( + mojom::Renderer::RequestVideoDecodedBufferCallback cb) { + renderer_->RequestVideoDecodedBuffer(std::move(cb)); +} + void MojoRendererService::ToggleFullscreenMode( bool is_fullscreen, ToggleFullscreenModeCallback callback) { @@ -178,12 +195,21 @@ void MojoRendererService::SetCdm( } #if defined(TIZEN_VIDEO_HOLE) +void MojoRendererService::SetPlayerVideoAbove(int32_t other_id) { + renderer_->SetPlayerVideoAbove(other_id); +} + +void MojoRendererService::UseSubsurfaceController() { + renderer_->UseSubsurfaceController(); +} + void MojoRendererService::SetVideoHole(bool is_video_hole) { renderer_->SetVideoHole(is_video_hole); } -void MojoRendererService::SetMediaGeometry(const gfx::RectF& rect) { - renderer_->SetMediaGeometry(rect); +void MojoRendererService::SetMediaGeometry(const gfx::RectF& rect, + VideoRotation rotation) { + renderer_->SetMediaGeometry(rect, rotation); } #endif @@ -210,6 +236,12 @@ void MojoRendererService::OnStatisticsUpdate(const PipelineStatistics& stats) { } #if BUILDFLAG(IS_TIZEN_TV) +void MojoRendererService::GetVideoId(GetVideoIdCallback cb) { + DVLOG(3) << __func__; + if (renderer_) + renderer_->GetVideoId(std::move(cb)); +} + void MojoRendererService::SetContentMimeType(const std::string& mime_type) { DVLOG(3) << __func__ << ", mime_type: " << mime_type; if (renderer_) diff --git a/media/mojo/services/mojo_renderer_service.h b/media/mojo/services/mojo_renderer_service.h index c4ced5f..4ddd5a5 100644 --- a/media/mojo/services/mojo_renderer_service.h +++ b/media/mojo/services/mojo_renderer_service.h @@ -68,6 +68,12 @@ class MEDIA_MOJO_EXPORT MojoRendererService final : public mojom::Renderer, #if defined(TIZEN_MULTIMEDIA) void Seek(base::TimeDelta time, base::OnceClosure seek_cb) final; void Suspend() final; + void EnableLowLatencyMode() final; + void SetHardwareResource( + media::mojom::HardwareResourceConfig config, + mojom::Renderer::SetHardwareResourceCallback cb) final; + void RequestVideoDecodedBuffer( + mojom::Renderer::RequestVideoDecodedBufferCallback cb) final; void ToggleFullscreenMode(bool is_fullscreen, ToggleFullscreenModeCallback callback) final; #endif @@ -79,10 +85,13 @@ class MEDIA_MOJO_EXPORT MojoRendererService final : public mojom::Renderer, #if defined(TIZEN_VIDEO_HOLE) void SetVideoHole(bool is_video_hole) final; - void SetMediaGeometry(const gfx::RectF& rect) final; + void SetMediaGeometry(const gfx::RectF& rect, VideoRotation rotation) final; + void SetPlayerVideoAbove(int32_t other_id) final; + void UseSubsurfaceController() final; #endif #if BUILDFLAG(IS_TIZEN_TV) + void GetVideoId(GetVideoIdCallback cb) final; void SetContentMimeType(const std::string& mime_type) final; void SetParentalRatingResult(bool is_pass) final; void SetActiveTextTrack(int id, bool is_in_band) final; diff --git a/third_party/blink/public/platform/modules/mediastream/web_media_stream_sink.h b/third_party/blink/public/platform/modules/mediastream/web_media_stream_sink.h index 263cbea..e30f95c 100644 --- a/third_party/blink/public/platform/modules/mediastream/web_media_stream_sink.h +++ b/third_party/blink/public/platform/modules/mediastream/web_media_stream_sink.h @@ -9,6 +9,7 @@ #include "third_party/blink/public/platform/modules/mediastream/web_media_stream_source.h" #include "third_party/blink/public/platform/modules/mediastream/web_media_stream_track.h" #include "third_party/blink/public/platform/web_common.h" +#include "ui/gfx/geometry/rect_f.h" namespace blink { diff --git a/third_party/blink/public/web/modules/mediastream/webmediaplayer_ms.h b/third_party/blink/public/web/modules/mediastream/webmediaplayer_ms.h index ac40925..36d2c4e 100644 --- a/third_party/blink/public/web/modules/mediastream/webmediaplayer_ms.h +++ b/third_party/blink/public/web/modules/mediastream/webmediaplayer_ms.h @@ -187,6 +187,9 @@ class BLINK_MODULES_EXPORT WebMediaPlayerMS bool is_opaque); void OnOpacityChanged(bool is_opaque); void OnTransformChanged(media::VideoTransformation video_transform); +#if defined(TIZEN_VIDEO_HOLE) && BUILDFLAG(IS_TIZEN_TV) + void SetPlayerId(int id); +#endif // defined(TIZEN_VIDEO_HOLE) && BUILDFLAG(IS_TIZEN_TV) // WebMediaStreamObserver implementation void TrackAdded(const WebString& track_id) override; @@ -349,6 +352,10 @@ class BLINK_MODULES_EXPORT WebMediaPlayerMS // Whether the use of a surface layer instead of a video layer is enabled. bool use_surface_layer_ = false; +#if BUILDFLAG(IS_TIZEN_TV) + int player_id_{0}; +#endif + // Owns the weblayer and obtains/maintains SurfaceIds for // kUseSurfaceLayerForVideo feature. std::unique_ptr bridge_; diff --git a/third_party/blink/renderer/modules/mediastream/local_video_capturer_source.cc b/third_party/blink/renderer/modules/mediastream/local_video_capturer_source.cc index dfbbff4..f4796ac 100644 --- a/third_party/blink/renderer/modules/mediastream/local_video_capturer_source.cc +++ b/third_party/blink/renderer/modules/mediastream/local_video_capturer_source.cc @@ -138,18 +138,30 @@ void LocalVideoCapturerSource::OnStateUpdate(blink::VideoCaptureState state) { case VIDEO_CAPTURE_STATE_ERROR: case VIDEO_CAPTURE_STATE_ERROR_SYSTEM_PERMISSIONS_DENIED: case VIDEO_CAPTURE_STATE_ERROR_CAMERA_BUSY: - case VIDEO_CAPTURE_STATE_ENDED: + case VIDEO_CAPTURE_STATE_ENDED: { + // |release_device_cb_| will unref device by one, and UseDevice will ref + // device by one, call |release_device_cb_| first will cause a unnecessary + // device re-creating opt. for currently camera preview playback solution, + // geometry info from renderer may be missed durnning device recreating. +#if BUILDFLAG(IS_TIZEN_TV) && defined(TIZEN_MULTIMEDIA) + base::OnceClosure post_release_device_cb = std::move(release_device_cb_); +#else std::move(release_device_cb_).Run(); +#endif release_device_cb_ = frame && frame->Client() ? manager_->UseDevice(session_id_, &frame->GetBrowserInterfaceBroker()) : base::DoNothing(); +#if BUILDFLAG(IS_TIZEN_TV) && defined(TIZEN_MULTIMEDIA) + std::move(post_release_device_cb).Run(); +#endif OnLog( "LocalVideoCapturerSource::OnStateUpdate signaling to " "consumer that source is no longer running."); running_callback_.Run(run_state); break; + } case VIDEO_CAPTURE_STATE_STARTING: case VIDEO_CAPTURE_STATE_PAUSED: diff --git a/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms.cc b/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms.cc index bb3277e..cd2f694 100644 --- a/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms.cc +++ b/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms.cc @@ -56,6 +56,10 @@ #include "third_party/blink/renderer/platform/wtf/cross_thread_copier_media.h" #include "third_party/blink/renderer/platform/wtf/cross_thread_functional.h" +#if defined(TIZEN_VIDEO_HOLE) +#include "ui/gfx/geometry/rect_f.h" +#endif + #if BUILDFLAG(IS_TIZEN) #include "tizen/system_info.h" #endif @@ -189,6 +193,63 @@ class WebMediaPlayerMS::FrameDeliverer { void OnVideoFrame(scoped_refptr frame) { DCHECK_CALLED_ON_VALID_SEQUENCE(video_sequence_checker_); +#if defined(TIZEN_VIDEO_HOLE) && BUILDFLAG(IS_TIZEN_TV) + if (frame->metadata().player_id.has_value()) { + const int player_id = frame->metadata().player_id.value_or(0); + if (player_id != player_id_) { + player_id_ = player_id; + main_task_runner_->PostTask( + FROM_HERE, base::BindOnce(&WebMediaPlayerMS::SetPlayerId, player_, + player_id_)); + } + if (frame->format() == media::PIXEL_FORMAT_ENCODED) { + auto orig_frame = frame; + frame = media::VideoFrame::CreateHoleFrame(orig_frame->natural_size()); + frame->set_timestamp(orig_frame->timestamp()); + frame->metadata().player_id = player_id_; + } + } + + // Make new frame in case there is any TBM buffer attached to prevent + // keeping the buffer in case when rendering stalls + if (frame->storage_type() == media::VideoFrame::STORAGE_HOLE) { +#if defined(TIZEN_TBM_SUPPORT) + if (frame->format() == media::PIXEL_FORMAT_TBM_INTER_PROCESS_BUFFER && + request_frame_in_progress_) { + base::AutoLock auto_lock(request_buffer_lock_); + scoped_refptr decoded_video_frame = + media::VideoFrame::WrapExternalYuvData( + media::VideoPixelFormat::PIXEL_FORMAT_NV12, frame->coded_size(), + frame->visible_rect(), frame->natural_size(), + frame->stride(media::VideoFrame::kYPlane), + frame->stride(media::VideoFrame::kUVPlane), + frame->GetWritableVisibleData(media::VideoFrame::kYPlane), + frame->GetWritableVisibleData(media::VideoFrame::kUVPlane), + frame->timestamp()); + request_frame_in_progress_ = false; + if (decoded_video_frame) { + decoded_video_frame->metadata().MergeMetadataFrom(frame->metadata()); + decoded_frame_cb_.Run(std::move(decoded_video_frame)); + } + } +#endif // defined(TIZEN_TBM_SUPPORT) + auto orig_frame = frame; + frame = media::VideoFrame::CreateHoleFrame(orig_frame->natural_size()); + frame->set_timestamp(orig_frame->timestamp()); + frame->metadata().MergeMetadataFrom(orig_frame->metadata()); + EnqueueFrame(orig_frame->unique_id(), std::move(frame)); + return; + } else if (frame->metadata().end_of_stream) { + // create a hole frame to prevent renderer from reading the dirty data in + // eos frame + auto orig_frame = frame; + frame = media::VideoFrame::CreateHoleFrame(orig_frame->natural_size()); + frame->set_timestamp(orig_frame->timestamp()); + frame->metadata().MergeMetadataFrom(orig_frame->metadata()); + EnqueueFrame(orig_frame->unique_id(), std::move(frame)); + return; + } +#endif // defined(TIZEN_VIDEO_HOLE) && BUILDFLAG(IS_TIZEN_TV) // On Android, stop passing frames. #if BUILDFLAG(IS_ANDROID) @@ -330,6 +391,20 @@ class WebMediaPlayerMS::FrameDeliverer { weak_factory_for_pool_.InvalidateWeakPtrs(); } +#if BUILDFLAG(IS_TIZEN_TV) && defined(TIZEN_TBM_SUPPORT) + void RequestVideoDecodedBuffer() { + base::AutoLock auto_lock(request_buffer_lock_); + request_frame_in_progress_ = true; + } + + RequestCB decoded_frame_cb_; + base::Lock request_buffer_lock_; + bool request_frame_in_progress_ = false; +#endif + +#if defined(TIZEN_VIDEO_HOLE) && BUILDFLAG(IS_TIZEN_TV) + int player_id_{0}; +#endif // defined(TIZEN_VIDEO_HOLE) && BUILDFLAG(IS_TIZEN_TV) bool render_frame_suspended_ = false; const scoped_refptr main_task_runner_; @@ -1313,12 +1388,31 @@ void WebMediaPlayerMS::OnTransformChanged( // Keep the old |video_layer_| alive until SetCcLayer() is called with a new // pointer, as it may use the pointer from the last call. auto new_video_layer = - cc::VideoLayer::Create(compositor_.get(), video_transform); + cc::VideoLayer::Create(compositor_.get(), video_transform +#if defined(TIZEN_VIDEO_HOLE) && BUILDFLAG(IS_TIZEN_TV) + , + absl::optional(player_id_) +#endif + ); + get_client()->SetCcLayer(new_video_layer.get()); video_layer_ = std::move(new_video_layer); } } +#if defined(TIZEN_VIDEO_HOLE) && BUILDFLAG(IS_TIZEN_TV) +void WebMediaPlayerMS::SetPlayerId(int player_id) { + LOG(INFO) << __func__ << " player_id: " << player_id; + player_id_ = player_id; + + if (video_layer_) { + // If we have a video_layer_ already, then we need to call + // OnTransformChanged to reset it with new player_id_. + OnTransformChanged(video_layer_->GetTransform()); + } +} +#endif // defined(TIZEN_VIDEO_HOLE) && BUILDFLAG(IS_TIZEN_TV) + bool WebMediaPlayerMS::IsInPictureInPicture() const { DCHECK(client_); return (!client_->IsInAutoPIP() && diff --git a/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms_compositor.cc b/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms_compositor.cc index 745f009..337cf39 100644 --- a/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms_compositor.cc +++ b/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms_compositor.cc @@ -39,6 +39,11 @@ #include "third_party/libyuv/include/libyuv/video_common.h" #include "third_party/skia/include/core/SkSurface.h" +#if BUILDFLAG(IS_TIZEN_TV) && defined(TIZEN_VIDEO_HOLE) && \ + defined(TIZEN_MULTIMEDIA) +#include "media/blink/renderer/tizen_esplusplayer_renderer.h" +#endif + namespace WTF { template @@ -299,6 +304,37 @@ WebMediaPlayerMSCompositor::Metadata WebMediaPlayerMSCompositor::GetMetadata() { return current_metadata_; } +#if defined(TIZEN_VIDEO_HOLE) +void WebMediaPlayerMSCompositor::OnDrawableContentRectChanged( + const gfx::Rect& rect) { +#if BUILDFLAG(IS_TIZEN_TV) + media::VideoRotation rotation = media::VIDEO_ROTATION_0; + if (current_frame_ && current_frame_->metadata().transformation.has_value()) + rotation = current_frame_->metadata().transformation.value().rotation; + + std::int32_t player_id{0}; + { + base::AutoLock auto_lock(current_frame_lock_); + if (current_frame_) { + player_id = current_frame_->metadata().player_id.value_or(0); + } + } + + LOG(INFO) << "WebMediaPlayerMSCompositor::OnDrawableContentRectChanged: " + << ", player id:" << player_id << ", rect:" << rect.ToString() + << ", rotation " << media::VideoRotationToString(rotation); + + if (player_id != 0) { +#if BUILDFLAG(IS_TIZEN_TV) && defined(TIZEN_VIDEO_HOLE) && \ + defined(TIZEN_MULTIMEDIA) + media::TizenEsPlusPlayerRendererManager::GetInstance() + .OnVideoSinkGeometryChange(player_id, gfx::RectF{rect}, rotation); +#endif + } +#endif // BUILDFLAG(IS_TIZEN_TV) +} +#endif // defined(TIZEN_VIDEO_HOLE) + void WebMediaPlayerMSCompositor::SetForceSubmit(bool force_submit) { DCHECK(video_frame_compositor_task_runner_->BelongsToCurrentThread()); submitter_->SetForceSubmit(force_submit); diff --git a/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms_compositor.h b/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms_compositor.h index c6d73a6..9b81ccb 100644 --- a/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms_compositor.h +++ b/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms_compositor.h @@ -153,7 +153,7 @@ class MODULES_EXPORT WebMediaPlayerMSCompositor DrawableContentRectChangedCallback cb) override {} // Notifies the client of video plane geometry to be use. - void OnDrawableContentRectChanged(const gfx::Rect&) override {} + void OnDrawableContentRectChanged(const gfx::Rect& rect) override; #endif private: diff --git a/third_party/blink/renderer/platform/media/BUILD.gn b/third_party/blink/renderer/platform/media/BUILD.gn index 7062313..4a6bb85 100644 --- a/third_party/blink/renderer/platform/media/BUILD.gn +++ b/third_party/blink/renderer/platform/media/BUILD.gn @@ -4,6 +4,10 @@ import("//media/media_options.gni") +if (tizen_multimedia) { + import("//tizen_src/chromium_impl/media/media_efl.gni") +} + # TODO(https://crbug.com/1198341): use blink_platform_sources once the code is # ported to Blink code conventions. component("media") { @@ -108,6 +112,11 @@ component("media") { "hls_data_source_provider_impl.h", ] } + + if (tizen_multimedia) { + configs += external_media_efl_blink_config + sources += external_media_efl_blink_sources + } } source_set("unit_tests") { diff --git a/third_party/blink/renderer/platform/media/web_media_player_impl.cc b/third_party/blink/renderer/platform/media/web_media_player_impl.cc index 1542bc1..f11a400 100644 --- a/third_party/blink/renderer/platform/media/web_media_player_impl.cc +++ b/third_party/blink/renderer/platform/media/web_media_player_impl.cc @@ -2104,7 +2104,12 @@ void WebMediaPlayerImpl::OnMetadata(const media::PipelineMetadata& metadata) { DCHECK(!video_layer_); video_layer_ = cc::VideoLayer::Create( compositor_.get(), - pipeline_metadata_.video_decoder_config.video_transformation()); + pipeline_metadata_.video_decoder_config.video_transformation() +#if defined(TIZEN_VIDEO_HOLE) && BUILDFLAG(IS_TIZEN_TV) + , + absl::nullopt +#endif + ); video_layer_->SetContentsOpaque(opaque_); client_->SetCcLayer(video_layer_.get()); } diff --git a/third_party/blink/renderer/platform/peerconnection/webrtc_video_track_source.cc b/third_party/blink/renderer/platform/peerconnection/webrtc_video_track_source.cc index d3218bc3..ef39ad3 100644 --- a/third_party/blink/renderer/platform/peerconnection/webrtc_video_track_source.cc +++ b/third_party/blink/renderer/platform/peerconnection/webrtc_video_track_source.cc @@ -10,6 +10,7 @@ #include "base/trace_event/trace_event.h" #include "base/types/optional_util.h" #include "media/base/media_switches.h" +#include "media/base/video_types.h" #include "third_party/abseil-cpp/absl/types/optional.h" #include "third_party/blink/renderer/platform/webrtc/convert_to_webrtc_video_frame_buffer.h" #include "third_party/blink/renderer/platform/webrtc/webrtc_video_utils.h" @@ -223,6 +224,26 @@ void WebRtcVideoTrackSource::OnFrameCaptured( webrtc::Timestamp::Micros(frame->timestamp().InMicroseconds()); } +#if BUILDFLAG(IS_TIZEN) + if (frame->format() == media::PIXEL_FORMAT_ENCODED +#if defined(TIZEN_VIDEO_HOLE) + || frame->storage_type() == media::VideoFrame::STORAGE_HOLE +#endif + ) { + // The webrtc::VideoFrame::UpdateRect expected by WebRTC must + // be relative to the |visible_rect()|. We need to translate. + absl::optional cropped_rect; + if (accumulated_update_rect_) { + cropped_rect = + CropRectangle(*accumulated_update_rect_, frame->visible_rect()); + } + + DeliverFrame(std::move(frame), base::OptionalToPtr(cropped_rect), + translated_camera_time_us, capture_time_identifier); + return; + } +#endif + // Translate the |crop_*| values output by AdaptFrame() from natural size to // visible size. This is needed to apply the new cropping on top of any // existing soft-applied cropping and scaling when using diff --git a/third_party/blink/renderer/platform/video_capture/video_capture_impl.cc b/third_party/blink/renderer/platform/video_capture/video_capture_impl.cc index 68bbcb5..0fcf81e 100644 --- a/third_party/blink/renderer/platform/video_capture/video_capture_impl.cc +++ b/third_party/blink/renderer/platform/video_capture/video_capture_impl.cc @@ -854,7 +854,14 @@ void VideoCaptureImpl::StopCapture(int client_id) { DVLOG(1) << "StopCapture: No more client, stopping ..."; StopDevice(); client_buffers_.clear(); +#if !BUILDFLAG(IS_TIZEN_TV) && !defined(TIZEN_MULTIMEDIA) + // the current weak ptr is owned by capture impl manager, and this capture + // impl instance shall not be able to re-start again by invalidate weak ptr. + // it is supposed to re-creating capture impl instead, but re-creating is + // skipped on tizen tv product, so remove this line to make it available + // to respond to the follow-up callings. weak_factory_.InvalidateWeakPtrs(); +#endif } void VideoCaptureImpl::RequestRefreshFrame() { @@ -940,7 +947,10 @@ void VideoCaptureImpl::OnStateChanged( OnLog("VideoCaptureImpl changing state to VIDEO_CAPTURE_STATE_STOPPED"); state_ = VIDEO_CAPTURE_STATE_STOPPED; client_buffers_.clear(); +#if !BUILDFLAG(IS_TIZEN_TV) && !defined(TIZEN_MULTIMEDIA) + // see comments in StopCapture weak_factory_.InvalidateWeakPtrs(); +#endif if (!clients_.empty() || !clients_pending_on_restart_.empty()) { OnLog("VideoCaptureImpl restarting capture"); RestartCapture(); @@ -1026,6 +1036,28 @@ void VideoCaptureImpl::OnBufferReady( (reference_time - base::TimeTicks()).InMicroseconds(), "time_delta", buffer->info->timestamp.InMicroseconds()); +#if BUILDFLAG(IS_TIZEN_TV) && defined(TIZEN_VIDEO_HOLE) && \ + defined(TIZEN_MULTIMEDIA) + // push shared buffer handle to tizen esplusplayer renderer + const auto& iter = client_buffers_.find(buffer->buffer_id); + DCHECK(iter != client_buffers_.end()); + scoped_refptr buffer_context = iter->second; + if (buffer_context->buffer_type() == + VideoFrameBufferHandleType::kUnsafeShmemRegion && + buffer->info->pixel_format == media::PIXEL_FORMAT_ENCODED) { + if (renderer_ && renderer_->IsReady()) { + renderer_->QueueBuffer(buffer->info->metadata, buffer->info->coded_size, + buffer_context->data(), + buffer->info->encoded_data_size, + true /* key frame */); + GetVideoCaptureHost()->ReleaseBuffer(device_id_, buffer->buffer_id, + media::VideoCaptureFeedback()); + return; + } + LOG(INFO) << "renderer is not exists, or not prepared."; + } +#endif + // Create and initialize frame preparers for the non-scaled and the scaled // frames. auto frame_preparer = @@ -1076,6 +1108,18 @@ void VideoCaptureImpl::BindVideoFrameOnMediaThread( std::move(on_frame_ready_callback).Run(std::move(frame_preparer)); } +#if BUILDFLAG(IS_TIZEN_TV) && defined(TIZEN_VIDEO_HOLE) && \ + defined(TIZEN_MULTIMEDIA) +void VideoCaptureImpl::OnVideoFrameReadyFromRenderer( + scoped_refptr frame, + base::TimeTicks reference_time) { + DCHECK_CALLED_ON_VALID_THREAD(io_thread_checker_); + for (const auto& client : clients_) { + client.second.deliver_frame_cb.Run(frame, reference_time); + } +} +#endif + void VideoCaptureImpl::OnVideoFrameReady( base::TimeTicks reference_time, std::unique_ptr frame_preparer) { @@ -1217,6 +1261,27 @@ void VideoCaptureImpl::StartCaptureInternal() { } start_outcome_reported_ = false; base::UmaHistogramBoolean("Media.VideoCapture.Start", true); +#if BUILDFLAG(IS_TIZEN_TV) && defined(TIZEN_VIDEO_HOLE) && \ + defined(TIZEN_MULTIMEDIA) + const media::VideoCodec codec = + (params_.requested_format.pixel_format == media::PIXEL_FORMAT_ENCODED + ? media::VideoCodec::kH264 + : media::VideoCodec::kMJPEG); + if (!renderer_) + renderer_ = media::TizenEsPlusPlayerRendererManager::GetInstance() + .CreateTizenEsPlusPlayerRenderer( + codec, gfx::Size(1920, 1080), + media::HardwareResouceType::kSub, /* sub-scaler */ + media::HardwareResouceType::kMain, /* main-decoder */ + media::CanDropFrames::kYes, media::Mode::kVideoHole, + base::DoNothing(), + base::BindPostTaskToCurrentDefault(base::BindRepeating( + &VideoCaptureImpl::OnVideoFrameReadyFromRenderer, + base::Unretained(this))), + true /* do not handle sink changes by listener */, + true /* enable espp manual copy */); +#endif // BUILDFLAG(IS_TIZEN_TV) && defined(TIZEN_VIDEO_HOLE) && + // defined(TIZEN_MULTIMEDIA) GetVideoCaptureHost()->Start(device_id_, session_id_, params_, observer_receiver_.BindNewPipeAndPassRemote()); diff --git a/third_party/blink/renderer/platform/video_capture/video_capture_impl.h b/third_party/blink/renderer/platform/video_capture/video_capture_impl.h index b0d9da0..bf4fb98 100644 --- a/third_party/blink/renderer/platform/video_capture/video_capture_impl.h +++ b/third_party/blink/renderer/platform/video_capture/video_capture_impl.h @@ -29,6 +29,11 @@ #include "third_party/blink/renderer/platform/allow_discouraged_type.h" #include "third_party/blink/renderer/platform/platform_export.h" +#if BUILDFLAG(IS_TIZEN_TV) && defined(TIZEN_VIDEO_HOLE) && \ + defined(TIZEN_MULTIMEDIA) +#include "media/blink/renderer/tizen_esplusplayer_renderer.h" +#endif + namespace base { class SequencedTaskRunner; } // namespace base @@ -201,6 +206,11 @@ class PLATFORM_EXPORT VideoCaptureImpl base::OnceCallback)> on_frame_ready_callback, base::OnceCallback on_gpu_context_lost); +#if BUILDFLAG(IS_TIZEN_TV) && defined(TIZEN_VIDEO_HOLE) && \ + defined(TIZEN_MULTIMEDIA) + void OnVideoFrameReadyFromRenderer(scoped_refptr frame, + base::TimeTicks reference_time); +#endif void OnVideoFrameReady( base::TimeTicks reference_time, std::unique_ptr frame_preparer); @@ -309,6 +319,11 @@ class PLATFORM_EXPORT VideoCaptureImpl THREAD_CHECKER(io_thread_checker_); base::OneShotTimer startup_timeout_; +#if BUILDFLAG(IS_TIZEN_TV) && defined(TIZEN_VIDEO_HOLE) && \ + defined(TIZEN_MULTIMEDIA) + std::unique_ptr renderer_; +#endif // BUILDFLAG(IS_TIZEN_TV) && defined(TIZEN_VIDEO_HOLE) && + // defined(TIZEN_MULTIMEDIA) base::WeakPtr weak_this_; // WeakPtrFactory pointing back to |this| object, for use with diff --git a/third_party/blink/renderer/platform/webrtc/convert_to_webrtc_video_frame_buffer.cc b/third_party/blink/renderer/platform/webrtc/convert_to_webrtc_video_frame_buffer.cc index fa8aaca..770f54b 100644 --- a/third_party/blink/renderer/platform/webrtc/convert_to_webrtc_video_frame_buffer.cc +++ b/third_party/blink/renderer/platform/webrtc/convert_to_webrtc_video_frame_buffer.cc @@ -285,7 +285,10 @@ bool CanConvertToWebRtcVideoFrameBuffer(const media::VideoFrame* frame) { frame->format())) || frame->storage_type() == media::VideoFrame::STORAGE_GPU_MEMORY_BUFFER || - frame->HasTextures(); +#if defined(TIZEN_VIDEO_HOLE) + frame->storage_type() == media::VideoFrame::STORAGE_HOLE || +#endif + frame->format() == media::PIXEL_FORMAT_ENCODED || frame->HasTextures(); } // static diff --git a/tizen_src/chromium_impl/content/browser/media/tizen_renderer_impl.cc b/tizen_src/chromium_impl/content/browser/media/tizen_renderer_impl.cc index 7278fa9..51abec6 100644 --- a/tizen_src/chromium_impl/content/browser/media/tizen_renderer_impl.cc +++ b/tizen_src/chromium_impl/content/browser/media/tizen_renderer_impl.cc @@ -62,6 +62,8 @@ TizenRendererImpl::TizenRendererImpl( video_rect_(gfx::RectF()), #endif #if BUILDFLAG(IS_TIZEN_TV) + is_low_latency_(false), + hw_res_cfg_(-1), notify_playback_state_(media::kPlaybackStop), #endif renderer_extension_receiver_(this, @@ -232,11 +234,20 @@ void TizenRendererImpl::SetPlayerInitialize() { #if defined(TIZEN_VIDEO_HOLE) if (is_video_hole_) { SetPlayerVideoHole(); - SetPlayerMediaGeometry(); + SetPlayerMediaGeometry(media::VIDEO_ROTATION_0); } #endif media_player_->Initialize(sink_); + +#if BUILDFLAG(IS_TIZEN_TV) + if (is_low_latency_) { + EnablePlayerLowLatencyMode(); + } + if (hw_res_cfg_ != -1) { + SetPlayerHardwareResource(hw_res_cfg_); + } +#endif } void TizenRendererImpl::SetPlayerPrepare() { @@ -294,6 +305,24 @@ void TizenRendererImpl::Seek(base::TimeDelta time, base::OnceClosure seek_cb) { } #if defined(TIZEN_VIDEO_HOLE) +void TizenRendererImpl::SetPlayerVideoAbove(int32_t other_id) { + if (media_player_) { + media_player_->SetPlayerVideoAbove(other_id); + } +} + +void TizenRendererImpl::UseSubsurfaceController() { + if (use_subsurface_controller_ == true) { + LOG(INFO) << "Skip same setting."; + return; + } + + if (media_player_) { + media_player_->UseSubsurfaceController(); + use_subsurface_controller_ = true; + } +} + void TizenRendererImpl::SetVideoHole(bool is_video_hole) { if (is_video_hole_ == is_video_hole) return; @@ -307,15 +336,17 @@ void TizenRendererImpl::SetPlayerVideoHole() { media_player_->SetVideoHole(is_video_hole_); } -void TizenRendererImpl::SetMediaGeometry(const gfx::RectF& rect) { +void TizenRendererImpl::SetMediaGeometry(const gfx::RectF& rect, + media::VideoRotation rotation) { if (video_rect_ == rect) return; video_rect_ = rect; - SetPlayerMediaGeometry(); + video_rotation_ = rotation; + SetPlayerMediaGeometry(rotation); } -void TizenRendererImpl::SetPlayerMediaGeometry() { +void TizenRendererImpl::SetPlayerMediaGeometry(media::VideoRotation rotation) { if (media_player_) { // Always get the latest viewport rect. media_player_->SetMediaGeometry(GetViewportRect(), video_rect_); @@ -343,7 +374,7 @@ gfx::Rect TizenRendererImpl::GetViewportRect() const { void TizenRendererImpl::OnWebViewMoved() { if (media_player_) { LOG_ID(INFO, player_id_) << __func__ << " Reset WebView-Position."; - SetPlayerMediaGeometry(); + SetPlayerMediaGeometry(video_rotation_); } } #endif @@ -370,7 +401,72 @@ void TizenRendererImpl::Suspend() { is_suspended_ = true; } +void TizenRendererImpl::EnableLowLatencyMode() { +#if BUILDFLAG(IS_TIZEN_TV) + if (is_low_latency_) + return; + + is_low_latency_ = true; + EnablePlayerLowLatencyMode(); +#endif +} + +int ToPlayerHardwareResourceConfig( + media::mojom::HardwareResourceConfig config) { + switch (config) { + case media::mojom::HardwareResourceConfig::kMainDecoderMainScaler: + return 0; + case media::mojom::HardwareResourceConfig::kSubDecoderSubScaler: + return 1; + case media::mojom::HardwareResourceConfig::kSubDecoderMainScaler: + return 2; + case media::mojom::HardwareResourceConfig::kMainDecoderSubScaler: + return 3; + default: + return -1; + } +} + +void TizenRendererImpl::SetHardwareResource( + media::mojom::HardwareResourceConfig config, + SetHardwareResourceCB cb) { +#if BUILDFLAG(IS_TIZEN_TV) + int player_cfg = ToPlayerHardwareResourceConfig(config); + if (player_cfg == -1) { + LOG(ERROR) << "Invalid config."; + std::move(cb).Run(false); + return; + } + + if (hw_res_cfg_ == player_cfg) { + std::move(cb).Run(true); + return; + } + hw_res_cfg_ = player_cfg; + SetPlayerHardwareResource(player_cfg); +#endif + std::move(cb).Run(true); +} + #if BUILDFLAG(IS_TIZEN_TV) +void TizenRendererImpl::EnablePlayerLowLatencyMode() { + if (!media_player_) { + LOG_ID(ERROR, player_id_) << "media_player_ is not created yet"; + return; + } + + media_player_->EnableLowLatencyMode(); +} + +void TizenRendererImpl::SetPlayerHardwareResource(int config) { + if (!media_player_) { + LOG_ID(ERROR, player_id_) << "media_player_ is not created yet"; + return; + } + + media_player_->SetHardwareResource(config); +} + void TizenRendererImpl::SetActiveTextTrack(int id, bool is_in_band) { LOG_ID(INFO, player_id_) << "(" << static_cast(this) << ") " << __func__ << " " << id << "/ " << is_in_band; @@ -438,6 +534,18 @@ content::WebContentsDelegate* TizenRendererImpl::GetWebContentsDelegate() } #endif +void TizenRendererImpl::RequestVideoDecodedBuffer( + RequestVideoDecodedBufferCB cb) { + if (!media_player_) { + LOG_ID(ERROR, player_id_) << "media_player_ is not created yet"; + std::move(cb).Run(false); + return; + } + + media_player_->RequestVideoDecodedBuffer(); + std::move(cb).Run(true); +} + void TizenRendererImpl::ToggleFullscreenMode(bool is_fullscreen, ToggledFullscreenCB cb) { if (media_player_) @@ -539,6 +647,7 @@ void TizenRendererImpl::OnStatisticsUpdate( const media::PipelineStatistics& stats) { NOTIMPLEMENTED(); } + #if BUILDFLAG(IS_TIZEN_TV) void TizenRendererImpl::NotifyTrackInfoToBrowser(int active_track_id) { LOG_ID(INFO, player_id_) @@ -657,7 +766,27 @@ void TizenRendererImpl::OnLivePlaybackComplete() { } client_->OnLivePlaybackComplete(); } -#endif + +void TizenRendererImpl::GetVideoId(GetVideoIdCB cb) { + std::move(cb).Run(player_id_); +} + +void TizenRendererImpl::EnableTbmBufferCallback(bool enable) { + if (!media_player_) { + LOG_ID(ERROR, player_id_) << "media_player_ is not created yet"; + return; + } + media_player_->EnableTbmBufferCallback(enable); +} + +void TizenRendererImpl::SetCallBackFrameSize(const gfx::Size& size) { + if (!media_player_) { + LOG_ID(ERROR, player_id_) << "media_player_ is not created yet"; + return; + } + media_player_->SetCallBackFrameSize(size); +} +#endif // BUILDFLAG(IS_TIZEN_TV) void TizenRendererImpl::OnSeekableTimeChange(base::TimeDelta min_time, base::TimeDelta max_time, diff --git a/tizen_src/chromium_impl/content/browser/media/tizen_renderer_impl.h b/tizen_src/chromium_impl/content/browser/media/tizen_renderer_impl.h index e45d45a..6753740 100644 --- a/tizen_src/chromium_impl/content/browser/media/tizen_renderer_impl.h +++ b/tizen_src/chromium_impl/content/browser/media/tizen_renderer_impl.h @@ -17,6 +17,7 @@ #include "media/base/renderer_client.h" #include "media/base/video_renderer_sink.h" #include "media/base/waiting.h" +#include "media/mojo/mojom/renderer.mojom.h" #include "media/mojo/mojom/renderer_extensions.mojom.h" #include "mojo/public/cpp/bindings/pending_receiver.h" #include "mojo/public/cpp/bindings/pending_remote.h" @@ -87,11 +88,19 @@ class CONTENT_EXPORT TizenRendererImpl void OnUpdateAudioMutingState(bool muted) {} void OnWebContentsDestroyed(); - void Seek(base::TimeDelta time, base::OnceClosure seek_cb); + void Seek(base::TimeDelta time, base::OnceClosure seek_cb) override; void Suspend() override; + void EnableLowLatencyMode() override; + void SetHardwareResource(media::mojom::HardwareResourceConfig config, + SetHardwareResourceCB cb) override; + void RequestVideoDecodedBuffer(RequestVideoDecodedBufferCB cb) override; void ToggleFullscreenMode(bool is_fullscreen, ToggledFullscreenCB cb) final; +#if defined(TIZEN_VIDEO_HOLE) + void SetPlayerVideoAbove(int32_t other_id) override; + void UseSubsurfaceController() override; +#endif // MediaPlayerTizenClient implementation. void OnError(media::PipelineStatus error) override; @@ -130,6 +139,9 @@ class CONTENT_EXPORT TizenRendererImpl std::string* drm_info = NULL) override; void UpdateCurrentTime(base::TimeDelta current_time) override; void OnLivePlaybackComplete() override; + void GetVideoId(GetVideoIdCB cb) override; + void SetCallBackFrameSize(const gfx::Size& size) override; + void EnableTbmBufferCallback(bool enable) override; #endif #if defined(TIZEN_TBM_SUPPORT) @@ -152,7 +164,8 @@ class CONTENT_EXPORT TizenRendererImpl #if defined(TIZEN_VIDEO_HOLE) void SetVideoHole(bool is_video_hole) final; - void SetMediaGeometry(const gfx::RectF& rect) final; + void SetMediaGeometry(const gfx::RectF& rect, + media::VideoRotation rotation) final; gfx::Rect GetViewportRect() const; #endif @@ -182,10 +195,12 @@ class CONTENT_EXPORT TizenRendererImpl void SetPlayerPrepare(); #if defined(TIZEN_VIDEO_HOLE) void SetPlayerVideoHole(); - void SetPlayerMediaGeometry(); + void SetPlayerMediaGeometry(media::VideoRotation rotation); void OnWebViewMoved(); #endif #if BUILDFLAG(IS_TIZEN_TV) + void EnablePlayerLowLatencyMode(); + void SetPlayerHardwareResource(int config); void SetActiveTextTrack(int id, bool is_in_band) override; void SetActiveAudioTrack(int index) override; void SetActiveVideoTrack(int index) override; @@ -242,11 +257,16 @@ class CONTENT_EXPORT TizenRendererImpl bool is_suspended_ = false; #if defined(TIZEN_VIDEO_HOLE) + bool use_subsurface_controller_ = false; bool is_video_hole_ = false; gfx::RectF video_rect_; + media::VideoRotation video_rotation_ = media::VIDEO_ROTATION_0; #endif #if BUILDFLAG(IS_TIZEN_TV) + bool is_low_latency_; + int hw_res_cfg_; + int notify_playback_state_; // Stores the mime type. Required for URL streams which are DASH // content, so that we can set it to the media_player_ before calling diff --git a/tizen_src/chromium_impl/content/renderer/media/tizen/media_player_renderer_client.cc b/tizen_src/chromium_impl/content/renderer/media/tizen/media_player_renderer_client.cc index caf7284..7c8729e 100644 --- a/tizen_src/chromium_impl/content/renderer/media/tizen/media_player_renderer_client.cc +++ b/tizen_src/chromium_impl/content/renderer/media/tizen/media_player_renderer_client.cc @@ -75,8 +75,10 @@ void MediaPlayerRendererClient::SetVideoHole(bool is_video_hole) { MojoRendererWrapper::SetVideoHole(is_video_hole); } -void MediaPlayerRendererClient::SetMediaGeometry(const gfx::RectF& rect) { - MojoRendererWrapper::SetMediaGeometry(rect); +void MediaPlayerRendererClient::SetMediaGeometry( + const gfx::RectF& rect, + media::VideoRotation rotation) { + MojoRendererWrapper::SetMediaGeometry(rect, rotation); } #endif diff --git a/tizen_src/chromium_impl/content/renderer/media/tizen/media_player_renderer_client.h b/tizen_src/chromium_impl/content/renderer/media/tizen/media_player_renderer_client.h index 5109bf4..884695e 100644 --- a/tizen_src/chromium_impl/content/renderer/media/tizen/media_player_renderer_client.h +++ b/tizen_src/chromium_impl/content/renderer/media/tizen/media_player_renderer_client.h @@ -67,7 +67,8 @@ class CONTENT_EXPORT MediaPlayerRendererClient #if defined(TIZEN_VIDEO_HOLE) void SetVideoHole(bool is_video_hole) override; - void SetMediaGeometry(const gfx::RectF& rect) override; + void SetMediaGeometry(const gfx::RectF& rect, + media::VideoRotation rotation) override; #endif // media::mojom::MediaPlayerRendererClientExtension implementation diff --git a/tizen_src/chromium_impl/media/audio/tizen/capi_usb_audio_input_stream.cc b/tizen_src/chromium_impl/media/audio/tizen/capi_usb_audio_input_stream.cc index da4df17..a5653b0 100644 --- a/tizen_src/chromium_impl/media/audio/tizen/capi_usb_audio_input_stream.cc +++ b/tizen_src/chromium_impl/media/audio/tizen/capi_usb_audio_input_stream.cc @@ -60,7 +60,7 @@ bool CapiUsbAudioInputStream::OpenMic() { return false; } - int device_id = std::stoi(device_name_, nullptr, 0); + int device_id = std::atoi(device_name_.c_str()); sound_device_h device; sound_device_type_e device_type; sound_stream_type_e stream_type = SOUND_STREAM_TYPE_MEDIA_EXTERNAL_ONLY; diff --git a/tizen_src/chromium_impl/media/blink/renderer/tizen_esplusplayer_renderer.cc b/tizen_src/chromium_impl/media/blink/renderer/tizen_esplusplayer_renderer.cc new file mode 100644 index 0000000..306588d --- /dev/null +++ b/tizen_src/chromium_impl/media/blink/renderer/tizen_esplusplayer_renderer.cc @@ -0,0 +1,883 @@ +// Copyright 2022 Samsung Electronics Inc. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "media/blink/renderer/tizen_esplusplayer_renderer.h" + +#include "base/base_switches.h" +#include "base/command_line.h" +#include "base/functional/callback_forward.h" +#include "base/functional/callback_helpers.h" +#include "base/logging.h" +#include "base/time/time.h" +#include "base/trace_event/trace_event.h" +#include "content/public/renderer/render_frame.h" +#include "content/public/renderer/render_frame_visitor.h" +#include "content/renderer/media/media_interface_factory.h" +#include "media/base/video_codecs.h" +#include "media/renderers/video_overlay_factory.h" +// #include "ui/gfx/tbm_buffer_handle_inter_process.h" + +#if defined(ENABLE_AUTO_ZOOM) +#include "media/mojo/mojom/ai_zoom_settings.mojom.h" +#endif // defined(ENABLE_AUTO_ZOOM) + +#if defined(TIZEN_HW_ENCODER) && !defined(TIZEN_CAPI_ENCODER_TV_API) +#include "content/renderer/render_thread_impl.h" +#endif + +#define LOG_ID(severity) LOG(severity) << "[" << id_ << "]: " + +namespace { +class MainFrameFinder : public content::RenderFrameVisitor { + public: + content::RenderFrame* result{nullptr}; + bool Visit(content::RenderFrame* render_frame) final { + if (render_frame && render_frame->IsMainFrame()) { + result = render_frame; + return false; + } + return true; + } +}; +} // namespace + +namespace media { + +TizenEsPlusPlayerRendererManager::TizenEsPlusPlayerRendererManager() = default; + +TizenEsPlusPlayerRendererManager::~TizenEsPlusPlayerRendererManager() { + NOTREACHED(); +} + +// static +TizenEsPlusPlayerRendererManager& +TizenEsPlusPlayerRendererManager::GetInstance() { + static base::NoDestructor instance; + return *instance; +} + +std::unique_ptr +TizenEsPlusPlayerRendererManager::CreateTizenEsPlusPlayerRenderer( + media::VideoCodec codec, + gfx::Size init_size, + media::HardwareResouceType scaler_type, + media::HardwareResouceType decoder_type, + media::CanDropFrames can_drop_frames, + media::Mode mode, + media::InitCb init_cb, + media::FrameCb frame_cb, + bool has_id, + bool could_enable_user_data) { + base::AutoLock lk(lock_); + + // An instance with |renderer_id| equal to 0 means that it will update the + // geometry to ESPP by registering and responding to listener events. + auto selected_id = 0; + if (has_id) + selected_id = ++index_; + + auto id_iter = id_to_renderers_.find(selected_id); + if (id_iter != id_to_renderers_.end()) { + LOG(ERROR) << "Renderer already exists."; + return nullptr; + } + + if (!SelectHWResource(scaler_type, decoder_type, mode)) { + LOG(ERROR) << "Resource conflicts or invalid combination."; + return nullptr; + } + + auto renderer = base::WrapUnique(new TizenEsPlusPlayerRenderer( + codec, init_size, scaler_type, decoder_type, can_drop_frames, mode, + std::move(init_cb), std::move(frame_cb), selected_id, + could_enable_user_data)); + id_to_renderers_[selected_id] = renderer->GetWeakPtr(); + return renderer; +} + +base::WeakPtr +TizenEsPlusPlayerRendererManager::GetTizenEsPlusPlayerRenderer(int id) { + auto id_iter = id_to_renderers_.find(id); + if (id_iter == id_to_renderers_.end()) { + LOG(ERROR) << "Renderer does not exist:" << id; + return nullptr; + } + + auto renderer = id_to_renderers_[id]; + if (!renderer) { + LOG(ERROR) << "Renderer is invalid:" << id; + return nullptr; + } + + return renderer; +} + +void TizenEsPlusPlayerRendererManager::OnVideoSinkGeometryChange( + int id, + const gfx::RectF& rect, + media::VideoRotation rotation) { + base::AutoLock lk(lock_); + auto renderer = GetTizenEsPlusPlayerRenderer(id); + if (renderer) + renderer->OnVideoSinkGeometryChange(rect, rotation); +} + +void TizenEsPlusPlayerRendererManager::OnZOrderChanged( + int broadcast_id, + const std::vector& video_ids) { + base::AutoLock lk(lock_); + + size_t size = video_ids.size(); + if (size < 2) { + return; + } + + // Skip same z-order + if (video_ids_order_ == video_ids) { + return; + } + + for (size_t i = 0; i < size - 1; i++) { + auto renderer = GetTizenEsPlusPlayerRenderer(video_ids[i]); + if (!renderer) + continue; + + for (size_t j = i + 1; j < size; j++) { + auto renderer_other = GetTizenEsPlusPlayerRenderer(video_ids[j]); + if (!renderer_other) + continue; + renderer->SetPlayerVideoAbove(renderer_other->GetVideoId()); + break; + } + } + video_ids_order_ = video_ids; +} + +void TizenEsPlusPlayerRendererManager::RemoveTizenEsPlusPlayerRenderer(int id) { + base::AutoLock lk(lock_); + auto it = id_to_renderers_.find(id); + video_ids_order_.clear(); + if (it != id_to_renderers_.end()) + id_to_renderers_.erase(it); +} + +bool TizenEsPlusPlayerRendererManager::HasResourceConflict( + const media::SelectedResource& type) { + for (const auto& it : id_to_renderers_) { + if (it.second->selected_resource().first == type.first || + it.second->selected_resource().second == type.second) { + return true; + } + } + return false; +}; + +bool TizenEsPlusPlayerRendererManager::HasResourceConflictScaler( + const media::HardwareResouceType& type) { + for (const auto& it : id_to_renderers_) { + if (it.second->selected_resource().first == type) { + return true; + } + } + return false; +}; + +bool TizenEsPlusPlayerRendererManager::HasResourceConflictDecoder( + const media::HardwareResouceType& type) { + for (const auto& it : id_to_renderers_) { + if (it.second->selected_resource().second == type) { + return true; + } + } + return false; +}; + +bool TizenEsPlusPlayerRendererManager::SelectHWResource( + media::HardwareResouceType& scaler_type, + media::HardwareResouceType& decoder_type, + const media::Mode& mode) { + if (mode == media::Mode::kVideoHoleWithMappingBuffer && + scaler_type == media::HardwareResouceType::kSub) { + LOG(ERROR) << "Invalid combination, mode:" << static_cast(mode) + << " scaler_type:" << static_cast(scaler_type) + << " mode:" << static_cast(mode); + return false; + } + + if (HasResourceConflict({scaler_type, decoder_type})) { + return false; + } + + // select for scaler kAny case + if (scaler_type == media::HardwareResouceType::kAny) { + while (scaler_type != media::HardwareResouceType::kEnd) { + scaler_type = static_cast( + static_cast(scaler_type) + 1); + if (!HasResourceConflictScaler(scaler_type)) { + break; + } + } + } + if (scaler_type == media::HardwareResouceType::kEnd) { + return false; + } + + // select for decoder kAny case + if (decoder_type == media::HardwareResouceType::kAny) { + while (decoder_type != media::HardwareResouceType::kEnd) { + decoder_type = static_cast( + static_cast(decoder_type) + 1); + if (!HasResourceConflictDecoder(decoder_type)) { + break; + } + } + } + if (decoder_type == media::HardwareResouceType::kEnd) { + return false; + } + + return true; +} + +TizenEsPlusPlayerRenderer::TizenEsPlusPlayerRenderer( + media::VideoCodec codec, + gfx::Size init_size, + HardwareResouceType scaler_type, + HardwareResouceType decoder_type, + CanDropFrames can_drop_frames, + Mode mode, + InitCb init_cb, + FrameCb frame_cb, + int renderer_id, + bool could_enable_user_data) + : player_state_(Status::NONE), + codec_(codec), + current_frame_size_(init_size), + init_cb_(std::move(init_cb)), + frame_cb_(std::move(frame_cb)), + mode_(mode), + tbm_frame_in_use_(0), + pending_disable_tbm_(false), + id_(renderer_id), + could_enable_user_data_(could_enable_user_data) { + LOG_ID(INFO) << "Create renderer id:" << id_ + << " mode:" << static_cast(mode) + << " codec:" << static_cast(codec) + << " hardware scaler:" << static_cast(scaler_type) + << " hardware decoder:" << static_cast(decoder_type) + << " can_drop_frames:" << static_cast(can_drop_frames) + << " init size:" << init_size.ToString() + << " could_enable_user_data:" << could_enable_user_data; + log_ = std::make_unique(); + selected_resource_ = std::make_pair(scaler_type, decoder_type); + +#if defined(TIZEN_HW_ENCODER) && !defined(TIZEN_CAPI_ENCODER_TV_API) + GetScalerUsageManager(); +#endif + + // Unretained is safe because |this| will outlive |worker_task_runner_|. + worker_task_runner_->PostTask( + FROM_HERE, + base::BindOnce(&TizenEsPlusPlayerRenderer::Init, base::Unretained(this))); +} + +TizenEsPlusPlayerRenderer::~TizenEsPlusPlayerRenderer() { + // Make sure |mojo_renderer_| is deleted before |worker_task_runner_| on which + // all |mojo_renderer_| related task is running + base::WaitableEvent sync_with_worker_task_runner{ + base::WaitableEvent::ResetPolicy::MANUAL}; + worker_task_runner_->PostTask( + FROM_HERE, + base::BindOnce(&TizenEsPlusPlayerRenderer::ReleaseRendererOnWorkThread, + base::Unretained(this), &sync_with_worker_task_runner)); + sync_with_worker_task_runner.Wait(); + LOG_ID(INFO) << " Mojo renderer released."; +} + +void TizenEsPlusPlayerRenderer::DidTakeResources() { +#if defined(TIZEN_HW_ENCODER) && !defined(TIZEN_CAPI_ENCODER_TV_API) + if (scaler_manager_ && uses_subresource_.has_value() && + uses_subresource_.value()) + scaler_manager_->SetUsed(true); +#endif +} + +void TizenEsPlusPlayerRenderer::DidFreeResources() { +#if defined(TIZEN_HW_ENCODER) && !defined(TIZEN_CAPI_ENCODER_TV_API) + if (scaler_manager_ && uses_subresource_.has_value() && + uses_subresource_.value()) + scaler_manager_->SetUsed(false); +#endif +} + +void TizenEsPlusPlayerRenderer::SetGeometryOnWorkerThread( + const gfx::RectF& rect, + media::VideoRotation rotation) { + DCHECK(worker_task_runner_->BelongsToCurrentThread()); + mojo_renderer_->SetMediaGeometry(rect, rotation); +} + +void TizenEsPlusPlayerRenderer::StartPlayingOnWorkerThread( + base::TimeDelta time) { + DCHECK(worker_task_runner_->BelongsToCurrentThread()); + mojo_renderer_->StartPlayingFrom(time); + player_state_ = Status::PREPARED; +} + +void TizenEsPlusPlayerRenderer::ReleaseRendererOnWorkThread( + base::WaitableEvent* event) { + DCHECK(worker_task_runner_->BelongsToCurrentThread()); + media::TizenEsPlusPlayerRendererManager::GetInstance() + .RemoveTizenEsPlusPlayerRenderer(id_); + // invalidate all weak ptrs at once to prevent any task from running again. + weak_factory_.InvalidateWeakPtrs(); + mojo_renderer_.reset(); + renderer_extension_remote_.reset(); + client_extension_receiver_.reset(); + event->Signal(); +} + +void TizenEsPlusPlayerRenderer::OnHardwareResourcesComplete(bool success) { + LOG_ID(INFO) << " success:" << success; + DCHECK(worker_task_runner_->BelongsToCurrentThread()); + if (success && selected_resource_.first == HardwareResouceType::kSub) { + uses_subresource_ = true; + DidTakeResources(); + } +} + +#if defined(TIZEN_HW_ENCODER) && !defined(TIZEN_CAPI_ENCODER_TV_API) +void TizenEsPlusPlayerRenderer::GetScalerUsageManager() { + LOG_ID(INFO) << __func__; + base::WaitableEvent event{base::WaitableEvent::ResetPolicy::MANUAL}; + content::RenderThreadImpl::DeprecatedGetMainTaskRunner()->PostTask( + FROM_HERE, + base::BindOnce( + [](base::WaitableEvent* event, media::ScalerUsageManager** manager) { + *manager = + content::RenderThreadImpl::current()->GetScalerUsageManager(); + event->Signal(); + }, + &event, &scaler_manager_)); + + event.Wait(); +} +#endif + +mojom::HardwareResourceConfig +TizenEsPlusPlayerRenderer::ToMojomHardwareResourceConfig( + SelectedResource types) { + if (types.first == HardwareResouceType::kMain) { + if (types.second == HardwareResouceType::kMain) { + return mojom::HardwareResourceConfig::kMainDecoderMainScaler; + } else if (types.second == HardwareResouceType::kSub) { + return mojom::HardwareResourceConfig::kSubDecoderMainScaler; + } + } else if (types.first == HardwareResouceType::kSub) { + if (types.second == HardwareResouceType::kMain) { + return mojom::HardwareResourceConfig::kMainDecoderSubScaler; + } else if (types.second == HardwareResouceType::kSub) { + return mojom::HardwareResourceConfig::kSubDecoderSubScaler; + } + } + return mojom::HardwareResourceConfig::kNone; +} + +void TizenEsPlusPlayerRenderer::SelectHardwareResources() { + LOG_ID(INFO) << __func__; + if (mode_ != Mode::kVideoHole && mode_ != Mode::kVideoHoleWithMappingBuffer) { + LOG_ID(INFO) << "Skip hardware resource selecting."; + return; + } + + mojom::HardwareResourceConfig cfg = + ToMojomHardwareResourceConfig(selected_resource_); + if (cfg == mojom::HardwareResourceConfig::kNone) { + LOG_ID(INFO) << "Invalid hardware resource selecting."; + return; + } + + mojo_renderer_->SetHardwareResource( + std::move(cfg), + base::BindOnce(&TizenEsPlusPlayerRenderer::OnHardwareResourcesComplete, + GetWeakPtr())); +} + +void TizenEsPlusPlayerRenderer::SetupBeforePlaying() { + LOG_ID(INFO) << __func__; + DCHECK(worker_task_runner_->BelongsToCurrentThread()); + + if (player_state_ != Status::INITIALISING) { + LOG_ID(ERROR) << "Wrong status."; + return; + } + + bool OffscreenRenderingEnabled = + base::CommandLine::ForCurrentProcess()->HasSwitch( + switches::kEnableOffscreenRendering); + if (mode_ == Mode::kVideoHole || mode_ == Mode::kVideoHoleWithMappingBuffer) { + mojo_renderer_->SetVideoHole(true); + if (!OffscreenRenderingEnabled) { + LOG_ID(INFO) + << __func__ + << ", offscreen rendering is not enabled, use subsurface controller"; + mojo_renderer_->UseSubsurfaceController(); + } else { + // fixme: in this case (web browser), there will be z-order issues in dual + // decoder + LOG_ID(INFO) << __func__ + << ", offscreen rendering is enabled, can't use subsurface " + "controller"; + } + } + + mojo_renderer_->EnableLowLatencyMode(); + mojo_renderer_->SetPlaybackRate(1.0); + SelectHardwareResources(); + mojo_renderer_->GetVideoId(base::BindOnce( + &TizenEsPlusPlayerRenderer::OnGetVideoId, weak_factory_.GetWeakPtr())); +} + +VideoCodecProfile TizenEsPlusPlayerRenderer::GetCodecProfile(VideoCodec codec) { + LOG_ID(INFO) << __func__; + VideoCodecProfile profile = VIDEO_CODEC_PROFILE_UNKNOWN; + if (codec_ == VideoCodec::kMJPEG) { + profile = VIDEO_CODEC_PROFILE_UNKNOWN; + } else if (codec == VideoCodec::kH264) { + profile = H264PROFILE_BASELINE; + } else if (codec == VideoCodec::kVP8) { + profile = VP8PROFILE_MIN; + } else { + LOG_ID(ERROR) << "Unknown codec:" << codec; + } + + return profile; +} + +bool TizenEsPlusPlayerRenderer::UpdateVideoConfig() { + LOG_ID(INFO) << __func__; + DCHECK(worker_task_runner_->BelongsToCurrentThread()); + + if (!media_resource_) { + LOG_ID(INFO) << "No source created yet, create new one."; + media_resource_ = std::make_unique(); + media_resource_->ResetStream(); + } + + ChunkDemuxerStream* stream = media_resource_->GetVideoStream(); + if (!stream) { + LOG_ID(ERROR) << "No video stream."; + return false; + } + + VideoDecoderConfig cfg = VideoDecoderConfig( + codec_, GetCodecProfile(codec_), VideoDecoderConfig::AlphaMode::kIsOpaque, + VideoColorSpace(), VideoTransformation(), current_frame_size_, + gfx::Rect{0, 0, current_frame_size_.width(), + current_frame_size_.height()}, + current_frame_size_, std::vector{}, + EncryptionScheme::kUnencrypted); + // it is needed to set espp to manual copy mode now if we want to enable user + // data later. + cfg.set_enable_manual_copy(could_enable_user_data_); + + // Fix the video max resolution to FHD before setting it to ESPP to ensure + // that our hardware decoder selection logic is not disrupted. That is to say + // we hope the allocated decoder is 'just enough' rather than 'more than + // enough'. + cfg.set_max_coded_size({kFHDVideoMaxWidth, kFHDVideoMaxHeight}); + cfg.set_is_rtc(true); + return stream->UpdateVideoConfig(cfg, false, log_.get()); +} + +void TizenEsPlusPlayerRenderer::Init() { + TRACE_EVENT0("media", "TizenEsPlusPlayerRenderer::Init"); + LOG_ID(INFO) << __func__; + DCHECK(worker_task_runner_->BelongsToCurrentThread()); + + MainFrameFinder find_main_frame; + content::RenderFrame::ForEach(&find_main_frame); + if (!find_main_frame.result) { + LOG_ID(ERROR) + << "Couldn't find main render frame, EsPlusPlayer Renderer will " + "be disabled"; + return; + } + + player_state_ = Status::INITIALISING; + + // init mojo + media_interface_factory_ = std::make_unique( + find_main_frame.result->GetBrowserInterfaceBroker()); + + mojo::PendingRemote renderer_remote; + media_interface_factory_->CreateMediaPlayerRenderer( + client_extension_receiver_.BindNewPipeAndPassRemote(), + renderer_remote.InitWithNewPipeAndPassReceiver(), + renderer_extension_remote_.BindNewPipeAndPassReceiver()); + + mojo_renderer_ = std::make_unique( + worker_task_runner_, nullptr, /* VideoOverlayFactory */ + nullptr, /* VideoRendererSink */ + std::move(renderer_remote)); + + // init source and esplusplayer settings + UpdateVideoConfig(); + + // init renderer + mojo_renderer_->Initialize( + media_resource_.get(), this, + base::BindOnce(&TizenEsPlusPlayerRenderer::OnRendererInitResult, + GetWeakPtr())); + +#if defined(ENABLE_AUTO_ZOOM) + if (pending_ai_zoom_settings_) { + SetAiZoomSettings(*pending_ai_zoom_settings_); + pending_ai_zoom_settings_.reset(); + } +#endif // defined(ENABLE_AUTO_ZOOM) +} + +void TizenEsPlusPlayerRenderer::OnGetVideoId(int32_t player_id) { + LOG_ID(INFO) << " player_id:" << player_id; + DCHECK(worker_task_runner_->BelongsToCurrentThread()); + video_id_ = player_id; +} + +void TizenEsPlusPlayerRenderer::OnRendererInitResult(PipelineStatus status) { + LOG_ID(INFO) << " status:" << status; + DCHECK(worker_task_runner_->BelongsToCurrentThread()); + + if (status != PIPELINE_OK) { + player_state_ = Status::ERROR; + if (init_cb_) + std::move(init_cb_).Run(false); + return; + } + + SetupBeforePlaying(); + player_state_ = Status::INITIALISED; + if (init_cb_) + std::move(init_cb_).Run(true); +} + +bool TizenEsPlusPlayerRenderer::IsReady() { + if (player_state_ == Status::INITIALISED || + player_state_ == Status::PREPARED) { + return true; + } + return false; +} + +VideoFrameMetadata TizenEsPlusPlayerRenderer::GetMetaData( + base::TimeDelta timestamp) { + PendingFrame pending_frame; + { + base::AutoLock lk(pending_frames_lock_); + while (!pending_frames_.empty()) { + pending_frame = pending_frames_.front(); + if (pending_frame.timestamp.InMilliseconds() >= + timestamp.InMilliseconds()) { + if (pending_frame.timestamp.InMilliseconds() == + timestamp.InMilliseconds()) { + pending_frames_.pop_front(); + } + break; + } else { + pending_frames_.pop_front(); + } + } + } + if (pending_frame.timestamp.InMilliseconds() != timestamp.InMilliseconds()) { + LOG_ID(ERROR) << "Could not find pending frame by timestamp: " + << timestamp.InMilliseconds(); + return lastVideoFrameMeta_; + } + return pending_frame.metadata.value(); +} + +bool TizenEsPlusPlayerRenderer::QueueBuffer(const VideoFrameMetadata& meta, + const gfx::Size& coded_size, + const uint8_t* data, + std::size_t size, + bool key_frame) { + UpdateLastCaptureResolution(meta); + + ChunkDemuxerStream* stream = media_resource_->GetVideoStream(); + if (!stream) { + LOG_ID(ERROR) << "No video stream."; + return true; + } + + base::TimeDelta ts = + meta.reference_time.value_or(base::TimeTicks()) - base::TimeTicks(); + TRACE_EVENT2("media", "TizenEsPlusPlayerRenderer::QueueBuffer", "key_frame", + key_frame, "timestamp", ts.InMilliseconds()); + bool request_key_frame = false; + { + base::AutoLock lk(append_frame_lock_); + StreamParser::BufferQueue buffer_queue; + auto buffer = StreamParserBuffer::CopyFrom(data, size, key_frame, + DemuxerStream::Type::VIDEO, 0); + buffer->set_timestamp(ts); + buffer->set_duration(base::Milliseconds(33)); + buffer->set_is_duration_estimated(true); + buffer_queue.push_back(std::move(buffer)); + stream->Append(buffer_queue); + + // we could not clean buffer until key frame received. + double queue_buffer_size = stream->GetBufferedSize(); + if (queue_buffer_size >= kMaxBufferSize) { + LOG_ID(INFO) << "Max buffer size(" << kMaxBufferSize << ") reached."; + request_key_frame = true; + if (key_frame) { + LOG_ID(INFO) << "Clean bufer"; + stream->Remove(first_buffer_ts.value_or(base::Seconds(0)), ts, ts); + stream->Seek(ts); + } + } + } + + if (!first_buffer_ts.has_value()) { + LOG_ID(INFO) << "Seek to the stream beginning timestamp:" + << ts.InMilliseconds() << "(" << ts << ")" + << " from where the esplusplayer shall read."; + stream->Seek(ts); + first_buffer_ts = ts; + + // prepare and start player from now + worker_task_runner_->PostTask( + FROM_HERE, + base::BindOnce(&TizenEsPlusPlayerRenderer::StartPlayingOnWorkerThread, + GetWeakPtr(), ts)); + } + + if (mode_ == Mode::kVideoHole) { + auto frame = media::VideoFrame::CreateHoleFrame(coded_size); + if (!frame) { + LOG_ID(ERROR) << "create hole frame failed!"; + return request_key_frame; + } + frame->set_timestamp(ts); + frame->metadata().MergeMetadataFrom(meta); + frame->metadata().player_id = id_; + if (frame_cb_) + frame_cb_.Run(std::move(frame), *meta.reference_time); + } else if (mode_ == Mode::kVideoHoleWithMappingBuffer) { + base::AutoLock lk(pending_frames_lock_); + pending_frames_.push_back(PendingFrame{ts, meta}); + } + lastVideoFrameMeta_ = meta; + + return request_key_frame; +} + +void TizenEsPlusPlayerRenderer::OnRequestSeek(base::TimeDelta time) { + mojo_renderer_->Seek(time, base::DoNothing()); + ChunkDemuxerStream* stream = media_resource_->GetVideoStream(); + if (!stream) { + LOG_ID(ERROR) << "No video stream."; + return; + } + + // ESPP shall flush all frames cached after seek, so it should not feed any + // frame before seek. + stream->StartReturningData(); +} + +void TizenEsPlusPlayerRenderer::OnError(PipelineStatus status) { + LOG_ID(INFO) << " status:" << status; + DCHECK(worker_task_runner_->BelongsToCurrentThread()); + player_state_ = Status::ERROR; +} + +#if defined(TIZEN_TBM_SUPPORT) +void TizenEsPlusPlayerRenderer::OnNewTbmFrameAvailable( + uint32_t player_id, + gfx::TbmBufferHandleInterProcess tbm_buffer_handle_inter_process, + base::TimeDelta timestamp) { + TRACE_EVENT1("media", "TizenEsPlusPlayerRenderer::OnNewTbmFrameAvailable", + "timestamp", timestamp.InMilliseconds()); + DCHECK(worker_task_runner_->BelongsToCurrentThread()); + auto [tbm_buffer_handle, tbm_surface_release_cb_runner] = + gfx::ToTbmBufferHandle(tbm_buffer_handle_inter_process); + + auto frame = media::VideoFrame::WrapTBMInterProcessBuffer( + gfx::Size(tbm_buffer_handle.width, tbm_buffer_handle.height), timestamp, + tbm_buffer_handle); + if (!frame) { + LOG_ID(ERROR) << "Failed to wrap TBM IPC buffer."; + return; + } + + frame->AddDestructionObserver(tbm_surface_release_cb_runner.Release()); + frame->metadata().player_id = id_; + + // Webrtc TBM from esplayer will be destroyed from + // video frame DestructionObserver + frame->SetTbmDestroyType(gfx::kDestroyTbmByVideoFrame); + frame->AddDestructionObserver(BindToCurrentLoop(base::BindOnce( + &TizenEsPlusPlayerRenderer::ReleaseMediaPacket, GetWeakPtr(), + reinterpret_cast(tbm_buffer_handle.media_packet)))); + frame->metadata().MergeMetadataFrom(GetMetaData(timestamp)); + if (frame_cb_) { + frame_cb_.Run(std::move(frame), timestamp + base::TimeTicks()); + } + tbm_frame_in_use_++; +} + +void TizenEsPlusPlayerRenderer::ReleaseMediaPacket(uintptr_t media_packet) { + if (!worker_task_runner_->BelongsToCurrentThread()) { + worker_task_runner_->PostTask( + FROM_HERE, + base::BindOnce(&TizenEsPlusPlayerRenderer::ReleaseMediaPacket, + GetWeakPtr(), media_packet)); + return; + } + + if (!renderer_extension_remote_.is_bound()) { + LOG_ID(INFO) << "Extension mojo is unbound."; + return; + } + + renderer_extension_remote_->OnMediaPacketExhausted(media_packet); + tbm_frame_in_use_--; + if (tbm_frame_in_use_ == 0 && pending_disable_tbm_) + EnableTbmBufferCallback(false); +} +#endif + +void TizenEsPlusPlayerRenderer::EnableTbmBufferCallback(bool enable) { + if (!worker_task_runner_->BelongsToCurrentThread()) { + worker_task_runner_->PostTask( + FROM_HERE, + base::BindOnce(&TizenEsPlusPlayerRenderer::EnableTbmBufferCallback, + GetWeakPtr(), enable)); + return; + } + + if (!could_enable_user_data_) { + LOG_ID(INFO) + << " Current instance is initialized without user data support."; + return; + } + + // ESPP will delete all TBM buffers immediately when disable TBM, + // so we need to make sure there is no TBM buffer in use currently, + // or disable TBM later. + if (!enable && tbm_frame_in_use_ > 0) { + LOG_ID(INFO) << " There are still " << tbm_frame_in_use_ + << " TBM buffer(s) in use, pending disable TBM."; + pending_disable_tbm_ = true; + return; + } + pending_disable_tbm_ = false; + + // TODO(vd.wasm) This assumes that initial mode will be `kVideoHole`. + auto new_mode = + (enable ? Mode::kVideoHoleWithMappingBuffer : Mode::kVideoHole); + if (mode_ == new_mode) { + return; + } + + mode_ = new_mode; + renderer_extension_remote_->EnableTbmBufferCallback(enable); + LOG_ID(INFO) << " new mode:" << static_cast(mode_); +} + +void TizenEsPlusPlayerRenderer::SetCallBackFrameSize(const gfx::Size& size) { + if (!worker_task_runner_->BelongsToCurrentThread()) { + worker_task_runner_->PostTask( + FROM_HERE, + base::BindOnce(&TizenEsPlusPlayerRenderer::SetCallBackFrameSize, + GetWeakPtr(), size)); + return; + } + + LOG_ID(INFO) << " new size:" << size.ToString(); + renderer_extension_remote_->SetCallBackFrameSize(size); +} + +void TizenEsPlusPlayerRenderer::UpdateLastCaptureResolution( + const VideoFrameMetadata& meta) { + if (!meta.source_size.has_value()) + return; + + gfx::Size source_size = *meta.source_size; + if (last_capture_size_ != source_size) { + LOG_ID(INFO) << ", capture source size changed from " + << last_capture_size_.ToString() << " to " + << source_size.ToString(); + SetCallBackFrameSize(source_size); + last_capture_size_ = source_size; + } +} + +#if defined(ENABLE_AUTO_ZOOM) +void TizenEsPlusPlayerRenderer::SetAiZoomSettings( + const media::TizenAiZoomSettings& settings) { + if (!worker_task_runner_->BelongsToCurrentThread()) { + worker_task_runner_->PostTask( + FROM_HERE, base::BindOnce(&TizenEsPlusPlayerRenderer::SetAiZoomSettings, + GetWeakPtr(), settings)); + return; + } + + LOG_ID(INFO) << " renderer extensions bound = " + << renderer_extension_remote_.is_bound() + << ", ai zoom settings = " << settings.AsHumanReadableString(); + + if (!renderer_extension_remote_.is_bound()) { + pending_ai_zoom_settings_ = settings; + return; + } + + renderer_extension_remote_->SetAiZoomSettings(settings); +} +#endif // defined(ENABLE_AUTO_ZOOM) + +void TizenEsPlusPlayerRenderer::SetPlayerVideoAbove(int32_t other_id) { + if (!worker_task_runner_->BelongsToCurrentThread()) { + worker_task_runner_->PostTask( + FROM_HERE, + base::BindOnce(&TizenEsPlusPlayerRenderer::SetPlayerVideoAbove, + base::Unretained(this), other_id)); + return; + } + + LOG_ID(INFO) << __func__ << " other_id:" << other_id; + mojo_renderer_->SetPlayerVideoAbove(other_id); +} + +void TizenEsPlusPlayerRenderer::OnVideoSinkGeometryChange( + const gfx::RectF& rect, + media::VideoRotation rotation) { + LOG_ID(INFO) << " rect:" << rect.ToString() << " rotation:" << rotation; + worker_task_runner_->PostTask( + FROM_HERE, + base::BindOnce(&TizenEsPlusPlayerRenderer::SetGeometryOnWorkerThread, + GetWeakPtr(), rect, rotation)); +} + +base::WeakPtr +TizenEsPlusPlayerRenderer::GetWeakPtr() { + return weak_factory_.GetWeakPtr(); +} + +void TizenEsPlusPlayerRenderer::StreamResource::ResetStream() { + LOG(INFO) << __func__; + demuxer_streamer_ = std::make_unique( + DemuxerStream::VIDEO, MediaTrack::Id("tizen renderer video stream")); +} + +std::vector +TizenEsPlusPlayerRenderer::StreamResource::GetAllStreams() { + LOG(INFO) << __func__; + std::vector v; + if (demuxer_streamer_) + v.push_back(demuxer_streamer_.get()); + return v; +} + +} // namespace media diff --git a/tizen_src/chromium_impl/media/blink/renderer/tizen_esplusplayer_renderer.h b/tizen_src/chromium_impl/media/blink/renderer/tizen_esplusplayer_renderer.h new file mode 100644 index 0000000..8addc02 --- /dev/null +++ b/tizen_src/chromium_impl/media/blink/renderer/tizen_esplusplayer_renderer.h @@ -0,0 +1,304 @@ +// Copyright 2022 Samsung Electronics Inc. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef MEDIA_RENDERER_TIZEN_ESPLUSPLAYER_RENDERER +#define MEDIA_RENDERER_TIZEN_ESPLUSPLAYER_RENDERER + +#include +#include + +#include "base/memory/ref_counted.h" +#include "base/memory/scoped_refptr.h" +#include "base/synchronization/waitable_event.h" +#include "base/task/single_thread_task_runner.h" +#include "base/task/thread_pool.h" +#include "content/renderer/media/media_interface_factory.h" +#include "media/base/media_util.h" +#include "media/base/renderer_client.h" +#include "media/filters/chunk_demuxer.h" +#include "media/mojo/clients/mojo_renderer.h" +#include "media/mojo/mojom/interface_factory.mojom.h" +#include "media/mojo/mojom/renderer_extensions.mojom.h" +#include "mojo/public/cpp/bindings/pending_receiver.h" +#include "mojo/public/cpp/bindings/pending_remote.h" +#include "mojo/public/cpp/bindings/receiver.h" +#include "mojo/public/cpp/bindings/remote.h" +#include "third_party/abseil-cpp/absl/types/optional.h" +#include "third_party/blink/public/platform/modules/mediastream/web_media_stream_sink.h" + +#if defined(TIZEN_TBM_SUPPORT) +#include "tizen_src/chromium_impl/ui/gfx/tbm_buffer_handle_inter_process.h" +#endif + +#if defined(TIZEN_HW_ENCODER) && !defined(TIZEN_CAPI_ENCODER_TV_API) +#include "tizen_src/chromium_impl/media/base/tizen/scaler_usage_manager.h" +#endif + +namespace media { + +enum class CanDropFrames { kNo, kYes }; +enum class HardwareResouceCategory { kScaler, kDeocder }; +enum class HardwareResouceType { kAny, kMain, kSub, kEnd }; +enum class Mode { kVideoHole, kTexture, kVideoHoleWithMappingBuffer }; + +using FrameCb = base::RepeatingCallback, + base::TimeTicks)>; +using InitCb = base::OnceCallback; +using SelectedResource = std::pair; + +class TizenEsPlusPlayerRenderer; + +class TizenEsPlusPlayerRendererManager { + public: + static TizenEsPlusPlayerRendererManager& GetInstance(); + std::unique_ptr CreateTizenEsPlusPlayerRenderer( + media::VideoCodec codec, + gfx::Size init_size, + media::HardwareResouceType scaler_type, + media::HardwareResouceType decoder_type, + media::CanDropFrames can_drop_frames, + media::Mode mode, + media::InitCb init_cb, + media::FrameCb frame_cb, + bool has_id, + bool could_enable_user_data); + + void RemoveTizenEsPlusPlayerRenderer(int id); + void OnVideoSinkGeometryChange(int id, + const gfx::RectF& rect, + media::VideoRotation rotation); + void OnZOrderChanged(int broadcast_id, const std::vector& video_ids); + + private: + friend class base::NoDestructor; + + TizenEsPlusPlayerRendererManager(); + ~TizenEsPlusPlayerRendererManager(); + // this function should be carefully used, as the got weakptr could + // be invalid anytime. + base::WeakPtr GetTizenEsPlusPlayerRenderer(int id); + bool HasResourceConflict(const media::SelectedResource& type); + bool HasResourceConflictScaler(const media::HardwareResouceType& type); + bool HasResourceConflictDecoder(const media::HardwareResouceType& type); + bool SelectHWResource(media::HardwareResouceType& scaler_type, + media::HardwareResouceType& decoder_type, + const media::Mode& mode); + + int index_{0}; + std::unordered_map> + id_to_renderers_; + std::vector video_ids_order_; + base::Lock lock_; +}; + +// This class is used for rendering camera video stream by upstream +// mojo renderer interface on Tizen TV products. +// all mojo related process should be handled on |worker_task_runner_|. +class TizenEsPlusPlayerRenderer final + : public RendererClient, + public media::mojom::MediaPlayerRendererClientExtension { + public: + // max buffer queue size, clear the whole buffer queue once it is exceeded. + static constexpr double kMaxBufferSize = 8 * 1024 * 1024; + + // We need a way to get the meta data in TBM callback to constructe video + // frame: store meta data in pending frame, and get it by timestamp in TBM + // callback. + struct PendingFrame { + base::TimeDelta timestamp; + absl::optional metadata{}; + }; + VideoFrameMetadata GetMetaData(base::TimeDelta timestamp); + + ~TizenEsPlusPlayerRenderer() override; + + int32_t GetVideoId() { return video_id_; } + void OnGetVideoId(int32_t player_id); + void OnRendererInitResult(PipelineStatus status); + bool IsReady(); + // QueueBuffer should be called on IO thread + bool QueueBuffer(const VideoFrameMetadata& meta, + const gfx::Size& coded_size, + const uint8_t* data, + std::size_t size, + bool key_frame); + + // RendererClient implementation + void OnError(PipelineStatus status) override; + void OnFallback(PipelineStatus status) override {} + void OnEnded() override {} + void OnStatisticsUpdate(const PipelineStatistics&) override {} + // void OnPlayerStarted(bool) override {} + void OnBufferingStateChange(BufferingState, + BufferingStateChangeReason) override {} + void OnWaiting(WaitingReason) override {} + void OnAudioConfigChange(const AudioDecoderConfig&) override {} + void OnVideoConfigChange(const VideoDecoderConfig&) override {} + void OnVideoNaturalSizeChange(const gfx::Size&) override {} + void OnVideoOpacityChange(bool) override {} + bool IsVideoStreamAvailable() override { return IsReady(); } + void OnVideoFrameRateChange(absl::optional) override {} + + // media::mojom::MediaPlayerRendererClientExtension implementation + void OnDurationChange(base::TimeDelta duration) override {} + void OnVideoSizeChange(const gfx::Size& size) override {} +#if defined(TIZEN_MULTIMEDIA) + void OnBufferUpdate(base::TimeDelta time) override {} + void OnRequestSeek(base::TimeDelta time) override; +#endif + void OnNewFrameAvailable(uint32_t playerId, + base::UnsafeSharedMemoryRegion frame, + uint32_t size, + base::TimeDelta timestamp, + uint32_t width, + uint32_t height) override {} +#if defined(TIZEN_TBM_SUPPORT) + void OnNewTbmFrameAvailable( + uint32_t playerId, + gfx::TbmBufferHandleInterProcess tbm_buffer_handle, + base::TimeDelta timestamp) override; + void ReleaseMediaPacket(uintptr_t media_packet); +#endif + void EnableTbmBufferCallback(bool enable); + void SetCallBackFrameSize(const gfx::Size& size); + void UpdateLastCaptureResolution(const VideoFrameMetadata& meta); + void NotifyTrackInfoToBrowser(int) override {} + using RendererClient::AddTrackInfo; + void AddTrackInfo(media::mojom::MediaTrackInfoPtr trackinfo) override {} + // using RendererClient::OnRegisterTimelineCbInfo; + // void OnRegisterTimelineCbInfo( + // media::mojom::register_timeline_cb_info_sPtr info) override {} + // void OnSyncTimelineCbInfo(const std::string& timeline_selector, + // int sync) override {} + // void OnMrsUrlChange(const std::string& url) override {} + // void OnContentIdChange(const std::string& id) override {} +#if defined(ENABLE_AUTO_ZOOM) + void SetAiZoomSettings(const media::TizenAiZoomSettings& settings); +#endif // defined(ENABLE_AUTO_ZOOM) + void SetPlayerVideoAbove(int32_t other_id); + void OnVideoSinkGeometryChange(const gfx::RectF& rect, + media::VideoRotation rotation); + + const SelectedResource& selected_resource() const { + return selected_resource_; + } + + base::WeakPtr GetWeakPtr(); + + private: + friend class TizenEsPlusPlayerRendererManager; + TizenEsPlusPlayerRenderer(media::VideoCodec codec, + gfx::Size init_size, + HardwareResouceType scaler_type, + HardwareResouceType decoder_type, + CanDropFrames can_drop_frames, + Mode mode, + InitCb init_cb, + FrameCb frame_cb, + int renderer_id, + bool could_enable_user_data); + + void Init(); + bool UpdateVideoConfig(); + VideoCodecProfile GetCodecProfile(VideoCodec codec); + // something must be done before esplusplayer prepared + void SetupBeforePlaying(); + + // HW resources + void OnHardwareResourcesComplete(bool success); +#if defined(TIZEN_HW_ENCODER) && !defined(TIZEN_CAPI_ENCODER_TV_API) + void GetScalerUsageManager(); +#endif + void SelectHardwareResources(); + void DidTakeResources(); + void DidFreeResources(); + + void ReleaseRendererOnWorkThread(base::WaitableEvent* event); + void StartPlayingOnWorkerThread(base::TimeDelta time); + void SetGeometryOnWorkerThread(const gfx::RectF& rect, + media::VideoRotation rotation); + mojom::HardwareResourceConfig ToMojomHardwareResourceConfig( + SelectedResource types); + + mojo::Remote + renderer_extension_remote_; + mojo::Receiver + client_extension_receiver_{this}; + std::unique_ptr media_interface_factory_; + std::unique_ptr mojo_renderer_; + + // all mojo IPC should be handled and posted to this dedicated runner. + scoped_refptr worker_task_runner_{ + base::ThreadPool::CreateSingleThreadTaskRunner( + {base::TaskPriority::USER_VISIBLE, + base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN})}; + + class StreamResource : public MediaResource { + public: + ~StreamResource() override = default; + std::vector GetAllStreams() override; + ChunkDemuxerStream* GetVideoStream() { return demuxer_streamer_.get(); } + void ResetStream(); + + private: + std::unique_ptr demuxer_streamer_; + }; + + enum class Status { + NONE, + ERROR, + SUSPENDED, + INITIALISING, + INITIALISED, + PREPARED + }; + +#if defined(TIZEN_HW_ENCODER) && !defined(TIZEN_CAPI_ENCODER_TV_API) + ScalerUsageManager* scaler_manager_; +#endif + SelectedResource selected_resource_; + absl::optional uses_subresource_; + + std::unique_ptr media_resource_; + std::atomic player_state_; + + VideoCodec codec_; + gfx::Size current_frame_size_; + std::unique_ptr log_; + + InitCb init_cb_; + FrameCb frame_cb_; + Mode mode_; + + absl::optional first_buffer_ts; + + int tbm_frame_in_use_; + bool pending_disable_tbm_; + int id_; + int video_id_; + // it indicates whether the current player could be running in TBM mode. + bool could_enable_user_data_; + +#if defined(ENABLE_AUTO_ZOOM) + std::optional pending_ai_zoom_settings_; +#endif // defined(ENABLE_AUTO_ZOOM) + + base::Lock pending_frames_lock_{}; + base::Lock append_frame_lock_{}; + std::deque pending_frames_{}; + + // In case get none from pending_frames_, use latest meta data + VideoFrameMetadata lastVideoFrameMeta_; + + // Save the latest capture resolution, when it's changed, send + // SetCallBackFrameSize to UI process + gfx::Size last_capture_size_; + + base::WeakPtrFactory weak_factory_{this}; +}; + +} // namespace media + +#endif // MEDIA_RENDERER_TIZEN_ESPLUSPLAYER_RENDERER diff --git a/tizen_src/chromium_impl/media/capture/video/tizen/video_capture_device_tizen.cc b/tizen_src/chromium_impl/media/capture/video/tizen/video_capture_device_tizen.cc index 729eff0..86ea118 100644 --- a/tizen_src/chromium_impl/media/capture/video/tizen/video_capture_device_tizen.cc +++ b/tizen_src/chromium_impl/media/capture/video/tizen/video_capture_device_tizen.cc @@ -591,9 +591,10 @@ void VideoCaptureDeviceTizen::OnCameraCaptured(camera_preview_data_s* frame, if (self->first_ref_time_.is_null()) self->first_ref_time_ = now; - self->client_->OnIncomingCapturedBuffer(std::move(self->buffer_), - videocaptureformat, now, - now - self->first_ref_time_); + self->client_->OnIncomingCapturedBufferExt( + std::move(self->buffer_), videocaptureformat, gfx::ColorSpace(), now, + now - self->first_ref_time_, gfx::Rect(videocaptureformat.frame_size), + VideoFrameMetadata(), frame->data.encoded_plane.size); // statistics & log every seconds ++(self->frame_total_); diff --git a/tizen_src/chromium_impl/media/filters/esplusplayer_util.cc b/tizen_src/chromium_impl/media/filters/esplusplayer_util.cc index 1e42c3d..a4efe57 100644 --- a/tizen_src/chromium_impl/media/filters/esplusplayer_util.cc +++ b/tizen_src/chromium_impl/media/filters/esplusplayer_util.cc @@ -142,6 +142,11 @@ esplusplayer_video_mime_type ConvertToESPlusVideoMimeType( case media::VideoCodec::kAV1: videoMimeType = ESPLUSPLAYER_VIDEO_MIME_TYPE_AV1; break; +#if defined(TIZEN_MULTIMEDIA_MJPEG_SUPPORT) + case media::VideoCodec::kMJPEG: + videoMimeType = ESPLUSPLAYER_VIDEO_MIME_TYPE_MJPEG; + break; +#endif default: { LOG(WARNING) << "Unknown codec :" << codec << ". Returning H264."; videoMimeType = ESPLUSPLAYER_VIDEO_MIME_TYPE_H264; diff --git a/tizen_src/chromium_impl/media/filters/media_player_esplusplayer_tv.cc b/tizen_src/chromium_impl/media/filters/media_player_esplusplayer_tv.cc index c781940..a56e135 100644 --- a/tizen_src/chromium_impl/media/filters/media_player_esplusplayer_tv.cc +++ b/tizen_src/chromium_impl/media/filters/media_player_esplusplayer_tv.cc @@ -156,8 +156,8 @@ bool MediaPlayerESPlusPlayerTV::ReadFromBufferQueue(DemuxerStream::Type type) { } bool MediaPlayerESPlusPlayerTV::SetSubmitDataType( - const bool is_drm_eme, - const bool single_process_mode) { + const bool& is_drm_eme, + const bool& single_process_mode) { int error = ESPLUSPLAYER_ERROR_TYPE_NONE; is_drm_eme_ = is_drm_eme; if (is_drm_eme) { @@ -176,8 +176,8 @@ bool MediaPlayerESPlusPlayerTV::SetSubmitDataType( esplayer_, ESPLUSPLAYER_SUBMIT_DATA_TYPE_CLEAN_DATA); } if (error != ESPLUSPLAYER_ERROR_TYPE_NONE) { - LOG(ERROR) << "esplusplayer_set_submit_data_type failed. error code " - << error; + LOG_ID(ERROR, player_id_) + << "esplusplayer_set_submit_data_type failed. error code " << error; return false; } return true; @@ -314,14 +314,154 @@ esplusplayer_submit_status MediaPlayerESPlusPlayerTV::SubmitEsPacket( void MediaPlayerESPlusPlayerTV::EnableLowLatencyMode() { - NOTIMPLEMENTED(); + if (!esplayer_) { + LOG(ERROR) << "Invalid player handle."; + return; + } + + if (GetPlayerState() != ESPLUSPLAYER_STATE_IDLE) { + LOG(ERROR) << "Invalid player state."; + return; + } + + auto error = esplusplayer_set_low_latency_mode( + esplayer_, ESPLUSPLAYER_LOW_LATENCY_MODE_VIDEO); + if (error != ESPLUSPLAYER_ERROR_TYPE_NONE) { + LOG(ERROR) << "esplusplayer_set_low_latency_mode failed. error #" + << esplusplayer_get_error_string( + static_cast(error)); + } + error = esplusplayer_set_low_latency_mode( + esplayer_, ESPLUSPLAYER_LOW_LATENCY_MODE_DISABLE_SYNC); + if (error != ESPLUSPLAYER_ERROR_TYPE_NONE) { + LOG(ERROR) << "esplusplayer_set_low_latency_mode failed. error #" + << esplusplayer_get_error_string( + static_cast(error)); + } + is_video_low_latency_ = true; } void MediaPlayerESPlusPlayerTV::SetHardwareResource(int config) { - NOTIMPLEMENTED(); + LOG(INFO) << __func__ << " config:" << config; + if (!esplayer_) { + LOG(ERROR) << "Invalid player handle."; + return; + } + + if (GetPlayerState() == ESPLUSPLAYER_STATE_NONE) { + LOG(ERROR) << "Invalid player state."; + return; + } + + auto error = esplusplayer_set_alternative_video_resource(esplayer_, config); + if (error != ESPLUSPLAYER_ERROR_TYPE_NONE) { + LOG(ERROR) << "esplusplayer_set_alternative_video_resource failed. error #" + << esplusplayer_get_error_string( + static_cast(error)); + return; + } + + return; } void MediaPlayerESPlusPlayerTV::EnableTbmBufferCallback(bool enable) { + LOG_ID(INFO, player_id_) << __func__ << " enable: " << enable; +#if TIZEN_VERSION_AT_LEAST(6, 0, 0) + if (decoded_frame_buffer_type_ == + ESPLUSPLAYER_DECODED_VIDEO_FRAME_BUFFER_TYPE_SCALE) { + LOG_ID(INFO, player_id_) << "tbm buffer callback had enabled, skip it"; + return; + } + + enable_tbm_buffer_callback_ = enable; + if (enable && GetPlayerState() == ESPLUSPLAYER_STATE_NONE) { + LOG_ID(INFO, player_id_) + << "Invalid player state. To enable Tbm buffer callback the " + "player must not be NONE."; + return; + } + + // fixme: ESPP crash if set type to none, so skip it. + if (!enable) + return; + + esplusplayer_decoded_video_frame_buffer_type type = + (enable ? ESPLUSPLAYER_DECODED_VIDEO_FRAME_BUFFER_TYPE_SCALE + : ESPLUSPLAYER_DECODED_VIDEO_FRAME_BUFFER_TYPE_NONE); + + int error = esplusplayer_set_video_frame_buffer_type(esplayer_, type); + if (error != ESPLUSPLAYER_ERROR_TYPE_NONE) { + LOG_ID(ERROR, player_id_) + << "esplusplayer_set_video_frame_buffer_type failed. error #" + << esplusplayer_get_error_string( + static_cast(error)); + return; + } + decoded_frame_buffer_type_ = type; + + // TODO(vd.wasm) Add method for setting buffer resolution. + if (decoded_frame_buffer_type_ == + ESPLUSPLAYER_DECODED_VIDEO_FRAME_BUFFER_TYPE_SCALE) { + int width = + pending_cb_frame_width_ > 0 ? pending_cb_frame_width_ : cb_frame_width_; + width = width > 0 ? width : kDefaultCallBackFrameWidth; + int height = pending_cb_frame_height_ > 0 ? pending_cb_frame_height_ + : cb_frame_height_; + height = height > 0 ? height : kDefaultCallBackFrameHeight; + SetCallBackFrameSize(gfx::Size(width, height)); + } + +#else + LOG_ID(INFO, player_id_) + << "EnableTbmBufferCallback not support in this version"; +#endif +} + +void MediaPlayerESPlusPlayerTV::SetCallBackFrameSize(const gfx::Size& size) { + LOG_ID(INFO, player_id_) << "Going to set callback frame size: " + << size.width() << "x" << size.height(); +#if TIZEN_VERSION_AT_LEAST(6, 0, 0) + if (size.width() <= 0 || size.height() <= 0 || + size.width() > kMaxCallBackFrameWidth || + size.height() > kMaxCallBackFrameHeight) { + LOG(WARNING) << "invalid callback frame size:" << size.width() << "x" + << size.height(); + return; + } + if (cb_frame_width_ == size.width() && cb_frame_height_ == size.height()) + return; + if (decoded_frame_buffer_type_ == + ESPLUSPLAYER_DECODED_VIDEO_FRAME_BUFFER_TYPE_SCALE && + GetPlayerState() != ESPLUSPLAYER_STATE_NONE) { + int player_error = esplusplayer_set_video_frame_buffer_scale_resolution( + esplayer_, size.width(), size.height()); + if (player_error != ESPLUSPLAYER_ERROR_TYPE_NONE) { + LOG_ID(ERROR, player_id_) + << "esplusplayer_set_video_frame_buffer_scale_resolution " + "failed, error code " + << player_error; + pending_cb_frame_width_ = size.width(); + pending_cb_frame_height_ = size.height(); + return; + } + LOG_ID(INFO, player_id_) + << "callback frame size successfully set to:" << size.width() << "x" + << size.height(); + cb_frame_width_ = size.width(); + cb_frame_height_ = size.height(); + pending_cb_frame_width_ = 0; + pending_cb_frame_height_ = 0; + } else { + LOG_ID(INFO, player_id_) + << "callback frame size setting will handled later: " << size.width() + << "x" << size.height(); + pending_cb_frame_width_ = size.width(); + pending_cb_frame_height_ = size.height(); + } +#endif +} + +bool MediaPlayerESPlusPlayerTV::RequestVideoDecodedBuffer() { NOTIMPLEMENTED(); } @@ -334,6 +474,12 @@ void MediaPlayerESPlusPlayerTV::OnVideoFrameDropped( NOTIMPLEMENTED(); } +void MediaPlayerESPlusPlayerTV::OnEos() { + MediaPlayerESPlusPlayer::OnEos(); + if (GetMediaPlayerClient()) + GetMediaPlayerClient()->NotifyPlaybackState(kPlaybackFinish, player_id_); +} + void MediaPlayerESPlusPlayerTV::OnPrepareComplete(bool result) { if (!task_runner_->BelongsToCurrentThread()) { task_runner_->PostTask( @@ -342,13 +488,13 @@ void MediaPlayerESPlusPlayerTV::OnPrepareComplete(bool result) { return; } - return MediaPlayerESPlusPlayer::OnPrepareComplete(result); -} + if (result && is_video_low_latency_ && IsValid(DemuxerStream::VIDEO) && + !ReadRequested(DemuxerStream::VIDEO)) { + SetShouldFeed(DemuxerStream::VIDEO, true); + ReadBuffer(DemuxerStream::VIDEO); + } -void MediaPlayerESPlusPlayerTV::OnEos() { - MediaPlayerESPlusPlayer::OnEos(); - if (GetMediaPlayerClient()) - GetMediaPlayerClient()->NotifyPlaybackState(kPlaybackFinish, player_id_); + return MediaPlayerESPlusPlayer::OnPrepareComplete(result); } void ReleaseTzHandle(int tz_handle, int size) { diff --git a/tizen_src/chromium_impl/media/filters/media_player_esplusplayer_tv.h b/tizen_src/chromium_impl/media/filters/media_player_esplusplayer_tv.h index 4a9d6c6..0a23727 100644 --- a/tizen_src/chromium_impl/media/filters/media_player_esplusplayer_tv.h +++ b/tizen_src/chromium_impl/media/filters/media_player_esplusplayer_tv.h @@ -24,6 +24,13 @@ void ReleaseTzHandle(int tz_handle, int size); class MEDIA_EXPORT MediaPlayerESPlusPlayerTV : public MediaPlayerESPlusPlayer { public: + enum { + kDefaultCallBackFrameHeight = 540, + kDefaultCallBackFrameWidth = 960, + kMaxCallBackFrameHeight = 720, + kMaxCallBackFrameWidth = 1280, + }; + MediaPlayerESPlusPlayerTV(); ~MediaPlayerESPlusPlayerTV() override; @@ -35,12 +42,13 @@ class MEDIA_EXPORT MediaPlayerESPlusPlayerTV : public MediaPlayerESPlusPlayer { void EnableLowLatencyMode() override; void SetHardwareResource(int config) override; void EnableTbmBufferCallback(bool enable) override; + void SetCallBackFrameSize(const gfx::Size& size) override; + bool RequestVideoDecodedBuffer() override; void SetAppInfo() override; void OnVideoFrameDropped(const uint64_t dropped_count); void OnPrepareComplete(bool result) override; void OnEos() override; - #if defined(TIZEN_VIDEO_HOLE) void ToggleFullscreenMode(bool is_fullscreen) override {} #endif @@ -91,7 +99,8 @@ class MEDIA_EXPORT MediaPlayerESPlusPlayerTV : public MediaPlayerESPlusPlayer { #endif bool SetVideoSubmitDataType(const media::VideoDecoderConfig& video_config); void SetAudioSubmitDataType(); - bool SetSubmitDataType(const bool is_drm_eme, const bool single_process_mode); + bool SetSubmitDataType(const bool& is_drm_eme, + const bool& single_process_mode); void SetAudioDecoderTypeIfNeeded(const media::AudioCodec& codec); bool is_drm_eme_{false}; @@ -109,6 +118,15 @@ class MEDIA_EXPORT MediaPlayerESPlusPlayerTV : public MediaPlayerESPlusPlayer { bool is_hdr_changed_{false}; esplusplayer_matroska_color matroska_color_; + bool is_video_low_latency_{false}; + esplusplayer_decoded_video_frame_buffer_type decoded_frame_buffer_type_{ + ESPLUSPLAYER_DECODED_VIDEO_FRAME_BUFFER_TYPE_NONE}; + bool enable_tbm_buffer_callback_{false}; + int cb_frame_width_{0}; + int cb_frame_height_{0}; + int pending_cb_frame_width_{0}; + int pending_cb_frame_height_{0}; + base::WeakPtrFactory weak_factory_{this}; }; } // namespace media diff --git a/tizen_src/chromium_impl/media/filters/media_player_tizen.h b/tizen_src/chromium_impl/media/filters/media_player_tizen.h index 3caf276..63194a9 100644 --- a/tizen_src/chromium_impl/media/filters/media_player_tizen.h +++ b/tizen_src/chromium_impl/media/filters/media_player_tizen.h @@ -8,6 +8,7 @@ #include "base/memory/unsafe_shared_memory_region.h" #include "base/task/single_thread_task_runner.h" #include "media/base/demuxer_stream.h" +#include "media/base/renderer.h" #include "media/filters/flags.h" #include "third_party/blink/public/platform/web_application_type.h" #include "third_party/blink/public/platform/web_media_player.h" @@ -97,6 +98,8 @@ class MEDIA_EXPORT MediaPlayerTizen { virtual void SetMediaGeometry(const gfx::Rect& viewport_rect, const gfx::RectF& rect) = 0; virtual void PrepareVideoHole() {} + virtual void SetPlayerVideoAbove(int32_t other_id) {} + virtual void UseSubsurfaceController() {} #endif virtual void RequestSuspend(bool resource_conflicted = false) = 0; @@ -107,6 +110,8 @@ class MEDIA_EXPORT MediaPlayerTizen { virtual void EnableLowLatencyMode() {} virtual void SetHardwareResource(int config) {} virtual void EnableTbmBufferCallback(bool enable) {} + virtual void SetCallBackFrameSize(const gfx::Size& size) {} + virtual bool RequestVideoDecodedBuffer() { return false; } virtual void SetAppInfo() {} virtual int GetPlayerId() { return -1; } virtual void SetContentMimeType(const std::string& mime_type) {} diff --git a/tizen_src/chromium_impl/media/media_efl.gni b/tizen_src/chromium_impl/media/media_efl.gni index 7b41f67..5abc8b7 100644 --- a/tizen_src/chromium_impl/media/media_efl.gni +++ b/tizen_src/chromium_impl/media/media_efl.gni @@ -19,6 +19,9 @@ if (use_ozone) { external_media_efl_deps += [ "//tizen_src/chromium_impl/ui/ozone:ozone_efl" ] } +external_media_efl_blink_config = [] +external_media_efl_blink_sources = [] + if (tizen_multimedia) { external_media_video_decode_config += [ "//tizen_src/build:esplusplayer", @@ -127,6 +130,15 @@ if (tizen_multimedia) { ] } + if(tizen_product_tv) { + if(tizen_video_hole) { + external_media_efl_blink_sources += [ + "//tizen_src/chromium_impl/media/blink/renderer/tizen_esplusplayer_renderer.cc", + "//tizen_src/chromium_impl/media/blink/renderer/tizen_esplusplayer_renderer.h", + ] + } + } + external_media_capture_config += [ "//tizen_src/build:capi-media-camera", "//tizen_src/build:libcapi-media-camera", -- 2.7.4 From e0640adc00b71f4210eed2f90001b9b2ebea727a Mon Sep 17 00:00:00 2001 From: zhaodan Date: Sun, 7 Apr 2024 18:14:30 +0800 Subject: [PATCH 10/16] [M120 Migration]Define correct type as gfx::AcceleratedWidget for arch64 Issue: gfx::AcceleratedWidget was defined as uint32_t while using OZone, so when cast Window pointer to gfx::AcceleratedWidget on 64bit build, the address will lose higher bits and become invalid. Then when EGL APIs accessing the window pointer, the process will crash. Ref: https://review.tizen.org/gerrit/#/c/294274 Change-Id: I2a843f63bae185122a02a75d198cdd929ee23247 Signed-off-by: zhaodan --- ui/gfx/native_widget_types.h | 4 ++++ ui/linux/linux_ui_delegate.h | 5 +++++ 2 files changed, 9 insertions(+) diff --git a/ui/gfx/native_widget_types.h b/ui/gfx/native_widget_types.h index 8cdd0cb..d558d12 100644 --- a/ui/gfx/native_widget_types.h +++ b/ui/gfx/native_widget_types.h @@ -270,7 +270,11 @@ constexpr AcceleratedWidget kNullAcceleratedWidget = 0; using AcceleratedWidget = ANativeWindow*; constexpr AcceleratedWidget kNullAcceleratedWidget = nullptr; #elif BUILDFLAG(IS_OZONE) +#if defined(ARCH_CPU_64_BITS) +using AcceleratedWidget = uint64_t; +#else using AcceleratedWidget = uint32_t; +#endif constexpr AcceleratedWidget kNullAcceleratedWidget = 0; #else #error unknown platform diff --git a/ui/linux/linux_ui_delegate.h b/ui/linux/linux_ui_delegate.h index e86644e9..9742960 100644 --- a/ui/linux/linux_ui_delegate.h +++ b/ui/linux/linux_ui_delegate.h @@ -10,9 +10,14 @@ #include "base/component_export.h" #include "base/functional/callback_forward.h" +#include "build/build_config.h" namespace gfx { +#if defined(ARCH_CPU_64_BITS) +using AcceleratedWidget = uint64_t; +#else using AcceleratedWidget = uint32_t; +#endif } namespace ui { -- 2.7.4 From 757a5cf97a546e04cb74a2e9423e0b1043a391a8 Mon Sep 17 00:00:00 2001 From: wangjing Date: Sun, 7 Apr 2024 10:26:26 +0800 Subject: [PATCH 11/16] Fix for emulator build error need to modify header file fix patch: https://review.tizen.org/gerrit/#/c/308930/ Change-Id: I22f1f88b86a68059b1ef1b490b8862a77f413ea7 Signed-off-by: wangjing --- content/browser/renderer_host/render_widget_host_view_aura.cc | 2 +- content/browser/renderer_host/render_widget_host_view_aura.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/content/browser/renderer_host/render_widget_host_view_aura.cc b/content/browser/renderer_host/render_widget_host_view_aura.cc index 8dc88b6..d8f0ffd 100644 --- a/content/browser/renderer_host/render_widget_host_view_aura.cc +++ b/content/browser/renderer_host/render_widget_host_view_aura.cc @@ -487,7 +487,6 @@ bool RenderWidgetHostViewAura::IsMultiviewMode() { return false; } -#endif void RenderWidgetHostViewAura::DidMoveWebView() { #if defined(TIZEN_VIDEO_HOLE) @@ -495,6 +494,7 @@ void RenderWidgetHostViewAura::DidMoveWebView() { on_webview_moved_callback_.Run(); #endif } +#endif void RenderWidgetHostViewAura::SetSize(const gfx::Size& size) { // For a SetSize operation, we don't care what coordinate system the origin diff --git a/content/browser/renderer_host/render_widget_host_view_aura.h b/content/browser/renderer_host/render_widget_host_view_aura.h index fa133fa..24d4f17 100644 --- a/content/browser/renderer_host/render_widget_host_view_aura.h +++ b/content/browser/renderer_host/render_widget_host_view_aura.h @@ -197,6 +197,7 @@ class CONTENT_EXPORT RenderWidgetHostViewAura // Sets rotation degrees. Expected values are one of { 0, 90, 180, 270 }. void UpdateRotationDegrees(int rotation_degrees); bool IsMultiviewMode(); + void DidMoveWebView(); #endif base::flat_map GetKeyboardLayoutMap() override; void InvalidateLocalSurfaceIdAndAllocationGroup() override; @@ -228,7 +229,6 @@ class CONTENT_EXPORT RenderWidgetHostViewAura #endif ) override; #if defined(TIZEN_VIDEO_HOLE) - void DidMoveWebView(); void SetWebViewMovedCallback(const base::RepeatingClosure on_webview_moved); #endif -- 2.7.4 From 30296629f566e905cb739beec5c6a41d33b85479 Mon Sep 17 00:00:00 2001 From: wangjing Date: Mon, 8 Apr 2024 14:28:13 +0800 Subject: [PATCH 12/16] [M120 Migration] Disable badge service As badge is not enable on TV, so we need to disable it. Or it will cause js error ref: https://review.tizen.org/gerrit/#/c/276311/ Change-Id: Ic87ce222c90d33206ccfef335f5e8e10469d1557 Signed-off-by: wangjing --- third_party/blink/renderer/modules/badging/navigator_badge.cc | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/third_party/blink/renderer/modules/badging/navigator_badge.cc b/third_party/blink/renderer/modules/badging/navigator_badge.cc index bc722ad..a832ce4 100644 --- a/third_party/blink/renderer/modules/badging/navigator_badge.cc +++ b/third_party/blink/renderer/modules/badging/navigator_badge.cc @@ -93,6 +93,9 @@ ScriptPromise NavigatorBadge::SetAppBadgeHelper( ScriptState* script_state, mojom::blink::BadgeValuePtr badge_value, ExceptionState& exception_state) { +#if BUILDFLAG(IS_TIZEN_TV) + return ScriptPromise::CastUndefined(script_state); +#endif if (badge_value->is_number() && badge_value->get_number() == 0) return ClearAppBadgeHelper(script_state, exception_state); @@ -122,7 +125,7 @@ ScriptPromise NavigatorBadge::ClearAppBadgeHelper( return ScriptPromise(); } -#if !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_FUCHSIA) +#if !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_FUCHSIA) && !BUILDFLAG(IS_TIZEN_TV) // TODO(crbug.com/1413916): The service is implemented in Chrome, so it may // not be provided in other embedders. Ensure that case is handled properly. From(script_state).badge_service()->ClearBadge(); -- 2.7.4 From b8dc205f59d302c3e279b11261d2958f43411f18 Mon Sep 17 00:00:00 2001 From: Akshay Kanagali Date: Thu, 4 Apr 2024 13:21:23 +0530 Subject: [PATCH 13/16] fixup! [NUI] NUI implementation for |SkiaRenderer| Replacing gl_image_egl with scoped_egl_image. Change-Id: Iaa7f75b1704d9d156db00f68e82d092c7c156867 Signed-off-by: Akshay Kanagali --- .../skia_output_device_offscreen_tbm.cc | 20 +++++++------------- .../skia_output_device_offscreen_tbm.h | 7 ++----- 2 files changed, 9 insertions(+), 18 deletions(-) diff --git a/tizen_src/chromium_impl/components/viz/service/display_embedder/skia_output_device_offscreen_tbm.cc b/tizen_src/chromium_impl/components/viz/service/display_embedder/skia_output_device_offscreen_tbm.cc index a1e20db..e0aaea9 100644 --- a/tizen_src/chromium_impl/components/viz/service/display_embedder/skia_output_device_offscreen_tbm.cc +++ b/tizen_src/chromium_impl/components/viz/service/display_embedder/skia_output_device_offscreen_tbm.cc @@ -8,7 +8,6 @@ #include "third_party/skia/include/core/SkSurface.h" #include "ui/gl/gl_bindings.h" -#include "ui/gl/gl_image_egl.h" namespace viz { @@ -34,30 +33,25 @@ void SkiaOutputDeviceOffscreenTBM::EnsureBackbuffer() { size_.width(), size_.height(), TBM_FORMAT_ARGB8888); EGLint attrs[] = {EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, EGL_NONE}; - image_egl_ = base::MakeRefCounted(size_); - if (!image_egl_->Initialize(EGL_NATIVE_SURFACE_TIZEN, - static_cast(tbm_surface_), - attrs, 0, 0)) { - return; - } + egl_image_ = + gl::MakeScopedEGLImage(EGL_NO_CONTEXT, EGL_NATIVE_SURFACE_TIZEN, + static_cast(tbm_surface_), attrs); GLuint texture_id = 0; glGenTextures(1, &texture_id); glBindTexture(GL_TEXTURE_2D, texture_id); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - image_egl_->BindTexImage(GL_TEXTURE_2D); - gpu::GetGrBackendTexture(context_state_->feature_info(), GL_TEXTURE_2D, - size_, texture_id, RGBA_8888, + glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, egl_image_.get()); + + gpu::GetGrBackendTexture(context_state_->feature_info(), GL_TEXTURE_2D, size_, + texture_id, kRGBA_8888_SkColorType, context_state_->gr_context()->threadSafeProxy(), &backend_texture_); } void SkiaOutputDeviceOffscreenTBM::DiscardBackbuffer() { - if (image_egl_) - image_egl_.release(); - if (tbm_surface_) { if (tbm_surface_destroy(tbm_surface_) != TBM_SURFACE_ERROR_NONE) LOG(ERROR) << "Failed to destroy tbm surface."; diff --git a/tizen_src/chromium_impl/components/viz/service/display_embedder/skia_output_device_offscreen_tbm.h b/tizen_src/chromium_impl/components/viz/service/display_embedder/skia_output_device_offscreen_tbm.h index b600f4a..a816992 100644 --- a/tizen_src/chromium_impl/components/viz/service/display_embedder/skia_output_device_offscreen_tbm.h +++ b/tizen_src/chromium_impl/components/viz/service/display_embedder/skia_output_device_offscreen_tbm.h @@ -7,10 +7,7 @@ #include "components/viz/service/display_embedder/skia_output_device_offscreen.h" #include "ui/gfx/tbm_buffer_handle.h" - -namespace gl { -class GLImageEGL; -} +#include "ui/gl/scoped_egl_image.h" namespace viz { @@ -34,7 +31,7 @@ class SkiaOutputDeviceOffscreenTBM : public SkiaOutputDeviceOffscreen { private: tbm_surface_h tbm_surface_ = 0; - scoped_refptr image_egl_; + gl::ScopedEGLImage egl_image_; }; } // namespace viz -- 2.7.4 From effde2838f04f5a8f36335cd44dd7fd9f331d91a Mon Sep 17 00:00:00 2001 From: jinbei09 Date: Wed, 27 Mar 2024 14:54:32 +0800 Subject: [PATCH 14/16] [M120 Migration][NaCl][PPFwk]Use GetWaylandWindowId to get window id For chromium aura, Previously the 'GetWaylandWindowId' api can't return window id normally, so use ecore_evas_gl_x11_window_get instead. This will lead to the app can not get the window id correctly. For latest chromium aura, 'GetWaylandWindowId' can return window id normally, so use it to fix the issue Migrated from tizen 8.0: https://review.tizen.org/gerrit/#/c/platform/framework/web/chromium-efl/+/304538/ Change-Id: Iac8cf838da27e55dc11710cd79b8583ef48891cb Signed-off-by: jinbei09 --- tizen_src/ewk/efl_integration/ewk_extension_system_delegate.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tizen_src/ewk/efl_integration/ewk_extension_system_delegate.cc b/tizen_src/ewk/efl_integration/ewk_extension_system_delegate.cc index 1eefb1a..48c3c73 100644 --- a/tizen_src/ewk/efl_integration/ewk_extension_system_delegate.cc +++ b/tizen_src/ewk/efl_integration/ewk_extension_system_delegate.cc @@ -252,7 +252,7 @@ void EwkExtensionSystemDelegate::SetWindowId(const Evas_Object* main_window) { LOG(ERROR) << "Ecore_Evas can`t be acquired from main window Evas"; return; } -#if defined(USE_WAYLAND)&&!defined(USE_AURA) +#if defined(USE_WAYLAND) #if TIZEN_VERSION_AT_LEAST(5, 0, 0) Ecore_Wl2_Window* ww = ecore_evas_wayland2_window_get(ee); #else -- 2.7.4 From d770c486fd14d09491571f9f35d44c60534eb372 Mon Sep 17 00:00:00 2001 From: "peng.yin" Date: Tue, 6 Jun 2023 14:47:24 +0800 Subject: [PATCH 15/16] [M120 Migration][WebRTC] Tbm mapping buffer support in webrtc video sink video frame with PIXEL_FORMAT_TBM_INTER_PROCESS_BUFFER format is not correctly handled in webrtc video sink pipe, this format is same as NV12 actually, so add same logic as NV12 format to handle it. Change-Id: Id54be9723f86910c397aea8ecc9bfece25070fe0 Signed-off-by: peng.yin --- media/base/video_util.cc | 16 ++++++++-- .../webrtc/convert_to_webrtc_video_frame_buffer.cc | 35 +++++++++++++++++++++- 2 files changed, 48 insertions(+), 3 deletions(-) diff --git a/media/base/video_util.cc b/media/base/video_util.cc index aa61c52..d21b1d2 100644 --- a/media/base/video_util.cc +++ b/media/base/video_util.cc @@ -811,7 +811,12 @@ EncoderStatus ConvertAndScaleFrame(const VideoFrame& src_frame, VideoPixelFormatToString(src_frame.format()), "dst_format", VideoPixelFormatToString(dst_frame.format())); constexpr auto kDefaultFiltering = libyuv::kFilterBox; - if (!src_frame.IsMappable() || !dst_frame.IsMappable()) + if ((!src_frame.IsMappable() +#if defined(TIZEN_TBM_SUPPORT) + && src_frame.format() != PIXEL_FORMAT_TBM_INTER_PROCESS_BUFFER +#endif + ) || + !dst_frame.IsMappable()) return EncoderStatus::Codes::kUnsupportedFrameFormat; if ((dst_frame.format() == PIXEL_FORMAT_I420A || @@ -952,6 +957,9 @@ EncoderStatus ConvertAndScaleFrame(const VideoFrame& src_frame, if ((dst_frame.format() == PIXEL_FORMAT_NV12 || dst_frame.format() == PIXEL_FORMAT_NV12A) && (src_frame.format() == PIXEL_FORMAT_NV12 || +#if defined(TIZEN_TBM_SUPPORT) + src_frame.format() == PIXEL_FORMAT_TBM_INTER_PROCESS_BUFFER || +#endif src_frame.format() == PIXEL_FORMAT_NV12A)) { if (dst_frame.format() == PIXEL_FORMAT_NV12A) { libyuv::ScalePlane( @@ -981,7 +989,11 @@ EncoderStatus ConvertAndScaleFrame(const VideoFrame& src_frame, } if (dst_frame.format() == PIXEL_FORMAT_I420 && - src_frame.format() == PIXEL_FORMAT_NV12) { + ( +#if defined(TIZEN_TBM_SUPPORT) + src_frame.format() == PIXEL_FORMAT_TBM_INTER_PROCESS_BUFFER || +#endif + src_frame.format() == PIXEL_FORMAT_NV12)) { if (src_frame.visible_rect().size() == dst_frame.visible_rect().size()) { // Both frames have the same size, only NV12-to-I420 conversion is // required. diff --git a/third_party/blink/renderer/platform/webrtc/convert_to_webrtc_video_frame_buffer.cc b/third_party/blink/renderer/platform/webrtc/convert_to_webrtc_video_frame_buffer.cc index 770f54b..7fc4d98 100644 --- a/third_party/blink/renderer/platform/webrtc/convert_to_webrtc_video_frame_buffer.cc +++ b/third_party/blink/renderer/platform/webrtc/convert_to_webrtc_video_frame_buffer.cc @@ -181,6 +181,11 @@ rtc::scoped_refptr MakeFrameAdapter( case media::PIXEL_FORMAT_NV12: return rtc::scoped_refptr( new rtc::RefCountedObject(std::move(video_frame))); +#if defined(TIZEN_TBM_SUPPORT) + case media::PIXEL_FORMAT_TBM_INTER_PROCESS_BUFFER: + return rtc::scoped_refptr( + new rtc::RefCountedObject(std::move(video_frame))); +#endif default: NOTREACHED(); return nullptr; @@ -195,7 +200,9 @@ scoped_refptr MakeScaledVideoFrame( media::VideoPixelFormat dst_format = media::PIXEL_FORMAT_UNKNOWN; bool tmp_buffer_needed = false; if (source_is_nv12) { +#if !defined(TIZEN_TBM_SUPPORT) DCHECK_EQ(source_frame->format(), media::PIXEL_FORMAT_NV12); +#endif dst_format = media::PIXEL_FORMAT_NV12; } else { // ARGB pixel format may be produced by readback of texture backed frames. @@ -253,6 +260,10 @@ scoped_refptr MaybeConvertAndScaleFrame( source_frame->format() == media::PIXEL_FORMAT_ARGB || source_frame->format() == media::PIXEL_FORMAT_XRGB || source_frame->format() == media::PIXEL_FORMAT_ABGR || +#if defined(TIZEN_TBM_SUPPORT) + source_frame->format() == + media::PIXEL_FORMAT_TBM_INTER_PROCESS_BUFFER || +#endif source_frame->format() == media::PIXEL_FORMAT_XBGR); RTC_DCHECK(shared_resources); @@ -260,6 +271,9 @@ scoped_refptr MaybeConvertAndScaleFrame( source_frame->format() == media::PIXEL_FORMAT_I420 || source_frame->format() == media::PIXEL_FORMAT_I420A; const bool source_is_nv12 = +#if defined(TIZEN_TBM_SUPPORT) + source_frame->format() == media::PIXEL_FORMAT_TBM_INTER_PROCESS_BUFFER || +#endif source_frame->format() == media::PIXEL_FORMAT_NV12; const bool no_scaling_needed = source_frame->natural_size() == source_frame->visible_rect().size(); @@ -288,7 +302,14 @@ bool CanConvertToWebRtcVideoFrameBuffer(const media::VideoFrame* frame) { #if defined(TIZEN_VIDEO_HOLE) frame->storage_type() == media::VideoFrame::STORAGE_HOLE || #endif - frame->format() == media::PIXEL_FORMAT_ENCODED || frame->HasTextures(); +#if BUILDFLAG(IS_TIZEN) + frame->format() == media::PIXEL_FORMAT_ENCODED || +#if defined(TIZEN_TBM_SUPPORT) + frame->format() == + media::VideoPixelFormat::PIXEL_FORMAT_TBM_INTER_PROCESS_BUFFER || +#endif +#endif + frame->HasTextures(); } // static @@ -324,6 +345,18 @@ rtc::scoped_refptr ConvertToWebRtcVideoFrameBuffer( video_frame->timestamp())); } return MakeFrameAdapter(std::move(converted_frame)); +#if defined(TIZEN_TBM_SUPPORT) + } else if (video_frame->format() == + media::VideoPixelFormat::PIXEL_FORMAT_TBM_INTER_PROCESS_BUFFER) { + // the video frame with tbm buffer type is native, handle it here + scoped_refptr scaled_frame = + MaybeConvertAndScaleFrame(video_frame, shared_resources); + if (!scaled_frame) { + DLOG(ERROR) << "Make scaled frame failed."; + return MakeFrameAdapter(std::move(video_frame)); + } + return MakeFrameAdapter(std::move(scaled_frame)); +#endif } else if (video_frame->HasTextures()) { auto converted_frame = shared_resources -- 2.7.4 From c5b20b17413fabb6821e5f10fe144cbd66ed40a7 Mon Sep 17 00:00:00 2001 From: jiangyuwei Date: Mon, 8 Apr 2024 16:34:14 +0800 Subject: [PATCH 16/16] [M120 Migration] Add error check when get system info Add error check when get system info. References: - https://review.tizen.org/gerrit/#/c/295962/ Change-Id: I8fdf2e49049ee3c05802b63dc6dfe9443170704b Signed-off-by: jiangyuwei --- tizen_src/chromium_impl/tizen/system_info.cc | 56 +++++++++++++++------------- 1 file changed, 30 insertions(+), 26 deletions(-) diff --git a/tizen_src/chromium_impl/tizen/system_info.cc b/tizen_src/chromium_impl/tizen/system_info.cc index 30223cd..569ee0d 100644 --- a/tizen_src/chromium_impl/tizen/system_info.cc +++ b/tizen_src/chromium_impl/tizen/system_info.cc @@ -26,8 +26,19 @@ void GetProfile(void) { return; #if BUILDFLAG(IS_TIZEN) - char *profileName; - system_info_get_platform_string("http://tizen.org/feature/profile", &profileName); + char* profileName = nullptr; + int result = system_info_get_platform_string( + "http://tizen.org/feature/profile", &profileName); + + if (result != SYSTEM_INFO_ERROR_NONE || !profileName) { +#if (IS_TIZEN_TV) + g_profile__ = PROFILE_TV; +#else + g_profile__ = PROFILE_COMMON; +#endif + free(profileName); + return; + } #if defined(ARCH_CPU_RISCV_FAMILY) if (const char* env_profile = std::getenv(PROFILE_ENV_STRING)) { @@ -97,30 +108,23 @@ void GetArch(void) { if (g_arch__ != ARCH_UNKNOWN) return; - char *archName; - system_info_get_platform_string("http://tizen.org/feature/platform.core.cpu.arch", &archName); - - int archNamelen = strlen(archName); - if (strncmp(archName, "armv7", archNamelen) == 0) { - g_arch__ = ARCH_ARMV7; - } - else if (strncmp(archName, "aarch64", archNamelen) == 0) { - g_arch__ = ARCH_AARCH64; - } - else if (strncmp(archName, "x86", archNamelen) == 0) { - g_arch__ = ARCH_X86; - } - else if (strncmp(archName, "x86_64", archNamelen) == 0) { - g_arch__ = ARCH_X86_64; - } - else if (strncmp(archName, "rv32", archNamelen) == 0) { - g_arch__ = ARCH_RV32; - } - else if (strncmp(archName, "rv64", archNamelen) == 0) { - g_arch__ = ARCH_RV64; - } - else { - g_arch__ = ARCH_UNKNOWN; + char* archName = nullptr; + int result = system_info_get_platform_string( + "http://tizen.org/feature/platform.core.cpu.arch", &archName); + + if (result == SYSTEM_INFO_ERROR_NONE && archName) { + int archNamelen = strlen(archName); + if (strncmp(archName, "armv7", archNamelen) == 0) { + g_arch__ = ARCH_ARMV7; + } else if (strncmp(archName, "aarch64", archNamelen) == 0) { + g_arch__ = ARCH_AARCH64; + } else if (strncmp(archName, "x86", archNamelen) == 0) { + g_arch__ = ARCH_X86; + } else if (strncmp(archName, "x86_64", archNamelen) == 0) { + g_arch__ = ARCH_X86_64; + } else { + g_arch__ = ARCH_UNKNOWN; + } } free(archName); #endif -- 2.7.4