From 67b311ed5bf6336cdda5cbccd51147014c5fce8d Mon Sep 17 00:00:00 2001 From: Leonid Date: Tue, 27 Feb 2024 13:05:39 +0100 Subject: [PATCH 01/16] Feat: runtime profile override with getenv Rebasing previous change 301607 from tizen.riscv Change-Id: I411fa84ced46e5220c59e7b43e3bd7a840044dde Signed-off-by: Leonid --- tizen_src/chromium_impl/tizen/system_info.cc | 21 +++++++++++++++++++++ tizen_src/chromium_impl/tizen/system_info.h | 4 +++- 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/tizen_src/chromium_impl/tizen/system_info.cc b/tizen_src/chromium_impl/tizen/system_info.cc index 07392b2..30223cd 100644 --- a/tizen_src/chromium_impl/tizen/system_info.cc +++ b/tizen_src/chromium_impl/tizen/system_info.cc @@ -11,6 +11,10 @@ #if BUILDFLAG(IS_TIZEN) #include +#if defined(ARCH_CPU_RISCV_FAMILY) +#include +#define PROFILE_ENV_STRING "CHROMIUM_PROFILE" +#endif #endif @@ -24,11 +28,22 @@ void GetProfile(void) { #if BUILDFLAG(IS_TIZEN) char *profileName; system_info_get_platform_string("http://tizen.org/feature/profile", &profileName); +#if defined(ARCH_CPU_RISCV_FAMILY) + if (const char* env_profile = std::getenv(PROFILE_ENV_STRING)) + { + free(profileName); + profileName = strdup(env_profile); + } +#endif switch (*profileName) { case 'm': case 'M': g_profile__ = PROFILE_MOBILE; break; + case 'd': + case 'D': + g_profile__ = PROFILE_DESKTOP; + break; case 'w': case 'W': g_profile__ = PROFILE_WEARABLE; @@ -98,6 +113,12 @@ void GetArch(void) { 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; } diff --git a/tizen_src/chromium_impl/tizen/system_info.h b/tizen_src/chromium_impl/tizen/system_info.h index e6e17e7..540d64d 100644 --- a/tizen_src/chromium_impl/tizen/system_info.h +++ b/tizen_src/chromium_impl/tizen/system_info.h @@ -30,7 +30,9 @@ typedef enum { ARCH_ARMV7 = 1 << 2, ARCH_AARCH64 = 1 << 3, ARCH_X86 = 1 << 4, - ARCH_X86_64 = 1 << 5 + ARCH_X86_64 = 1 << 5, + ARCH_RV32 = 1 << 6, + ARCH_RV64 = 1 << 7, } Arch_Inform; #ifdef __cplusplus -- 2.7.4 From a0abc23a8a028e8580ac54473f07fd5450cf383e Mon Sep 17 00:00:00 2001 From: fangfengrong Date: Tue, 12 Mar 2024 08:40:21 +0800 Subject: [PATCH 02/16] [M120 Migration][VD] Fix window lost focus after dialog close Here an issue: When dialog show and hide, app only receive the window.blur event, without the window.focus event. when dialog show, chromium set Process blocked(IsIgnoringInputEvents is true); when dialog hide, chromium reset Process block(IsIgnoringInputEvents is false); Once app set focus before Process block reset, the focus will been blocked. OnWindowFocused Function, only IgnoringInputEvents for gained_focus case, don't IgnoringInputEvents for lost_focus case, it cause the blur event been delivered to app, but the focus event don't. Whenever dialog show, chromium ignores the input event to avoid dismissing dialog. While app might forcefully set focus on webview even if dialog are being shown. So don't check IgnoringInputEvents both for gained_focus and lost_focus. refer: https://review.tizen.org/gerrit/#/c/304248 Change-Id: Ia998518560b7816129518a51c779d728168d8190 Signed-off-by: fangfengrong --- content/browser/renderer_host/render_frame_host_impl.cc | 2 ++ content/browser/renderer_host/render_widget_host_view_aura.cc | 2 ++ third_party/blink/renderer/core/dom/document.cc | 9 +++++++++ third_party/blink/renderer/core/page/focus_controller.cc | 1 + 4 files changed, 14 insertions(+) diff --git a/content/browser/renderer_host/render_frame_host_impl.cc b/content/browser/renderer_host/render_frame_host_impl.cc index adba336..7cb8e72 100644 --- a/content/browser/renderer_host/render_frame_host_impl.cc +++ b/content/browser/renderer_host/render_frame_host_impl.cc @@ -5652,6 +5652,7 @@ void RenderFrameHostImpl::RunJavaScriptDialog( // While a JS message dialog is showing, tabs in the same process shouldn't // process input events. + LOG(INFO) << "RunJavaScriptDialog,SetBlocked TRUE"; GetProcess()->SetBlocked(true); delegate_->RunJavaScriptDialog( @@ -10046,6 +10047,7 @@ void RenderFrameHostImpl::JavaScriptDialogClosed( JavaScriptDialogCallback dialog_closed_callback, bool success, const std::u16string& user_input) { + LOG(INFO) << "JavaScriptDialogClosed,SetBlocked FALSE"; GetProcess()->SetBlocked(false); std::move(dialog_closed_callback).Run(success, user_input); // If executing as part of beforeunload event handling, there may have been 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 9bfdcaf..d737845 100644 --- a/content/browser/renderer_host/render_widget_host_view_aura.cc +++ b/content/browser/renderer_host/render_widget_host_view_aura.cc @@ -2366,11 +2366,13 @@ void RenderWidgetHostViewAura::OnWindowFocused(aura::Window* gained_focus, LOG(INFO) << "OnWindowFocused, Gained : " << gained_focus << ", Lost : " << lost_focus; if (window_ == gained_focus) { +#if !BUILDFLAG(IS_TIZEN_TV) // We need to honor input bypass if the associated tab does not want input. // This gives the current focused window a chance to be the text input // client and handle events. if (host()->IsIgnoringInputEvents()) return; +#endif host()->GotFocus(); UpdateActiveState(true); diff --git a/third_party/blink/renderer/core/dom/document.cc b/third_party/blink/renderer/core/dom/document.cc index c057ad2..0bd12e6 100644 --- a/third_party/blink/renderer/core/dom/document.cc +++ b/third_party/blink/renderer/core/dom/document.cc @@ -5218,6 +5218,7 @@ bool Document::SetFocusedElement(Element* new_focused_element, DCHECK(!lifecycle_.InDetach()); clear_focused_element_timer_.Stop(); + LOG(INFO) << "setFocusedElement to element " << (void*)new_focused_element; // Make sure new_focused_element is actually in this document. if (new_focused_element) { @@ -5391,6 +5392,14 @@ bool Document::SetFocusedElement(Element* new_focused_element, } if (!focus_change_blocked) { + LOG(INFO) << "setFocusedElement focus changed from: " + << (old_focused_element + ? old_focused_element->outerHTML().Utf8().data() + : "nullptr"); + LOG(INFO) << "setFocusedElement focus changed to: " + << (new_focused_element + ? new_focused_element->outerHTML().Utf8().data() + : "nullptr"); NotifyFocusedElementChanged(old_focused_element, focused_element_.Get(), params.type); } diff --git a/third_party/blink/renderer/core/page/focus_controller.cc b/third_party/blink/renderer/core/page/focus_controller.cc index 6ac3b81..bc5bf51 100644 --- a/third_party/blink/renderer/core/page/focus_controller.cc +++ b/third_party/blink/renderer/core/page/focus_controller.cc @@ -465,6 +465,7 @@ inline void DispatchEventsOnWindowAndFocusedElement(Document* document, if (page->Paused()) return; } + LOG(INFO) << "DispatchEventsOnWindowAndFocusedElement,focused:" << focused; if (!focused && document->FocusedElement()) { Element* focused_element = document->FocusedElement(); -- 2.7.4 From 421d9a489bc355aaaeb80a276ecab02adbcd7a6c Mon Sep 17 00:00:00 2001 From: fang fengrong Date: Mon, 11 Mar 2024 17:21:44 +0800 Subject: [PATCH 03/16] [M120 Migration][VD] Fix some focus issues for offscreen mode 1.focus can't move to webview with arrow key. In WebBrowser, create two or more tab pages. When switch to another tab, the arrow key can't move to web-page. because focus isnot sync to efl window. 2.The webview focus should been controled by app through ewk_view_set focus api, chromium should not set default focus. 3.on hbbtv, press any key no response, because of webview on focus out status. 4.Keeps same with M94, register focusin/focusout for content_image_elm_host; when content_image_elm_host focusin/focusout, sync the focus to content_image. 5.Add some log for debug. refer: https://review.tizen.org/gerrit/#/c/297117/ https://review.tizen.org/gerrit/#/c/297301/ Change-Id: Ia2677e488c26ced5a81ae5973fc91e7789877cf2 Signed-off-by: fang fengrong --- .../renderer_host/render_widget_host_view_aura.cc | 3 ++- .../renderer_host/rwhv_aura_offscreen_helper_efl.cc | 19 +++++++++++++++++++ .../ui/ozone/platform/efl/efl_event_handler.cc | 8 +++++++- .../chromium_impl/ui/ozone/platform/efl/efl_window.cc | 13 +++++++++++-- .../chromium_impl/ui/ozone/platform/efl/efl_window.h | 2 +- ui/platform_window/platform_window.h | 1 + 6 files changed, 41 insertions(+), 5 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 d737845..2a443c9 100644 --- a/content/browser/renderer_host/render_widget_host_view_aura.cc +++ b/content/browser/renderer_host/render_widget_host_view_aura.cc @@ -553,7 +553,8 @@ void RenderWidgetHostViewAura::Focus() { window_->Focus(); #if BUILDFLAG(IS_EFL) - efl_helper_->Focus(true); + if (!efl_helper_->HasFocus()) + efl_helper_->Focus(true); #endif } diff --git a/tizen_src/chromium_impl/content/browser/renderer_host/rwhv_aura_offscreen_helper_efl.cc b/tizen_src/chromium_impl/content/browser/renderer_host/rwhv_aura_offscreen_helper_efl.cc index bfb1e76..6c498af 100644 --- a/tizen_src/chromium_impl/content/browser/renderer_host/rwhv_aura_offscreen_helper_efl.cc +++ b/tizen_src/chromium_impl/content/browser/renderer_host/rwhv_aura_offscreen_helper_efl.cc @@ -181,6 +181,10 @@ RWHVAuraOffscreenHelperEfl::~RWHVAuraOffscreenHelperEfl() { OnFocusIn); evas_object_event_callback_del(content_image_, EVAS_CALLBACK_FOCUS_OUT, OnFocusOut); + evas_object_smart_callback_del(content_image_elm_host_, "focused", + OnHostFocusIn); + evas_object_smart_callback_del(content_image_elm_host_, "unfocused", + OnHostFocusOut); evas_event_callback_del_full(evas_, EVAS_CALLBACK_RENDER_FLUSH_PRE, OnEvasRenderFlushPre, this); evas_object_del(content_image_); @@ -559,8 +563,19 @@ void RWHVAuraOffscreenHelperEfl::NotifySwap(const size_t texture_id) { } void RWHVAuraOffscreenHelperEfl::Focus(bool focus) { + LOG(INFO) << "evas_object_focus_set:" << focus; elm_object_focus_set(content_image_elm_host_, focus); evas_object_focus_set(content_image_, focus); + +#if BUILDFLAG(IS_TIZEN_TV) + // sync focus on efl window + aura::WindowTreeHost* window_host = rwhva()->window()->GetHost(); + if (window_host) { + static_cast(window_host) + ->platform_window() + ->UpdateFocus(focus); + } +#endif } bool RWHVAuraOffscreenHelperEfl::HasFocus() { @@ -578,6 +593,7 @@ void RWHVAuraOffscreenHelperEfl::OnFocusIn(void* data, Evas* evas, Evas_Object* obj, void* event_info) { + LOG(INFO) << "OnFocusIn"; RWHVAuraOffscreenHelperEfl* thiz = static_cast(data); thiz->FocusRWHVA(); @@ -594,6 +610,7 @@ void RWHVAuraOffscreenHelperEfl::OnFocusOut(void* data, Evas* evas, Evas_Object* obj, void* event_info) { + LOG(INFO) << "OnFocusOut"; RWHVAuraOffscreenHelperEfl* thiz = static_cast(data); aura::WindowTreeHost* window_host = thiz->rwhva()->window()->GetHost(); @@ -624,6 +641,7 @@ void RWHVAuraOffscreenHelperEfl::OnFocusOut(void* data, void RWHVAuraOffscreenHelperEfl::OnHostFocusIn(void* data, Evas_Object*, void*) { + LOG(INFO) << "OnHostFocusIn"; RWHVAuraOffscreenHelperEfl* thiz = static_cast(data); thiz->Focus(true); @@ -632,6 +650,7 @@ void RWHVAuraOffscreenHelperEfl::OnHostFocusIn(void* data, void RWHVAuraOffscreenHelperEfl::OnHostFocusOut(void* data, Evas_Object*, void*) { + LOG(INFO) << "OnHostFocusOut"; RWHVAuraOffscreenHelperEfl* thiz = static_cast(data); if (thiz && thiz->GetRenderWidgetHostImpl()) diff --git a/tizen_src/chromium_impl/ui/ozone/platform/efl/efl_event_handler.cc b/tizen_src/chromium_impl/ui/ozone/platform/efl/efl_event_handler.cc index d7e93d7..91ca651 100644 --- a/tizen_src/chromium_impl/ui/ozone/platform/efl/efl_event_handler.cc +++ b/tizen_src/chromium_impl/ui/ozone/platform/efl/efl_event_handler.cc @@ -28,6 +28,8 @@ #endif #if BUILDFLAG(IS_TIZEN_TV) +#include "base/base_switches.h" +#include "base/command_line.h" #include "third_party/blink/public/platform/web_application_type.h" #endif @@ -174,7 +176,11 @@ void EflEventHandler::RegisterCallbacks() { if (key_events_enabled_) AddKeyCallbacks(); - evas_object_focus_set(events_overlay_, EINA_TRUE); +#if BUILDFLAG(IS_TIZEN_TV) + if (!base::CommandLine::ForCurrentProcess()->HasSwitch( + switches::kEnableOffscreenRendering)) +#endif + evas_object_focus_set(events_overlay_, EINA_TRUE); if (touch_events_enabled_) AddTouchCallbacks(); diff --git a/tizen_src/chromium_impl/ui/ozone/platform/efl/efl_window.cc b/tizen_src/chromium_impl/ui/ozone/platform/efl/efl_window.cc index af45ee1..bd607d9 100644 --- a/tizen_src/chromium_impl/ui/ozone/platform/efl/efl_window.cc +++ b/tizen_src/chromium_impl/ui/ozone/platform/efl/efl_window.cc @@ -307,6 +307,7 @@ void EflWindow::UpdateFocus(bool focused) { if (has_focus_ == focused) return; + LOG(INFO) << "EflWindow Focus:" << focused; has_focus_ = focused; if (events_overlay_) { @@ -479,7 +480,11 @@ void EflWindow::InitializeEventHandler() { // Set focus active for a newly opened window. #if !defined(BUILD_CHROME) - UpdateFocus(true); +#if BUILDFLAG(IS_TIZEN_TV) + if (!base::CommandLine::ForCurrentProcess()->HasSwitch( + switches::kEnableOffscreenRendering)) +#endif + UpdateFocus(true); #endif efl_event_handler_ = std::make_unique(this); PlatformEventSource::GetInstance()->AddPlatformEventDispatcher(this); @@ -495,7 +500,11 @@ void EflWindow::EnsureIMContextEfl() { void EflWindow::ResetEventHandler() { delegate_->OnActivationChanged(false /*active*/); - UpdateFocus(false); +#if BUILDFLAG(IS_TIZEN_TV) + if (!base::CommandLine::ForCurrentProcess()->HasSwitch( + switches::kEnableOffscreenRendering)) +#endif + UpdateFocus(false); efl_event_handler_.reset(); PlatformEventSource::GetInstance()->RemovePlatformEventDispatcher(this); } diff --git a/tizen_src/chromium_impl/ui/ozone/platform/efl/efl_window.h b/tizen_src/chromium_impl/ui/ozone/platform/efl/efl_window.h index 4da7edb..1e99f25 100644 --- a/tizen_src/chromium_impl/ui/ozone/platform/efl/efl_window.h +++ b/tizen_src/chromium_impl/ui/ozone/platform/efl/efl_window.h @@ -76,7 +76,7 @@ class EflWindow : public PlatformWindow, public PlatformEventDispatcher { // Called only in case of offscreen rendering void SetEventsOverlayForOffscreen(Evas_Object* events_overlay) override; - void UpdateFocus(bool focused); + void UpdateFocus(bool focused) override; void SetFocus(bool focused) { has_focus_ = focused; } void OnWindowLostCapture(); diff --git a/ui/platform_window/platform_window.h b/ui/platform_window/platform_window.h index 7aac100..c9aab7f 100644 --- a/ui/platform_window/platform_window.h +++ b/ui/platform_window/platform_window.h @@ -233,6 +233,7 @@ class COMPONENT_EXPORT(PLATFORM_WINDOW) PlatformWindow #if BUILDFLAG(IS_EFL) // Sets view created in RWHVAura as events overlay for offscreen rendering. virtual void SetEventsOverlayForOffscreen(Evas_Object* events_overlay) {} + virtual void UpdateFocus(bool focused) {} virtual EflEventHandler* GetEventHandler() { return nullptr; } #endif -- 2.7.4 From 9416c0fa497fadee4a33ab8dcdf002515e147b33 Mon Sep 17 00:00:00 2001 From: wuxiaoliang Date: Tue, 12 Mar 2024 13:35:46 +0800 Subject: [PATCH 04/16] [M120 Migration][MM] Framerate calculation Migrated from: https://review.tizen.org/gerrit/#/c/platform/framework/web/chromium-efl/+/290568/ https://review.tizen.org/gerrit/#/c/platform/framework/web/chromium-efl/+/296928/ Change-Id: Ib627bb501bcc64895ab93189c35507598106ac5b Signed-off-by: wuxiaoliang --- media/base/stream_parser.h | 14 +++ media/base/video_decoder_config.h | 6 + media/filters/chunk_demuxer.cc | 84 ++++++++++++-- media/filters/chunk_demuxer.h | 15 ++- media/filters/source_buffer_state.cc | 25 +++- media/filters/source_buffer_state.h | 6 + media/filters/source_buffer_stream.cc | 11 ++ media/filters/source_buffer_stream.h | 4 + media/filters/stream_parser_factory.cc | 6 +- media/filters/stream_parser_factory.h | 4 +- media/formats/mp4/avc.cc | 14 +++ media/formats/mp4/avc.h | 12 ++ media/formats/mp4/bitstream_converter.h | 9 ++ media/formats/mp4/hevc.cc | 26 +++++ media/formats/mp4/hevc.h | 12 ++ media/formats/mp4/mp4_stream_parser.cc | 63 ++++++++++ media/formats/mp4/mp4_stream_parser.h | 12 ++ media/formats/mp4/track_run_iterator.cc | 32 +++++ media/formats/mp4/track_run_iterator.h | 18 +++ media/formats/webm/webm_cluster_parser.cc | 12 ++ media/formats/webm/webm_cluster_parser.h | 10 ++ media/formats/webm/webm_stream_parser.cc | 59 ++++++++++ media/formats/webm/webm_stream_parser.h | 11 ++ media/formats/webm/webm_tracks_parser.h | 6 + media/mojo/mojom/media_types.mojom | 4 + .../mojom/video_decoder_config_mojom_traits.cc | 3 + .../mojo/mojom/video_decoder_config_mojom_traits.h | 8 ++ media/video/BUILD.gn | 2 + media/video/h264_parser.cc | 118 ++++++++++++++++++- media/video/h264_parser.h | 12 ++ media/video/h265_parser.cc | 129 ++++++++++++++++++++- media/video/h265_parser.h | 15 +++ media/video/h26x_tools.cc | 33 ++++++ media/video/h26x_tools.h | 35 ++++++ .../media/base/tizen/stream_framerate.cc | 87 ++++++++++++++ .../media/base/tizen/stream_framerate.h | 58 +++++++++ .../media/filters/media_player_esplusplayer_tv.cc | 18 +++ tizen_src/chromium_impl/media/media_efl.gni | 2 + 38 files changed, 970 insertions(+), 25 deletions(-) create mode 100644 media/video/h26x_tools.cc create mode 100644 media/video/h26x_tools.h create mode 100644 tizen_src/chromium_impl/media/base/tizen/stream_framerate.cc create mode 100644 tizen_src/chromium_impl/media/base/tizen/stream_framerate.h diff --git a/media/base/stream_parser.h b/media/base/stream_parser.h index 2e8fbfe..51b87e8 100644 --- a/media/base/stream_parser.h +++ b/media/base/stream_parser.h @@ -20,6 +20,10 @@ #include "media/base/eme_constants.h" #include "media/base/media_export.h" +#if BUILDFLAG(IS_TIZEN_TV) +#include "tizen_src/chromium_impl/media/base/tizen/stream_framerate.h" +#endif + namespace media { class MediaLog; @@ -81,6 +85,12 @@ class MEDIA_EXPORT StreamParser { int detected_video_track_count = 0; }; +#if BUILDFLAG(IS_TIZEN_TV) + typedef base::RepeatingCallback + FramerateSetCB; +#endif + // Indicates completion of parser initialization. // params - Stream parameters. typedef base::OnceCallback InitCB; @@ -180,6 +190,10 @@ class MEDIA_EXPORT StreamParser { [[nodiscard]] virtual ParseStatus Parse(int max_pending_bytes_to_inspect) = 0; [[nodiscard]] virtual bool ProcessChunks( std::unique_ptr buffer_queue); + +#if BUILDFLAG(IS_TIZEN_TV) + virtual void SetFramerateCallback(const FramerateSetCB& framerate_set_cb) {} +#endif }; // Appends to |merged_buffers| the provided buffers in decode-timestamp order. diff --git a/media/base/video_decoder_config.h b/media/base/video_decoder_config.h index 32d882d..436cfc0 100644 --- a/media/base/video_decoder_config.h +++ b/media/base/video_decoder_config.h @@ -167,6 +167,10 @@ 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; } + int framerate_num() const { return framerate_num_; } + int framerate_den() const { return framerate_den_; } #endif private: @@ -197,6 +201,8 @@ class MEDIA_EXPORT VideoDecoderConfig { bool is_rtc_ = false; #if BUILDFLAG(IS_TIZEN_TV) + int framerate_num_ = 0; + int framerate_den_ = 0; std::string hdr_info_; #endif diff --git a/media/filters/chunk_demuxer.cc b/media/filters/chunk_demuxer.cc index 908d252..df72051 100644 --- a/media/filters/chunk_demuxer.cc +++ b/media/filters/chunk_demuxer.cc @@ -37,11 +37,13 @@ namespace { std::unique_ptr CreateParserForTypeAndCodecs( const std::string& content_type, const std::string& codecs, - media::MediaLog* media_log) { + media::MediaLog* media_log, + bool* has_audio, + bool* has_video) { std::vector parsed_codec_ids; media::SplitCodecs(codecs, &parsed_codec_ids); return media::StreamParserFactory::Create(content_type, parsed_codec_ids, - media_log); + media_log, has_audio, has_video); } // Helper to calculate the expected codecs parsed from initialization segments @@ -74,6 +76,17 @@ void ChunkDemuxerStream::StartReturningData() { ChangeState_Locked(RETURNING_DATA_FOR_READS); } +#if BUILDFLAG(IS_TIZEN_TV) +void ChunkDemuxerStream::SetFramerate( + const StreamFramerate::Framerate& framerate) { + if (!stream_) { + LOG(ERROR) << "stream is null,this:" << (void*)this; + return; + } + stream_->updateFramerate(framerate); +} +#endif + void ChunkDemuxerStream::AbortReads() { DVLOG(1) << "ChunkDemuxerStream::AbortReads()"; base::AutoLock auto_lock(lock_); @@ -510,6 +523,11 @@ void ChunkDemuxer::Initialize(DemuxerHost* host, } std::move(open_cb).Run(); + +#if BUILDFLAG(IS_TIZEN_TV) + framerate_set_cb_ = base::BindPostTaskToCurrentDefault(base::BindRepeating( + &ChunkDemuxer::OnFramerateSet, base::Unretained(this))); +#endif } void ChunkDemuxer::Stop() { @@ -676,7 +694,7 @@ ChunkDemuxer::Status ChunkDemuxer::AddId( media::StreamParserFactory::Create(std::move(audio_config))); DCHECK(stream_parser); - return AddIdInternal(id, std::move(stream_parser), expected_codec); + return AddIdInternal(id, std::move(stream_parser), expected_codec, false); } ChunkDemuxer::Status ChunkDemuxer::AddId( @@ -704,7 +722,7 @@ ChunkDemuxer::Status ChunkDemuxer::AddId( media::StreamParserFactory::Create(std::move(video_config))); DCHECK(stream_parser); - return AddIdInternal(id, std::move(stream_parser), expected_codec); + return AddIdInternal(id, std::move(stream_parser), expected_codec, true); } ChunkDemuxer::Status ChunkDemuxer::AddId(const std::string& id, @@ -723,8 +741,12 @@ ChunkDemuxer::Status ChunkDemuxer::AddId(const std::string& id, // needed. See https://crbug.com/786975. CHECK(init_cb_); + bool has_audio = false; + bool has_video = false; + std::unique_ptr stream_parser( - CreateParserForTypeAndCodecs(content_type, codecs, media_log_)); + CreateParserForTypeAndCodecs(content_type, codecs, media_log_, &has_audio, + &has_video)); if (!stream_parser) { DVLOG(1) << __func__ << " failed: unsupported content_type=" << content_type << " codecs=" << codecs; @@ -732,13 +754,14 @@ ChunkDemuxer::Status ChunkDemuxer::AddId(const std::string& id, } return AddIdInternal(id, std::move(stream_parser), - ExpectedCodecs(content_type, codecs)); + ExpectedCodecs(content_type, codecs), has_video); } ChunkDemuxer::Status ChunkDemuxer::AddIdInternal( const std::string& id, std::unique_ptr stream_parser, - std::string expected_codecs) { + std::string expected_codecs, + bool has_video) { DVLOG(2) << __func__ << " id=" << id << " expected_codecs=" << expected_codecs; lock_.AssertAcquired(); @@ -756,6 +779,15 @@ ChunkDemuxer::Status ChunkDemuxer::AddIdInternal( base::Unretained(this), id), media_log_); +#if BUILDFLAG(IS_TIZEN_TV) + StreamParser::FramerateSetCB framerate_set_cb; + if (has_video) + framerate_set_cb = framerate_set_cb_; + else + // Audio don't need this call back. + framerate_set_cb.Reset(); +#endif + // TODO(wolenetz): Change these to DCHECKs or switch to returning // kReachedIdLimit once less verification in release build is needed. See // https://crbug.com/786975. @@ -767,7 +799,11 @@ ChunkDemuxer::Status ChunkDemuxer::AddIdInternal( source_state->Init(base::BindOnce(&ChunkDemuxer::OnSourceInitDone, base::Unretained(this), id), - expected_codecs, encrypted_media_init_data_cb_); + expected_codecs, +#if BUILDFLAG(IS_TIZEN_TV) + framerate_set_cb, +#endif + encrypted_media_init_data_cb_); // TODO(wolenetz): Change to DCHECKs once less verification in release build // is needed. See https://crbug.com/786975. @@ -1193,9 +1229,12 @@ bool ChunkDemuxer::CanChangeType(const std::string& id, // CanChangeType() doesn't care if there has or hasn't been received a first // initialization segment for the source buffer corresponding to |id|. + bool has_audio = false; + bool has_video = false; std::unique_ptr stream_parser( - CreateParserForTypeAndCodecs(content_type, codecs, media_log_)); + CreateParserForTypeAndCodecs(content_type, codecs, media_log_, &has_audio, + &has_video)); return !!stream_parser; } @@ -1210,11 +1249,27 @@ void ChunkDemuxer::ChangeType(const std::string& id, DCHECK(state_ == INITIALIZING || state_ == INITIALIZED) << state_; DCHECK(IsValidId_Locked(id)); + bool has_audio = false; + bool has_video = false; + std::unique_ptr stream_parser( - CreateParserForTypeAndCodecs(content_type, codecs, media_log_)); + CreateParserForTypeAndCodecs(content_type, codecs, media_log_, &has_audio, + &has_video)); // Caller should query CanChangeType() first to protect from failing this. DCHECK(stream_parser); + +#if BUILDFLAG(IS_TIZEN_TV) + StreamParser::FramerateSetCB framerate_set_cb; + if (has_video) + framerate_set_cb = framerate_set_cb_; + else + // Audio don't need this call back. + framerate_set_cb.Reset(); +#endif source_state_map_[id]->ChangeType(std::move(stream_parser), +#if BUILDFLAG(IS_TIZEN_TV) + framerate_set_cb, +#endif ExpectedCodecs(content_type, codecs)); } @@ -1456,6 +1511,15 @@ bool ChunkDemuxer::IsSeekWaitingForData_Locked() const { return false; } +#if BUILDFLAG(IS_TIZEN_TV) +void ChunkDemuxer::OnFramerateSet(const StreamFramerate::Framerate& framerate) { + if (framerate.num && framerate.den) { + for (const auto& s : video_streams_) + s->SetFramerate(framerate); + } +} +#endif + void ChunkDemuxer::OnSourceInitDone( const std::string& source_id, const StreamParser::InitParameters& params) { diff --git a/media/filters/chunk_demuxer.h b/media/filters/chunk_demuxer.h index 013993f..b38efa0 100644 --- a/media/filters/chunk_demuxer.h +++ b/media/filters/chunk_demuxer.h @@ -54,6 +54,10 @@ class MEDIA_EXPORT ChunkDemuxerStream : public DemuxerStream { void CompletePendingReadIfPossible(); void Shutdown(); +#if BUILDFLAG(IS_TIZEN_TV) + void SetFramerate(const StreamFramerate::Framerate& framerate); +#endif + // SourceBufferStream manipulation methods. void Seek(base::TimeDelta time); bool IsSeekWaitingForData() const; @@ -467,7 +471,8 @@ class MEDIA_EXPORT ChunkDemuxer : public Demuxer { ChunkDemuxer::Status AddIdInternal( const std::string& id, std::unique_ptr stream_parser, - std::string expected_codecs); + std::string expected_codecs, + bool has_video); // Helper for vide and audio track changing. void FindAndEnableProperTracks(const std::vector& track_ids, @@ -492,6 +497,10 @@ class MEDIA_EXPORT ChunkDemuxer : public Demuxer { void OnSourceInitDone(const std::string& source_id, const StreamParser::InitParameters& params); +#if BUILDFLAG(IS_TIZEN_TV) + void OnFramerateSet(const StreamFramerate::Framerate& framerate); +#endif + // Creates a DemuxerStream of the specified |type| for the SourceBufferState // with the given |source_id|. // Returns a pointer to a new ChunkDemuxerStream instance, which is owned by @@ -571,6 +580,10 @@ class MEDIA_EXPORT ChunkDemuxer : public Demuxer { // into the INITIALIZED only after all ids/SourceBuffers got init segment. std::set pending_source_init_ids_; +#if BUILDFLAG(IS_TIZEN_TV) + StreamParser::FramerateSetCB framerate_set_cb_; +#endif + base::TimeDelta duration_ = kNoTimestamp; // The duration passed to the last SetDuration(). If SetDuration() is never diff --git a/media/filters/source_buffer_state.cc b/media/filters/source_buffer_state.cc index 039ada0..60d1051 100644 --- a/media/filters/source_buffer_state.cc +++ b/media/filters/source_buffer_state.cc @@ -140,19 +140,31 @@ SourceBufferState::~SourceBufferState() { Shutdown(); } -void SourceBufferState::Init(StreamParser::InitCB init_cb, - const std::string& expected_codecs, - const StreamParser::EncryptedMediaInitDataCB& - encrypted_media_init_data_cb) { +void SourceBufferState::Init( + StreamParser::InitCB init_cb, + const std::string& expected_codecs, +#if BUILDFLAG(IS_TIZEN_TV) + const StreamParser::FramerateSetCB& framerate_set_cb, +#endif + const StreamParser::EncryptedMediaInitDataCB& + encrypted_media_init_data_cb) { DCHECK_EQ(state_, UNINITIALIZED); init_cb_ = std::move(init_cb); encrypted_media_init_data_cb_ = encrypted_media_init_data_cb; state_ = PENDING_PARSER_CONFIG; InitializeParser(expected_codecs); + +#if BUILDFLAG(IS_TIZEN_TV) + if (framerate_set_cb) + stream_parser_->SetFramerateCallback(framerate_set_cb); +#endif } void SourceBufferState::ChangeType( std::unique_ptr new_stream_parser, +#if BUILDFLAG(IS_TIZEN_TV) + const StreamParser::FramerateSetCB& framerate_set_cb, +#endif const std::string& new_expected_codecs) { DCHECK_GE(state_, PENDING_PARSER_CONFIG); DCHECK_NE(state_, PENDING_PARSER_INIT); @@ -165,6 +177,11 @@ void SourceBufferState::ChangeType( stream_parser_ = std::move(new_stream_parser); InitializeParser(new_expected_codecs); + +#if BUILDFLAG(IS_TIZEN_TV) + if (framerate_set_cb) + stream_parser_->SetFramerateCallback(framerate_set_cb); +#endif } void SourceBufferState::SetSequenceMode(bool sequence_mode) { diff --git a/media/filters/source_buffer_state.h b/media/filters/source_buffer_state.h index 53e98cf..30df4bf 100644 --- a/media/filters/source_buffer_state.h +++ b/media/filters/source_buffer_state.h @@ -44,6 +44,9 @@ class MEDIA_EXPORT SourceBufferState { void Init(StreamParser::InitCB init_cb, const std::string& expected_codecs, +#if BUILDFLAG(IS_TIZEN_TV) + const StreamParser::FramerateSetCB& framerate_set_cb, +#endif const StreamParser::EncryptedMediaInitDataCB& encrypted_media_init_data_cb); @@ -51,6 +54,9 @@ class MEDIA_EXPORT SourceBufferState { // first ensure that ResetParserState() was done to flush any pending frames // from the old stream parser. void ChangeType(std::unique_ptr new_stream_parser, +#if BUILDFLAG(IS_TIZEN_TV) + const StreamParser::FramerateSetCB& framerate_set_cb, +#endif const std::string& new_expected_codecs); // Appends media data to the StreamParser, but no parsing is done of it yet, diff --git a/media/filters/source_buffer_stream.cc b/media/filters/source_buffer_stream.cc index c909fa1..031f38d 100644 --- a/media/filters/source_buffer_stream.cc +++ b/media/filters/source_buffer_stream.cc @@ -1783,6 +1783,17 @@ base::TimeDelta SourceBufferStream::GetMaxInterbufferDistance() const { return max_interbuffer_distance_; } +#if BUILDFLAG(IS_TIZEN_TV) +void SourceBufferStream::updateFramerate( + const StreamFramerate::Framerate& framerate) { + CHECK(current_config_index_ >= 0 && + static_cast(current_config_index_) < video_configs_.size()); + + video_configs_[current_config_index_].set_framerate_num(framerate.num); + video_configs_[current_config_index_].set_framerate_den(framerate.den); +} +#endif + bool SourceBufferStream::UpdateAudioConfig(const AudioDecoderConfig& config, bool allow_codec_change) { DCHECK(!audio_configs_.empty()); diff --git a/media/filters/source_buffer_stream.h b/media/filters/source_buffer_stream.h index 403bbda..4cc450a 100644 --- a/media/filters/source_buffer_stream.h +++ b/media/filters/source_buffer_stream.h @@ -157,6 +157,10 @@ class MEDIA_EXPORT SourceBufferStream { const AudioDecoderConfig& GetCurrentAudioDecoderConfig(); const VideoDecoderConfig& GetCurrentVideoDecoderConfig(); +#if BUILDFLAG(IS_TIZEN_TV) + void updateFramerate(const StreamFramerate::Framerate& framerate); +#endif + // Notifies this object that the audio config has changed and buffers in // future Append() calls should be associated with this new config. // If the codec is allowed to change, the caller should set diff --git a/media/filters/stream_parser_factory.cc b/media/filters/stream_parser_factory.cc index aca8dff..5ed64e5 100644 --- a/media/filters/stream_parser_factory.cc +++ b/media/filters/stream_parser_factory.cc @@ -602,7 +602,9 @@ SupportsType StreamParserFactory::IsTypeSupported( std::unique_ptr StreamParserFactory::Create( base::StringPiece type, base::span codecs, - MediaLog* media_log) { + MediaLog* media_log, + bool* has_audio, + bool* has_video) { std::unique_ptr stream_parser; ParserFactoryFunction factory_function; std::vector audio_codecs; @@ -637,6 +639,8 @@ std::unique_ptr StreamParserFactory::Create( } } + *has_audio = !audio_codecs.empty(); + *has_video = !video_codecs.empty(); stream_parser.reset(factory_function(codecs, media_log)); } diff --git a/media/filters/stream_parser_factory.h b/media/filters/stream_parser_factory.h index 14a550b..57d87ab 100644 --- a/media/filters/stream_parser_factory.h +++ b/media/filters/stream_parser_factory.h @@ -57,7 +57,9 @@ class MEDIA_EXPORT StreamParserFactory { static std::unique_ptr Create( base::StringPiece type, base::span codecs, - MediaLog* media_log); + MediaLog* media_log, + bool* has_audio, + bool* has_video); static std::unique_ptr Create( std::unique_ptr audio_config); static std::unique_ptr Create( diff --git a/media/formats/mp4/avc.cc b/media/formats/mp4/avc.cc index 40609a8..2420fd5 100644 --- a/media/formats/mp4/avc.cc +++ b/media/formats/mp4/avc.cc @@ -357,6 +357,12 @@ bool AVCBitstreamConverter::ConvertAndAnalyzeFrame( *analysis_result = Analyze(frame_buf, subsamples); if (analysis_result->is_keyframe.value_or(is_keyframe)) { +#if BUILDFLAG(IS_TIZEN_TV) + if (framerate_.has_value()) { + H264Parser{}.UpdateTimingInfoIfNeeded( + &avc_config_->sps_list, framerate_->den, 2 * framerate_->num); + } +#endif // If this is a keyframe, we (re-)inject SPS and PPS headers at the start of // a frame. If subsample info is present, we also update the clear byte // count for that first subsample. @@ -366,6 +372,14 @@ bool AVCBitstreamConverter::ConvertAndAnalyzeFrame( return true; } +#if BUILDFLAG(IS_TIZEN_TV) +void AVCBitstreamConverter::SetFramerate( + const StreamFramerate::Framerate& framerate) { + framerate_ = framerate; + LOG(INFO) << "frame rate: " << framerate_->toDouble(); +} +#endif + BitstreamConverter::AnalysisResult AVCBitstreamConverter::Analyze( std::vector* frame_buf, std::vector* subsamples) const { diff --git a/media/formats/mp4/avc.h b/media/formats/mp4/avc.h index 97a3502..17e5c36 100644 --- a/media/formats/mp4/avc.h +++ b/media/formats/mp4/avc.h @@ -14,6 +14,11 @@ #include "media/base/media_export.h" #include "media/formats/mp4/bitstream_converter.h" +#if BUILDFLAG(IS_TIZEN_TV) +#include "media/video/h264_parser.h" +#include "third_party/abseil-cpp/absl/types/optional.h" +#endif + namespace media { struct SubsampleEntry; @@ -78,6 +83,9 @@ class AVCBitstreamConverter : public BitstreamConverter { bool is_keyframe, std::vector* subsamples, AnalysisResult* analysis_result) const override; +#if BUILDFLAG(IS_TIZEN_TV) + void SetFramerate(const StreamFramerate::Framerate& framerate) override; +#endif private: ~AVCBitstreamConverter() override; @@ -85,6 +93,10 @@ class AVCBitstreamConverter : public BitstreamConverter { std::vector* frame_buf, std::vector* subsamples) const override; std::unique_ptr avc_config_; + +#if BUILDFLAG(IS_TIZEN_TV) + absl::optional framerate_; +#endif }; } // namespace mp4 diff --git a/media/formats/mp4/bitstream_converter.h b/media/formats/mp4/bitstream_converter.h index 072c485..2a315d2 100644 --- a/media/formats/mp4/bitstream_converter.h +++ b/media/formats/mp4/bitstream_converter.h @@ -13,6 +13,10 @@ #include "media/base/media_export.h" #include "third_party/abseil-cpp/absl/types/optional.h" +#if BUILDFLAG(IS_TIZEN_TV) +#include "media/base/tizen/stream_framerate.h" +#endif + namespace media { struct SubsampleEntry; @@ -55,6 +59,11 @@ class MEDIA_EXPORT BitstreamConverter std::vector* subsamples, AnalysisResult* analysis_result) const = 0; +#if BUILDFLAG(IS_TIZEN_TV) + // For overriding timing info in SPS/VPS. + virtual void SetFramerate(const StreamFramerate::Framerate& framerate) = 0; +#endif + protected: friend class base::RefCountedThreadSafe; virtual ~BitstreamConverter(); diff --git a/media/formats/mp4/hevc.cc b/media/formats/mp4/hevc.cc index e186e37..d9605c2 100644 --- a/media/formats/mp4/hevc.cc +++ b/media/formats/mp4/hevc.cc @@ -23,6 +23,10 @@ #include "media/video/h265_nalu_parser.h" #endif // BUILDFLAG(ENABLE_HEVC_PARSER_AND_HW_DECODER) +#if BUILDFLAG(IS_TIZEN_TV) +#include "media/video/h265_parser.h" +#endif + namespace media { namespace mp4 { @@ -643,12 +647,34 @@ bool HEVCBitstreamConverter::ConvertAndAnalyzeFrame( // If this is a keyframe, we (re-)inject HEVC params headers at the start of // a frame. If subsample info is present, we also update the clear byte // count for that first subsample. +#if BUILDFLAG(IS_TIZEN_TV) + if (framerate_.has_value()) { + auto spses_array_iterator = + find_if(hevc_config_->arrays.begin(), hevc_config_->arrays.end(), + [](const HEVCDecoderConfigurationRecord::HVCCNALArray& ref) { + return (ref.first_byte & 0x3f) == H265NALU::SPS_NUT; + }); + + if (spses_array_iterator != hevc_config_->arrays.end()) { + H265Parser{}.UpdateTimingInfoIfNeeded(&spses_array_iterator->units, + framerate_->den, framerate_->num); + } + } +#endif RCHECK(HEVC::InsertParamSetsAnnexB(*hevc_config_, frame_buf, subsamples)); } return true; } +#if BUILDFLAG(IS_TIZEN_TV) +void HEVCBitstreamConverter::SetFramerate( + const StreamFramerate::Framerate& framerate) { + framerate_ = framerate; + LOG(INFO) << "frame rate: " << framerate_->toDouble(); +} +#endif + BitstreamConverter::AnalysisResult HEVCBitstreamConverter::Analyze( std::vector* frame_buf, std::vector* subsamples) const { diff --git a/media/formats/mp4/hevc.h b/media/formats/mp4/hevc.h index f286f89..b973f8b 100644 --- a/media/formats/mp4/hevc.h +++ b/media/formats/mp4/hevc.h @@ -17,6 +17,10 @@ #include "media/formats/mp4/bitstream_converter.h" #include "media/formats/mp4/box_definitions.h" +#if BUILDFLAG(IS_TIZEN_TV) +#include "third_party/abseil-cpp/absl/types/optional.h" +#endif + namespace media { struct SubsampleEntry; @@ -119,12 +123,20 @@ class HEVCBitstreamConverter : public BitstreamConverter { std::vector* subsamples, AnalysisResult* analysis_result) const override; +#if BUILDFLAG(IS_TIZEN_TV) + void SetFramerate(const StreamFramerate::Framerate& framerate) override; +#endif + private: ~HEVCBitstreamConverter() override; AnalysisResult Analyze( std::vector* frame_buf, std::vector* subsamples) const override; std::unique_ptr hevc_config_; + +#if BUILDFLAG(IS_TIZEN_TV) + absl::optional framerate_; +#endif }; } // namespace mp4 diff --git a/media/formats/mp4/mp4_stream_parser.cc b/media/formats/mp4/mp4_stream_parser.cc index 436f0ce..9214b68 100644 --- a/media/formats/mp4/mp4_stream_parser.cc +++ b/media/formats/mp4/mp4_stream_parser.cc @@ -40,6 +40,7 @@ namespace { const int kMaxEmptySampleLogs = 20; const int kMaxInvalidConversionLogs = 20; const int kMaxVideoKeyframeMismatchLogs = 10; +StreamParser::InitParameters params_(kInfiniteDuration); // Caller should be prepared to handle return of EncryptionScheme::kUnencrypted // in case of unsupported scheme. @@ -118,6 +119,14 @@ void MP4StreamParser::Init( media_log_ = media_log; } +#if BUILDFLAG(IS_TIZEN_TV) +void MP4StreamParser::SetFramerateCallback( + const FramerateSetCB& framerate_set_cb) { + DCHECK(!framerate_set_cb.is_null()); + framerate_set_cb_ = framerate_set_cb; +} +#endif + void MP4StreamParser::Reset() { queue_.Reset(); max_parse_offset_ = 0; @@ -702,6 +711,12 @@ bool MP4StreamParser::ParseMoov(BoxReader* reader) { RCHECK(config_cb_.Run(std::move(media_tracks))); +#if BUILDFLAG(IS_TIZEN_TV) + // Recheck framerate when video config change happen. + if (has_video_) + average_framerate_.reset(); +#endif + StreamParser::InitParameters params(kInfiniteDuration); if (moov_->extends.header.fragment_duration > 0) { params.duration = TimeDeltaFromRational( @@ -751,7 +766,12 @@ bool MP4StreamParser::ParseMoov(BoxReader* reader) { if (init_cb_) { params.detected_audio_track_count = detected_audio_track_count; params.detected_video_track_count = detected_video_track_count; + +#if BUILDFLAG(IS_TIZEN_TV) + params_ = params; +#else std::move(init_cb_).Run(params); +#endif } return true; @@ -766,6 +786,49 @@ bool MP4StreamParser::ParseMoof(BoxReader* reader) { RCHECK(runs_->Init(moof)); RCHECK(ComputeHighestEndOffset(moof)); +#if BUILDFLAG(IS_TIZEN_TV) + if (runs_ && !runs_->is_audio() && !average_framerate_.has_value()) { + // Min Trun sample count for calculate fps. + constexpr const size_t kMinTrunSampleCount = 10; + + const TrackRunSampleInfo& trun_sample_info = runs_->GetTrunSampleInfo(); + const auto& traf_sample_count = trun_sample_info.trun_sample_size; + const auto& total_duration = trun_sample_info.trun_duration; + + LOG(INFO) << "Estimating framerate" + << ", total traf sample count: " << traf_sample_count + << ", total duration: " << total_duration + << ", time scale: " << trun_sample_info.time_scale; + + if (traf_sample_count == 0 || total_duration == 0) { + LOG(ERROR) << "Cannot estimate framerate"; + } else { + if (traf_sample_count < kMinTrunSampleCount) { + LOG(WARNING) << "Low sample count for framerate estimation"; + } + // Base num to calculate mp4 framerate + constexpr const int64_t kMp4FramerateBase = 1001; + StreamFramerate sft(kMp4FramerateBase * trun_sample_info.time_scale * + traf_sample_count / total_duration, + kMp4FramerateBase); + int num{0}; + int den{0}; + sft.Calculate(&num, &den); + average_framerate_ = StreamFramerate::Framerate{num, den}; + + if (!framerate_set_cb_.is_null()) { + framerate_set_cb_.Run(average_framerate_.value()); + } + if (runs_ && runs_->video_description().frame_bitstream_converter) + runs_->video_description().frame_bitstream_converter->SetFramerate( + average_framerate_.value()); + } + } + if (init_cb_) { + std::move(init_cb_).Run(params_); + } +#endif + if (!moof.pssh.empty()) OnEncryptedMediaInitData(moof.pssh); diff --git a/media/formats/mp4/mp4_stream_parser.h b/media/formats/mp4/mp4_stream_parser.h index abae96d..100e470 100644 --- a/media/formats/mp4/mp4_stream_parser.h +++ b/media/formats/mp4/mp4_stream_parser.h @@ -59,6 +59,10 @@ class MEDIA_EXPORT MP4StreamParser : public StreamParser { VideoTransformation CalculateRotation(const TrackHeader& track, const MovieHeader& movie); +#if BUILDFLAG(IS_TIZEN_TV) + void SetFramerateCallback(const FramerateSetCB& framerate_set_cb) override; +#endif + private: enum State { kWaitingForInit, @@ -125,6 +129,10 @@ class MEDIA_EXPORT MP4StreamParser : public StreamParser { EndMediaSegmentCB end_of_segment_cb_; raw_ptr media_log_; +#if BUILDFLAG(IS_TIZEN_TV) + FramerateSetCB framerate_set_cb_; +#endif + // Bytes of the mp4 stream. // `max_parse_offset_` tracks the point in `queue_` beyond which no data may // yet be parsed even if it is less than the queue's tail offset. This allows @@ -168,6 +176,10 @@ class MEDIA_EXPORT MP4StreamParser : public StreamParser { const bool has_sbr_; const bool has_flac_; +#if BUILDFLAG(IS_TIZEN_TV) + absl::optional average_framerate_; +#endif + // Tracks the number of MEDIA_LOGS for skipping empty trun samples. int num_empty_samples_skipped_; diff --git a/media/formats/mp4/track_run_iterator.cc b/media/formats/mp4/track_run_iterator.cc index c20a501..299510c6 100644 --- a/media/formats/mp4/track_run_iterator.cc +++ b/media/formats/mp4/track_run_iterator.cc @@ -284,6 +284,10 @@ class CompareMinTrackRunDataOffset { bool TrackRunIterator::Init(const MovieFragment& moof) { runs_.clear(); +#if BUILDFLAG(IS_TIZEN_TV) + trun_sample_info_ = {0, 0, 0}; +#endif + for (size_t i = 0; i < moof.tracks.size(); i++) { const TrackFragment& traf = moof.tracks[i]; @@ -453,6 +457,28 @@ bool TrackRunIterator::Init(const MovieFragment& moof) { run_start_dts += tri.samples[k].duration; +#if BUILDFLAG(IS_TIZEN_TV) + if (tri.samples[k].duration && !tri.is_audio) { + trun_sample_info_.time_scale = tri.timescale; + const size_t kMinTrunSampleCount = 10; + // The duration gap should be in range : [-%20~ 20%]. + const size_t kBaseDividerCount = 5; + if (trun_sample_info_.trun_sample_size > kMinTrunSampleCount) { + const int64_t average_duration = trun_sample_info_.trun_duration / + trun_sample_info_.trun_sample_size; + const int64_t duration_gap = + std::abs(tri.samples[k].duration - average_duration); + if (duration_gap <= average_duration / kBaseDividerCount) { + trun_sample_info_.trun_duration += tri.samples[k].duration; + trun_sample_info_.trun_sample_size++; + } + } else { + trun_sample_info_.trun_duration += tri.samples[k].duration; + trun_sample_info_.trun_sample_size++; + } + } +#endif + if (!is_sample_to_group_valid) { // Set group description index to 0 to read encryption information // from TrackEncryption Box. @@ -548,6 +574,12 @@ bool TrackRunIterator::AdvanceRun() { return ResetRun(); } +#if BUILDFLAG(IS_TIZEN_TV) +const TrackRunSampleInfo& TrackRunIterator::GetTrunSampleInfo() { + return trun_sample_info_; +} +#endif + bool TrackRunIterator::ResetRun() { // TODO(sandersd): Should we clear all the values if the run is not valid? if (!IsRunValid()) diff --git a/media/formats/mp4/track_run_iterator.h b/media/formats/mp4/track_run_iterator.h index c7fd267..eb37840 100644 --- a/media/formats/mp4/track_run_iterator.h +++ b/media/formats/mp4/track_run_iterator.h @@ -33,6 +33,14 @@ DecodeTimestamp MEDIA_EXPORT DecodeTimestampFromRational(int64_t numer, struct SampleInfo; struct TrackRunInfo; +#if BUILDFLAG(IS_TIZEN_TV) +struct TrackRunSampleInfo { + int64_t time_scale; + int64_t trun_duration; + size_t trun_sample_size; +}; +#endif + class MEDIA_EXPORT TrackRunIterator { public: // Create a new TrackRunIterator. A reference to |moov| will be retained for @@ -74,6 +82,11 @@ class MEDIA_EXPORT TrackRunIterator { // in bytes past the the head of the MOOF box). int64_t GetMaxClearOffset(); +#if BUILDFLAG(IS_TIZEN_TV) + // Get trun samples' info : duration, sample count and time_scale. + const TrackRunSampleInfo& GetTrunSampleInfo(); +#endif + // Property of the current run. Only valid if IsRunValid(). uint32_t track_id() const; int64_t aux_info_offset() const; @@ -120,6 +133,11 @@ class MEDIA_EXPORT TrackRunIterator { int64_t sample_dts_; int64_t sample_cts_; int64_t sample_offset_; + +#if BUILDFLAG(IS_TIZEN_TV) + // Accumulates info on samples from all trun boxes in a traf box. + TrackRunSampleInfo trun_sample_info_; +#endif }; } // namespace mp4 diff --git a/media/formats/webm/webm_cluster_parser.cc b/media/formats/webm/webm_cluster_parser.cc index f44fe5f..3f6bc7f 100644 --- a/media/formats/webm/webm_cluster_parser.cc +++ b/media/formats/webm/webm_cluster_parser.cc @@ -70,6 +70,10 @@ WebMClusterParser::~WebMClusterParser() = default; void WebMClusterParser::Reset() { last_block_timecode_.reset(); cluster_timecode_ = -1; +#if BUILDFLAG(IS_TIZEN_TV) + block_count_ = 0; + block_time_code_ = 0; +#endif cluster_start_time_ = kNoTimestamp; cluster_ended_ = false; parser_.Reset(); @@ -234,6 +238,10 @@ WebMParserClient* WebMClusterParser::OnListStart(int id) { if (id == kWebMIdCluster) { cluster_timecode_ = -1; cluster_start_time_ = kNoTimestamp; +#if BUILDFLAG(IS_TIZEN_TV) + block_count_ = 0; + block_time_code_ = 0; +#endif } else if (id == kWebMIdBlockGroup) { block_data_.reset(); block_data_size_ = -1; @@ -445,6 +453,10 @@ bool WebMClusterParser::OnBlock(bool is_simple_block, track = &video_; encryption_key_id = video_encryption_key_id_; buffer_type = DemuxerStream::VIDEO; +#if BUILDFLAG(IS_TIZEN_TV) + block_count_++; + block_time_code_ = timecode; +#endif } else if (ignored_tracks_.find(track_num) != ignored_tracks_.end()) { return true; } else { diff --git a/media/formats/webm/webm_cluster_parser.h b/media/formats/webm/webm_cluster_parser.h index 350b669..57aa295 100644 --- a/media/formats/webm/webm_cluster_parser.h +++ b/media/formats/webm/webm_cluster_parser.h @@ -192,6 +192,11 @@ class MEDIA_EXPORT WebMClusterParser : public WebMParserClient { // Returns true if the last Parse() call stopped at the end of a cluster. bool cluster_ended() const { return cluster_ended_; } +#if BUILDFLAG(IS_TIZEN_TV) + int BlockCount() const { return block_count_; } + int BlockTimeCode() const { return block_time_code_; } +#endif + private: // WebMParserClient methods. WebMParserClient* OnListStart(int id) override; @@ -292,6 +297,11 @@ class MEDIA_EXPORT WebMClusterParser : public WebMParserClient { DecodeTimestamp ready_buffer_upper_bound_; raw_ptr media_log_; + +#if BUILDFLAG(IS_TIZEN_TV) + int block_count_{0}; + int block_time_code_{0}; +#endif }; } // namespace media diff --git a/media/formats/webm/webm_stream_parser.cc b/media/formats/webm/webm_stream_parser.cc index db4ed43..3b59407 100644 --- a/media/formats/webm/webm_stream_parser.cc +++ b/media/formats/webm/webm_stream_parser.cc @@ -27,6 +27,10 @@ namespace media { WebMStreamParser::WebMStreamParser() : state_(kWaitingForInit), +#if BUILDFLAG(IS_TIZEN_TV) + is_framerate_set_(false), + has_default_duration_(true), +#endif unknown_segment_size_(false) { } @@ -59,6 +63,14 @@ void WebMStreamParser::Init( media_log_ = media_log; } +#if BUILDFLAG(IS_TIZEN_TV) +void WebMStreamParser::SetFramerateCallback( + const FramerateSetCB& framerate_set_cb) { + DCHECK(!framerate_set_cb.is_null()); + framerate_set_cb_ = framerate_set_cb; +} +#endif + void WebMStreamParser::Flush() { DCHECK_NE(state_, kWaitingForInit); @@ -285,6 +297,33 @@ int WebMStreamParser::ParseInfoAndTracks(const uint8_t* data, int size) { if (video_config.is_encrypted()) OnEncryptedMediaInitData(tracks_parser.video_encryption_key_id()); +#if BUILDFLAG(IS_TIZEN_TV) + if (!framerate_set_cb_.is_null()) { + is_framerate_set_ = false; + StreamFramerate::Framerate framerate; + + if (tracks_parser.GetVideoDefaultDuration(timecode_scale_in_us) != + kNoTimestamp) { + const int64_t default_video_duration = + tracks_parser.video_default_duration(); + + // Base num to calculate webm framerate + constexpr const int64_t kWebmFramerateBase = 1000000000; + + StreamFramerate sft(kWebmFramerateBase, default_video_duration); + sft.Calculate(&framerate.num, &framerate.den); + is_framerate_set_ = true; + has_default_duration_ = true; + framerate_set_cb_.Run(framerate); + } else { + stream_scale_time_ = info_parser.timecode_scale_ns(); + // Try other way to calculate framerate if default_video_duration not + // exists. + has_default_duration_ = false; + } + } +#endif + std::unique_ptr media_tracks = tracks_parser.media_tracks(); CHECK(media_tracks.get()); if (!config_cb_.Run(std::move(media_tracks))) { @@ -329,6 +368,26 @@ int WebMStreamParser::ParseCluster(const uint8_t* data, int size) { return -1; } +#if BUILDFLAG(IS_TIZEN_TV) + if (!framerate_set_cb_.is_null() && !is_framerate_set_ && + !has_default_duration_) { + const int cluster_block_count = cluster_parser_->BlockCount(); + const int cluster_block_time_code = cluster_parser_->BlockTimeCode(); + const int kMinBlockCount = 20; + if (cluster_block_count >= kMinBlockCount && cluster_block_time_code) { + StreamFramerate::Framerate framerate; + // avg_frame_duration in us + const int64_t avg_frame_duration = + cluster_block_time_code * 1000 / (cluster_block_count - 1); + + StreamFramerate sft(stream_scale_time_, avg_frame_duration); + sft.Calculate(&framerate.num, &framerate.den); + is_framerate_set_ = true; + framerate_set_cb_.Run(framerate); + } + } +#endif + if (cluster_ended) { ChangeState(kParsingHeaders); end_of_segment_cb_.Run(); diff --git a/media/formats/webm/webm_stream_parser.h b/media/formats/webm/webm_stream_parser.h index ffcac85..cfe5e54 100644 --- a/media/formats/webm/webm_stream_parser.h +++ b/media/formats/webm/webm_stream_parser.h @@ -43,6 +43,10 @@ class MEDIA_EXPORT WebMStreamParser : public StreamParser { size_t size) override; [[nodiscard]] ParseStatus Parse(int max_pending_bytes_to_inspect) override; +#if BUILDFLAG(IS_TIZEN_TV) + void SetFramerateCallback(const FramerateSetCB& framerate_set_cb) override; +#endif + private: enum State { kWaitingForInit, @@ -85,6 +89,13 @@ class MEDIA_EXPORT WebMStreamParser : public StreamParser { EndMediaSegmentCB end_of_segment_cb_; raw_ptr media_log_; +#if BUILDFLAG(IS_TIZEN_TV) + FramerateSetCB framerate_set_cb_; + bool is_framerate_set_; + int64_t stream_scale_time_; + bool has_default_duration_; +#endif + bool unknown_segment_size_; std::unique_ptr cluster_parser_; diff --git a/media/formats/webm/webm_tracks_parser.h b/media/formats/webm/webm_tracks_parser.h index 99b000e..78d621f 100644 --- a/media/formats/webm/webm_tracks_parser.h +++ b/media/formats/webm/webm_tracks_parser.h @@ -88,6 +88,12 @@ class MEDIA_EXPORT WebMTracksParser : public WebMParserClient { return std::move(media_tracks_); } +#if BUILDFLAG(IS_TIZEN_TV) + const int64_t video_default_duration() const { + return video_default_duration_; + } +#endif + private: // To test PrecisionCappedDefaultDuration. FRIEND_TEST_ALL_PREFIXES(WebMTracksParserTest, PrecisionCapping); diff --git a/media/mojo/mojom/media_types.mojom b/media/mojo/mojom/media_types.mojom index 475edc8..d86cdf8 100644 --- a/media/mojo/mojom/media_types.mojom +++ b/media/mojo/mojom/media_types.mojom @@ -198,6 +198,10 @@ struct VideoDecoderConfig { gfx.mojom.HDRMetadata? hdr_metadata; [EnableIf=is_tizen_tv] string hdr_info; + [EnableIf=is_tizen_tv] + int32 framerate_num; + [EnableIf=is_tizen_tv] + int32 framerate_den; }; // Native struct media::SubsampleEntry; diff --git a/media/mojo/mojom/video_decoder_config_mojom_traits.cc b/media/mojo/mojom/video_decoder_config_mojom_traits.cc index a292413..ed74736 100644 --- a/media/mojo/mojom/video_decoder_config_mojom_traits.cc +++ b/media/mojo/mojom/video_decoder_config_mojom_traits.cc @@ -68,6 +68,9 @@ bool StructTraitsset_hdr_info(hdr.c_str()); + + output->set_framerate_num(input.framerate_num()); + output->set_framerate_den(input.framerate_den()); #endif if (!output->IsValidConfig()) diff --git a/media/mojo/mojom/video_decoder_config_mojom_traits.h b/media/mojo/mojom/video_decoder_config_mojom_traits.h index 072da542..5dff94d 100644 --- a/media/mojo/mojom/video_decoder_config_mojom_traits.h +++ b/media/mojo/mojom/video_decoder_config_mojom_traits.h @@ -78,6 +78,14 @@ struct StructTraits>* spses_array, + int num_units_in_tick, + int time_scale) { + media::H264Parser::Result result; + media::H264NALU nalu; + + for (auto& sps : *spses_array) { + // Reset bit reader, skip first byte with NAL identifier + br_.Initialize(sps.data() + 1, sps.size() - 1); + int sps_id = 0; + result = ParseSPS(&sps_id); + DCHECK(result == media::H264Parser::kOk); + + if (active_SPSes_.find(sps_id) == active_SPSes_.end()) { + DVLOG(3) << "Error while parsing SPS unit"; + continue; + } + + if (!active_SPSes_[sps_id]->vui_parameters_present_flag) { + DVLOG(1) << "VUI parameters are not present in SPS. " + << "Adding framerate information skipped."; + continue; + } + + if (active_SPSes_[sps_id]->timing_info_present_flag) { + LOG(INFO) << "VUI timing info present in SPS " << sps_id; + continue; + } + + auto new_sps = + PrepareSPSWithTimingInfo(sps, sps_id, num_units_in_tick, time_scale); + + LOG(INFO) << "Inserting VUI timing info: " << time_scale << '/' + << num_units_in_tick << " into SPS " << sps_id; + + sps.swap(new_sps); + } +} + +std::vector H264Parser::PrepareSPSWithTimingInfo( + const std::vector& old_sps, + int sps_id, + int num_units_in_tick, + int time_scale) { + const auto& sps_parameters = active_SPSes_[sps_id]; + + int bit_offset_from_end = sps_parameters->timing_info_bit_offset_from_nal_end; + int currently_processed_bit_index = + (bit_offset_from_end - 1 + kBitsInByte) % kBitsInByte; + int byte_number = + ((old_sps.size() * kBitsInByte) - bit_offset_from_end) / kBitsInByte; + + std::vector new_sps(old_sps.begin(), + std::next(old_sps.begin(), byte_number + 1)); + + // SPS will be extended by the following parameters + // num_units_in_tick - 4 bytes + // time_scale - 4 bytes + // fixed_frame_rate_flag - 1 bit + // + // Summarizing - 4 + 4 + 1 = 9 bytes need to be added + new_sps.reserve(old_sps.size() + 9); + + // Enable timing_info_present_flag + InsertBitIntoVector(&new_sps, ¤tly_processed_bit_index, &byte_number, + 1); + + // Rewritten value of timing_info_present_flag, so offset from end needs to be + // decreased + --bit_offset_from_end; + + // Add num_units_in_tick value + InsertValueIntoVector(&new_sps, ¤tly_processed_bit_index, &byte_number, + num_units_in_tick); + + // Add time_scale value + InsertValueIntoVector(&new_sps, ¤tly_processed_bit_index, &byte_number, + time_scale); + + // Add fixed_frame_rate_flag value + InsertBitIntoVector(&new_sps, ¤tly_processed_bit_index, &byte_number, + 0); + + // Add remaining values from old_sps + for (int offset = bit_offset_from_end; offset > 0; --offset) { + int o_byte_number = ((old_sps.size() * kBitsInByte) - offset) / kBitsInByte; + int o_byte_value = old_sps[o_byte_number]; + + // Don't propagate emulation_prevention_three_byte added to original SPS + if (o_byte_number > 1 && !old_sps[o_byte_number - 2] && + !old_sps[o_byte_number - 1] && old_sps[o_byte_number] == 3) { + continue; + } + + int o_bit_number = (offset - 1 + kBitsInByte) % kBitsInByte; + int o_bit_value = (1u << o_bit_number) & o_byte_value; + InsertBitIntoVector(&new_sps, ¤tly_processed_bit_index, &byte_number, + o_bit_value); + } + + // 7.4.1 General NAL unit semantics + // "The last byte of the NAL unit shall not be equal to 0x00." + while (!new_sps.back()) { + new_sps.pop_back(); + } + + return new_sps; +} + void H264Parser::SetStream(const uint8_t* stream, off_t stream_size) { std::vector subsamples; SetEncryptedStream(stream, stream_size, subsamples); @@ -874,9 +985,12 @@ H264Parser::Result H264Parser::ParseVUIParameters(H264SPS* sps) { READ_UE_OR_RETURN(&data); // chroma_sample_loc_type_bottom_field } + sps->timing_info_bit_offset_from_nal_end = br_.NumBitsLeft(); + // Read and ignore timing info. - READ_BOOL_OR_RETURN(&data); // timing_info_present_flag - if (data) { + READ_BOOL_OR_RETURN( + &sps->timing_info_present_flag); // timing_info_present_flag + if (sps->timing_info_present_flag) { READ_BITS_OR_RETURN(16, &data); // num_units_in_tick READ_BITS_OR_RETURN(16, &data); // num_units_in_tick READ_BITS_OR_RETURN(16, &data); // time_scale diff --git a/media/video/h264_parser.h b/media/video/h264_parser.h index f927ade..604f06c 100644 --- a/media/video/h264_parser.h +++ b/media/video/h264_parser.h @@ -208,6 +208,9 @@ struct MEDIA_EXPORT H264SPS { int chroma_array_type; + // Not part of standard, used only for replacing timing_info data + int timing_info_bit_offset_from_nal_end; + // Get corresponding SPS |level_idc| and |constraint_set3_flag| value from // requested |profile| and |level| (see Spec A.3.1). static void GetLevelConfigFromProfileLevel(VideoCodecProfile profile, @@ -535,6 +538,10 @@ class MEDIA_EXPORT H264Parser { // Parse a SEI, returning it in |*sei|, provided and managed by the caller. Result ParseSEI(H264SEI* sei); + void UpdateTimingInfoIfNeeded(std::vector>* spses_array, + int num_units_in_tick, + int time_scale); + // The return value of this method changes for every successful call to // AdvanceToNextNALU(). // This returns the subsample information for the last NALU that was output @@ -542,6 +549,11 @@ class MEDIA_EXPORT H264Parser { std::vector GetCurrentSubsamples(); private: + std::vector PrepareSPSWithTimingInfo( + const std::vector& old_sps, + int sps_id, + int num_units_in_tick, + int time_scale); // Move the stream pointer to the beginning of the next NALU, // i.e. pointing at the next start code. // Return true if a NALU has been found. diff --git a/media/video/h265_parser.cc b/media/video/h265_parser.cc index 7871795..2883eb5 100644 --- a/media/video/h265_parser.cc +++ b/media/video/h265_parser.cc @@ -17,6 +17,7 @@ #include "media/base/decrypt_config.h" #include "media/base/video_codecs.h" #include "media/video/bit_reader_macros.h" +#include "media/video/h26x_tools.h" #include "ui/gfx/geometry/rect.h" #include "ui/gfx/geometry/size.h" #include "ui/gfx/hdr_metadata.h" @@ -138,6 +139,120 @@ H265Parser::H265Parser() = default; H265Parser::~H265Parser() = default; +void H265Parser::UpdateTimingInfoIfNeeded( + std::vector>* spses_array, + int num_units_in_tick, + int time_scale) { + media::H265Parser::Result result; + + for (auto& sps : *spses_array) { + // Reset bit reader, skip first 2 bytes with NAL header + br_.Initialize(sps.data() + 2, sps.size() - 2); + int sps_id = 0; + result = ParseSPS(&sps_id); + DCHECK(result == media::H265Parser::kOk); + + if (active_sps_.find(sps_id) == active_sps_.end()) { + DVLOG(3) << "Error while parsing SPS unit"; + continue; + } + + if (!active_sps_[sps_id]->vui_parameters_present_flag) { + DVLOG(1) << "VUI parameters are not present in SPS. " + << "Adding framerate information skipped."; + continue; + } + + if (active_sps_[sps_id]->vui_parameters.timing_info_present_flag) { + LOG(INFO) << "VUI timing info present in SPS " << sps_id; + continue; + } + + auto new_sps = + PrepareSPSWithTimingInfo(sps, sps_id, num_units_in_tick, time_scale); + + LOG(INFO) << "Inserting VUI timing info: " << time_scale << '/' + << num_units_in_tick << " into SPS " << sps_id; + + sps.swap(new_sps); + } +} + +std::vector H265Parser::PrepareSPSWithTimingInfo( + const std::vector& old_sps, + int sps_id, + int num_units_in_tick, + int time_scale) { + const auto& vui_parameters = active_sps_[sps_id]->vui_parameters; + + int bit_offset_from_end = vui_parameters.timing_info_bit_offset_from_nal_end; + int currently_processed_bit_index = + (bit_offset_from_end - 1 + kBitsInByte) % kBitsInByte; + int byte_number = + ((old_sps.size() * kBitsInByte) - bit_offset_from_end) / kBitsInByte; + + std::vector new_sps(old_sps.begin(), + std::next(old_sps.begin(), byte_number + 1)); + + // SPS will be extended by the following parameters + // num_units_in_tick - 4 bytes + // time_scale - 4 bytes + // vui_poc_proportional_to_timing_flag - 1 bit + // vui_hrd_parameters_present_flag - 1 bit + // + // Summarizing - 4 + 4 + 1 = 9 bytes need to be added + new_sps.reserve(old_sps.size() + 9); + + // Enable timing_info_present_flag + InsertBitIntoVector(&new_sps, ¤tly_processed_bit_index, &byte_number, + 1); + + // Rewritten value of timing_info_present_flag, so offset from end needs to be + // decreased + --bit_offset_from_end; + + // Add num_units_in_tick value + InsertValueIntoVector(&new_sps, ¤tly_processed_bit_index, &byte_number, + num_units_in_tick); + + // Add time_scale value + InsertValueIntoVector(&new_sps, ¤tly_processed_bit_index, &byte_number, + time_scale); + + // Add vui_poc_proportional_to_timing_flag value + InsertBitIntoVector(&new_sps, ¤tly_processed_bit_index, &byte_number, + 0); + + // Add vui_hrd_parameters_present_flag value + InsertBitIntoVector(&new_sps, ¤tly_processed_bit_index, &byte_number, + 0); + + // Add remaining values from old_sps + for (int offset = bit_offset_from_end; offset > 0; --offset) { + int o_byte_number = ((old_sps.size() * kBitsInByte) - offset) / kBitsInByte; + int o_byte_value = old_sps[o_byte_number]; + + // Don't propagate emulation_prevention_three_byte added to original SPS + if (o_byte_number > 1 && !old_sps[o_byte_number - 2] && + !old_sps[o_byte_number - 1] && old_sps[o_byte_number] == 3) { + continue; + } + + int o_bit_number = (offset - 1 + kBitsInByte) % kBitsInByte; + int o_bit_value = (1u << o_bit_number) & o_byte_value; + InsertBitIntoVector(&new_sps, ¤tly_processed_bit_index, &byte_number, + o_bit_value); + } + + // 7.4.2.1 General NAL unit semantics + // "The last byte of the NAL unit shall not be equal to 0x00." + while (!new_sps.back()) { + new_sps.pop_back(); + } + + return new_sps; +} + int H265ProfileTierLevel::GetMaxLumaPs() const { // From Table A.8 - General tier and level limits. // |general_level_idc| is 30x the actual level. @@ -733,9 +848,8 @@ H265Parser::Result H265Parser::ParseSPS(int* sps_id) { } READ_BOOL_OR_RETURN(&sps->sps_temporal_mvp_enabled_flag); READ_BOOL_OR_RETURN(&sps->strong_intra_smoothing_enabled_flag); - bool vui_parameters_present_flag; - READ_BOOL_OR_RETURN(&vui_parameters_present_flag); - if (vui_parameters_present_flag) { + READ_BOOL_OR_RETURN(&sps->vui_parameters_present_flag); + if (sps->vui_parameters_present_flag) { res = ParseVuiParameters(*sps, &sps->vui_parameters); if (res != kOk) return res; @@ -1799,9 +1913,12 @@ H265Parser::Result H265Parser::ParseVuiParameters(const H265SPS& sps, READ_UE_OR_RETURN(&vui->def_disp_win_bottom_offset); } - // Read and ignore timing info. - READ_BOOL_OR_RETURN(&data); // timing_info_present_flag - if (data) { + vui->timing_info_bit_offset_from_nal_end = br_.NumBitsLeft(); + + // timing_info_present_flag + READ_BOOL_OR_RETURN(&vui->timing_info_present_flag); + + if (vui->timing_info_present_flag) { SKIP_BITS_OR_RETURN(32); // vui_num_units_in_tick SKIP_BITS_OR_RETURN(32); // vui_time_scale READ_BOOL_OR_RETURN(&data); // vui_poc_proportional_to_timing_flag diff --git a/media/video/h265_parser.h b/media/video/h265_parser.h index 0d7ab99..4f3687f 100644 --- a/media/video/h265_parser.h +++ b/media/video/h265_parser.h @@ -127,6 +127,11 @@ struct MEDIA_EXPORT H265VUIParameters { int def_disp_win_right_offset; int def_disp_win_top_offset; int def_disp_win_bottom_offset; + + bool timing_info_present_flag = false; + // Not part of standard, used only for replacing timing_info data + int timing_info_bit_offset_from_nal_end = 0; + bool bitstream_restriction_flag; int min_spatial_segmentation_idc; int max_bytes_per_pic_denom; @@ -237,6 +242,7 @@ struct MEDIA_EXPORT H265SPS { int pic_size_in_ctbs_y; int wp_offset_half_range_y; int wp_offset_half_range_c; + bool vui_parameters_present_flag = false; uint32_t sps_max_latency_pictures[kMaxSubLayers]; // Helpers to compute frequently-used values. They do not verify that the @@ -542,6 +548,10 @@ class MEDIA_EXPORT H265Parser : public H265NaluParser { static VideoCodecProfile ProfileIDCToVideoCodecProfile(int profile_idc); + void UpdateTimingInfoIfNeeded(std::vector>* spses_array, + int num_units_in_tick, + int time_scale); + private: Result ParseProfileTierLevel(bool profile_present, int max_num_sub_layers_minus1, @@ -562,6 +572,11 @@ class MEDIA_EXPORT H265Parser : public H265NaluParser { Result ParsePredWeightTable(const H265SPS& sps, const H265SliceHeader& shdr, H265PredWeightTable* pred_weight_table); + std::vector PrepareSPSWithTimingInfo( + const std::vector& old_sps, + int sps_id, + int num_units_in_tick, + int time_scale); // VPSes, PPSes and SPSes stored for future reference. base::flat_map> active_vps_; diff --git a/media/video/h26x_tools.cc b/media/video/h26x_tools.cc new file mode 100644 index 0000000..d62b0c6 --- /dev/null +++ b/media/video/h26x_tools.cc @@ -0,0 +1,33 @@ +// Copyright 2023 Samsung Electronics. 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/video/h26x_tools.h" + +namespace media { + +void InsertBitIntoVector(std::vector* vec, + int* bits_left_in_byte, + int* current_index, + int value) { + if (*bits_left_in_byte < 0) { + // 7.4.2.1 General NAL unit semantics - emulation_prevention_three_byte + if (*current_index > 1 && !(*vec)[*current_index - 2] && + !(*vec)[*current_index - 1] && (*vec)[*current_index] <= 3) { + vec->push_back((*vec)[*current_index]); + (*vec)[*current_index] = 3; + ++(*current_index); + } + + *bits_left_in_byte = (*bits_left_in_byte + kBitsInByte) % kBitsInByte; + vec->push_back(0); + ++(*current_index); + } + + unsigned bit_value = !!value; + (*vec)[*current_index] ^= + (-bit_value ^ (*vec)[*current_index]) & (1u << *bits_left_in_byte); + --(*bits_left_in_byte); +} + +} // namespace media diff --git a/media/video/h26x_tools.h b/media/video/h26x_tools.h new file mode 100644 index 0000000..da10652 --- /dev/null +++ b/media/video/h26x_tools.h @@ -0,0 +1,35 @@ +// Copyright 2023 Samsung Electronics. 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_VIDEO_H26X_TOOLS_H_ +#define MEDIA_VIDEO_H26X_TOOLS_H_ + +#include +#include + +namespace media { + +constexpr const int kBitsInByte = 8; + +void InsertBitIntoVector(std::vector* vec, + int* bits_left_in_byte, + int* current_index, + int value); + +template +void InsertValueIntoVector(std::vector* vec, + int* bits_left_in_byte, + int* current_index, + T value) { + int value_size_in_bits = sizeof(value) * kBitsInByte; + for (int value_index = value_size_in_bits - 1; value_index >= 0; + --value_index) { + InsertBitIntoVector(vec, bits_left_in_byte, current_index, + value & (1u << value_index)); + } +} + +} // namespace media + +#endif // MEDIA_VIDEO_H26X_TOOLS_H_ diff --git a/tizen_src/chromium_impl/media/base/tizen/stream_framerate.cc b/tizen_src/chromium_impl/media/base/tizen/stream_framerate.cc new file mode 100644 index 0000000..a41bfaf --- /dev/null +++ b/tizen_src/chromium_impl/media/base/tizen/stream_framerate.cc @@ -0,0 +1,87 @@ +// Copyright 2018 Samsung Electronics. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +/** + * @file stream_framerate.cc + * @brief This file implement method to calculate stream framerate. + */ + +#include "tizen_src/chromium_impl/media/base/tizen/stream_framerate.h" + +const int64_tz kMaxFramerateReduceNum = 30000; + +#define FFABS(a) ((a) >= 0 ? (a) : (-(a))) +#define FFMIN(a, b) ((a) > (b) ? (b) : (a)) + +static int64_tz inline av_gcd(int64_tz a, int64_tz b) { + if (b) + return av_gcd(b, a % b); + else + return a; +} + +namespace media { + +StreamFramerate::StreamFramerate(const int64_tz base_num, + const int64_tz base_den) { + framerate_num_base_ = base_num; + framerate_den_base_ = base_den; +} + +bool StreamFramerate::Calculate(int* framerate_num, int* framerate_den) { + // Calculate reduced framerate_num and framerate_den. + return Reduce(framerate_num, framerate_den, framerate_num_base_, + framerate_den_base_, kMaxFramerateReduceNum); +} + +bool StreamFramerate::Reduce(int* dst_num, + int* dst_den, + int64_tz num, + int64_tz den, + int64_tz max) { + // Do reduction of a fraction to get reduced framerate_num and framerate_den. + Framerate a0 = {0, 1}, a1 = {1, 0}; + int sign = (num < 0) ^ (den < 0); + int64_tz gcd = av_gcd(FFABS(num), FFABS(den)); + + if (gcd) { + num = FFABS(num) / gcd; + den = FFABS(den) / gcd; + } + if (num <= max && den <= max) { + a1 = (Framerate){(int)num, (int)den}; + den = 0; + } + + while (den) { + uint64_tz x = num / den; + int64_tz next_den = num - den * x; + int64_tz a2n = x * a1.num + a0.num; + int64_tz a2d = x * a1.den + a0.den; + + if (a2n > max || a2d > max) { + if (a1.num) + x = (max - a0.num) / a1.num; + if (a1.den) + x = FFMIN((int64_tz)x, (max - a0.den) / a1.den); + + if (den * (2 * (int64_tz)x * a1.den + a0.den) > num * a1.den) + a1 = + (Framerate){(int)(x * a1.num) + a0.num, (int)(x * a1.den) + a0.den}; + break; + } + + a0 = a1; + a1 = (Framerate){(int)a2n, (int)a2d}; + num = den; + den = next_den; + } + + *dst_num = sign ? -a1.num : a1.num; + *dst_den = a1.den; + + return den == 0; +} + +} // namespace media diff --git a/tizen_src/chromium_impl/media/base/tizen/stream_framerate.h b/tizen_src/chromium_impl/media/base/tizen/stream_framerate.h new file mode 100644 index 0000000..37bf0e6 --- /dev/null +++ b/tizen_src/chromium_impl/media/base/tizen/stream_framerate.h @@ -0,0 +1,58 @@ +// Copyright 2023 Samsung Electronics. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +/** + * @file stream_framerate.h + * @brief This file implement method to calculate stream framerate. + */ + +#ifndef MEDIA_BASE_STREAM_FRAMERATE_H_ +#define MEDIA_BASE_STREAM_FRAMERATE_H_ + +#include +#include + +#include "media/base/media_export.h" + +typedef signed long long int int64_tz; +typedef unsigned long long int uint64_tz; + +namespace media { + +class MEDIA_EXPORT StreamFramerate { + public: + // Framerate struct. + struct Framerate { + int num; + int den; + double toDouble() const { return den ? static_cast(num) / den : 0; } + }; + + StreamFramerate(const int64_tz base_num, const int64_tz base_den); + + // Do reduction of a fraction to get reduced framerate_num and framerate_den. + bool Reduce(int* dst_num, + int* dst_den, + int64_tz num, + int64_tz den, + int64_tz max); + + bool Calculate(int* framerate_num, int* framerate_den); + + private: + int64_tz framerate_num_base_; + int64_tz framerate_den_base_; + + friend bool operator==(const StreamFramerate::Framerate& lhs, + const StreamFramerate::Framerate& rhs); +}; + +inline bool operator==(const StreamFramerate::Framerate& lhs, + const StreamFramerate::Framerate& rhs) { + return lhs.num == rhs.num && lhs.den == rhs.den; +} + +} // namespace media + +#endif // MEDIA_BASE_STREAM_FRAMERATE_H_ 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 f220826..33d2e73 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 @@ -96,6 +96,24 @@ int MediaPlayerESPlusPlayerTV::SetVideoStreamInfo( const media::VideoDecoderConfig& video_config, esplusplayer_video_stream_info& video_stream_info) { MediaPlayerESPlusPlayer::SetVideoStreamInfo(video_config, video_stream_info); + + bool validFramerate = + video_config.framerate_num() > 0 && video_config.framerate_den() > 0; + if (validFramerate) { + double framerate = static_cast(video_config.framerate_num()) / + static_cast(video_config.framerate_den()); + if (framerate > kMaxFramerate) { + video_stream_info.framerate_num = kMaxFramerate; + video_stream_info.framerate_den = 1; + } else { + video_stream_info.framerate_num = video_config.framerate_num(); + video_stream_info.framerate_den = video_config.framerate_den(); + } + } + + LOG(INFO) << "Framerate: [" << video_stream_info.framerate_num << "] [" + << video_stream_info.framerate_den << "]"; + if (!SetVideoSubmitDataType(video_config)) { LOG(ERROR) << "SetVideoSubmitDataType failed."; return -1; diff --git a/tizen_src/chromium_impl/media/media_efl.gni b/tizen_src/chromium_impl/media/media_efl.gni index ead5b06..02bc620 100644 --- a/tizen_src/chromium_impl/media/media_efl.gni +++ b/tizen_src/chromium_impl/media/media_efl.gni @@ -88,6 +88,8 @@ if (tizen_multimedia) { "//tizen_src/chromium_impl/media/filters/media_player_bridge_capi_tv.h", "//tizen_src/chromium_impl/media/filters/media_player_esplusplayer_tv.cc", "//tizen_src/chromium_impl/media/filters/media_player_esplusplayer_tv.h", + "//tizen_src/chromium_impl/media/base/tizen/stream_framerate.cc", + "//tizen_src/chromium_impl/media/base/tizen/stream_framerate.h", ] external_media_video_decode_config += [ "//tizen_src/build:drmdecrypt", -- 2.7.4 From fc86f05658181160ebf6a93bc7b3069e7d1897f2 Mon Sep 17 00:00:00 2001 From: "zhishun.zhou" Date: Wed, 13 Mar 2024 14:23:51 +0800 Subject: [PATCH 05/16] fixup! [M120 Migration] Notify media device state to webbrowser Fix build error with flag "--build-chrome": gen/media/mojo/mojom/audio_input_stream.mojom.h:151:16: note: unimplemented pure virtual method 'OnMediaStateChanged' in 'CapturedAudioInput' [ 340s] 151 | virtual void OnMediaStateChanged(uint32_t previous, uint32_t current) = 0; Change-Id: I2dcf7941f1f40e3ccd230a73bff10c030b1b3850 Signed-off-by: zhishun.zhou --- components/mirroring/service/captured_audio_input.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/components/mirroring/service/captured_audio_input.h b/components/mirroring/service/captured_audio_input.h index 25105be..a3be441 100644 --- a/components/mirroring/service/captured_audio_input.h +++ b/components/mirroring/service/captured_audio_input.h @@ -57,6 +57,9 @@ class COMPONENT_EXPORT(MIRRORING_SERVICE) CapturedAudioInput final // media::mojom::AudioInputStreamClient implementation. void OnError(media::mojom::InputStreamErrorCode code) override; void OnMutedStateChanged(bool is_muted) override; +#if BUILDFLAG(IS_TIZEN_TV) + void OnMediaStateChanged(uint32_t previous, uint32_t current) override {} +#endif SEQUENCE_CHECKER(sequence_checker_); -- 2.7.4 From f9c89d9701ea557fe29254cb953d1550646f900e Mon Sep 17 00:00:00 2001 From: =?utf8?q?Aleksander=20=C5=9Awiniarski?= Date: Tue, 12 Mar 2024 14:31:40 +0100 Subject: [PATCH 06/16] Add support to build using Tizen-X repo MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Commit introduces ability to build the chromium-efl on riscv64, x86_64, i586 and armv7l architecture, using Tizen-X repos * Added scripts of format tizen_src/build/build_x_{arch}.sh to quickly run builds for specific architerctures using Tizen-X repository * Added Tizen-X repo and profile to gbs.conf.in in form of tz_X* * Added if switch in common.sh. When the platform is defined as base-X we are assigning profile as tz_X Change-Id: I92e80ce5efe353d849a5e0ff747f782ed91f7d9b Signed-off-by: Aleksander Świniarski --- tizen_src/build/build_x_armv7l.sh | 5 +++++ tizen_src/build/build_x_ix86.sh | 5 +++++ tizen_src/build/build_x_riscv.sh | 5 +++++ tizen_src/build/build_x_x86_64.sh | 5 +++++ tizen_src/build/common.sh | 2 ++ tizen_src/build/gbs.conf.in | 19 +++++++++++++++++++ 6 files changed, 41 insertions(+) create mode 100755 tizen_src/build/build_x_armv7l.sh create mode 100755 tizen_src/build/build_x_ix86.sh create mode 100755 tizen_src/build/build_x_riscv.sh create mode 100755 tizen_src/build/build_x_x86_64.sh diff --git a/tizen_src/build/build_x_armv7l.sh b/tizen_src/build/build_x_armv7l.sh new file mode 100755 index 0000000..3097ee7 --- /dev/null +++ b/tizen_src/build/build_x_armv7l.sh @@ -0,0 +1,5 @@ +#!/bin/bash + +. `dirname $0`/common.sh + +setupAndExecuteTargetBuild Base-X "$@" -A armv7l diff --git a/tizen_src/build/build_x_ix86.sh b/tizen_src/build/build_x_ix86.sh new file mode 100755 index 0000000..2c0605b --- /dev/null +++ b/tizen_src/build/build_x_ix86.sh @@ -0,0 +1,5 @@ +#!/bin/bash + +. `dirname $0`/common.sh + +setupAndExecuteTargetBuild Base-X "$@" -A i586 diff --git a/tizen_src/build/build_x_riscv.sh b/tizen_src/build/build_x_riscv.sh new file mode 100755 index 0000000..411c39d --- /dev/null +++ b/tizen_src/build/build_x_riscv.sh @@ -0,0 +1,5 @@ +#!/bin/bash + +. `dirname $0`/common.sh + +setupAndExecuteTargetBuild Base-X "$@" -A riscv64 diff --git a/tizen_src/build/build_x_x86_64.sh b/tizen_src/build/build_x_x86_64.sh new file mode 100755 index 0000000..0d504e6 --- /dev/null +++ b/tizen_src/build/build_x_x86_64.sh @@ -0,0 +1,5 @@ +#!/bin/bash + +. `dirname $0`/common.sh + +setupAndExecuteTargetBuild Base-X "$@" -A x86_64 diff --git a/tizen_src/build/common.sh b/tizen_src/build/common.sh index be6701a..c0b3c33 100755 --- a/tizen_src/build/common.sh +++ b/tizen_src/build/common.sh @@ -352,6 +352,8 @@ function setupAndExecuteTargetBuild() { PROFILE=tz_${DEFAULT_TIZEN_VERSION}_riscv elif [[ $platform == "wearable" ]]; then PROFILE=tzwr_5.5_arm-spin + elif [[ $platform == "Base-X" ]]; then + PROFILE=tz_X else echo "Cannot set default PROFILE for platform=${platform}" exit 1 diff --git a/tizen_src/build/gbs.conf.in b/tizen_src/build/gbs.conf.in index e266c30..1268d40 100755 --- a/tizen_src/build/gbs.conf.in +++ b/tizen_src/build/gbs.conf.in @@ -35,6 +35,16 @@ passwdx = QlpoOTFBWSZTWd0JOhUAAACBAABgIAAhAIIjF3JFOFCQ3Qk6FQ== ############################################### # +# The Tizen X +# +[repo.tz_X_base] +url = http://download.tizen.org/snapshots/TIZEN/Tizen/Tizen-Base-X/reference/repos/standard/packages/ + +[repo.tz_X_unified] +url = http://download.tizen.org/snapshots/TIZEN/Tizen/Tizen-Unified-X/reference/repos/standard/packages/ + +############################################### +# # The latest Tizen public standard # [profile.tz_standard] @@ -44,6 +54,15 @@ buildroot = ~/GBS-ROOT-TZ_@TIZEN_VERSION@_STANDARD ############################################### # +# The latest Tizen X +# +[profile.tz_X] +obs = obs.tizen +repos = repo.tz_X_base, repo.tz_X_unified +buildroot = ~/GBS-ROOT-TZ_X_@_STANDARD + +############################################### +# # The latest Tizen public emulator # [profile.tz_emulator] -- 2.7.4 From cd8468b85c3964dcc98873220bcde1622a022aa8 Mon Sep 17 00:00:00 2001 From: fang fengrong Date: Mon, 11 Mar 2024 11:09:43 +0800 Subject: [PATCH 07/16] [M120 Migration][VD] Support usb keyboard special keys Wildcard Character Some website("office 365") need use the keycode to distinguish the keys. But now the special keys haven't added on the map, the keycode is 0, website can not distinguish the specail keys, cause the keys which after these specail keys been lost when change line. Add the usb keyboard keys "~!@#$%^&*()_+`-={}|[]\:";'<>?,./" on the windows_key_codeFromEflKey map. Also covert " " to "space" key for avoid page scroll. refer: https://review.tizen.org/gerrit/#/c/301464 Change-Id: I5077b1238e0efaa929842ac6708df15bc2a0efe0 Signed-off-by: fang fengrong --- .../ui/ozone/platform/efl/efl_keycode_map.h | 47 ++++++++++++++++------ .../ui/ozone/platform/efl/im_context_efl.cc | 6 +++ 2 files changed, 41 insertions(+), 12 deletions(-) diff --git a/tizen_src/chromium_impl/ui/ozone/platform/efl/efl_keycode_map.h b/tizen_src/chromium_impl/ui/ozone/platform/efl/efl_keycode_map.h index 7c0e258..4d98157 100644 --- a/tizen_src/chromium_impl/ui/ozone/platform/efl/efl_keycode_map.h +++ b/tizen_src/chromium_impl/ui/ozone/platform/efl/efl_keycode_map.h @@ -375,18 +375,41 @@ static ui::KeyboardCode UIKeyCodeFromEflKey(const char* key) { {"Select", ui::VKEY_RETURN}, {"Clear", ui::VKEY_DELETE}, - // Support "+" "-" "*" "/" "," on the main keyboard zone of the USB keyboard: - // "+" ,"-","*","/" and "," delivered from EFL have key "plus","minus","asterisk", - // "slash","comma", that have already mapped to right keycode. - // But on TV all keys will go through IME,after processing of IME, the key changed - // from "plus","minus","asterisk","slash","comma" to "+" "-" "*" "/" ",". - // If "+" "-" "*" "/" "," have no map here, then their keycode will be 229, - // that will cause some website like office 365 excel check keycode failed. - {"+", ui::VKEY_OEM_PLUS}, - {"-", ui::VKEY_OEM_MINUS}, - {"*", ui::VKEY_8}, - {"/", ui::VKEY_OEM_2}, - {",", ui::VKEY_OEM_COMMA}, + // Support all special keys on physical keyboard + {"~", ui::VKEY_OEM_3},//asciitilde + {"`", ui::VKEY_OEM_3},//grave + {"!", ui::VKEY_1},//exclam + {"@", ui::VKEY_2},//at + {"#", ui::VKEY_3},//numbersign + {"$", ui::VKEY_4},//dollar + {"%", ui::VKEY_5},//percent + {"^", ui::VKEY_6},//asciicircum + {"&", ui::VKEY_7},//ampersand + {"*", ui::VKEY_8},//asterisk + {"(", ui::VKEY_9},//parenleft + {")", ui::VKEY_0},//parenright + {"_", ui::VKEY_OEM_MINUS},//underscore + {"-", ui::VKEY_OEM_MINUS},//minus + {"+", ui::VKEY_OEM_PLUS},//plus + {"=", ui::VKEY_OEM_PLUS},//equal + + {"{", ui::VKEY_OEM_4},//braceleft + {"[", ui::VKEY_OEM_4},//bracketleft + {"}", ui::VKEY_OEM_6},//braceright + {"]", ui::VKEY_OEM_6},//bracketright + {"|", ui::VKEY_OEM_5},//bar + {"\\", ui::VKEY_OEM_5},//backslash + + {":", ui::VKEY_OEM_1},//colon + {";", ui::VKEY_OEM_1},//semicolon + {"\"", ui::VKEY_OEM_7},//quotedbl + {"'", ui::VKEY_OEM_7},//apostrophe + {"<", ui::VKEY_OEM_COMMA},//less + {",", ui::VKEY_OEM_COMMA},//comma + {">", ui::VKEY_OEM_PERIOD},//greater + {".", ui::VKEY_OEM_PERIOD},//period + {"?", ui::VKEY_OEM_2},//question + {"/", ui::VKEY_OEM_2},//slash // The key value of the "Tab" is "ISO_Left_Tab" on "shift+ Tab" case. // Add "ISO_Left_Tab" mapping for supporting cell switch on Hancom Space Excel. diff --git a/tizen_src/chromium_impl/ui/ozone/platform/efl/im_context_efl.cc b/tizen_src/chromium_impl/ui/ozone/platform/efl/im_context_efl.cc index c1236a6..f4441fc 100644 --- a/tizen_src/chromium_impl/ui/ozone/platform/efl/im_context_efl.cc +++ b/tizen_src/chromium_impl/ui/ozone/platform/efl/im_context_efl.cc @@ -495,6 +495,12 @@ void IMContextEfl::OnCommit(void* event_info) { void IMContextEfl::SendFakeCompositionKeyEvent(const std::u16string& buf) { std::string str = base::UTF16ToUTF8(buf); + // We should process both " " and "space" which IME sends. + // Otherwise " " would be received by engine and cause unnecessary page + // scroll. + if (str == " ") + str = "space"; + Evas_Event_Key_Down downEvent; memset(&downEvent, 0, sizeof(Evas_Event_Key_Down)); downEvent.key = str.c_str(); -- 2.7.4 From 101f2d5fb87ba832c8ca8a47c7c693e9fe4900d2 Mon Sep 17 00:00:00 2001 From: yangzhiwen Date: Wed, 13 Mar 2024 09:35:25 +0800 Subject: [PATCH 08/16] [M120 Migration][VD] Optimize debugging in log Add player id in logs. patch from: https://review.tizen.org/gerrit/#/c/platform/framework/web/chromium-efl/+/301267/ Change-Id: Ib05a00ca6b1d147e8418b081f4b70aa6a9c7dfa0 Signed-off-by: yangzhiwen --- base/logging.h | 2 + media/base/pipeline_impl.cc | 23 ++-- .../content/browser/media/tizen_renderer_impl.cc | 63 +++++---- .../media/filters/media_player_bridge_capi.h | 1 + .../media/filters/media_player_bridge_capi_tv.cc | 146 ++++++++++++--------- .../media/filters/media_player_tizen.h | 1 + 6 files changed, 136 insertions(+), 100 deletions(-) diff --git a/base/logging.h b/base/logging.h index 0955b9c..19a7de2 100644 --- a/base/logging.h +++ b/base/logging.h @@ -511,6 +511,8 @@ BASE_EXPORT int GetDisableAllVLogLevel(); #define LOG_IF(severity, condition) \ LAZY_STREAM(LOG_STREAM(severity), LOG_IS_ON(severity) && (condition)) +#define LOG_ID(severity, id) LOG(severity) << "[" << id << "]: " + // The VLOG macros log with negative verbosities. #define VLOG_STREAM(verbose_level) \ ::logging::LogMessage(__FILE__, __LINE__, -(verbose_level)).stream() diff --git a/media/base/pipeline_impl.cc b/media/base/pipeline_impl.cc index e707a0d..63aaf7d 100644 --- a/media/base/pipeline_impl.cc +++ b/media/base/pipeline_impl.cc @@ -1093,7 +1093,7 @@ void PipelineImpl::RendererWrapper::OnVideoConfigChange( void PipelineImpl::RendererWrapper::ToggleFullscreenMode( bool is_fullscreen, ToggledFullscreenCB cb) { - LOG(INFO) << __func__; + LOG(INFO) << "(" << static_cast(this) << ") " << __func__; if (shared_state_.renderer) shared_state_.renderer->ToggleFullscreenMode(is_fullscreen, std::move(cb)); } @@ -1102,7 +1102,7 @@ void PipelineImpl::RendererWrapper::OnRequestSuspend(bool resource_conflict) { if (state_ == kSuspending || state_ == kSuspended) return; - LOG(INFO) << __func__; + LOG(INFO) << "(" << static_cast(this) << ") " << __func__; request_suspend_task_handle_ = main_task_runner_->PostCancelableDelayedTask( base::subtle::PostDelayedTaskPassKey(), FROM_HERE, base::BindOnce(&PipelineImpl::OnRequestSuspend, weak_pipeline_, @@ -1111,7 +1111,8 @@ void PipelineImpl::RendererWrapper::OnRequestSuspend(bool resource_conflict) { } void PipelineImpl::RendererWrapper::OnRequestSeek(base::TimeDelta time) { - LOG(INFO) << __func__ << " time:" << time; + LOG(INFO) << "(" << static_cast(this) << ") " << __func__ + << " time:" << time; if (!media_task_runner_->RunsTasksInCurrentSequence()) { media_task_runner_->PostTask( @@ -1218,7 +1219,8 @@ void PipelineImpl::RendererWrapper::SetState(State next_state) { void PipelineImpl::RendererWrapper::CompleteSeek(base::TimeDelta seek_time, PipelineStatus status) { - DVLOG(1) << __func__ << ": seek_time=" << seek_time << ", status=" << status; + DVLOG(1) << "(" << static_cast(this) << ") " << __func__ + << ": status=" << status; DCHECK(media_task_runner_->RunsTasksInCurrentSequence()); DCHECK(state_ == kStarting || state_ == kSeeking || state_ == kResuming); @@ -1297,7 +1299,7 @@ void PipelineImpl::RendererWrapper::InitializeDemuxer( void PipelineImpl::RendererWrapper::CreateRenderer( PipelineStatusCallback done_cb) { - DVLOG(1) << __func__; + DVLOG(1) << "(" << static_cast(this) << ") " << __func__; DCHECK(media_task_runner_->RunsTasksInCurrentSequence()); DCHECK(state_ == kStarting || state_ == kResuming); @@ -1314,7 +1316,8 @@ void PipelineImpl::RendererWrapper::CreateRenderer( void PipelineImpl::RendererWrapper::OnRendererCreated( PipelineStatusCallback done_cb, std::unique_ptr renderer) { - DVLOG(1) << __func__ << ": renderer=" << renderer.get(); + DVLOG(1) << "(" << static_cast(this) << ") " << __func__ + << ": renderer=" << renderer.get(); DCHECK(media_task_runner_->RunsTasksInCurrentSequence()); if (!renderer) { @@ -1333,7 +1336,7 @@ void PipelineImpl::RendererWrapper::OnRendererCreated( void PipelineImpl::RendererWrapper::InitializeRenderer( PipelineStatusCallback done_cb) { - DVLOG(1) << __func__; + DVLOG(1) << "(" << static_cast(this) << ") " << __func__; DCHECK(media_task_runner_->RunsTasksInCurrentSequence()); switch (demuxer_->GetType()) { @@ -1377,7 +1380,8 @@ void PipelineImpl::RendererWrapper::InitializeRenderer( was_played_with_user_activation_); #if defined(TIZEN_VIDEO_HOLE) - LOG(INFO) << __func__ << " call SetVideoHole : " << is_video_hole_; + LOG(INFO) << "(" << static_cast(this) << ") " << __func__ + << " call SetVideoHole : " << is_video_hole_; shared_state_.renderer->SetVideoHole(is_video_hole_); #endif #if BUILDFLAG(IS_TIZEN_TV) @@ -1783,7 +1787,8 @@ base::TimeDelta PipelineImpl::GetMediaTime() const { return last_media_time_; } - DVLOG(3) << __func__ << ": " << media_time.InMilliseconds() << " ms"; + DVLOG(3) << "(" << this << ") " << __func__ << ": " + << media_time.InMilliseconds() << " ms"; last_media_time_ = media_time; return last_media_time_; } 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 5d58dd6..46c28dc 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 @@ -67,7 +67,8 @@ TizenRendererImpl::TizenRendererImpl( renderer_extension_receiver_(this, std::move(renderer_extension_receiver)), web_contents_(web_contents) { - LOG(INFO) << "(" << static_cast(this) << ") " << __func__; + LOG_ID(INFO, player_id_) << "(" << static_cast(this) << ") " + << __func__; DCHECK_EQ(WebContents::FromRenderFrameHost( RenderFrameHost::FromID(process_id, routing_id)), web_contents); @@ -96,7 +97,8 @@ TizenRendererImpl::TizenRendererImpl( video_rect_(gfx::RectF()), #endif renderer_extension_receiver_(this) { - LOG(INFO) << "(" << static_cast(this) << ") " << __func__; + LOG_ID(INFO, player_id_) << "(" << static_cast(this) << ") " + << __func__; // TODO(dalecurtis): Remove once experiments for http://crbug.com/470940 are // complete. int threshold_ms = 0; @@ -109,7 +111,8 @@ TizenRendererImpl::TizenRendererImpl( } TizenRendererImpl::~TizenRendererImpl() { - LOG(INFO) << "(" << static_cast(this) << ") " << __func__; + LOG_ID(INFO, player_id_) << "(" << static_cast(this) << ") " + << __func__; DCHECK(task_runner_->BelongsToCurrentThread()); weak_factory_.InvalidateWeakPtrs(); @@ -128,7 +131,8 @@ TizenRendererImpl::~TizenRendererImpl() { void TizenRendererImpl::Initialize(media::MediaResource* media_resource, media::RendererClient* client, media::PipelineStatusCallback init_cb) { - LOG(INFO) << "(" << static_cast(this) << ") " << __func__; + LOG_ID(INFO, player_id_) << "(" << static_cast(this) << ") " + << __func__; DCHECK(task_runner_->BelongsToCurrentThread()); DCHECK_EQ(state_, STATE_UNINITIALIZED); DCHECK(init_cb); @@ -178,7 +182,7 @@ void TizenRendererImpl::Initialize(media::MediaResource* media_resource, web_contents->GetRenderWidgetHostView())) { view_aura->SetWebViewMovedCallback(base::BindRepeating( &TizenRendererImpl::OnWebViewMoved, base::Unretained(this))); - LOG(INFO) << "SetPositionMovedCallbacks called!"; + LOG_ID(INFO, player_id_) << "SetPositionMovedCallbacks called!"; } } #endif @@ -191,8 +195,9 @@ void TizenRendererImpl::Initialize(media::MediaResource* media_resource, if (!media::MediaPlayerRegistry::GetInstance()->ActivateMediaPlayer( player_id_, !resource_conflicted_)) { - LOG(INFO) << "(" << static_cast(this) << ") " << __func__ - << " Can not initialize the player id: " << player_id_; + LOG_ID(INFO, player_id_) + << "(" << static_cast(this) << ") " << __func__ + << " Can not initialize the player id: " << player_id_; return; } @@ -220,7 +225,7 @@ void TizenRendererImpl::SetStreamInfo() { void TizenRendererImpl::SetPlayerInitialize() { if (media_player_->IsInitialized()) { - LOG(INFO) << __func__ << " Already initialized."; + LOG_ID(INFO, player_id_) << __func__ << " Already initialized."; return; } @@ -236,7 +241,7 @@ void TizenRendererImpl::SetPlayerInitialize() { void TizenRendererImpl::SetPlayerPrepare() { if (!media_player_->CanPrepare()) { - LOG(INFO) << __func__ << " Already preparing or prepared."; + LOG_ID(INFO, player_id_) << __func__ << " Already preparing or prepared."; return; } @@ -283,8 +288,8 @@ void TizenRendererImpl::Flush(base::OnceClosure flush_cb) { } void TizenRendererImpl::Seek(base::TimeDelta time, base::OnceClosure seek_cb) { - LOG(INFO) << "(" << static_cast(this) << ") " << __func__ - << " time : " << time.InMicroseconds(); + LOG_ID(INFO, player_id_) << "(" << static_cast(this) << ") " + << __func__ << " time : " << time.InMicroseconds(); media_player_->Seek(time, std::move(seek_cb)); } @@ -337,7 +342,7 @@ gfx::Rect TizenRendererImpl::GetViewportRect() const { void TizenRendererImpl::OnWebViewMoved() { if (media_player_) { - LOG(INFO) << __func__ << " Reset WebView-Position."; + LOG_ID(INFO, player_id_) << __func__ << " Reset WebView-Position."; SetPlayerMediaGeometry(); } } @@ -349,12 +354,13 @@ content::WebContents* TizenRendererImpl::GetWebContents() const { } void TizenRendererImpl::Suspend() { - LOG(INFO) << "(" << static_cast(this) << ") " << __func__; + LOG_ID(INFO, player_id_) << "(" << static_cast(this) << ") " + << __func__; if (is_suspended_) return; if (!media_player_) { - LOG(INFO) << "media_player_ is not created yet"; + LOG_ID(INFO, player_id_) << "media_player_ is not created yet"; return; } @@ -369,7 +375,7 @@ content::WebContentsDelegate* TizenRendererImpl::GetWebContentsDelegate() const { content::WebContents* web_contents = GetWebContents(); if (!web_contents) { - LOG(ERROR) << "web_contents is nullptr"; + LOG_ID(ERROR, player_id_) << "web_contents is nullptr"; return nullptr; } return web_contents->GetDelegate(); @@ -384,8 +390,8 @@ void TizenRendererImpl::ToggleFullscreenMode(bool is_fullscreen, } void TizenRendererImpl::StartPlayingFrom(base::TimeDelta time) { - LOG(INFO) << "(" << static_cast(this) << ") " << __func__ - << " time : " << time.InMicroseconds(); + LOG_ID(INFO, player_id_) << "(" << static_cast(this) << ") " + << __func__ << " time : " << time.InMicroseconds(); DCHECK(media_player_); DCHECK(task_runner_->BelongsToCurrentThread()); TRACE_EVENT1("media", "TizenRendererImpl::StartPlayingFrom", "time_us", @@ -400,8 +406,9 @@ void TizenRendererImpl::StartPlayingFrom(base::TimeDelta time) { } void TizenRendererImpl::SetPlaybackRate(double playback_rate) { - LOG(INFO) << "(" << static_cast(this) << ") " << __func__ << " " - << playback_rate << "/ " << playback_rate_; + LOG_ID(INFO, player_id_) << "(" << static_cast(this) << ") " + << __func__ << " " << playback_rate << "/ " + << playback_rate_; DCHECK(task_runner_->BelongsToCurrentThread()); TRACE_EVENT1("media", "TizenRendererImpl::SetPlaybackRate", "rate", playback_rate); @@ -420,7 +427,8 @@ void TizenRendererImpl::SetPlaybackRate(double playback_rate) { } void TizenRendererImpl::SetVolume(float volume) { - LOG(INFO) << "(" << static_cast(this) << ") " << __func__; + LOG_ID(INFO, player_id_) << "(" << static_cast(this) << ") " + << __func__; DCHECK(task_runner_->BelongsToCurrentThread()); if (volume_ == volume) return; @@ -486,19 +494,19 @@ void TizenRendererImpl::SetParentalRatingResult(bool is_pass) { if (media_player_) media_player_->SetParentalRatingResult(is_pass); else - LOG(ERROR) << "media_player_ is null"; + LOG_ID(ERROR, player_id_) << "media_player_ is null"; } bool TizenRendererImpl::PlaybackNotificationEnabled() { content::WebContents* web_contents = GetWebContents(); if (!web_contents) { - LOG(ERROR) << "web_contents is nullptr"; + LOG_ID(ERROR, player_id_) << "web_contents is nullptr"; return false; } blink::web_pref::WebPreferences web_preference = web_contents->GetOrCreateWebPreferences(); bool enable = web_preference.media_playback_notification_enabled; - LOG(INFO) << "media_playback_notification_enabled:" << enable; + LOG_ID(INFO, player_id_) << "media_playback_notification_enabled:" << enable; return enable; } @@ -514,13 +522,13 @@ void TizenRendererImpl::NotifyPlaybackState(int state, content::WebContentsDelegate* web_contents_delegate = GetWebContentsDelegate(); if (!web_contents_delegate) { - LOG(ERROR) << "GetWebContentsDelegate failed"; + LOG_ID(ERROR, player_id_) << "GetWebContentsDelegate failed"; return; } if (notify_playback_state_ < media::kPlaybackReady && state == media::kPlaybackStop) { - LOG(ERROR) << "player not Ready but notify Stop"; + LOG_ID(ERROR, player_id_) << "player not Ready but notify Stop"; } notify_playback_state_ = state; @@ -600,10 +608,11 @@ void TizenRendererImpl::OnRequestSeek(base::TimeDelta time) { } void TizenRendererImpl::OnRequestSuspend(bool resource_conflicted) { - LOG(INFO) << "(" << static_cast(this) << ") " << __func__; + LOG_ID(INFO, player_id_) << "(" << static_cast(this) << ") " + << __func__; if (is_suspended_) { - LOG(INFO) << " Media is already suspended."; + LOG_ID(INFO, player_id_) << " Media is already suspended."; return; } diff --git a/tizen_src/chromium_impl/media/filters/media_player_bridge_capi.h b/tizen_src/chromium_impl/media/filters/media_player_bridge_capi.h index 4f408b5..5d5025c 100644 --- a/tizen_src/chromium_impl/media/filters/media_player_bridge_capi.h +++ b/tizen_src/chromium_impl/media/filters/media_player_bridge_capi.h @@ -118,6 +118,7 @@ class MEDIA_EXPORT MediaPlayerBridgeCapi : public MediaPlayerTizen { void OnMediaDataChange(int player_id, int width, int height, int media); bool IsPlayerSuspended() { return suspended_; } bool player_prepared_{false}; + int GetPlayerId() override { return player_id_; } protected: void OnMediaError(MediaError error_type); diff --git a/tizen_src/chromium_impl/media/filters/media_player_bridge_capi_tv.cc b/tizen_src/chromium_impl/media/filters/media_player_bridge_capi_tv.cc index b18eaa3..8e7420a 100644 --- a/tizen_src/chromium_impl/media/filters/media_player_bridge_capi_tv.cc +++ b/tizen_src/chromium_impl/media/filters/media_player_bridge_capi_tv.cc @@ -38,17 +38,19 @@ MediaPlayerBridgeCapiTV::MediaPlayerBridgeCapiTV(const GURL& url, const std::string& user_agent, double volume) : MediaPlayerBridgeCapi(url, user_agent, volume), weak_factory_(this) { - LOG(INFO) << "(" << static_cast(this) << ") " << __func__; + LOG_ID(INFO, GetPlayerId()) + << "(" << static_cast(this) << ") " << __func__; } MediaPlayerBridgeCapiTV::~MediaPlayerBridgeCapiTV() { - LOG(INFO) << "(" << static_cast(this) << ") " << __func__; + LOG_ID(INFO, GetPlayerId()) + << "(" << static_cast(this) << ") " << __func__; weak_factory_.InvalidateWeakPtrs(); } void MediaPlayerBridgeCapiTV::SetContentMimeType(const std::string& mime_type) { - LOG(INFO) << "(" << static_cast(this) << ") " << __func__ - << " mime_type : " << mime_type; + LOG_ID(INFO, GetPlayerId()) << "(" << static_cast(this) << ") " + << __func__ << " mime_type : " << mime_type; mime_type_ = mime_type; } @@ -62,14 +64,15 @@ void MediaPlayerBridgeCapiTV::Prepare() { kPlaybackLoad, player_id_, url_.spec(), mime_type_, &media_resource_acquired, &translated_url, &drm_info); - LOG(INFO) << "media_resource_acquired: " << media_resource_acquired - << ",translated_url:" << translated_url - << ",drm_info: " << drm_info; + LOG_ID(INFO, GetPlayerId()) + << "media_resource_acquired: " << media_resource_acquired + << ",translated_url:" << translated_url << ",drm_info: " << drm_info; if (mime_type_.find("application/vnd.oipf.contentaccessstreaming+xml") != std::string::npos) { - LOG(INFO) << "CASD url,waiting for hbbtv parse the real url and set " - "translated url"; + LOG_ID(INFO, GetPlayerId()) + << "CASD url,waiting for hbbtv parse the real url and set " + "translated url"; return; } @@ -77,7 +80,7 @@ void MediaPlayerBridgeCapiTV::Prepare() { GetMediaPlayerClient()->PlaybackNotificationEnabled() && blink::IsHbbTV()) { if (!SetDrmInfo(drm_info)) { - LOG(ERROR) << "SetDrmInfo failed"; + LOG_ID(ERROR, GetPlayerId()) << "SetDrmInfo failed"; return; } if (!translated_url.empty()) @@ -116,19 +119,21 @@ void MediaPlayerBridgeCapiTV::Release() { } bool MediaPlayerBridgeCapiTV::Play() { - LOG(INFO) << "(" << static_cast(this) << ") " << __func__ - << ",current_time:" << GetCurrentTime().InSecondsF(); + LOG_ID(INFO, GetPlayerId()) + << "(" << static_cast(this) << ") " << __func__ + << ",current_time:" << GetCurrentTime().InSecondsF(); // HBBTV run in preloading and preplay mode. If no prepread do prepare // in PlayerPrePlay(), otherwise do normal Play. if (blink::IsHbbTV() && !player_prepared_) { if (!PlayerPrePlay()) - LOG(ERROR) << "HBBTV prePlay fail."; + LOG_ID(ERROR, GetPlayerId()) << "HBBTV prePlay fail."; return false; } if (blink::IsHbbTV() && !parental_rating_pass_) { - LOG(INFO) << "parental rating authenticatoin is not pass yet,waiting..."; + LOG_ID(INFO, GetPlayerId()) + << "parental rating authenticatoin is not pass yet,waiting..."; delayed_player_state_ = PLAYER_STATE_DELAYED_PLAY; MediaPlayerBridgeCapi::ExecuteDelayedPlayerState(); return false; @@ -143,8 +148,9 @@ bool MediaPlayerBridgeCapiTV::Play() { void MediaPlayerBridgeCapiTV::Pause(bool is_media_related_action) { if (!player_prepared_) { - LOG(INFO) << "(" << static_cast(this) - << "), pause while player is not prepared, pause delay"; + LOG_ID(INFO, GetPlayerId()) + << "(" << static_cast(this) + << "), pause while player is not prepared, pause delay"; delayed_player_state_ = PLAYER_STATE_DELAYED_PAUSE; return; } @@ -196,9 +202,9 @@ void MediaPlayerBridgeCapiTV::OnSeekableTimeUpdateTimerFired() { void MediaPlayerBridgeCapiTV::GetAdaptiveStreamingInfo() { int ret = player_get_adaptive_streaming_info(player_, &is_live_stream_, PLAYER_ADAPTIVE_INFO_IS_LIVE); - if (ret == PLAYER_ERROR_NONE && is_live_stream_) { - LOG(INFO) << "(" << static_cast(this) << ") " << __func__ - << " A live stream."; + if (ret != PLAYER_ERROR_NONE || is_live_stream_) { + LOG_ID(INFO, GetPlayerId()) << "(" << static_cast(this) << ") " + << __func__ << " A live stream."; } } @@ -222,8 +228,8 @@ void MediaPlayerBridgeCapiTV::UpdateSeekableTime() { GetAdaptiveStreamingInfo(); if (!is_live_stream_) { - LOG(INFO) << "(" << static_cast(this) << ") " << __func__ - << " changed to static stream"; + LOG_ID(INFO, GetPlayerId()) << "(" << static_cast(this) << ") " + << __func__ << " changed to static stream"; if (GetMediaPlayerClient()) GetMediaPlayerClient()->OnSeekableTimeChange({}, {}, is_live_stream_); MediaPlayerBridgeCapi::UpdateDuration(); @@ -250,37 +256,41 @@ bool MediaPlayerBridgeCapiTV::GetLiveStreamingDuration(int64_t* min, const std::string duration(live_duration); const std::string::size_type delimiter = duration.find('|'); if (delimiter == std::string::npos) { - LOG(ERROR) << "(" << static_cast(this) << ") " << __func__ - << " Failed to find delimiter | in duration: " << duration; + LOG_ID(ERROR, GetPlayerId()) + << "(" << static_cast(this) << ") " << __func__ + << " Failed to find delimiter | in duration: " << duration; return false; } const std::string duration_min = duration.substr(0, delimiter); if (duration_min.empty()) { - LOG(ERROR) << "(" << static_cast(this) << ") " << __func__ - << " Failed empty min sub str: " << duration << ", " - << delimiter; + LOG_ID(ERROR, GetPlayerId()) + << "(" << static_cast(this) << ") " << __func__ + << " Failed empty min sub str: " << duration << ", " << delimiter; return false; } int64_t out_min = 0; if (!base::StringToInt64(duration_min, &out_min)) { - LOG(ERROR) << "(" << static_cast(this) << ") " << __func__ - << " Failed to get min from duration: " << duration; + LOG_ID(ERROR, GetPlayerId()) + << "(" << static_cast(this) << ") " << __func__ + << " Failed to get min from duration: " << duration; return false; } const std::string duration_max = duration.substr(delimiter + 1); if (duration_max.empty()) { - LOG(ERROR) << "(" << static_cast(this) << ") " << __func__ - << " empty max sub str: " << duration << ", " << delimiter; + LOG_ID(ERROR, GetPlayerId()) + << "(" << static_cast(this) << ") " << __func__ + << " empty max sub str: " << duration << ", " << delimiter; return false; } int64_t out_max = 0; if (!base::StringToInt64(duration_max, &out_max)) { - LOG(ERROR) << "(" << static_cast(this) << ") " << __func__ - << " Failed to get max from duration: " << duration; + LOG_ID(ERROR, GetPlayerId()) + << "(" << static_cast(this) << ") " << __func__ + << " Failed to get max from duration: " << duration; return false; } @@ -365,22 +375,22 @@ void MediaPlayerBridgeCapiTV::AppendUrlHighBitRate(const std::string& url) { strncat(str_url, high_bitrate, strlen(high_bitrate)); hbbtv_url_ = str_url; BLINKFREE(str_url); - LOG(INFO) << "hbbtv url:" << hbbtv_url_.c_str(); + LOG_ID(INFO, GetPlayerId()) << "hbbtv url:" << hbbtv_url_.c_str(); } bool MediaPlayerBridgeCapiTV::CheckHighBitRate() { if (!GetMediaPlayerClient()) { - LOG(ERROR) << "MediaPlayerClient is null"; + LOG_ID(ERROR, GetPlayerId()) << "MediaPlayerClient is null"; return false; } content::WebContentsDelegate* web_contents_delegate = GetMediaPlayerClient()->GetWebContentsDelegate(); if (!web_contents_delegate) { - LOG(ERROR) << "get web_contents_delegate fail"; + LOG_ID(ERROR, GetPlayerId()) << "get web_contents_delegate fail"; return false; } bool ret = web_contents_delegate->IsHighBitRate(); - LOG(INFO) << "get high bit rate: " << std::boolalpha << ret; + LOG_ID(INFO, GetPlayerId()) << "get high bit rate: " << std::boolalpha << ret; return ret; } @@ -398,7 +408,8 @@ void MediaPlayerBridgeCapiTV::HandleDownloadableFontInfo( } bool MediaPlayerBridgeCapiTV::PreloadIfNeeded(int& ret) { - LOG(INFO) << "PreloadIfNeeded, is_preloaded_ " << is_preloaded_; + LOG_ID(INFO, GetPlayerId()) + << "PreloadIfNeeded, is_preloaded_ " << is_preloaded_; if (blink::IsHbbTV() && !is_preloaded_) { ret = player_preloading_async(player_, -1, PlayerPreLoadingCb, this); return true; @@ -408,8 +419,8 @@ bool MediaPlayerBridgeCapiTV::PreloadIfNeeded(int& ret) { if (GetMediaPlayerClient()) GetMediaPlayerClient()->NotifyPlaybackState(kPlaybackReady, player_id_); else - LOG(ERROR) << "(" << static_cast(this) - << "), GetMediaPlayerClient return null"; + LOG_ID(ERROR, GetPlayerId()) << "(" << static_cast(this) + << "), GetMediaPlayerClient return null"; SetDisplayAtPausedState(); return false; } @@ -422,13 +433,16 @@ void MediaPlayerBridgeCapiTV::SetDisplayAtPausedState() { ret = player_display_video_at_paused_state(player_, true); if (ret != PLAYER_ERROR_NONE) - LOG(ERROR) << "player_display_video_at_paused_state() failed"; + LOG_ID(ERROR, GetPlayerId()) + << "player_display_video_at_paused_state() failed"; } void MediaPlayerBridgeCapiTV::UpdateDuration() { - LOG(INFO) << "(" << static_cast(this) << ") " << __func__; + LOG_ID(INFO, GetPlayerId()) + << "(" << static_cast(this) << ") " << __func__; if (blink::IsHbbTV() && !is_preloaded_) { - LOG(INFO) << "HBBTV preload not finished, no need update duration. "; + LOG_ID(INFO, GetPlayerId()) + << "HBBTV preload not finished, no need update duration. "; return; } if (is_live_stream_) { @@ -466,10 +480,12 @@ void MediaPlayerBridgeCapiTV::UpdateDuration() { } void MediaPlayerBridgeCapiTV::UpdateMediaType() { - LOG(INFO) << "(" << static_cast(this) << ") " << __func__; + LOG_ID(INFO, GetPlayerId()) + << "(" << static_cast(this) << ") " << __func__; if (blink::IsHbbTV() && !is_preloaded_) { - LOG(INFO) << "HBBTV preload not finished, no need update media type. "; + LOG_ID(INFO, GetPlayerId()) + << "HBBTV preload not finished, no need update media type. "; return; } MediaPlayerBridgeCapi::UpdateMediaType(); @@ -501,7 +517,7 @@ void MediaPlayerBridgeCapiTV::OnPlayerPreloading() { bool MediaPlayerBridgeCapiTV::HBBTVResourceAcquired() { bool media_resource_acquired = false; if (!GetMediaPlayerClient()) { - LOG(ERROR) << "MediaPlayerTizenClient is nullptr"; + LOG_ID(ERROR, GetPlayerId()) << "MediaPlayerTizenClient is nullptr"; return false; } @@ -510,14 +526,14 @@ bool MediaPlayerBridgeCapiTV::HBBTVResourceAcquired() { &media_resource_acquired, NULL, NULL); if (!media_resource_acquired) { GetMediaPlayerClient()->NotifyPlaybackState(kPlaybackStop, player_id_); - LOG(ERROR) << "HBBTV media resource acquired failed"; + LOG_ID(ERROR, GetPlayerId()) << "HBBTV media resource acquired failed"; } return media_resource_acquired; } void MediaPlayerBridgeCapiTV::PlayerPreloaded() { - LOG(INFO) << "PlayerPreloaded,this: " << this - << ",player_prepared_:" << player_prepared_; + LOG_ID(INFO, GetPlayerId()) << "PlayerPreloaded,this: " << this + << ",player_prepared_:" << player_prepared_; is_preloaded_ = true; is_live_stream_ = CheckLiveStreaming(); @@ -533,7 +549,7 @@ void MediaPlayerBridgeCapiTV::PlayerPreloaded() { UpdateDuration(); UpdateMediaType(); if (GetMediaType() == MediaType::Invalid) { - LOG(ERROR) << "Media type is not valid!"; + LOG_ID(ERROR, GetPlayerId()) << "Media type is not valid!"; return; } @@ -550,21 +566,21 @@ void MediaPlayerBridgeCapiTV::PlayerPreloaded() { } bool MediaPlayerBridgeCapiTV::PlayerPrePlay() { - LOG(INFO) << "PlayerPrePlay, this: " << this - << ",is_player_prepared : " << player_prepared_; + LOG_ID(INFO, GetPlayerId()) << "PlayerPrePlay, this: " << this + << ",is_player_prepared : " << player_prepared_; if (IsPlayerSuspended()) { - LOG(INFO) << "PlayerPrePlay while player is suspended"; + LOG_ID(INFO, GetPlayerId()) << "PlayerPrePlay while player is suspended"; return false; } if (!HBBTVResourceAcquired()) { - LOG(INFO) + LOG_ID(INFO, GetPlayerId()) << "PlayerPrePlay while it's not in case of HBBTV Resource Acquired"; return false; } delayed_player_state_ = PLAYER_STATE_DELAYED_PLAY; - LOG(INFO) << "begin to |player_prepare_async|"; + LOG_ID(INFO, GetPlayerId()) << "begin to |player_prepare_async|"; SetDisplayAtPausedState(); int ret = SetPlayerPrepareAsync(); @@ -596,11 +612,11 @@ bool MediaPlayerBridgeCapiTV::SetDrmInfo(std::string& drm_info) { std::string trim_key = drm_info_pair.at(0); std::string trim_value = drm_info_pair.at(1); - LOG(INFO) << "trim_key: " << trim_key.c_str() - << ",trim_value: " << trim_value.c_str(); + LOG_ID(INFO, GetPlayerId()) << "trim_key: " << trim_key.c_str() + << ",trim_value: " << trim_value.c_str(); if (!SetMediaDRMInfo(trim_key, trim_value)) { - LOG(ERROR) + LOG_ID(ERROR, GetPlayerId()) << "MediaPlayerBridgeCapiTV::SetDrmInfo SetMediaDRMInfo failed"; return false; } @@ -611,8 +627,9 @@ bool MediaPlayerBridgeCapiTV::SetDrmInfo(std::string& drm_info) { bool MediaPlayerBridgeCapiTV::SetMediaDRMInfo(const std::string& type_data, const std::string& value_data) { - LOG(INFO) << "player_set_drm_info(type_length(" << type_data.length() << ") " - << " value_length(" << value_data.length() << ")) "; + LOG_ID(INFO, GetPlayerId()) + << "player_set_drm_info(type_length(" << type_data.length() << ") " + << " value_length(" << value_data.length() << ")) "; int ret = PLAYER_ERROR_INVALID_OPERATION; const void* type_data_ptr = type_data.c_str(); const void* value_data_ptr = value_data.c_str(); @@ -628,7 +645,7 @@ bool MediaPlayerBridgeCapiTV::SetMediaDRMInfo(const std::string& type_data, } void MediaPlayerBridgeCapiTV::OnDrmError(int err_code, char* err_str) { - LOG(ERROR) << "OnDrmError err_str[" << err_str << "]"; + LOG_ID(ERROR, GetPlayerId()) << "OnDrmError err_str[" << err_str << "]"; if (!task_runner_->BelongsToCurrentThread()) { task_runner_->PostTask( FROM_HERE, @@ -642,15 +659,16 @@ void MediaPlayerBridgeCapiTV::HandleParentalRatingInfo(const std::string& info, const std::string& url) { content::WebContentsDelegate* web_contents_delegate = GetMediaPlayerClient()->GetWebContentsDelegate(); - if (!web_contents_delegate){ - LOG(ERROR) << "web_contents_delegate is null"; + if (!web_contents_delegate) { + LOG_ID(ERROR, GetPlayerId()) << "web_contents_delegate is null"; return; } web_contents_delegate->NotifyParentalRatingInfo(info, url); } void MediaPlayerBridgeCapiTV::SetParentalRatingResult(bool is_pass) { - LOG(INFO) << "ParentalRatingResult:" << std::boolalpha << is_pass; + LOG_ID(INFO, GetPlayerId()) + << "ParentalRatingResult:" << std::boolalpha << is_pass; parental_rating_pass_ = is_pass; // if authentication fail, raise MEDIA_ERROR_DECODE @@ -660,7 +678,7 @@ void MediaPlayerBridgeCapiTV::SetParentalRatingResult(bool is_pass) { } if (player_prepared_) { - LOG(INFO) << "player already prepared,execute play"; + LOG_ID(INFO, GetPlayerId()) << "player already prepared,execute play"; ExecuteDelayedPlayerState(); } } 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 b7da999..d4b9de5 100644 --- a/tizen_src/chromium_impl/media/filters/media_player_tizen.h +++ b/tizen_src/chromium_impl/media/filters/media_player_tizen.h @@ -107,6 +107,7 @@ class MEDIA_EXPORT MediaPlayerTizen { virtual void SetHardwareResource(int config) {} virtual void EnableTbmBufferCallback(bool enable) {} virtual void SetAppInfo() {} + virtual int GetPlayerId() { return -1; } virtual void SetContentMimeType(const std::string& mime_type) {} virtual void SetParentalRatingResult(bool is_pass) {} }; -- 2.7.4 From abc4d0f4f5df805367e032f2286c8a7bd8a4bbbe Mon Sep 17 00:00:00 2001 From: DongHyun Song Date: Tue, 12 Mar 2024 17:59:20 +0900 Subject: [PATCH 09/16] Fix build warning in third party modules Fix build warnings related to Tizen features in third party modules Change-Id: I7a830f11889acf9d4cc675aabd18e9a0c439f535 Signed-off-by: DongHyun Song --- third_party/blink/renderer/core/exported/web_view_impl.h | 5 +++-- third_party/blink/renderer/platform/fonts/font_palette.h | 6 ++---- third_party/blink/renderer/platform/widget/widget_base.h | 2 +- third_party/blink/renderer/platform/widget/widget_base_client.h | 2 +- 4 files changed, 7 insertions(+), 8 deletions(-) diff --git a/third_party/blink/renderer/core/exported/web_view_impl.h b/third_party/blink/renderer/core/exported/web_view_impl.h index b830376..9de841d 100644 --- a/third_party/blink/renderer/core/exported/web_view_impl.h +++ b/third_party/blink/renderer/core/exported/web_view_impl.h @@ -549,8 +549,9 @@ class CORE_EXPORT WebViewImpl final : public WebView, WebSettingsImpl* SettingsImpl(); #if BUILDFLAG(IS_TIZEN) - virtual void PauseScheduledTasks(); - virtual void UnpauseScheduledTasks(); + // WebView + void PauseScheduledTasks() override; + void UnpauseScheduledTasks() override; #endif BrowserControls& GetBrowserControls(); diff --git a/third_party/blink/renderer/platform/fonts/font_palette.h b/third_party/blink/renderer/platform/fonts/font_palette.h index c6024fe..04509d5 100644 --- a/third_party/blink/renderer/platform/fonts/font_palette.h +++ b/third_party/blink/renderer/platform/fonts/font_palette.h @@ -36,10 +36,8 @@ class PLATFORM_EXPORT FontPalette : public RefCounted { Color color; FontPaletteOverride(){} - FontPaletteOverride(int index, Color color) { - index = index; - color = color; - } + FontPaletteOverride(int index, Color color) + : index(index), color(color) {} bool operator==(const FontPaletteOverride& other) const { return index == other.index && color == other.color; } diff --git a/third_party/blink/renderer/platform/widget/widget_base.h b/third_party/blink/renderer/platform/widget/widget_base.h index 32cb498..a416c0c 100644 --- a/third_party/blink/renderer/platform/widget/widget_base.h +++ b/third_party/blink/renderer/platform/widget/widget_base.h @@ -172,7 +172,7 @@ class PLATFORM_EXPORT WidgetBase : public mojom::blink::Widget, #endif #if BUILDFLAG(IS_TIZEN_TV) - void SetTranslatedURL(const WTF::String& url); + void SetTranslatedURL(const WTF::String& url) override; void SetParentalRatingResult(const WTF::String& url, bool is_pass) override; #endif diff --git a/third_party/blink/renderer/platform/widget/widget_base_client.h b/third_party/blink/renderer/platform/widget/widget_base_client.h index 270a84b..0aa127e 100644 --- a/third_party/blink/renderer/platform/widget/widget_base_client.h +++ b/third_party/blink/renderer/platform/widget/widget_base_client.h @@ -195,7 +195,7 @@ class WidgetBaseClient { virtual bool IsMouseDownEventSwallowed() { return false; } virtual void SuspendNetworkLoading() {} virtual void ResumeNetworkLoading() {} - virtual void SetFloatVideoWindowState(bool enabled) {}; + virtual void SetFloatVideoWindowState(bool enabled) {} #endif // IS_TIZEN_TV #endif // IS_EFL -- 2.7.4 From 251037cf325c78ac95ed49a74cdf97d3c2e2f649 Mon Sep 17 00:00:00 2001 From: jiangyuwei Date: Wed, 13 Mar 2024 08:51:49 +0800 Subject: [PATCH 10/16] [M120 Migration] Implement hasEventListeners for Web Voice Touch In order to support more elements in Web Voice Touch, WebBrowser request new JS API for getting event listeners attached to html element. So implemented the JS API: bool hasEventListeners(const String eventType) References: - https://review.tizen.org/gerrit/#/c/299220/ Change-Id: I077701f36eaf12f25161fda8b513127fa177533f Signed-off-by: jiangyuwei --- third_party/blink/renderer/core/dom/events/event_target.cc | 4 ++++ third_party/blink/renderer/core/dom/events/event_target.h | 1 + third_party/blink/renderer/core/dom/events/event_target.idl | 1 + 3 files changed, 6 insertions(+) diff --git a/third_party/blink/renderer/core/dom/events/event_target.cc b/third_party/blink/renderer/core/dom/events/event_target.cc index b62911f..241e934 100644 --- a/third_party/blink/renderer/core/dom/events/event_target.cc +++ b/third_party/blink/renderer/core/dom/events/event_target.cc @@ -586,6 +586,10 @@ bool EventTarget::removeEventListener(const AtomicString& event_type, return removeEventListener(event_type, event_listener, /*use_capture=*/false); } +bool EventTarget::hasEventListeners(const AtomicString& event_type) { + return HasEventListeners(event_type); +} + bool EventTarget::removeEventListener( const AtomicString& event_type, V8EventListener* listener, diff --git a/third_party/blink/renderer/core/dom/events/event_target.h b/third_party/blink/renderer/core/dom/events/event_target.h index 022773b..768371b 100644 --- a/third_party/blink/renderer/core/dom/events/event_target.h +++ b/third_party/blink/renderer/core/dom/events/event_target.h @@ -171,6 +171,7 @@ class CORE_EXPORT EventTarget : public ScriptWrappable { const EventListener*, EventListenerOptions*); virtual void RemoveAllEventListeners(); + bool hasEventListeners(const AtomicString& event_type); DispatchEventResult DispatchEvent(Event&); diff --git a/third_party/blink/renderer/core/dom/events/event_target.idl b/third_party/blink/renderer/core/dom/events/event_target.idl index 94c0678..ef2aa40 100644 --- a/third_party/blink/renderer/core/dom/events/event_target.idl +++ b/third_party/blink/renderer/core/dom/events/event_target.idl @@ -26,5 +26,6 @@ [CallWith=ScriptState] constructor(); void addEventListener(DOMString type, EventListener? listener, optional (AddEventListenerOptions or boolean) options); void removeEventListener(DOMString type, EventListener? listener, optional (EventListenerOptions or boolean) options); + boolean hasEventListeners(DOMString type); [ImplementedAs=dispatchEventForBindings, RaisesException, RuntimeCallStatsCounter=EventTargetDispatchEvent] boolean dispatchEvent(Event event); }; -- 2.7.4 From def5dcbb9c71664ecc6f85bda220022f8249a294 Mon Sep 17 00:00:00 2001 From: utkarshlal Date: Fri, 23 Feb 2024 11:09:20 +0530 Subject: [PATCH 11/16] [M120 Migration] Support GLES 3.0 Enabled GLES3.0 support for m120 Tizen profile. Support is disabled for desktop profile. In case of desktop build, 2.x version context is created. Reference patch: https://review.tizen.org/gerrit/c/285983 Change-Id: I17d8a4b441c3e37811452e1e2f913719fb33dff3 Signed-off-by: utkarshlal --- tizen_src/chromium_impl/ui/gl/gl_shared_context_efl.cc | 15 ++++++--------- tizen_src/ewk/efl_integration/command_line_efl.cc | 5 ----- 2 files changed, 6 insertions(+), 14 deletions(-) diff --git a/tizen_src/chromium_impl/ui/gl/gl_shared_context_efl.cc b/tizen_src/chromium_impl/ui/gl/gl_shared_context_efl.cc index e42ff01..ff0a3e4 100644 --- a/tizen_src/chromium_impl/ui/gl/gl_shared_context_efl.cc +++ b/tizen_src/chromium_impl/ui/gl/gl_shared_context_efl.cc @@ -44,15 +44,12 @@ struct GLSharedContextEflPrivate : public gl::GLContext { evas_gl_config_->stencil_bits = EVAS_GL_STENCIL_BIT_8; evas_gl_ = evas_gl_new(evas); -#if !defined(EWK_BRINGUP) // FIXME: m114 bringup - if (!base::CommandLine::ForCurrentProcess()->HasSwitch( - switches::kDisableES3GLContext)) { - evas_gl_context_ = - evas_gl_context_version_create(evas_gl_, 0, EVAS_GL_GLES_3_X); - if (evas_gl_context_) { - GLSharedContextEfl::GetShareGroup()->SetUseGLES3(true); - LOG(INFO) << "GLSharedContextEflPrivate(): Create GLES 3.0 Context"; - } +#if BUILDFLAG(IS_TIZEN) + evas_gl_context_ = + evas_gl_context_version_create(evas_gl_, 0, EVAS_GL_GLES_3_X); + if (evas_gl_context_) { + GLSharedContextEfl::GetShareGroup()->SetUseGLES3(true); + LOG(INFO) << "GLSharedContextEflPrivate(): Create GLES 3.0 Context"; } #endif if (!evas_gl_context_) { diff --git a/tizen_src/ewk/efl_integration/command_line_efl.cc b/tizen_src/ewk/efl_integration/command_line_efl.cc index 6942111..96161d3 100644 --- a/tizen_src/ewk/efl_integration/command_line_efl.cc +++ b/tizen_src/ewk/efl_integration/command_line_efl.cc @@ -76,11 +76,6 @@ content::MainFunctionParams CommandLineEfl::GetDefaultPortParams() { AppendMemoryOptimizationSwitches(p_command_line); -#if !defined(EWK_BRINGUP) // FIXME: m114 bringup - if (IsDesktopProfile()) - p_command_line->AppendSwitch(switches::kDisableES3GLContext); -#endif - #if BUILDFLAG(IS_TIZEN) // For optimizing discardable memory. [limit:MB, delay:ms] if (!p_command_line->HasSwitch(switches::kDiscardableMemoryLimit)) -- 2.7.4 From 9e5c3bfbf91b33daa93ac690dd02eddcfc2ff51d Mon Sep 17 00:00:00 2001 From: Manjeet Date: Mon, 11 Mar 2024 21:11:23 +0530 Subject: [PATCH 12/16] [M120 Migration] Disable Trap Handler for 64-bit emulator The basic webapp crashes on 64-bit emulator for Tizen8.0 . The crash is related to trap handler. This patch disables it. Reference: https://review.tizen.org/gerrit/293489 Change-Id: If6d9d618998d0ff311443334e7d2c7bcd3a40a92 Signed-off-by: Manjeet --- content/public/common/content_features.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/public/common/content_features.cc b/content/public/common/content_features.cc index 305e451..3b5d353 100644 --- a/content/public/common/content_features.cc +++ b/content/public/common/content_features.cc @@ -1182,7 +1182,7 @@ BASE_FEATURE(kWebAssemblyTrapHandler, "WebAssemblyTrapHandler", #if ((BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_WIN) || \ BUILDFLAG(IS_MAC)) && \ - defined(ARCH_CPU_X86_64)) || \ + defined(ARCH_CPU_X86_64) && !BUILDFLAG(IS_TIZEN)) || \ (BUILDFLAG(IS_MAC) && defined(ARCH_CPU_ARM64)) base::FEATURE_ENABLED_BY_DEFAULT #else -- 2.7.4 From 8deb3fea680fd9ae99d9950509fa338a6287895b Mon Sep 17 00:00:00 2001 From: Manjeet Date: Mon, 11 Mar 2024 22:10:17 +0530 Subject: [PATCH 13/16] [M120 Migration] Remove hardcoded path of /opt/usr/apps inside bash script tests_run Currently tizen_src/ewk/tests_run script hardcodes path '/opt/usr/apps'. Instead use tzplatform-get tool to get value of TZ_SYS_RW_APP which returns the required path. Reference: https://review/tizen.org/gerrit/293968 Change-Id: Ice8fd487063bab7e7de55ea77b998b1f10bcb238 Signed-off-by: Manjeet --- tizen_src/ewk/tests_run | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tizen_src/ewk/tests_run b/tizen_src/ewk/tests_run index ed164dd..e98b6ad 100755 --- a/tizen_src/ewk/tests_run +++ b/tizen_src/ewk/tests_run @@ -104,12 +104,14 @@ done function it { sdb push ${rep_dir}${2}-0.1-0.armv7l.rpm /opt/usr/media/Downloads/ && sdb shell pkgcmd -i -t rpm -q -p /opt/usr/media/Downloads/${2}-0.1-0.armv7l.rpm || exit 7 + tz_sys_rw_app_value=`tzplatform-get -u 5001 TZ_SYS_RW_APP` + tz_sys_rw_app_path=${tz_sys_rw_app_value#*=} while read test ; do - echo /opt/usr/apps/${2}/bin/tct-${3}-core ${test} + echo ${tz_sys_rw_app_path}/${2}/bin/tct-${3}-core ${test} timeout 65 sdb shell > ${dir}${log}/${test}.log < Date: Mon, 11 Mar 2024 22:30:34 +0530 Subject: [PATCH 14/16] [M120 Migration] Fix Coverity Potential Defects The following patch fixes below coverity defects. Warning Group Ids = 1660602, 1079960, 1080164, 1080413, 1080440, 1080471, 1081102, 1081228, 1081511, 1082036, 1083035, 1083228, 1629438, 1637057, 1660550, 1660602 Reference: https://review.tizen.org/gerrit/294087 https://review.tizen.org/gerrit/294660 https://review.tizen.org/gerrit/293808 Change-Id: I8196bc6f8508ec235109949cf3f52f91e5459e4a Signed-off-by: Manjeet --- .../ewk_context_form_autofill_profile_private.cc | 9 ++++++--- tizen_src/ewk/efl_webview_app/app.c | 6 +++--- tizen_src/ewk/ubrowser/browser.cc | 22 +++++++++++----------- 3 files changed, 20 insertions(+), 17 deletions(-) diff --git a/tizen_src/ewk/efl_integration/private/ewk_context_form_autofill_profile_private.cc b/tizen_src/ewk/efl_integration/private/ewk_context_form_autofill_profile_private.cc index 1fb706b..f0fbcdb 100644 --- a/tizen_src/ewk/efl_integration/private/ewk_context_form_autofill_profile_private.cc +++ b/tizen_src/ewk/efl_integration/private/ewk_context_form_autofill_profile_private.cc @@ -78,14 +78,17 @@ void to_Autofill_Profile_set_data(const Ewk_Autofill_Profile* oldStyleProfile, DataType DataName, std::string locale, autofill::AutofillProfile &ret) { - std::u16string value; static std::map profile_map = create_EWK_to_Autofill_profile_map(); + if (profile_map.find(DataName) == profile_map.end()) { + return; + } + std::u16string value; if (0 < (value = oldStyleProfile->get16Data(DataName)).length()) { if (DataName == PROFILE_NAME || DataName == PROFILE_COUNTRY) { ret.SetInfo(autofill::AutofillType(profile_map.find(DataName)->second), value, locale); - } else + } else if (profile_map.find(DataName) != profile_map.end()) ret.SetRawInfo(profile_map.find(DataName)->second, value); } } @@ -147,7 +150,7 @@ void to_EWK_Profile_set_data(const autofill::AutofillProfile& newStyleProfile, value = newStyleProfile.GetRawInfo(DataName); } - if (value.length()) + if (value.length() && (profile_map.find(DataName) != profile_map.end())) ret->setData(profile_map.find(DataName)->second, base::UTF16ToASCII(value)); } diff --git a/tizen_src/ewk/efl_webview_app/app.c b/tizen_src/ewk/efl_webview_app/app.c index 15aaed9..a5dc463 100644 --- a/tizen_src/ewk/efl_webview_app/app.c +++ b/tizen_src/ewk/efl_webview_app/app.c @@ -1071,7 +1071,7 @@ Eina_Bool __notification_permission_cb(Evas_Object* o, Ewk_Notification_Permissi void __notification_cancel_cb(uint64_t notification_id, void* event_info) { evas_object_del(popup); - printf("APP.C callback __notification_cancel_cb with notification id = %Lu\n", (long long unsigned int)notification_id); + printf("APP.C callback __notification_cancel_cb with notification id = %llu\n", notification_id); } void __policy_response_decide_cb(void *data, Evas_Object *obj, void *event_info) @@ -1208,7 +1208,7 @@ void __customize_context_menu_item_selected_cb(void* data, Evas_Object *obj, voi } static char snapshot_filename[256]; static int snapshot_count = 1; - sprintf(snapshot_filename, "snapshot_img%04d.%s", snapshot_count++, "png"); + snprintf(snapshot_filename, sizeof(snapshot_filename), "snapshot_img%04d.%s", snapshot_count++, "png"); if (evas_object_image_save(snapshot, snapshot_filename, 0, 0)) printf("Snapshot image saved in %s\n", snapshot_filename); else @@ -1402,7 +1402,7 @@ void __hit_test_request_cb(Evas_Object* o, int x, int y, int hit_test_mode, Ewk_ evas_object_image_data_copy_set(image, ewk_hit_test_image_buffer_get(ht)); static char filename_buffer[256]; static int count = 1; - sprintf(filename_buffer, "hit_test_img%04d.%s", count++, ewk_hit_test_image_file_name_extension_get(ht)); + snprintf(filename_buffer, sizeof(filename_buffer), "hit_test_img%04d.%s", count++, ewk_hit_test_image_file_name_extension_get(ht)); if (evas_object_image_save(image, filename_buffer, 0, 0)) printf("Hit test image saved in %s\n", filename_buffer); else diff --git a/tizen_src/ewk/ubrowser/browser.cc b/tizen_src/ewk/ubrowser/browser.cc index 80a1754..a1d9a29 100644 --- a/tizen_src/ewk/ubrowser/browser.cc +++ b/tizen_src/ewk/ubrowser/browser.cc @@ -86,23 +86,23 @@ Browser::Browser(bool desktop, log_info("UI type: %s", desktop_ ? "desktop" : "mobile"); if (IsDesktopProfile()) { - log_info("Runtime Profile : DESKTOP : ", IsDesktopProfile()); + log_info("Runtime Profile : DESKTOP"); } else if (IsMobileProfile()) { - log_info("Runtime Profile : MOBILE : ", IsMobileProfile()); + log_info("Runtime Profile : MOBILE"); } else if (IsTvProfile()) { - log_info("Runtime Profile : TV : ", IsTvProfile()); + log_info("Runtime Profile : TV"); } else if (IsWearableProfile()) { - log_info("Runtime Profile : WEARABLE : ", IsWearableProfile()); + log_info("Runtime Profile : WEARABLE"); } else if (IsIviProfile()) { - log_info("Runtime Profile : IVI : ", IsIviProfile()); + log_info("Runtime Profile : IVI"); } else if (IsCommonProfile()) { - log_info("Runtime Profile : COMMON : ", IsCommonProfile()); + log_info("Runtime Profile : COMMON"); } else { - log_info("Runtime Profile : UNKNOWN : "); + log_info("Runtime Profile : UNKNOWN"); } if (IsEmulatorArch()) { - log_info("Runtime Architecture : EMULATOR : ", IsEmulatorArch()); + log_info("Runtime Architecture : EMULATOR"); } // If we don't call ewk_context_default_get here, ubrowser crashes in desktop @@ -226,7 +226,7 @@ Window& Browser::CreateWindow(bool incognito) { if (window_list_) elm_list_go(window_list_); - log_trace("%s: %x", __PRETTY_FUNCTION__, data.window->Id()); + log_trace("%s: %p", __PRETTY_FUNCTION__, data.window->Id()); return *data.window; } @@ -305,7 +305,7 @@ void Browser::StopTracing() { } void Browser::StartVibration(uint64_t duration) { - log_trace("%s: %d", __PRETTY_FUNCTION__, duration); + log_trace("%s: %llu", __PRETTY_FUNCTION__, duration); #if BUILDFLAG(IS_TIZEN) if (IsMobileProfile() || IsWearableProfile()) { if (haptic_timer_id_) { @@ -350,7 +350,7 @@ void Browser::StopVibration() { } void Browser::OnWindowDestroyed(Window::IdType id) { - log_trace("%s: %x", __PRETTY_FUNCTION__, id); + log_trace("%s: %p", __PRETTY_FUNCTION__, id); assert(window_map_.find(id) != window_map_.end()); WindowMapData window_map_data = window_map_[id]; if (window_map_data.list_elm) -- 2.7.4 From 7769aa83bfed5eb3907bbb09eabe2f27728e4ad6 Mon Sep 17 00:00:00 2001 From: Leonid Date: Wed, 28 Feb 2024 11:32:42 +0100 Subject: [PATCH 15/16] Fix: crash on tumblr.com, navigating to any link on the page Rebasing previous change 301429 Change-Id: I7ded331469a505794b5796d8c09acce12a4b31d7 Signed-off-by: Leonid --- third_party/blink/renderer/core/frame/web_frame_widget_impl.cc | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) 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 c6ff440..ad83c18 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 @@ -1115,8 +1115,12 @@ WebInputEventResult WebFrameWidgetImpl::HandleGestureEvent( if (web_view->SettingsImpl()->LinkEffectEnabled()) { HitTestResult result = targeted_event.GetHitTestResult(); result.SetToShadowHostIfInUAShadowRoot(); - if (result.CanPlayLinkEffect()) - FocusedWebLocalFrameInWidget()->Client()->PlayLinkEffect(); + if (result.CanPlayLinkEffect()) { + auto focused_frame = FocusedWebLocalFrameInWidget(); + if (focused_frame) { + focused_frame->Client()->PlayLinkEffect(); + } + } } #endif { -- 2.7.4 From a0dd74d06de8258cd943565605bba9f65dde8db2 Mon Sep 17 00:00:00 2001 From: Leonid Date: Wed, 28 Feb 2024 11:15:12 +0100 Subject: [PATCH 16/16] Fix: SEGFAULT in UBROWSER_GUI_LEVEL_ALL Rebasing previous change 300649 from tizen.riscv Change-Id: I1a451fb87da5e45b9ffa3537cfce4f1eaa37dd66 Signed-off-by: Leonid --- tizen_src/ewk/ubrowser/window_ui.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tizen_src/ewk/ubrowser/window_ui.cc b/tizen_src/ewk/ubrowser/window_ui.cc index ff28560..ac2fe2c 100644 --- a/tizen_src/ewk/ubrowser/window_ui.cc +++ b/tizen_src/ewk/ubrowser/window_ui.cc @@ -144,12 +144,14 @@ void WindowUI::CreateTopBar() { &url_entry_color_.b, &url_entry_color_.a); evas_object_show(url_entry_); +#if !ARCH_CPU_RISCV64 // RISC-V Tizen seems to have a broken implementation for elm_separator_add if (browser_.GetGUILevel() >= Browser::UBROWSER_GUI_LEVEL_ALL) { Evas_Object* separator = elm_separator_add(urlbar_); elm_separator_horizontal_set(separator, EINA_TRUE); elm_box_pack_end(urlbar_, separator); evas_object_show(separator); } +#endif } void WindowUI::CreateBottomBar() { -- 2.7.4