diff options
author | Ningyuan Li <mariotaku.lee@gmail.com> | 2023-09-28 11:25:53 +0900 |
---|---|---|
committer | Ningyuan Li <mariotaku.lee@gmail.com> | 2023-09-30 10:44:06 +0900 |
commit | d8ed2755d8d80eac1edd2d09d58ade18d202c4fd (patch) | |
tree | aae668f48a8d17c2ca31706c04f3aa1a0b26b40e | |
parent | d209845f11f9e648509f62e4a79bbe4d2a457ec9 (diff) |
Acb (pre-webOS 5.0) support
11 files changed, 146 insertions, 11 deletions
diff --git a/cmake/modules/FindAcbAPI.cmake b/cmake/modules/FindAcbAPI.cmake new file mode 100644 index 0000000000..89bdc38392 --- /dev/null +++ b/cmake/modules/FindAcbAPI.cmake @@ -0,0 +1,37 @@ +#.rst: +# FindAcbAPI +# -------- +# Finds the AcbAPI library +# +# This will define the following target: +# +# ACBAPI::ACBAPI - The acbAPI library + +if(NOT TARGET ACBAPI::ACBAPI) + find_package(PkgConfig) + if(PKG_CONFIG_FOUND) + pkg_check_modules(PC_ACBAPI libAcbAPI QUIET) + endif() + + find_path(ACBAPI_INCLUDE_DIR NAMES appswitching-control-block/AcbAPI.h + PATHS ${PC_ACBAPI_INCLUDEDIR} + NO_CACHE) + find_library(ACBAPI_LIBRARY NAMES AcbAPI + PATHS ${PC_ACBAPI_LIBDIR} + NO_CACHE) + + set(ACBAPI_VERSION ${PC_ACBAPI_VERSION}) + + include(FindPackageHandleStandardArgs) + find_package_handle_standard_args(AcbAPI + REQUIRED_VARS ACBAPI_LIBRARY ACBAPI_INCLUDE_DIR + VERSION_VAR ACBAPI_VERSION) + + if(ACBAPI_FOUND) + add_library(ACBAPI::ACBAPI UNKNOWN IMPORTED) + set_target_properties(ACBAPI::ACBAPI PROPERTIES + IMPORTED_LOCATION "${ACBAPI_LIBRARY}" + INTERFACE_INCLUDE_DIRECTORIES "${ACBAPI_INCLUDE_DIR}") + set_property(GLOBAL APPEND PROPERTY INTERNAL_DEPS_PROP ACBAPI::ACBAPI) + endif() +endif() diff --git a/cmake/platform/linux/webos.cmake b/cmake/platform/linux/webos.cmake index c740ecd277..ce60f79cce 100644 --- a/cmake/platform/linux/webos.cmake +++ b/cmake/platform/linux/webos.cmake @@ -4,7 +4,7 @@ include(${CMAKE_SOURCE_DIR}/cmake/platform/${CORE_SYSTEM_NAME}/wayland.cmake) # saves reworking other assumptions for linux windowing as the platform name. list(APPEND CORE_PLATFORM_NAME_LC wayland) -list(APPEND PLATFORM_REQUIRED_DEPS WaylandProtocolsWebOS PlayerAPIs PlayerFactory WebOSHelpers) +list(APPEND PLATFORM_REQUIRED_DEPS WaylandProtocolsWebOS PlayerAPIs PlayerFactory WebOSHelpers AcbAPI) list(APPEND ARCH_DEFINES -DTARGET_WEBOS) set(ENABLE_PULSEAUDIO OFF CACHE BOOL "" FORCE) set(TARGET_WEBOS TRUE) diff --git a/cmake/scripts/webos/Install.cmake b/cmake/scripts/webos/Install.cmake index ab894aa9df..fde84c1479 100644 --- a/cmake/scripts/webos/Install.cmake +++ b/cmake/scripts/webos/Install.cmake @@ -29,7 +29,8 @@ set(APP_INSTALL_DIRS ${CMAKE_BINARY_DIR}/addons ${CMAKE_BINARY_DIR}/system ${CMAKE_BINARY_DIR}/userdata) set(APP_TOOLCHAIN_FILES ${TOOLCHAIN}/${HOST}/sysroot/lib/libatomic.so.1 - ${TOOLCHAIN}/${HOST}/sysroot/lib/libcrypt.so.1) + ${TOOLCHAIN}/${HOST}/sysroot/lib/libcrypt.so.1 + ${DEPENDS_PATH}/lib/libAcbAPI.so.1) set(BIN_ADDONS_DIR ${DEPENDS_PATH}/addons) file(WRITE ${CMAKE_BINARY_DIR}/install.cmake " diff --git a/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecStarfish.cpp b/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecStarfish.cpp index c393fd6b6d..f919443451 100644 --- a/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecStarfish.cpp +++ b/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecStarfish.cpp @@ -28,6 +28,7 @@ #include <memory> #include <vector> +#include <appswitching-control-block/AcbAPI.h> #include <player-factory/custompipeline.hpp> #include <player-factory/customplayer.hpp> @@ -47,6 +48,20 @@ constexpr unsigned int MAX_SRC_BUFFER_LEVEL = 8 * 1024 * 1024; // 8 MB CDVDVideoCodecStarfish::CDVDVideoCodecStarfish(CProcessInfo& processInfo) : CDVDVideoCodec(processInfo), m_starfishMediaAPI(std::make_unique<StarfishMediaAPIs>()) { + using namespace KODI::WINDOWING::WAYLAND; + auto winSystem = static_cast<CWinSystemWaylandWebOS*>(CServiceBroker::GetWinSystem()); + if (!winSystem->SupportsExportedWindow()) + { + m_acbId = AcbAPI_create(); + if (m_acbId) + { + if (!AcbAPI_initialize(m_acbId, PLAYER_TYPE_MSE, getenv("APPID"), &AcbCallback)) + { + AcbAPI_destroy(m_acbId); + m_acbId = 0; + } + } + } } CDVDVideoCodecStarfish::~CDVDVideoCodecStarfish() @@ -200,10 +215,12 @@ bool CDVDVideoCodecStarfish::OpenInternal(CDVDStreamInfo& hints, CDVDCodecOption using namespace KODI::WINDOWING::WAYLAND; auto winSystem = static_cast<CWinSystemWaylandWebOS*>(CServiceBroker::GetWinSystem()); - std::string exportedWindowName = winSystem->GetExportedWindowName(); - payloadArg["mediaTransportType"] = "BUFFERSTREAM"; - payloadArg["option"]["windowId"] = exportedWindowName; + if (winSystem->SupportsExportedWindow()) + { + std::string exportedWindowName = winSystem->GetExportedWindowName(); + payloadArg["option"]["windowId"] = exportedWindowName; + } payloadArg["option"]["appId"] = CCompileInfo::GetPackage(); payloadArg["option"]["externalStreamingInfo"]["contents"]["codec"]["video"] = m_codecname; payloadArg["option"]["externalStreamingInfo"]["contents"]["esInfo"]["pauseAtDecodeTime"] = true; @@ -257,7 +274,9 @@ bool CDVDVideoCodecStarfish::OpenInternal(CDVDStreamInfo& hints, CDVDCodecOption m_videobuffer.iDisplayWidth = m_hints.width; m_videobuffer.iDisplayHeight = m_hints.height; m_videobuffer.stereoMode = m_hints.stereo_mode; - m_videobuffer.videoBuffer = new CStarfishVideoBuffer(0); + CStarfishVideoBuffer* starfishVideoBuffer = new CStarfishVideoBuffer(0); + m_videobuffer.videoBuffer = starfishVideoBuffer; + starfishVideoBuffer->m_acbId = m_acbId; m_opened = true; @@ -280,6 +299,12 @@ void CDVDVideoCodecStarfish::Dispose() m_starfishMediaAPI->Unload(); + if (m_acbId) + { + AcbAPI_finalize(m_acbId); + AcbAPI_destroy(m_acbId); + } + ms_instanceGuard.exchange(false); } @@ -533,17 +558,43 @@ void CDVDVideoCodecStarfish::PlayerCallback(const int32_t type, case PF_EVENT_TYPE_STR_RESOURCE_INFO: m_newFrame = true; break; + case PF_EVENT_TYPE_STR_VIDEO_INFO: + if (m_acbId) + AcbAPI_setMediaVideoData(m_acbId, logstr.c_str()); + break; case PF_EVENT_TYPE_STR_STATE_UPDATE__LOADCOMPLETED: + if (m_acbId) + { + AcbAPI_setSinkType(m_acbId, SINK_TYPE_MAIN); + AcbAPI_setMediaId(m_acbId, m_starfishMediaAPI->getMediaID()); + AcbAPI_setState(m_acbId, APPSTATE_FOREGROUND, PLAYSTATE_LOADED, nullptr); + } m_starfishMediaAPI->Play(); m_state = StarfishState::FLUSHED; break; + case PF_EVENT_TYPE_STR_STATE_UPDATE__PLAYING: + if (m_acbId) + AcbAPI_setState(m_acbId, APPSTATE_FOREGROUND, PLAYSTATE_PLAYING, nullptr); + break; + case PF_EVENT_TYPE_STR_STATE_UPDATE__PAUSED: + if (m_acbId) + AcbAPI_setState(m_acbId, APPSTATE_FOREGROUND, PLAYSTATE_PAUSED, nullptr); + break; case PF_EVENT_TYPE_STR_STATE_UPDATE__ENDOFSTREAM: m_state = StarfishState::EOS; break; + case PF_EVENT_TYPE_STR_STATE_UPDATE__UNLOADCOMPLETED: + if (m_acbId) + AcbAPI_setState(m_acbId, APPSTATE_FOREGROUND, PLAYSTATE_UNLOADED, nullptr); + break; case PF_EVENT_TYPE_INT_ERROR: + CLog::LogF(LOGERROR, "CDVDVideoCodecStarfish: Pipeline INT_ERROR numValue: {}, strValue: {}", + numValue, logstr); + m_state = StarfishState::ERROR; + break; case PF_EVENT_TYPE_STR_ERROR: - CLog::LogF(LOGERROR, "CDVDVideoCodecStarfish: Pipeline error numValue: {}, strValue: {}", - type, numValue, logstr); + CLog::LogF(LOGERROR, "CDVDVideoCodecStarfish: Pipeline STR_ERROR numValue: {}, strValue: {}", + numValue, logstr); m_state = StarfishState::ERROR; break; } @@ -556,3 +607,11 @@ void CDVDVideoCodecStarfish::PlayerCallback(const int32_t type, { static_cast<CDVDVideoCodecStarfish*>(data)->PlayerCallback(type, numValue, strValue); } + +void CDVDVideoCodecStarfish::AcbCallback( + long acbId, long taskId, long eventType, long appState, long playState, const char* reply) +{ + CLog::LogF(LOGDEBUG, + "ACB callback: acbId={}, taskId={}, eventType={}, appState={}, playState={}, reply={}", + acbId, taskId, eventType, appState, playState, reply); +}
\ No newline at end of file diff --git a/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecStarfish.h b/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecStarfish.h index ce24b1fce9..1ee1fb94b1 100644 --- a/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecStarfish.h +++ b/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecStarfish.h @@ -25,6 +25,7 @@ class CStarfishVideoBuffer : public CVideoBuffer public: explicit CStarfishVideoBuffer(int id) : CVideoBuffer(id) {} AVPixelFormat GetFormat() override { return AV_PIX_FMT_NONE; } + long m_acbId{0}; }; enum class StarfishState @@ -95,7 +96,10 @@ private: const int64_t numValue, const char* strValue, void* data); + static void AcbCallback( + long acbId, long taskId, long eventType, long appState, long playState, const char* reply); std::unique_ptr<StarfishMediaAPIs> m_starfishMediaAPI; + long m_acbId{0}; CDVDStreamInfo m_hints; std::string m_codecname; diff --git a/xbmc/cores/VideoPlayer/VideoRenderers/BaseRenderer.cpp b/xbmc/cores/VideoPlayer/VideoRenderers/BaseRenderer.cpp index b8649daaa8..a451bc4be7 100644 --- a/xbmc/cores/VideoPlayer/VideoRenderers/BaseRenderer.cpp +++ b/xbmc/cores/VideoPlayer/VideoRenderers/BaseRenderer.cpp @@ -218,7 +218,8 @@ void CBaseRenderer::CalcNormalRenderRect(float offsetX, return; // clip as needed - if (!(CServiceBroker::GetWinSystem()->GetGfxContext().IsFullScreenVideo() || CServiceBroker::GetWinSystem()->GetGfxContext().IsCalibrating())) + if (m_alwaysClip || !(CServiceBroker::GetWinSystem()->GetGfxContext().IsFullScreenVideo() || + CServiceBroker::GetWinSystem()->GetGfxContext().IsCalibrating())) { CRect original(m_destRect); m_destRect.Intersect(CRect(offsetX, offsetY, offsetX + width, offsetY + height)); @@ -501,6 +502,11 @@ void CBaseRenderer::MarkDirty() CServiceBroker::GetGUI()->GetWindowManager().MarkDirty(m_destRect); } +void CBaseRenderer::EnableAlwaysClip() +{ + m_alwaysClip = true; +} + void CBaseRenderer::SetVideoSettings(const CVideoSettings &settings) { m_videoSettings = settings; diff --git a/xbmc/cores/VideoPlayer/VideoRenderers/BaseRenderer.h b/xbmc/cores/VideoPlayer/VideoRenderers/BaseRenderer.h index 67871f9b9d..3fdac4149a 100644 --- a/xbmc/cores/VideoPlayer/VideoRenderers/BaseRenderer.h +++ b/xbmc/cores/VideoPlayer/VideoRenderers/BaseRenderer.h @@ -114,6 +114,7 @@ protected: virtual void ReorderDrawPoints(); virtual EShaderFormat GetShaderFormat(); void MarkDirty(); + void EnableAlwaysClip(); //@todo drop those void saveRotatedCoords();//saves the current state of m_rotatedDestCoords @@ -141,4 +142,7 @@ protected: AVPixelFormat m_format = AV_PIX_FMT_NONE; CVideoSettings m_videoSettings; + +private: + bool m_alwaysClip = false; }; diff --git a/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/RendererStarfish.cpp b/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/RendererStarfish.cpp index d268b6ca81..b2231ff84f 100644 --- a/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/RendererStarfish.cpp +++ b/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/RendererStarfish.cpp @@ -16,6 +16,8 @@ #include "utils/log.h" #include "windowing/wayland/WinSystemWaylandWebOS.h" +#include <appswitching-control-block/AcbAPI.h> + CRendererStarfish::CRendererStarfish() { CLog::LogF(LOGINFO, "CRendererStarfish: Instanced"); @@ -32,6 +34,12 @@ CBaseRenderer* CRendererStarfish::Create(CVideoBuffer* buffer) bool CRendererStarfish::Configure(const VideoPicture& picture, float fps, unsigned int orientation) { + auto buffer = static_cast<CStarfishVideoBuffer*>(picture.videoBuffer); + m_acbId = buffer->m_acbId; + if (m_acbId) + { + EnableAlwaysClip(); + } m_iFlags = GetFlagsChromaPosition(picture.chroma_position) | GetFlagsColorMatrix(picture.color_space, picture.iWidth, picture.iHeight) | GetFlagsColorPrimaries(picture.color_primaries) | @@ -84,8 +92,16 @@ void CRendererStarfish::ManageRenderArea() CRect{0, 0, static_cast<float>(m_sourceWidth), static_cast<float>(m_sourceHeight)}; using namespace KODI::WINDOWING::WAYLAND; auto winSystem = static_cast<CWinSystemWaylandWebOS*>(CServiceBroker::GetWinSystem()); - - winSystem->SetExportedWindow(origRect, m_sourceRect, m_destRect); + if (winSystem->SupportsExportedWindow()) + { + winSystem->SetExportedWindow(origRect, m_sourceRect, m_destRect); + } + else if (m_acbId) + { + AcbAPI_setCustomDisplayWindow(m_acbId, m_sourceRect.x1, m_sourceRect.y1, m_sourceRect.Width(), + m_sourceRect.Height(), m_destRect.x1, m_destRect.y1, + m_destRect.Width(), m_destRect.Height(), false, nullptr); + } m_exportedSourceRect = m_sourceRect; m_exportedDestRect = m_destRect; } diff --git a/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/RendererStarfish.h b/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/RendererStarfish.h index ca52c57209..5b261e60a7 100644 --- a/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/RendererStarfish.h +++ b/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/RendererStarfish.h @@ -48,4 +48,5 @@ private: CRect m_exportedSourceRect; CRect m_exportedDestRect; bool m_configured{false}; + long m_acbId{0}; }; diff --git a/xbmc/windowing/wayland/WinSystemWaylandWebOS.cpp b/xbmc/windowing/wayland/WinSystemWaylandWebOS.cpp index ec1567b2a2..18be9a613c 100644 --- a/xbmc/windowing/wayland/WinSystemWaylandWebOS.cpp +++ b/xbmc/windowing/wayland/WinSystemWaylandWebOS.cpp @@ -127,6 +127,11 @@ bool CWinSystemWaylandWebOS::SetExportedWindow(CRect orig, CRect src, CRect dest return false; } +bool CWinSystemWaylandWebOS::SupportsExportedWindow() +{ + return m_webosForeign; +} + IShellSurface* CWinSystemWaylandWebOS::CreateShellSurface(const std::string& name) { return new CShellSurfaceWebOSShell(*this, *GetConnection(), GetMainSurface(), name, diff --git a/xbmc/windowing/wayland/WinSystemWaylandWebOS.h b/xbmc/windowing/wayland/WinSystemWaylandWebOS.h index 5584d5eb32..a9427e299f 100644 --- a/xbmc/windowing/wayland/WinSystemWaylandWebOS.h +++ b/xbmc/windowing/wayland/WinSystemWaylandWebOS.h @@ -40,6 +40,8 @@ public: */ bool SetExportedWindow(CRect orig, CRect src, CRect dest); + bool SupportsExportedWindow(); + IShellSurface* CreateShellSurface(const std::string& name) override; bool CreateNewWindow(const std::string& name, bool fullScreen, RESOLUTION_INFO& res) override; ~CWinSystemWaylandWebOS() noexcept override; |