From ce6314cc6e7dccd2b29adcb5ba3b9e328c30467a Mon Sep 17 00:00:00 2001 From: CrystalP Date: Mon, 11 Mar 2024 00:32:21 -0400 Subject: [PATCH] [video] Fix large bookmark thumbnails To honour large advancedsettings.xml imageres values (also fix when screen size < 720). The max thumb size is still limited because the renderer sets the scissors to the size of the screen used by Kodi (global value from graphic context). A 4k played on 1080p screen can only be captured in 1080p at the most. Removing that coupling in the future would be a good idea. Optimization: a 4k thumbnail for a 480p source is a waste of resources, with upscale processing, storage at high resolution and later downscale for display. Instead capture at source resolution when source dimensions < screen dimensions --- xbmc/application/ApplicationPlayer.cpp | 12 ++++++++ xbmc/application/ApplicationPlayer.h | 1 + xbmc/cores/IPlayer.h | 7 ++++- xbmc/cores/VideoPlayer/VideoPlayer.cpp | 5 ++++ xbmc/cores/VideoPlayer/VideoPlayer.h | 1 + xbmc/video/dialogs/GUIDialogVideoBookmarks.cpp | 38 ++++++++++++++++++++------ 6 files changed, 54 insertions(+), 10 deletions(-) diff --git a/xbmc/application/ApplicationPlayer.cpp b/xbmc/application/ApplicationPlayer.cpp index 9d14233e22..ffda4e512b 100644 --- a/xbmc/application/ApplicationPlayer.cpp +++ b/xbmc/application/ApplicationPlayer.cpp @@ -865,6 +865,18 @@ float CApplicationPlayer::GetRenderAspectRatio() const return 1.0; } +bool CApplicationPlayer::GetRects(CRect& source, CRect& dest, CRect& view) const +{ + const std::shared_ptr player{GetInternal()}; + if (player) + { + player->GetRects(source, dest, view); + return true; + } + else + return false; +} + void CApplicationPlayer::TriggerUpdateResolution() { std::shared_ptr player = GetInternal(); diff --git a/xbmc/application/ApplicationPlayer.h b/xbmc/application/ApplicationPlayer.h index 2a641d0815..9407851cf8 100644 --- a/xbmc/application/ApplicationPlayer.h +++ b/xbmc/application/ApplicationPlayer.h @@ -55,6 +55,7 @@ public: void FlushRenderer(); void SetRenderViewMode(int mode, float zoom, float par, float shift, bool stretch); float GetRenderAspectRatio() const; + bool GetRects(CRect& source, CRect& dest, CRect& view) const; void TriggerUpdateResolution(); bool IsRenderingVideo() const; bool IsRenderingGuiLayer() const; diff --git a/xbmc/cores/IPlayer.h b/xbmc/cores/IPlayer.h index 9b04674c41..791d925637 100644 --- a/xbmc/cores/IPlayer.h +++ b/xbmc/cores/IPlayer.h @@ -231,7 +231,12 @@ public: virtual float GetRenderAspectRatio() const { return 1.0; } virtual void TriggerUpdateResolution() {} virtual bool IsRenderingVideo() const { return false; } - + virtual void GetRects(CRect& source, CRect& dest, CRect& view) const + { + source = {}; + dest = {}; + view = {}; + } virtual bool Supports(EINTERLACEMETHOD method) const { return false; } virtual EINTERLACEMETHOD GetDeinterlacingMethodDefault() const { diff --git a/xbmc/cores/VideoPlayer/VideoPlayer.cpp b/xbmc/cores/VideoPlayer/VideoPlayer.cpp index 22ff110501..3b28e338b7 100644 --- a/xbmc/cores/VideoPlayer/VideoPlayer.cpp +++ b/xbmc/cores/VideoPlayer/VideoPlayer.cpp @@ -5034,6 +5034,11 @@ float CVideoPlayer::GetRenderAspectRatio() const return m_renderManager.GetAspectRatio(); } +void CVideoPlayer::GetRects(CRect& source, CRect& dest, CRect& view) const +{ + m_renderManager.GetVideoRect(source, dest, view); +} + void CVideoPlayer::TriggerUpdateResolution() { std::string stereomode; diff --git a/xbmc/cores/VideoPlayer/VideoPlayer.h b/xbmc/cores/VideoPlayer/VideoPlayer.h index 01cbca0119..a40583e350 100644 --- a/xbmc/cores/VideoPlayer/VideoPlayer.h +++ b/xbmc/cores/VideoPlayer/VideoPlayer.h @@ -340,6 +340,7 @@ public: void FlushRenderer() override; void SetRenderViewMode(int mode, float zoom, float par, float shift, bool stretch) override; float GetRenderAspectRatio() const override; + void GetRects(CRect& source, CRect& dest, CRect& view) const override; void TriggerUpdateResolution() override; bool IsRenderingVideo() const override; bool Supports(EINTERLACEMETHOD method) const override; diff --git a/xbmc/video/dialogs/GUIDialogVideoBookmarks.cpp b/xbmc/video/dialogs/GUIDialogVideoBookmarks.cpp index 425344219e..73ec28ad2a 100644 --- a/xbmc/video/dialogs/GUIDialogVideoBookmarks.cpp +++ b/xbmc/video/dialogs/GUIDialogVideoBookmarks.cpp @@ -41,8 +41,6 @@ #include #include -#define BOOKMARK_THUMB_WIDTH CServiceBroker::GetSettingsComponent()->GetAdvancedSettings()->m_imageRes - #define CONTROL_ADD_BOOKMARK 2 #define CONTROL_CLEAR_BOOKMARKS 3 #define CONTROL_ADD_EPISODE_BOOKMARK 4 @@ -380,15 +378,37 @@ bool CGUIDialogVideoBookmarks::AddBookmark(CVideoInfoTag* tag) bookmark.player = g_application.GetCurrentPlayer(); // create the thumbnail image - float aspectRatio = appPlayer->GetRenderAspectRatio(); - int width = BOOKMARK_THUMB_WIDTH; - int height = (int)(BOOKMARK_THUMB_WIDTH / aspectRatio); - if (height > (int)BOOKMARK_THUMB_WIDTH) + const float aspectRatio{appPlayer->GetRenderAspectRatio()}; + CRect srcRect{}, renderRect{}, viewRect{}; + appPlayer->GetRects(srcRect, renderRect, viewRect); + const unsigned int srcWidth{static_cast(srcRect.Width())}; + const unsigned int srcHeight{static_cast(srcRect.Height())}; + const unsigned int renderWidth{static_cast(renderRect.Width())}; + const unsigned int renderHeight{static_cast(renderRect.Height())}; + const unsigned int viewWidth{static_cast(viewRect.Width())}; + const unsigned int viewHeight{static_cast(viewRect.Height())}; + + if (!srcWidth || !srcHeight || !renderWidth || !renderHeight || !viewWidth || !viewHeight) + return false; + + // FIXME: the renderer sets the scissors to the size of the screen (provided by graphiccontext), + // limiting the max size of thumbs (for example 4k video played on 1024x768 screen) + + // The advanced setting defines the max size of the largest dimension (depends on orientation) + const unsigned int maxThumbDim{ + CServiceBroker::GetSettingsComponent()->GetAdvancedSettings()->m_imageRes}; + unsigned int width{}, height{}; + + if (aspectRatio >= 1.0f) { - height = BOOKMARK_THUMB_WIDTH; - width = (int)(BOOKMARK_THUMB_WIDTH * aspectRatio); + width = std::min({maxThumbDim, viewWidth, renderWidth, srcWidth}); + height = static_cast(width / aspectRatio); + } + else + { + height = std::min({maxThumbDim, viewHeight, renderHeight, srcHeight}); + width = static_cast(height * aspectRatio); } - uint8_t *pixels = (uint8_t*)malloc(height * width * 4); unsigned int captureId = appPlayer->RenderCaptureAlloc(); -- 2.11.4.GIT