diff --git a/.github/workflows/build_and_deploy_gh_pages.yml b/.github/workflows/build_and_deploy_gh_pages.yml index 31685bae0..907d44b64 100644 --- a/.github/workflows/build_and_deploy_gh_pages.yml +++ b/.github/workflows/build_and_deploy_gh_pages.yml @@ -62,7 +62,7 @@ jobs: doxygen - name: Download Coverage Report - uses: dawidd6/action-download-artifact@v3 + uses: dawidd6/action-download-artifact@v6 with: workflow: build_ut.yml workflow_conclusion: success diff --git a/.github/workflows/build_ut.yml b/.github/workflows/build_ut.yml index fe1cb033c..ead24de26 100644 --- a/.github/workflows/build_ut.yml +++ b/.github/workflows/build_ut.yml @@ -674,7 +674,7 @@ jobs: # Download current master coverage statistics. Should be triggered only for PRs to master - name: Download Master Coverage Statistics - uses: dawidd6/action-download-artifact@v3 + uses: dawidd6/action-download-artifact@v6 if: ${{ success() && github.event_name == 'pull_request' && github.base_ref == 'master' }} with: workflow_conclusion: success diff --git a/.github/workflows/client_component_test.yml b/.github/workflows/client_component_test.yml index bc46552e8..9879d7d7c 100644 --- a/.github/workflows/client_component_test.yml +++ b/.github/workflows/client_component_test.yml @@ -137,4 +137,4 @@ jobs: # Run the check_coverage_stats script - name: Process Coverage Statistics if: ${{ success() && github.event_name == 'pull_request' && github.base_ref == 'master' }} - run: python scripts/coverage/check_coverage_stats.py build/coverage_statistics_public_apis.txt 98 + run: python scripts/coverage/check_coverage_stats.py build/coverage_statistics_public_apis.txt 97 diff --git a/.github/workflows/valgrind_server_component_test.yml b/.github/workflows/valgrind_server_component_test.yml index 76eaee4aa..01ca012ab 100644 --- a/.github/workflows/valgrind_server_component_test.yml +++ b/.github/workflows/valgrind_server_component_test.yml @@ -45,7 +45,7 @@ jobs: runs-on: ubuntu-24.04 # Timeout after - timeout-minutes: 10 + timeout-minutes: 20 # Steps represent a sequence of tasks that will be executed as part of the job steps: diff --git a/.gitignore b/.gitignore index 0a8ded2b9..aca35095f 100644 --- a/.gitignore +++ b/.gitignore @@ -10,6 +10,8 @@ /cmake/ocdm-config.cmake *__pycache__ /.vscode/* +/CMakeUserPresets.json +/CMakeLists.txt.user* # These files are fetched by cmake during building rialto for the native platform /stubs/opencdm/third-party/* diff --git a/CMakeLists.txt b/CMakeLists.txt index 234db9ea4..eb66410b7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -28,7 +28,8 @@ add_compile_definitions(PROJECT_VER_PATCH="${PROJECT_VERSION_PATCH}") set(CMAKE_CXX_STANDARD 17) if ( COVERAGE_ENABLED ) - add_compile_options(-coverage -fprofile-update=atomic) + add_compile_options(--coverage -fprofile-update=atomic) + add_link_options(--coverage) endif() add_compile_options(-Wall -Werror) @@ -55,7 +56,7 @@ else() option(RIALTO_LOG_DEBUG_ENABLED "Enable debug logging for RialtoServer" OFF) endif() -if (NOT RIALTO_LOG_FATAL_ENABLED OR +if (NOT RIALTO_LOG_FATAL_ENABLED OR NOT RIALTO_LOG_ERROR_ENABLED OR NOT RIALTO_LOG_WARN_ENABLED OR NOT RIALTO_LOG_MIL_ENABLED OR @@ -66,7 +67,7 @@ if (NOT RIALTO_LOG_FATAL_ENABLED OR add_compile_options(-Wno-error=unused-function -Wno-error=unused-variable) endif() - + if ( RIALTO_LOG_FATAL_ENABLED ) message("RIALTO_LOG_FATAL IS ENABLED") add_compile_definitions( RIALTO_LOG_FATAL_ENABLED ) @@ -104,13 +105,13 @@ if (TEXT_TRACK_INCLUDE_DIR) add_compile_definitions(RIALTO_ENABLE_TEXT_TRACK) endif() -# Retrieve the commit ID +# Retrieve the commit ID execute_process( COMMAND git rev-parse HEAD - WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} - RESULT_VARIABLE RESULT - OUTPUT_VARIABLE SRCREV - OUTPUT_STRIP_TRAILING_WHITESPACE + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} + RESULT_VARIABLE RESULT + OUTPUT_VARIABLE SRCREV + OUTPUT_STRIP_TRAILING_WHITESPACE ) if(RESULT) @@ -120,15 +121,15 @@ endif() # Retrieve release tag execute_process( COMMAND bash -c "git tag --points-at ${SRCREV} | grep -E '^v[0-9]+\.[0-9]+\.[0-9]+$'" - WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} OUTPUT_VARIABLE TAGS - OUTPUT_STRIP_TRAILING_WHITESPACE + OUTPUT_STRIP_TRAILING_WHITESPACE ) string(REPLACE "\n" ", " TAGS "${TAGS}") if(NOT TAGS STREQUAL "") set(TAGS ${TAGS}) -endif() +endif() # Preprocesser Variable add_compile_definitions(SRCREV="${SRCREV}") @@ -213,6 +214,9 @@ if( NATIVE_BUILD ) add_subdirectory( stubs/wpeframework-core ) add_subdirectory( stubs/wpeframework-com ) + add_compile_options(-DFREE_MEM_BEFORE_EXIT) + add_compile_options(-ggdb) + include( GNUInstallDirs ) configure_file( pkg-config/RialtoClient.in.pc ${CMAKE_BINARY_DIR}/RialtoClient.pc @ONLY ) install ( diff --git a/build_ct.py b/build_ct.py index 7ecfb96f3..21ca9f730 100755 --- a/build_ct.py +++ b/build_ct.py @@ -21,6 +21,7 @@ # Entry script for running rialto componenttests import argparse +import os from scripts.gtest.build_and_run_tests import getGenericArguments, buildAndRunGTests from scripts.gtest.utils import getSuitesToRun, getOutputFile from scripts.gtest.generate_coverage import generateCoverageReport, generateSpecificCoverageStats @@ -50,8 +51,8 @@ # Generate coverage if args['coverage'] == True: - generateCoverageReport(args['output'], outputFile, suitesToRun) + generateCoverageReport(os.getcwd(), args['output'], outputFile) # Also generate coverage stats for public interfaces source files = ["*/main/source/*"] - generateSpecificCoverageStats(args['output'], outputFile, files, "coverage_statistics_public_apis") + generateSpecificCoverageStats(os.getcwd(), args['output'], outputFile, files, "coverage_statistics_public_apis") diff --git a/build_ut.py b/build_ut.py index f4d408e02..e34173c45 100755 --- a/build_ut.py +++ b/build_ut.py @@ -21,6 +21,7 @@ # Entry script for running rialto unittests import argparse +import os from scripts.gtest.build_and_run_tests import getGenericArguments, buildAndRunGTests from scripts.gtest.utils import getSuitesToRun, getOutputFile from scripts.gtest.generate_coverage import generateCoverageReport @@ -58,4 +59,4 @@ buildAndRunGTests(args, outputFile, buildDefines, suitesToRun) if args['coverage'] == True: - generateCoverageReport(args['output'], outputFile, suitesToRun) + generateCoverageReport(os.getcwd(), args['output'], outputFile) diff --git a/cmake/FindEthanLog.cmake b/cmake/FindEthanLog.cmake new file mode 100644 index 000000000..e66fe6f21 --- /dev/null +++ b/cmake/FindEthanLog.cmake @@ -0,0 +1,43 @@ +# +# If not stated otherwise in this file or this component's LICENSE file the +# following copyright and licenses apply: +# +# Copyright 2025 Sky UK +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +find_path(EthanLog_INCLUDE_DIR + NAMES ethanlog.h + ) + +find_library(EthanLog_LIBRARY + NAMES ethanlog + ) + +include(FindPackageHandleStandardArgs) +FIND_PACKAGE_HANDLE_STANDARD_ARGS(EthanLog DEFAULT_MSG EthanLog_INCLUDE_DIR EthanLog_LIBRARY) + +mark_as_advanced(EthanLog_INCLUDE_DIR EthanLog_LIBRARY) + +if (ETHANLOG_FOUND OR EthanLog_FOUND) + set(EthanLog_INCLUDE_DIRS "${EthanLog_INCLUDE_DIR}") + set(EthanLog_LIBRARIES "${EthanLog_LIBRARY}") + set(EthanLog_FOUND TRUE) +endif() + +if (EthanLog_FOUND AND NOT TARGET EthanLog::EthanLog) + add_library(EthanLog::EthanLog INTERFACE IMPORTED) + set_property(TARGET EthanLog::EthanLog PROPERTY INTERFACE_INCLUDE_DIRECTORIES "${EthanLog_INCLUDE_DIR}") + set_property(TARGET EthanLog::EthanLog PROPERTY INTERFACE_LINK_LIBRARIES "${EthanLog_LIBRARY}") +endif() diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt index f5df87f31..42d7a115f 100644 --- a/common/CMakeLists.txt +++ b/common/CMakeLists.txt @@ -56,11 +56,3 @@ target_link_libraries ( PRIVATE RialtoLogging ) - -if ( COVERAGE_ENABLED ) - target_link_libraries( - RialtoCommon - PRIVATE - gcov - ) -endif() diff --git a/logging/CMakeLists.txt b/logging/CMakeLists.txt index 33ec074b2..2c0751238 100644 --- a/logging/CMakeLists.txt +++ b/logging/CMakeLists.txt @@ -2,7 +2,7 @@ # If not stated otherwise in this file or this component's LICENSE file the # following copyright and licenses apply: # -# Copyright 2022 Sky UK +# Copyright 2025 Sky UK # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -17,30 +17,37 @@ # limitations under the License. # -set(CMAKE_C_STANDARD 99) -set(CMAKE_CXX_STANDARD 17) +set(RialtoLogging_HEADERS + include/RialtoLogging.h + ) -set( CMAKE_CXX_STANDARD_REQUIRED ON ) -set( CMAKE_POSITION_INDEPENDENT_CODE ON ) -include( CheckCCompilerFlag ) -include( CheckCXXCompilerFlag ) +set(RialtoLogging_SOURCES + source/EnvVariableParser.cpp + source/EnvVariableParser.h + source/LogFileHandle.cpp + source/LogFileHandle.h + source/RialtoLogging.cpp + ) -set(LIB_RIALTO_LOGGING_SOURCES - source/EnvVariableParser.cpp - source/LogFileHandle.cpp - source/RialtoLogging.cpp - ) +set(RialtoLogging_INCLUDES + "${CMAKE_CURRENT_SOURCE_DIR}/include" + ) -set(LIB_RIALTO_LOGGING_PUBLIC_HEADERS - include/RialtoLogging.h - ) +add_library(RialtoLogging STATIC ${RialtoLogging_HEADERS} ${RialtoLogging_SOURCES}) +target_include_directories(RialtoLogging PUBLIC "$") +set_target_properties(RialtoLogging PROPERTIES CXX_STANDARD 17 CXX_STANDARD_REQUIRED ON CXX_EXTENSIONS OFF) +set_target_properties(RialtoLogging PROPERTIES POSITION_INDEPENDENT_CODE ON) -add_library(RialtoLogging STATIC ${LIB_RIALTO_LOGGING_SOURCES}) - -target_include_directories( - RialtoLogging - - PUBLIC - $ - $ - ) +find_package(EthanLog) +if (EthanLog_FOUND AND RIALTO_ENABLE_ETHAN_LOG) + message(STATUS "EthanLog is enabled") + add_library(RialtoEthanLog STATIC ${RialtoLogging_HEADERS} ${RialtoLogging_SOURCES}) + target_include_directories(RialtoEthanLog PUBLIC "$") + target_compile_definitions(RialtoEthanLog PRIVATE USE_ETHANLOG) + target_link_libraries(RialtoEthanLog PUBLIC EthanLog::EthanLog) + set_target_properties(RialtoEthanLog PROPERTIES CXX_STANDARD 17 CXX_STANDARD_REQUIRED ON CXX_EXTENSIONS OFF) + set_target_properties(RialtoEthanLog PROPERTIES POSITION_INDEPENDENT_CODE ON) +else () + message(STATUS "EthanLog is disabled") + add_library(RialtoEthanLog ALIAS RialtoLogging) +endif () diff --git a/logging/source/RialtoLogging.cpp b/logging/source/RialtoLogging.cpp index 802b852d2..099599a69 100644 --- a/logging/source/RialtoLogging.cpp +++ b/logging/source/RialtoLogging.cpp @@ -25,13 +25,38 @@ #include #include #include -#include #include #include "EnvVariableParser.h" #include "LogFileHandle.h" #include "RialtoLogging.h" +#ifdef USE_ETHANLOG + +#include + +#define SYSTEM_LOG_FATAL(filename, function, line, ...) ethanlog(ETHAN_LOG_FATAL, filename, function, line, __VA_ARGS__) +#define SYSTEM_LOG_ERROR(filename, function, line, ...) ethanlog(ETHAN_LOG_ERROR, filename, function, line, __VA_ARGS__) +#define SYSTEM_LOG_WARN(filename, function, line, ...) \ + ethanlog(ETHAN_LOG_WARNING, filename, function, line, __VA_ARGS__) +#define SYSTEM_LOG_MIL(filename, function, line, ...) \ + ethanlog(ETHAN_LOG_MILESTONE, filename, function, line, __VA_ARGS__) +#define SYSTEM_LOG_INFO(filename, function, line, ...) ethanlog(ETHAN_LOG_INFO, filename, function, line, __VA_ARGS__) +#define SYSTEM_LOG_DEBUG(filename, function, line, ...) ethanlog(ETHAN_LOG_DEBUG, filename, function, line, __VA_ARGS__) + +#else + +#include + +#define SYSTEM_LOG_FATAL(filename, function, line, ...) syslog(LOG_CRIT, __VA_ARGS__) +#define SYSTEM_LOG_ERROR(filename, function, line, ...) syslog(LOG_ERR, __VA_ARGS__) +#define SYSTEM_LOG_WARN(filename, function, line, ...) syslog(LOG_WARNING, __VA_ARGS__) +#define SYSTEM_LOG_MIL(filename, function, line, ...) syslog(LOG_NOTICE, __VA_ARGS__) +#define SYSTEM_LOG_INFO(filename, function, line, ...) syslog(LOG_INFO, __VA_ARGS__) +#define SYSTEM_LOG_DEBUG(filename, function, line, ...) syslog(LOG_DEBUG, __VA_ARGS__) + +#endif + namespace { /** @@ -203,25 +228,25 @@ void journaldLogHandler(RIALTO_COMPONENT component, RIALTO_DEBUG_LEVEL level, co switch (level) { case RIALTO_DEBUG_LEVEL_FATAL: - syslog(LOG_CRIT, "%s %s", fbuf, message); + SYSTEM_LOG_FATAL(file, function, line, "%s %s", fbuf, message); break; case RIALTO_DEBUG_LEVEL_ERROR: - syslog(LOG_ERR, "%s %s", fbuf, message); + SYSTEM_LOG_ERROR(file, function, line, "%s %s", fbuf, message); break; case RIALTO_DEBUG_LEVEL_WARNING: - syslog(LOG_WARNING, "%s %s", fbuf, message); + SYSTEM_LOG_WARN(file, function, line, "%s %s", fbuf, message); break; case RIALTO_DEBUG_LEVEL_MILESTONE: - syslog(LOG_NOTICE, "%s %s", fbuf, message); + SYSTEM_LOG_MIL(file, function, line, "%s %s", fbuf, message); break; case RIALTO_DEBUG_LEVEL_INFO: - syslog(LOG_INFO, "%s %s", fbuf, message); + SYSTEM_LOG_INFO(file, function, line, "%s %s", fbuf, message); break; case RIALTO_DEBUG_LEVEL_DEBUG: - syslog(LOG_DEBUG, "%s %s", fbuf, message); + SYSTEM_LOG_DEBUG(file, function, line, "%s %s", fbuf, message); break; case RIALTO_DEBUG_LEVEL_EXTERNAL: - syslog(LOG_INFO, "%s %s", fbuf, message); + SYSTEM_LOG_INFO(file, function, line, "%s %s", fbuf, message); break; default: break; diff --git a/media/client/ipc/CMakeLists.txt b/media/client/ipc/CMakeLists.txt index 9c2db8796..97d09750e 100644 --- a/media/client/ipc/CMakeLists.txt +++ b/media/client/ipc/CMakeLists.txt @@ -55,7 +55,6 @@ target_include_directories ( $ $ $ - $ ) target_link_libraries ( @@ -66,6 +65,6 @@ target_link_libraries ( RialtoIpcCommon RialtoCommon RialtoPlayerCommon - RialtoLogging + RialtoEthanLog RialtoProtobuf ) diff --git a/media/client/ipc/include/MediaPipelineCapabilitiesIpc.h b/media/client/ipc/include/MediaPipelineCapabilitiesIpc.h index 09fedad9f..19b63ee2d 100644 --- a/media/client/ipc/include/MediaPipelineCapabilitiesIpc.h +++ b/media/client/ipc/include/MediaPipelineCapabilitiesIpc.h @@ -92,6 +92,15 @@ class MediaPipelineCapabilitiesIpc : public IMediaPipelineCapabilities, public I std::vector getSupportedProperties(MediaSourceType mediaType, const std::vector &propertyNames) override; + /** + * @brief Checks if the platform is video master. + * + * @param[out] isVideoMaster : The output value. True if video is master otherwise false. + * + * @retval true on success false otherwise + */ + bool isVideoMaster(bool &isVideoMaster) override; + private: /** * @brief The ipc protobuf media Pipeline capabilities stub. diff --git a/media/client/ipc/source/MediaPipelineCapabilitiesIpc.cpp b/media/client/ipc/source/MediaPipelineCapabilitiesIpc.cpp index a866ce98a..68843ee9a 100644 --- a/media/client/ipc/source/MediaPipelineCapabilitiesIpc.cpp +++ b/media/client/ipc/source/MediaPipelineCapabilitiesIpc.cpp @@ -177,4 +177,32 @@ std::vector MediaPipelineCapabilitiesIpc::getSupportedProperties(Me return std::vector{response.supported_properties().begin(), response.supported_properties().end()}; } +bool MediaPipelineCapabilitiesIpc::isVideoMaster(bool &isVideoMaster) +{ + if (!reattachChannelIfRequired()) + { + RIALTO_CLIENT_LOG_ERROR("Reattachment of the ipc channel failed, ipc disconnected"); + return {}; + } + + firebolt::rialto::IsVideoMasterRequest request; + firebolt::rialto::IsVideoMasterResponse response; + auto ipcController = m_ipc.createRpcController(); + auto blockingClosure = m_ipc.createBlockingClosure(); + m_mediaPipelineCapabilitiesStub->isVideoMaster(ipcController.get(), &request, &response, blockingClosure.get()); + + // wait for the call to complete + blockingClosure->wait(); + + // check the result + if (ipcController->Failed()) + { + RIALTO_CLIENT_LOG_ERROR("failed due to '%s'", ipcController->ErrorText().c_str()); + return false; + } + + isVideoMaster = response.is_video_master(); + + return true; +} }; // namespace firebolt::rialto::client diff --git a/media/client/main/CMakeLists.txt b/media/client/main/CMakeLists.txt index d201d84cb..814f717d6 100644 --- a/media/client/main/CMakeLists.txt +++ b/media/client/main/CMakeLists.txt @@ -65,7 +65,6 @@ target_include_directories( $ $ $ - $ ) @@ -83,20 +82,11 @@ target_link_libraries( RialtoPlayerCommon RialtoClientIpcImpl RialtoCommon - RialtoLogging + RialtoEthanLog Threads::Threads ) -if ( COVERAGE_ENABLED ) - target_link_libraries( - RialtoClient - - PRIVATE - gcov - ) -endif() - include( GNUInstallDirs ) diff --git a/media/client/main/include/MediaPipelineCapabilities.h b/media/client/main/include/MediaPipelineCapabilities.h index f4853aff2..ccd36203b 100644 --- a/media/client/main/include/MediaPipelineCapabilities.h +++ b/media/client/main/include/MediaPipelineCapabilities.h @@ -95,6 +95,15 @@ class MediaPipelineCapabilities : public IMediaPipelineCapabilities std::vector getSupportedProperties(MediaSourceType mediaType, const std::vector &propertyNames) override; + /** + * @brief Checks if the platform is video master. + * + * @param[out] isVideoMaster : The output value. True if video is master otherwise false. + * + * @retval true on success false otherwise + */ + bool isVideoMaster(bool &isVideoMaster) override; + private: /** * @brief The media pipeline capabilities ipc object. diff --git a/media/client/main/source/ClientController.cpp b/media/client/main/source/ClientController.cpp index 8c27413e7..eac82154c 100644 --- a/media/client/main/source/ClientController.cpp +++ b/media/client/main/source/ClientController.cpp @@ -257,8 +257,8 @@ void ClientController::changeStateAndNotifyClients(ApplicationState state) std::vector> currentClients; { std::lock_guard lock{m_mutex}; - RIALTO_CLIENT_LOG_INFO("Rialto application state changed from %s to %s", stateToString(m_currentState).c_str(), - stateToString(state).c_str()); + RIALTO_CLIENT_LOG_MIL("Rialto application state changed from %s to %s", stateToString(m_currentState).c_str(), + stateToString(state).c_str()); m_currentState = state; for (const std::weak_ptr &client : m_clients) { diff --git a/media/client/main/source/MediaPipelineCapabilities.cpp b/media/client/main/source/MediaPipelineCapabilities.cpp index e2f4f0431..fdafd2c67 100644 --- a/media/client/main/source/MediaPipelineCapabilities.cpp +++ b/media/client/main/source/MediaPipelineCapabilities.cpp @@ -102,4 +102,10 @@ std::vector MediaPipelineCapabilities::getSupportedProperties(Media return m_mediaPipelineCapabilitiesIpc->getSupportedProperties(mediaType, propertyNames); } +bool MediaPipelineCapabilities::isVideoMaster(bool &isVideoMaster) +{ + RIALTO_CLIENT_LOG_DEBUG("entry:"); + + return m_mediaPipelineCapabilitiesIpc->isVideoMaster(isVideoMaster); +} }; // namespace firebolt::rialto::client diff --git a/media/common/source/MediaFrameWriterV2.cpp b/media/common/source/MediaFrameWriterV2.cpp index c4fc48016..808d0b470 100644 --- a/media/common/source/MediaFrameWriterV2.cpp +++ b/media/common/source/MediaFrameWriterV2.cpp @@ -148,6 +148,10 @@ MediaSegmentMetadata MediaFrameWriterV2::buildMetadata(const std::unique_ptrgetTimeStamp()); metadata.set_sample_duration(data->getDuration()); metadata.set_stream_id(static_cast(data->getId())); + if (data->getDisplayOffset()) + { + metadata.set_display_offset(data->getDisplayOffset().value()); + } if (MediaSourceType::AUDIO == data->getType()) { IMediaPipeline::MediaSegmentAudio &audioSegment = dynamic_cast(*data); diff --git a/media/public/include/IMediaPipeline.h b/media/public/include/IMediaPipeline.h index d63c3cc84..61b992b86 100644 --- a/media/public/include/IMediaPipeline.h +++ b/media/public/include/IMediaPipeline.h @@ -32,6 +32,7 @@ #include #include +#include #include #include @@ -460,7 +461,7 @@ class IMediaPipeline : m_sourceId(sourceId), m_type(type), m_data(nullptr), m_dataLength(0u), m_timeStamp(timeStamp), m_duration(duration), m_encrypted(false), m_mediaKeySessionId(0), m_initWithLast15(0), m_alignment(SegmentAlignment::UNDEFINED), m_cipherMode(CipherMode::UNKNOWN), m_crypt(0), m_skip(0), - m_encryptionPatternSet(false) + m_encryptionPatternSet(false), m_displayOffset(std::nullopt) { } @@ -608,6 +609,13 @@ class IMediaPipeline return m_encryptionPatternSet; } + /** + * @brief Gets the display offset + * + * @retval The offset in the source file of the beginning of the media segment. + */ + std::optional getDisplayOffset() const { return m_displayOffset; } + protected: /** * @brief The source id. @@ -705,6 +713,11 @@ class IMediaPipeline */ bool m_encryptionPatternSet; + /** + * @brief The offset in the source file of the beginning of the media segment. + */ + std::optional m_displayOffset; + public: /** * @brief Sets the segment data. @@ -818,6 +831,13 @@ class IMediaPipeline m_encryptionPatternSet = true; } + /** + * @brief Sets the display offset + * + * @param[in] displayOffset : The offset in the source file of the beginning of the media segment. + */ + void setDisplayOffset(uint64_t displayOffset) { m_displayOffset = displayOffset; } + /** * @brief Copies the data from other to this. */ diff --git a/media/public/include/IMediaPipelineCapabilities.h b/media/public/include/IMediaPipelineCapabilities.h index 3239a61b5..fa0c85628 100644 --- a/media/public/include/IMediaPipelineCapabilities.h +++ b/media/public/include/IMediaPipelineCapabilities.h @@ -107,6 +107,15 @@ class IMediaPipelineCapabilities */ virtual std::vector getSupportedProperties(MediaSourceType mediaType, const std::vector &propertyNames) = 0; + + /** + * @brief Checks if the platform is video master. + * + * @param[out] isVideoMaster : The output value. True if video is master otherwise false. + * + * @retval true on success false otherwise + */ + virtual bool isVideoMaster(bool &isVideoMaster) = 0; }; }; // namespace firebolt::rialto diff --git a/media/server/CMakeLists.txt b/media/server/CMakeLists.txt index ab25f78c7..05d4ec2a2 100644 --- a/media/server/CMakeLists.txt +++ b/media/server/CMakeLists.txt @@ -61,6 +61,7 @@ target_link_libraries( RialtoServerIpc RialtoServerMain RialtoServerService + protobuf::libprotobuf ) if( NATIVE_BUILD ) diff --git a/media/server/gstplayer/include/CapsBuilder.h b/media/server/gstplayer/include/CapsBuilder.h index a8ff38a79..283f7ac04 100644 --- a/media/server/gstplayer/include/CapsBuilder.h +++ b/media/server/gstplayer/include/CapsBuilder.h @@ -61,7 +61,8 @@ class MediaSourceAudioCapsBuilder : public MediaSourceCapsBuilder GstCaps *createOpusCaps(); GstCaps *getAudioSpecificConfiguration() const; void addSampleRateAndChannelsToCaps(GstCaps *caps) const; - void addMpegVersionToCaps(GstCaps *caps) const; + void addMpegVersion4ToCaps(GstCaps *caps) const; + void addMp3Caps(GstCaps *caps) const; void addRawAudioData(GstCaps *caps) const; void addFlacSpecificData(GstCaps *caps) const; diff --git a/media/server/gstplayer/include/FlushWatcher.h b/media/server/gstplayer/include/FlushWatcher.h index ce51d7b3a..5a43b5ded 100644 --- a/media/server/gstplayer/include/FlushWatcher.h +++ b/media/server/gstplayer/include/FlushWatcher.h @@ -21,8 +21,8 @@ #define FIREBOLT_RIALTO_SERVER_FLUSH_WATCHER_H_ #include "IFlushWatcher.h" +#include #include -#include namespace firebolt::rialto::server { @@ -32,13 +32,14 @@ class FlushWatcher : public IFlushWatcher FlushWatcher() = default; ~FlushWatcher() override = default; - void setFlushing(const MediaSourceType &type) override; + void setFlushing(const MediaSourceType &type, bool async) override; void setFlushed(const MediaSourceType &type) override; bool isFlushOngoing() const override; + bool isAsyncFlushOngoing() const override; private: mutable std::mutex m_mutex; - std::set m_flushingSources; + std::map m_flushingSources; }; } // namespace firebolt::rialto::server #endif // FIREBOLT_RIALTO_SERVER_FLUSH_WATCHER_H_ diff --git a/media/server/gstplayer/include/GenericPlayerContext.h b/media/server/gstplayer/include/GenericPlayerContext.h index 71383ead0..59187c865 100644 --- a/media/server/gstplayer/include/GenericPlayerContext.h +++ b/media/server/gstplayer/include/GenericPlayerContext.h @@ -179,6 +179,11 @@ struct GenericPlayerContext */ bool pendingRenderFrame{false}; + /** + * @brief Pending show video window + */ + std::optional pendingShowVideoWindow{}; + /** * @brief Last audio sample timestamps * TODO(LLDEV-31012) Needed to detect audio stream underflow diff --git a/media/server/gstplayer/include/GstCapabilities.h b/media/server/gstplayer/include/GstCapabilities.h index 57668fedd..742fc565f 100644 --- a/media/server/gstplayer/include/GstCapabilities.h +++ b/media/server/gstplayer/include/GstCapabilities.h @@ -95,6 +95,15 @@ class GstCapabilities : public IGstCapabilities std::vector getSupportedProperties(MediaSourceType mediaType, const std::vector &propertyNames) override; + /** + * @brief Checks if the platform is video master. + * + * @param[out] isVideoMaster : The output value. True if video is master otherwise false. + * + * @retval true on success false otherwise + */ + bool isVideoMaster(bool &isVideoMaster) override; + private: /** * @brief Sets list of supported mime types diff --git a/media/server/gstplayer/include/GstGenericPlayer.h b/media/server/gstplayer/include/GstGenericPlayer.h index bf4da0b1b..91548b7bb 100644 --- a/media/server/gstplayer/include/GstGenericPlayer.h +++ b/media/server/gstplayer/include/GstGenericPlayer.h @@ -124,7 +124,6 @@ class GstGenericPlayer : public IGstGenericPlayer, public IGstGenericPlayerPriva bool getVolume(double &volume) override; void setMute(const MediaSourceType &mediaSourceType, bool mute) override; bool getMute(const MediaSourceType &mediaSourceType, bool &mute) override; - bool isAsync(const MediaSourceType &mediaSourceType) const override; void setTextTrackIdentifier(const std::string &textTrackIdentifier) override; bool getTextTrackIdentifier(std::string &textTrackIdentifier) override; bool setLowLatency(bool lowLatency) override; @@ -134,7 +133,7 @@ class GstGenericPlayer : public IGstGenericPlayer, public IGstGenericPlayerPriva bool setStreamSyncMode(const MediaSourceType &mediaSourceType, int32_t streamSyncMode) override; bool getStreamSyncMode(int32_t &streamSyncMode) override; void ping(std::unique_ptr &&heartbeatHandler) override; - void flush(const MediaSourceType &mediaSourceType, bool resetTime) override; + void flush(const MediaSourceType &mediaSourceType, bool resetTime, bool &async) override; void setSourcePosition(const MediaSourceType &mediaSourceType, int64_t position, bool resetTime, double appliedRate, uint64_t stopPosition) override; void processAudioGap(int64_t position, uint32_t duration, int64_t discontinuityGap, bool audioAac) override; @@ -152,6 +151,7 @@ class GstGenericPlayer : public IGstGenericPlayer, public IGstGenericPlayerPriva void scheduleAllSourcesAttached() override; bool setVideoSinkRectangle() override; bool setImmediateOutput() override; + bool setShowVideoWindow() override; bool setLowLatency() override; bool setSync() override; bool setSyncOff() override; @@ -185,6 +185,7 @@ class GstGenericPlayer : public IGstGenericPlayer, public IGstGenericPlayerPriva bool reattachSource(const std::unique_ptr &source) override; GstElement *getSink(const MediaSourceType &mediaSourceType) const override; void setSourceFlushed(const MediaSourceType &mediaSourceType) override; + bool isAsync(const MediaSourceType &mediaSourceType) const; private: /** diff --git a/media/server/gstplayer/include/GstInitialiser.h b/media/server/gstplayer/include/GstInitialiser.h index 58dad9de0..cab3a9a6c 100644 --- a/media/server/gstplayer/include/GstInitialiser.h +++ b/media/server/gstplayer/include/GstInitialiser.h @@ -21,7 +21,9 @@ #define FIREBOLT_RIALTO_SERVER_GST_INITIALISER_H_ #include "IGstInitialiser.h" +#include "IGstWrapper.h" #include +#include #include #include @@ -41,6 +43,7 @@ class GstInitialiser : public IGstInitialiser mutable std::mutex m_mutex; mutable std::condition_variable m_cv; std::thread m_thread; + std::shared_ptr m_gstWrapper; }; }; // namespace firebolt::rialto::server diff --git a/media/server/gstplayer/include/GstMimeMapping.h b/media/server/gstplayer/include/GstMimeMapping.h index 620136600..b8d515312 100644 --- a/media/server/gstplayer/include/GstMimeMapping.h +++ b/media/server/gstplayer/include/GstMimeMapping.h @@ -46,21 +46,15 @@ namespace firebolt::rialto::server inline GstCaps *createSimpleCapsFromMimeType(std::shared_ptr m_gstWrapper, const IMediaPipeline::MediaSource &m_attachedSource) { - static const std::unordered_map mimeToMediaType = {{"video/h264", "video/x-h264"}, - {"video/h265", "video/x-h265"}, - {"video/x-av1", "video/x-av1"}, - {"video/x-vp9", "video/x-vp9"}, - {"video/mp4", "video/mpeg"}, - {"audio/mp4", "audio/mpeg"}, - {"audio/aac", "audio/mpeg"}, - {"audio/x-eac3", "audio/x-eac3"}, - {"audio/x-opus", "audio/x-opus"}, - {"audio/b-wav", "audio/b-wav"}, - {"audio/x-raw", "audio/x-raw"}, - {"audio/x-flac", "audio/x-flac"}, - {"text/vtt", - "application/x-subtitle-vtt"}, - {"text/ttml", "application/ttml+xml"}}; + static const std::unordered_map mimeToMediaType = + {{"video/h264", "video/x-h264"}, {"video/h265", "video/x-h265"}, + {"video/x-av1", "video/x-av1"}, {"video/x-vp9", "video/x-vp9"}, + {"video/mp4", "video/mpeg"}, {"audio/mp4", "audio/mpeg"}, + {"audio/mp3", "audio/mpeg"}, {"audio/aac", "audio/mpeg"}, + {"audio/x-eac3", "audio/x-eac3"}, {"audio/x-opus", "audio/x-opus"}, + {"audio/b-wav", "audio/b-wav"}, {"audio/x-raw", "audio/x-raw"}, + {"audio/x-flac", "audio/x-flac"}, {"text/vtt", "application/x-subtitle-vtt"}, + {"text/ttml", "application/ttml+xml"}}; auto mimeToMediaTypeIt = mimeToMediaType.find(m_attachedSource.getMimeType()); if (mimeToMediaTypeIt != mimeToMediaType.end()) { @@ -85,6 +79,7 @@ convertFromCapsVectorToMimeSet(const std::vector &supportedCaps, { std::vector>> capsToMimeVec = {{m_gstWrapper->gstCapsFromString("audio/mpeg, mpegversion=(int)4"), {"audio/mp4", "audio/aac", "audio/x-eac3"}}, + {m_gstWrapper->gstCapsFromString("audio/mpeg, mpegversion=(int)1, layer=(int)3"), {"audio/mp3"}}, {m_gstWrapper->gstCapsFromString("audio/x-eac3"), {"audio/x-eac3"}}, {m_gstWrapper->gstCapsFromString("audio/b-wav"), {"audio/b-wav"}}, {m_gstWrapper->gstCapsFromString("audio/x-raw"), {"audio/x-raw"}}, diff --git a/media/server/gstplayer/include/GstSrc.h b/media/server/gstplayer/include/GstSrc.h index 968f888ce..84f8f19de 100644 --- a/media/server/gstplayer/include/GstSrc.h +++ b/media/server/gstplayer/include/GstSrc.h @@ -122,7 +122,7 @@ class GstSrc : public IGstSrc void initSrc() override; - void setupAndAddAppArc(IDecryptionService *decryptionService, GstElement *source, StreamInfo &streamInfo, + void setupAndAddAppSrc(IDecryptionService *decryptionService, GstElement *source, StreamInfo &streamInfo, GstAppSrcCallbacks *callbacks, gpointer userData, firebolt::rialto::MediaSourceType type) override; diff --git a/media/server/gstplayer/include/IFlushWatcher.h b/media/server/gstplayer/include/IFlushWatcher.h index 7f6686bcf..e1386a7e6 100644 --- a/media/server/gstplayer/include/IFlushWatcher.h +++ b/media/server/gstplayer/include/IFlushWatcher.h @@ -29,9 +29,10 @@ class IFlushWatcher public: virtual ~IFlushWatcher() = default; - virtual void setFlushing(const MediaSourceType &type) = 0; + virtual void setFlushing(const MediaSourceType &type, bool async) = 0; virtual void setFlushed(const MediaSourceType &type) = 0; virtual bool isFlushOngoing() const = 0; + virtual bool isAsyncFlushOngoing() const = 0; }; } // namespace firebolt::rialto::server #endif // FIREBOLT_RIALTO_SERVER_I_FLUSH_WATCHER_H_ diff --git a/media/server/gstplayer/include/IGstGenericPlayerPrivate.h b/media/server/gstplayer/include/IGstGenericPlayerPrivate.h index 8df30e1a4..056f5177c 100644 --- a/media/server/gstplayer/include/IGstGenericPlayerPrivate.h +++ b/media/server/gstplayer/include/IGstGenericPlayerPrivate.h @@ -129,6 +129,13 @@ class IGstGenericPlayerPrivate */ virtual bool setUseBuffering() = 0; + /** + * @brief Sets Show Video Window property. Called by the worker thread. + * + * @retval true on success. + */ + virtual bool setShowVideoWindow() = 0; + /** * @brief Sends NeedMediaData notification. Called by the worker thread. */ diff --git a/media/server/gstplayer/include/IGstSrc.h b/media/server/gstplayer/include/IGstSrc.h index 0a83e2cac..76325e5e7 100644 --- a/media/server/gstplayer/include/IGstSrc.h +++ b/media/server/gstplayer/include/IGstSrc.h @@ -106,7 +106,7 @@ class IGstSrc * @param[in] userData : Data to be passed to the callbacks. * @param[in] type : The media type of the source. */ - virtual void setupAndAddAppArc(IDecryptionService *decryptionService, GstElement *source, StreamInfo &streamInfo, + virtual void setupAndAddAppSrc(IDecryptionService *decryptionService, GstElement *source, StreamInfo &streamInfo, GstAppSrcCallbacks *callbacks, gpointer userData, firebolt::rialto::MediaSourceType type) = 0; diff --git a/media/server/gstplayer/include/tasks/IGenericPlayerTaskFactory.h b/media/server/gstplayer/include/tasks/IGenericPlayerTaskFactory.h index 1544587e9..ea91604e2 100644 --- a/media/server/gstplayer/include/tasks/IGenericPlayerTaskFactory.h +++ b/media/server/gstplayer/include/tasks/IGenericPlayerTaskFactory.h @@ -22,6 +22,7 @@ #include "GenericPlayerContext.h" #include "IDataReader.h" +#include "IFlushWatcher.h" #include "IGstGenericPlayerPrivate.h" #include "IHeartbeatHandler.h" #include "IMediaPipeline.h" @@ -119,16 +120,16 @@ class IGenericPlayerTaskFactory /** * @brief Creates a HandleBusMessage task. * - * @param[in] context : The GstGenericPlayer context - * @param[in] player : The GstGenericPlayer instance - * @param[in] message : The message to be handled. - * @param[in] isFlushing : Current flushing state. True if flush for any source is queued + * @param[in] context : The GstGenericPlayer context + * @param[in] player : The GstGenericPlayer instance + * @param[in] message : The message to be handled. + * @param[in] flushWatcher : Flush watcher instance * * @retval the new HandleBusMessage task instance. */ virtual std::unique_ptr createHandleBusMessage(GenericPlayerContext &context, IGstGenericPlayerPrivate &player, GstMessage *message, - bool isFlushing) const = 0; + const IFlushWatcher &flushWatcher) const = 0; /** * @brief Creates a NeedData task. diff --git a/media/server/gstplayer/include/tasks/generic/GenericPlayerTaskFactory.h b/media/server/gstplayer/include/tasks/generic/GenericPlayerTaskFactory.h index a9bc236fd..be72f5136 100644 --- a/media/server/gstplayer/include/tasks/generic/GenericPlayerTaskFactory.h +++ b/media/server/gstplayer/include/tasks/generic/GenericPlayerTaskFactory.h @@ -55,7 +55,8 @@ class GenericPlayerTaskFactory : public IGenericPlayerTaskFactory std::unique_ptr createFinishSetupSource(GenericPlayerContext &context, IGstGenericPlayerPrivate &player) const override; std::unique_ptr createHandleBusMessage(GenericPlayerContext &context, IGstGenericPlayerPrivate &player, - GstMessage *message, bool isFlushing) const override; + GstMessage *message, + const IFlushWatcher &flushWatcher) const override; std::unique_ptr createNeedData(GenericPlayerContext &context, IGstGenericPlayerPrivate &player, GstAppSrc *src) const override; std::unique_ptr createPause(GenericPlayerContext &context, diff --git a/media/server/gstplayer/include/tasks/generic/HandleBusMessage.h b/media/server/gstplayer/include/tasks/generic/HandleBusMessage.h index cec810699..0db969cf4 100644 --- a/media/server/gstplayer/include/tasks/generic/HandleBusMessage.h +++ b/media/server/gstplayer/include/tasks/generic/HandleBusMessage.h @@ -21,6 +21,7 @@ #define FIREBOLT_RIALTO_SERVER_TASKS_GENERIC_HANDLE_BUS_MESSAGE_H_ #include "GenericPlayerContext.h" +#include "IFlushWatcher.h" #include "IGlibWrapper.h" #include "IGstGenericPlayerClient.h" #include "IGstGenericPlayerPrivate.h" @@ -35,9 +36,9 @@ class HandleBusMessage : public IPlayerTask { public: HandleBusMessage(GenericPlayerContext &context, IGstGenericPlayerPrivate &player, IGstGenericPlayerClient *client, - std::shared_ptr gstWrapper, - std::shared_ptr glibWrapper, GstMessage *message, - bool isFlushOngoing); + const std::shared_ptr &gstWrapper, + const std::shared_ptr &glibWrapper, GstMessage *message, + const IFlushWatcher &flushWatcher); ~HandleBusMessage() override; void execute() const override; @@ -50,7 +51,9 @@ class HandleBusMessage : public IPlayerTask std::shared_ptr m_gstWrapper; std::shared_ptr m_glibWrapper; GstMessage *m_message; - bool m_isFlushOngoing; + const IFlushWatcher &m_flushWatcher; + bool m_isFlushOngoingDuringCreation; + bool m_isAsyncFlushOngoingDuringCreation; }; } // namespace firebolt::rialto::server::tasks::generic diff --git a/media/server/gstplayer/interface/IGstCapabilities.h b/media/server/gstplayer/interface/IGstCapabilities.h index 2b9dbc5f8..68e09865b 100644 --- a/media/server/gstplayer/interface/IGstCapabilities.h +++ b/media/server/gstplayer/interface/IGstCapabilities.h @@ -89,6 +89,15 @@ class IGstCapabilities */ virtual std::vector getSupportedProperties(MediaSourceType mediaType, const std::vector &propertyNames) = 0; + + /** + * @brief Checks if the platform is video master. + * + * @param[out] isVideoMaster : The output value. True if video is master otherwise false. + * + * @retval true on success false otherwise + */ + virtual bool isVideoMaster(bool &isVideoMaster) = 0; }; }; // namespace firebolt::rialto::server diff --git a/media/server/gstplayer/interface/IGstGenericPlayer.h b/media/server/gstplayer/interface/IGstGenericPlayer.h index 9c11c07ef..a6c9532bf 100644 --- a/media/server/gstplayer/interface/IGstGenericPlayer.h +++ b/media/server/gstplayer/interface/IGstGenericPlayer.h @@ -275,15 +275,6 @@ class IGstGenericPlayer */ virtual bool getMute(const MediaSourceType &mediaSourceType, bool &mute) = 0; - /** - * @brief Checks if given source is asyncronous - * - * @param[in] mediaSourceType : The media source type - * - * @retval True if source is asynchronous. - */ - virtual bool isAsync(const MediaSourceType &mediaSourceType) const = 0; - /** * @brief Change Text Track Identifier * @@ -370,9 +361,10 @@ class IGstGenericPlayer * * @param[in] mediaSourceType : The media source type to flush. * @param[in] resetTime : True if time should be reset + * @param[out] async : True if flushed source is asynchronous (will preroll after flush) * */ - virtual void flush(const MediaSourceType &mediaSourceType, bool resetTime) = 0; + virtual void flush(const MediaSourceType &mediaSourceType, bool resetTime, bool &async) = 0; /** * @brief Set the source position in nanoseconds. diff --git a/media/server/gstplayer/source/CapsBuilder.cpp b/media/server/gstplayer/source/CapsBuilder.cpp index 4294fc8f8..4491b3656 100644 --- a/media/server/gstplayer/source/CapsBuilder.cpp +++ b/media/server/gstplayer/source/CapsBuilder.cpp @@ -109,7 +109,11 @@ GstCaps *MediaSourceAudioCapsBuilder::buildCaps() GstCaps *caps = MediaSourceCapsBuilder::buildCaps(); if (mimeType == "audio/mp4" || mimeType == "audio/aac") { - addMpegVersionToCaps(caps); + addMpegVersion4ToCaps(caps); + } + else if (mimeType == "audio/mp3") + { + addMp3Caps(caps); } else if (mimeType == "audio/b-wav" || mimeType == "audio/x-raw") { @@ -166,11 +170,17 @@ void MediaSourceAudioCapsBuilder::addSampleRateAndChannelsToCaps(GstCaps *caps) m_gstWrapper->gstCapsSetSimple(caps, "rate", G_TYPE_INT, audioConfig.sampleRate, nullptr); } -void MediaSourceAudioCapsBuilder::addMpegVersionToCaps(GstCaps *caps) const +void MediaSourceAudioCapsBuilder::addMpegVersion4ToCaps(GstCaps *caps) const { m_gstWrapper->gstCapsSetSimple(caps, "mpegversion", G_TYPE_INT, 4, nullptr); } +void MediaSourceAudioCapsBuilder::addMp3Caps(GstCaps *caps) const +{ + m_gstWrapper->gstCapsSetSimple(caps, "mpegversion", G_TYPE_INT, 1, nullptr); + m_gstWrapper->gstCapsSetSimple(caps, "layer", G_TYPE_INT, 3, nullptr); +} + void MediaSourceAudioCapsBuilder::addRawAudioData(GstCaps *caps) const { firebolt::rialto::AudioConfig audioConfig = m_attachedAudioSource.getAudioConfig(); diff --git a/media/server/gstplayer/source/FlushWatcher.cpp b/media/server/gstplayer/source/FlushWatcher.cpp index 203873f6e..5918b6e25 100644 --- a/media/server/gstplayer/source/FlushWatcher.cpp +++ b/media/server/gstplayer/source/FlushWatcher.cpp @@ -18,15 +18,16 @@ */ #include "FlushWatcher.h" +#include namespace firebolt::rialto::server { -void FlushWatcher::setFlushing(const MediaSourceType &type) +void FlushWatcher::setFlushing(const MediaSourceType &type, bool async) { std::unique_lock lock{m_mutex}; if (MediaSourceType::UNKNOWN != type) { - m_flushingSources.insert(type); + m_flushingSources[type] = async; } } @@ -41,4 +42,11 @@ bool FlushWatcher::isFlushOngoing() const std::unique_lock lock{m_mutex}; return !m_flushingSources.empty(); } + +bool FlushWatcher::isAsyncFlushOngoing() const +{ + std::unique_lock lock{m_mutex}; + return !m_flushingSources.empty() && std::any_of(m_flushingSources.begin(), m_flushingSources.end(), + [](const auto &source) { return source.second; }); +} } // namespace firebolt::rialto::server diff --git a/media/server/gstplayer/source/GstCapabilities.cpp b/media/server/gstplayer/source/GstCapabilities.cpp index d0080d3b4..b4d96e32f 100644 --- a/media/server/gstplayer/source/GstCapabilities.cpp +++ b/media/server/gstplayer/source/GstCapabilities.cpp @@ -439,6 +439,26 @@ void GstCapabilities::waitForInitialisation() m_initialisationCv.wait(lock, [this]() { return m_isInitialised; }); } +bool GstCapabilities::isVideoMaster(bool &isVideoMaster) +{ + waitForInitialisation(); + + GstRegistry *reg = m_gstWrapper->gstRegistryGet(); + if (!reg) + { + RIALTO_SERVER_LOG_ERROR("Failed get the gst registry"); + return false; + } + GstPluginFeature *feature{nullptr}; + isVideoMaster = true; + if (nullptr != (feature = m_gstWrapper->gstRegistryLookupFeature(reg, "amlhalasink"))) + { + isVideoMaster = false; + m_gstWrapper->gstObjectUnref(feature); + } + return true; +} + } // namespace firebolt::rialto::server // namespace firebolt::rialto::server diff --git a/media/server/gstplayer/source/GstGenericPlayer.cpp b/media/server/gstplayer/source/GstGenericPlayer.cpp index 2dff7b4b0..1e6f9f0f7 100644 --- a/media/server/gstplayer/source/GstGenericPlayer.cpp +++ b/media/server/gstplayer/source/GstGenericPlayer.cpp @@ -243,6 +243,7 @@ void GstGenericPlayer::initMsePipeline() { GST_WARNING("No playsink ?!?!?"); } + RIALTO_SERVER_LOG_MIL("New RialtoServer's pipeline created"); } void GstGenericPlayer::resetWorkerThread() @@ -289,6 +290,8 @@ void GstGenericPlayer::termPipeline() // Delete the pipeline m_gstWrapper->gstObjectUnref(m_context.pipeline); + + RIALTO_SERVER_LOG_MIL("RialtoServer's pipeline terminated"); } unsigned GstGenericPlayer::getGstPlayFlag(const char *nick) @@ -395,6 +398,7 @@ bool GstGenericPlayer::getPosition(std::int64_t &position) } if (!m_gstWrapper->gstElementQueryPosition(m_context.pipeline, GST_FORMAT_TIME, &position)) { + RIALTO_SERVER_LOG_WARN("Query position failed"); return false; } return true; @@ -811,6 +815,7 @@ void GstGenericPlayer::attachData(const firebolt::rialto::MediaSourceType mediaT { m_context.bufferedNotificationSent = true; m_gstPlayerClient->notifyNetworkState(NetworkState::BUFFERED); + RIALTO_SERVER_LOG_MIL("Buffered NetworkState reached"); } cancelUnderflow(mediaType); @@ -1010,6 +1015,8 @@ void GstGenericPlayer::setTextTrackPositionIfRequired(GstElement *source) return; } + RIALTO_SERVER_LOG_MIL("New subtitle position set %" GST_TIME_FORMAT, + GST_TIME_ARGS(initialPosition->second.back().position)); m_glibWrapper->gObjectSet(m_context.subtitleSink, "position", static_cast(initialPosition->second.back().position), nullptr); @@ -1258,6 +1265,35 @@ bool GstGenericPlayer::setImmediateOutput() return result; } +bool GstGenericPlayer::setShowVideoWindow() +{ + if (!m_context.pendingShowVideoWindow.has_value()) + { + RIALTO_SERVER_LOG_WARN("No show video window value to be set. Aborting..."); + return false; + } + + GstElement *videoSink{getSink(MediaSourceType::VIDEO)}; + if (!videoSink) + { + RIALTO_SERVER_LOG_DEBUG("Setting show video window queued. Video sink is NULL"); + return false; + } + bool result{false}; + if (m_glibWrapper->gObjectClassFindProperty(G_OBJECT_GET_CLASS(videoSink), "show-video-window")) + { + m_glibWrapper->gObjectSet(videoSink, "show-video-window", m_context.pendingShowVideoWindow.value(), nullptr); + result = true; + } + else + { + RIALTO_SERVER_LOG_ERROR("Setting show video window failed. Property does not exist"); + } + m_context.pendingShowVideoWindow.reset(); + m_gstWrapper->gstObjectUnref(GST_OBJECT(videoSink)); + return result; +} + bool GstGenericPlayer::setLowLatency() { bool result{false}; @@ -1881,11 +1917,12 @@ void GstGenericPlayer::ping(std::unique_ptr &&heartbeatHandle } } -void GstGenericPlayer::flush(const MediaSourceType &mediaSourceType, bool resetTime) +void GstGenericPlayer::flush(const MediaSourceType &mediaSourceType, bool resetTime, bool &async) { if (m_workerThread) { - m_flushWatcher->setFlushing(mediaSourceType); + async = isAsync(mediaSourceType); + m_flushWatcher->setFlushing(mediaSourceType, async); m_workerThread->enqueueTask(m_taskFactory->createFlush(m_context, *this, mediaSourceType, resetTime)); } } @@ -1986,8 +2023,7 @@ void GstGenericPlayer::switchSource(const std::unique_ptrenqueueTask( - m_taskFactory->createHandleBusMessage(m_context, *this, message, m_flushWatcher->isFlushOngoing())); + m_workerThread->enqueueTask(m_taskFactory->createHandleBusMessage(m_context, *this, message, *m_flushWatcher)); } void GstGenericPlayer::updatePlaybackGroup(GstElement *typefind, const GstCaps *caps) diff --git a/media/server/gstplayer/source/GstInitialiser.cpp b/media/server/gstplayer/source/GstInitialiser.cpp index b43b2d506..b701ed318 100644 --- a/media/server/gstplayer/source/GstInitialiser.cpp +++ b/media/server/gstplayer/source/GstInitialiser.cpp @@ -19,7 +19,6 @@ #include "GstInitialiser.h" #include "GstLogForwarding.h" -#include "IGstWrapper.h" #include "RialtoServerLogging.h" namespace firebolt::rialto::server @@ -30,6 +29,14 @@ GstInitialiser::~GstInitialiser() { m_thread.join(); } + +#ifdef FREE_MEM_BEFORE_EXIT + if (m_gstWrapper) + { + m_gstWrapper->gstDeinit(); + m_gstWrapper.reset(); + } +#endif } IGstInitialiser &IGstInitialiser::instance() @@ -51,22 +58,23 @@ void GstInitialiser::initialise(int *argc, char ***argv) { std::shared_ptr factory = firebolt::rialto::wrappers::IGstWrapperFactory::getFactory(); - std::shared_ptr gstWrapper = factory->getGstWrapper(); + m_gstWrapper = factory->getGstWrapper(); - if (!gstWrapper) + if (!m_gstWrapper) { RIALTO_SERVER_LOG_ERROR("Failed to create the gst wrapper"); return; } - gstWrapper->gstInit(argc, argv); + m_gstWrapper->gstInit(argc, argv); // remove rialto sinks from the registry - GstPlugin *rialtoPlugin = gstWrapper->gstRegistryFindPlugin(gstWrapper->gstRegistryGet(), "rialtosinks"); + GstPlugin *rialtoPlugin = + m_gstWrapper->gstRegistryFindPlugin(m_gstWrapper->gstRegistryGet(), "rialtosinks"); if (rialtoPlugin) { - gstWrapper->gstRegistryRemovePlugin(gstWrapper->gstRegistryGet(), rialtoPlugin); - gstWrapper->gstObjectUnref(rialtoPlugin); + m_gstWrapper->gstRegistryRemovePlugin(m_gstWrapper->gstRegistryGet(), rialtoPlugin); + m_gstWrapper->gstObjectUnref(rialtoPlugin); } enableGstLogForwarding(); diff --git a/media/server/gstplayer/source/GstSrc.cpp b/media/server/gstplayer/source/GstSrc.cpp index c8e753d09..d570ba671 100644 --- a/media/server/gstplayer/source/GstSrc.cpp +++ b/media/server/gstplayer/source/GstSrc.cpp @@ -389,7 +389,7 @@ void GstSrc::setDefaultStreamFormatIfNeeded(GstElement *appSrc) m_gstWrapper->gstCapsUnref(currentCaps); } -void GstSrc::setupAndAddAppArc(IDecryptionService *decryptionService, GstElement *source, StreamInfo &streamInfo, +void GstSrc::setupAndAddAppSrc(IDecryptionService *decryptionService, GstElement *source, StreamInfo &streamInfo, GstAppSrcCallbacks *callbacks, gpointer userData, firebolt::rialto::MediaSourceType type) { // Configure and add appsrc diff --git a/media/server/gstplayer/source/GstTextTrackSink.cpp b/media/server/gstplayer/source/GstTextTrackSink.cpp index 543947159..7e4d8db7e 100644 --- a/media/server/gstplayer/source/GstTextTrackSink.cpp +++ b/media/server/gstplayer/source/GstTextTrackSink.cpp @@ -188,7 +188,12 @@ static GstFlowReturn gst_rialto_text_track_sink_render(GstBaseSink *sink, GstBuf if (gst_buffer_map(buffer, &info, GST_MAP_READ)) { std::string data(reinterpret_cast(info.data), info.size); - textTrackSink->priv->m_textTrackSession->sendData(data); + int64_t displayOffset{0}; + if (GST_BUFFER_OFFSET_NONE != GST_BUFFER_OFFSET(buffer)) + { + displayOffset = static_cast(GST_BUFFER_OFFSET(buffer)); + } + textTrackSink->priv->m_textTrackSession->sendData(data, 0 - displayOffset); gst_buffer_unmap(buffer, &info); } diff --git a/media/server/gstplayer/source/GstWebAudioPlayer.cpp b/media/server/gstplayer/source/GstWebAudioPlayer.cpp index 7a632bb4c..ef6aa666a 100644 --- a/media/server/gstplayer/source/GstWebAudioPlayer.cpp +++ b/media/server/gstplayer/source/GstWebAudioPlayer.cpp @@ -154,6 +154,8 @@ bool GstWebAudioPlayer::initWebAudioPipeline(const uint32_t priority) return false; } + RIALTO_SERVER_LOG_MIL("RialtoServer's webaudio pipeline constructed"); + // Create and initalise appsrc m_context.source = m_gstWrapper->gstElementFactoryMake("appsrc", "audsrc"); if (!m_context.source) @@ -255,6 +257,7 @@ bool GstWebAudioPlayer::linkElementsToSrc(GstElement *sink) GstElement *convert{nullptr}; GstElement *resample{nullptr}; GstElement *volume{nullptr}; + GstElement *queue{nullptr}; convert = m_gstWrapper->gstElementFactoryMake("audioconvert", NULL); if (!convert) @@ -282,6 +285,20 @@ bool GstWebAudioPlayer::linkElementsToSrc(GstElement *sink) status = false; } } + if (status) + { + queue = m_gstWrapper->gstElementFactoryMake("queue", NULL); + if (!queue) + { + RIALTO_SERVER_LOG_ERROR("Failed create the queue"); + status = false; + } + else + { + constexpr guint kWebAudioQueueSize{8192}; + m_glibWrapper->gObjectSet(queue, "max-size-bytes", kWebAudioQueueSize, nullptr); + } + } std::queue elementsToAdd; elementsToAdd.push(m_context.source); @@ -291,6 +308,8 @@ bool GstWebAudioPlayer::linkElementsToSrc(GstElement *sink) elementsToAdd.push(resample); if (volume) elementsToAdd.push(volume); + if (queue) + elementsToAdd.push(queue); elementsToAdd.push(sink); if (status) @@ -314,7 +333,7 @@ bool GstWebAudioPlayer::linkElementsToSrc(GstElement *sink) { if ((!m_gstWrapper->gstElementLink(m_context.source, convert)) || (!m_gstWrapper->gstElementLink(convert, resample)) || (!m_gstWrapper->gstElementLink(resample, volume)) || - (!m_gstWrapper->gstElementLink(volume, sink))) + (!m_gstWrapper->gstElementLink(volume, queue)) || (!m_gstWrapper->gstElementLink(queue, sink))) { RIALTO_SERVER_LOG_ERROR("Failed to link elements"); status = false; @@ -350,6 +369,7 @@ void GstWebAudioPlayer::termWebAudioPipeline() m_gstWrapper->gstObjectUnref(m_context.pipeline); } + RIALTO_SERVER_LOG_MIL("RialtoServer's webaudio pipeline terminated."); } void GstWebAudioPlayer::resetWorkerThread() diff --git a/media/server/gstplayer/source/tasks/generic/AttachSource.cpp b/media/server/gstplayer/source/tasks/generic/AttachSource.cpp index 567d26e70..f65daa212 100644 --- a/media/server/gstplayer/source/tasks/generic/AttachSource.cpp +++ b/media/server/gstplayer/source/tasks/generic/AttachSource.cpp @@ -77,21 +77,21 @@ void AttachSource::addSource() const RIALTO_SERVER_LOG_ERROR("Failed to create caps from media source"); return; } - + gchar *capsStr = m_gstWrapper->gstCapsToString(caps); GstElement *appSrc = nullptr; if (m_attachedSource->getType() == MediaSourceType::AUDIO) { - RIALTO_SERVER_LOG_MIL("Adding Audio appsrc"); + RIALTO_SERVER_LOG_MIL("Adding Audio appsrc with caps %s", capsStr); appSrc = m_gstWrapper->gstElementFactoryMake("appsrc", "audsrc"); } else if (m_attachedSource->getType() == MediaSourceType::VIDEO) { - RIALTO_SERVER_LOG_MIL("Adding Video appsrc"); + RIALTO_SERVER_LOG_MIL("Adding Video appsrc with caps %s", capsStr); appSrc = m_gstWrapper->gstElementFactoryMake("appsrc", "vidsrc"); } else if (m_attachedSource->getType() == MediaSourceType::SUBTITLE) { - RIALTO_SERVER_LOG_MIL("Adding Subtitle appsrc"); + RIALTO_SERVER_LOG_MIL("Adding Subtitle appsrc with caps %s", capsStr); appSrc = m_gstWrapper->gstElementFactoryMake("appsrc", "subsrc"); if (m_glibWrapper->gObjectClassFindProperty(G_OBJECT_GET_CLASS(m_context.pipeline), "text-sink")) @@ -102,6 +102,7 @@ void AttachSource::addSource() const m_glibWrapper->gObjectSet(m_context.pipeline, "text-sink", elem, nullptr); } } + m_glibWrapper->gFree(capsStr); m_gstWrapper->gstAppSrcSetCaps(GST_APP_SRC(appSrc), caps); m_context.streamInfo.emplace(m_attachedSource->getType(), StreamInfo{appSrc, m_attachedSource->getHasDrm()}); @@ -124,5 +125,7 @@ void AttachSource::reattachAudioSource() const m_context.streamInfo[m_attachedSource->getType()].isDataNeeded = true; m_context.audioSourceRemoved = false; m_player.notifyNeedMediaData(MediaSourceType::AUDIO); + + RIALTO_SERVER_LOG_MIL("Audio source reattached"); } } // namespace firebolt::rialto::server::tasks::generic diff --git a/media/server/gstplayer/source/tasks/generic/FinishSetupSource.cpp b/media/server/gstplayer/source/tasks/generic/FinishSetupSource.cpp index f7e46621a..32d539a56 100644 --- a/media/server/gstplayer/source/tasks/generic/FinishSetupSource.cpp +++ b/media/server/gstplayer/source/tasks/generic/FinishSetupSource.cpp @@ -109,7 +109,7 @@ void FinishSetupSource::execute() const } StreamInfo &streamInfo = elem.second; - m_context.gstSrc->setupAndAddAppArc(m_context.decryptionService, m_context.source, streamInfo, &callbacks, + m_context.gstSrc->setupAndAddAppSrc(m_context.decryptionService, m_context.source, streamInfo, &callbacks, &m_player, sourceType); m_player.notifyNeedMediaData(sourceType); } @@ -121,5 +121,7 @@ void FinishSetupSource::execute() const m_gstPlayerClient->notifyPlaybackState(PlaybackState::IDLE); m_context.setupSourceFinished = true; + + RIALTO_SERVER_LOG_MIL("All sources attached."); } } // namespace firebolt::rialto::server::tasks::generic diff --git a/media/server/gstplayer/source/tasks/generic/Flush.cpp b/media/server/gstplayer/source/tasks/generic/Flush.cpp index 1343153e0..fca5731f1 100644 --- a/media/server/gstplayer/source/tasks/generic/Flush.cpp +++ b/media/server/gstplayer/source/tasks/generic/Flush.cpp @@ -103,5 +103,7 @@ void Flush::execute() const // Notify GstGenericPlayer, that flush has been finished m_player.setSourceFlushed(m_type); + + RIALTO_SERVER_LOG_MIL("%s source flushed.", common::convertMediaSourceType(m_type)); } } // namespace firebolt::rialto::server::tasks::generic diff --git a/media/server/gstplayer/source/tasks/generic/GenericPlayerTaskFactory.cpp b/media/server/gstplayer/source/tasks/generic/GenericPlayerTaskFactory.cpp index 693708ea9..b7ea1622f 100644 --- a/media/server/gstplayer/source/tasks/generic/GenericPlayerTaskFactory.cpp +++ b/media/server/gstplayer/source/tasks/generic/GenericPlayerTaskFactory.cpp @@ -114,10 +114,11 @@ std::unique_ptr GenericPlayerTaskFactory::createFinishSetupSource(G std::unique_ptr GenericPlayerTaskFactory::createHandleBusMessage(GenericPlayerContext &context, IGstGenericPlayerPrivate &player, - GstMessage *message, bool isFlushing) const + GstMessage *message, + const IFlushWatcher &flushWatcher) const { return std::make_unique(context, player, m_client, m_gstWrapper, m_glibWrapper, - message, isFlushing); + message, flushWatcher); } std::unique_ptr GenericPlayerTaskFactory::createNeedData(GenericPlayerContext &context, diff --git a/media/server/gstplayer/source/tasks/generic/HandleBusMessage.cpp b/media/server/gstplayer/source/tasks/generic/HandleBusMessage.cpp index b4d09fab3..bf88ca1d6 100644 --- a/media/server/gstplayer/source/tasks/generic/HandleBusMessage.cpp +++ b/media/server/gstplayer/source/tasks/generic/HandleBusMessage.cpp @@ -27,11 +27,13 @@ namespace firebolt::rialto::server::tasks::generic { HandleBusMessage::HandleBusMessage(GenericPlayerContext &context, IGstGenericPlayerPrivate &player, IGstGenericPlayerClient *client, - std::shared_ptr gstWrapper, - std::shared_ptr glibWrapper, - GstMessage *message, bool isFlushOngoing) + const std::shared_ptr &gstWrapper, + const std::shared_ptr &glibWrapper, + GstMessage *message, const IFlushWatcher &flushWatcher) : m_context{context}, m_player{player}, m_gstPlayerClient{client}, m_gstWrapper{gstWrapper}, - m_glibWrapper{glibWrapper}, m_message{message}, m_isFlushOngoing{isFlushOngoing} + m_glibWrapper{glibWrapper}, m_message{message}, m_flushWatcher{flushWatcher}, + m_isFlushOngoingDuringCreation{flushWatcher.isFlushOngoing()}, + m_isAsyncFlushOngoingDuringCreation{flushWatcher.isAsyncFlushOngoing()} { RIALTO_SERVER_LOG_DEBUG("Constructing HandleBusMessage"); } @@ -52,10 +54,10 @@ void HandleBusMessage::execute() const { GstState oldState, newState, pending; m_gstWrapper->gstMessageParseStateChanged(m_message, &oldState, &newState, &pending); - RIALTO_SERVER_LOG_INFO("State changed (old: %s, new: %s, pending: %s)", - m_gstWrapper->gstElementStateGetName(oldState), - m_gstWrapper->gstElementStateGetName(newState), - m_gstWrapper->gstElementStateGetName(pending)); + RIALTO_SERVER_LOG_MIL("State changed (old: %s, new: %s, pending: %s)", + m_gstWrapper->gstElementStateGetName(oldState), + m_gstWrapper->gstElementStateGetName(newState), + m_gstWrapper->gstElementStateGetName(pending)); std::string filename = std::string(m_gstWrapper->gstElementStateGetName(oldState)) + "-" + std::string(m_gstWrapper->gstElementStateGetName(newState)); @@ -76,6 +78,14 @@ void HandleBusMessage::execute() const { if (pending != GST_STATE_PAUSED) { + // If async flush was requested before HandleBusMessage task creation (but it was not executed yet) + // or if async flush was created after HandleBusMessage task creation (but before its execution) + // we can't report playback state, because async flush causes state loss - reported state is probably invalid. + if (m_isAsyncFlushOngoingDuringCreation || m_flushWatcher.isAsyncFlushOngoing()) + { + RIALTO_SERVER_LOG_WARN("Skip PAUSED notification - flush is ongoing"); + break; + } // newState==GST_STATE_PAUSED, pending==GST_STATE_PAUSED state transition is received as a result of // waiting for preroll after seek. // Subsequent newState==GST_STATE_PAUSED, pending!=GST_STATE_PAUSED transition will @@ -86,6 +96,14 @@ void HandleBusMessage::execute() const } case GST_STATE_PLAYING: { + // If async flush was requested before HandleBusMessage task creation (but it was not executed yet) + // or if async flush was created after HandleBusMessage task creation (but before its execution) + // we can't report playback state, because async flush causes state loss - reported state is probably invalid. + if (m_isAsyncFlushOngoingDuringCreation || m_flushWatcher.isAsyncFlushOngoing()) + { + RIALTO_SERVER_LOG_WARN("Skip PLAYING notification - flush is ongoing"); + break; + } if (m_context.pendingPlaybackRate != kNoPendingPlaybackRate) { m_player.setPendingPlaybackRate(); @@ -107,7 +125,10 @@ void HandleBusMessage::execute() const } case GST_MESSAGE_EOS: { - if (m_isFlushOngoing) + // If flush was requested before HandleBusMessage task creation (but it was not executed yet) + // or if flush was created after HandleBusMessage task creation (but before its execution) + // we can't report EOS, because flush clears EOS. + if (m_isFlushOngoingDuringCreation || m_flushWatcher.isFlushOngoing()) { RIALTO_SERVER_LOG_WARN("Skip EOS notification - flush is ongoing"); break; diff --git a/media/server/gstplayer/source/tasks/generic/Pause.cpp b/media/server/gstplayer/source/tasks/generic/Pause.cpp index 4a3bdd1fe..bb97ac3d9 100644 --- a/media/server/gstplayer/source/tasks/generic/Pause.cpp +++ b/media/server/gstplayer/source/tasks/generic/Pause.cpp @@ -39,5 +39,6 @@ void Pause::execute() const m_player.stopPositionReportingAndCheckAudioUnderflowTimer(); m_player.changePipelineState(GST_STATE_PAUSED); m_context.isPlaying = false; + RIALTO_SERVER_LOG_MIL("State change to PAUSED requested"); } } // namespace firebolt::rialto::server::tasks::generic diff --git a/media/server/gstplayer/source/tasks/generic/Play.cpp b/media/server/gstplayer/source/tasks/generic/Play.cpp index 6e0f588de..404a9cba6 100644 --- a/media/server/gstplayer/source/tasks/generic/Play.cpp +++ b/media/server/gstplayer/source/tasks/generic/Play.cpp @@ -37,5 +37,6 @@ void Play::execute() const { RIALTO_SERVER_LOG_DEBUG("Executing Play"); m_player.changePipelineState(GST_STATE_PLAYING); + RIALTO_SERVER_LOG_MIL("State change to PLAYING requested"); } } // namespace firebolt::rialto::server::tasks::generic diff --git a/media/server/gstplayer/source/tasks/generic/ReadShmDataAndAttachSamples.cpp b/media/server/gstplayer/source/tasks/generic/ReadShmDataAndAttachSamples.cpp index 0839468a1..1df7213a7 100644 --- a/media/server/gstplayer/source/tasks/generic/ReadShmDataAndAttachSamples.cpp +++ b/media/server/gstplayer/source/tasks/generic/ReadShmDataAndAttachSamples.cpp @@ -85,14 +85,26 @@ void ReadShmDataAndAttachSamples::execute() const RIALTO_SERVER_LOG_ERROR("Failed to get the audio segment, reason: %s", e.what()); } } - // no special action for SUBTITLE needed, just attach the buffer + else if (mediaSegment->getType() == firebolt::rialto::MediaSourceType::SUBTITLE) + { + if (mediaSegment->getDisplayOffset()) + { + GST_BUFFER_OFFSET(gstBuffer) = mediaSegment->getDisplayOffset().value(); + } + } attachData(mediaSegment->getType(), gstBuffer); } // All segments in vector have the same type if (!mediaSegments.empty()) { - m_player.notifyNeedMediaData(mediaSegments.front()->getType()); + const auto kMediaType{mediaSegments.front()->getType()}; + const auto kFirstTimestamp{mediaSegments.front()->getTimeStamp()}; + const auto kLastTimestamp{mediaSegments.back()->getTimeStamp()}; + RIALTO_SERVER_LOG_DEBUG("%s data received. First ts: %" GST_TIME_FORMAT " last ts: %" GST_TIME_FORMAT, + common::convertMediaSourceType(kMediaType), GST_TIME_ARGS(kFirstTimestamp), + GST_TIME_ARGS(kLastTimestamp)); + m_player.notifyNeedMediaData(kMediaType); } } diff --git a/media/server/gstplayer/source/tasks/generic/RemoveSource.cpp b/media/server/gstplayer/source/tasks/generic/RemoveSource.cpp index 16f03e6eb..29127c08c 100644 --- a/media/server/gstplayer/source/tasks/generic/RemoveSource.cpp +++ b/media/server/gstplayer/source/tasks/generic/RemoveSource.cpp @@ -75,5 +75,7 @@ void RemoveSource::execute() const // Turn audio off, removing audio sink from playsink m_player.setPlaybinFlags(false); + + RIALTO_SERVER_LOG_MIL("%s source removed", common::convertMediaSourceType(m_type)); } } // namespace firebolt::rialto::server::tasks::generic diff --git a/media/server/gstplayer/source/tasks/generic/SetMute.cpp b/media/server/gstplayer/source/tasks/generic/SetMute.cpp index 89096e9f9..da66764a8 100644 --- a/media/server/gstplayer/source/tasks/generic/SetMute.cpp +++ b/media/server/gstplayer/source/tasks/generic/SetMute.cpp @@ -62,26 +62,16 @@ void SetMute::execute() const } else if (m_mediaSourceType == MediaSourceType::VIDEO) { - GstElement *videoSink{m_player.getSink(MediaSourceType::VIDEO)}; - if (!videoSink) - { - RIALTO_SERVER_LOG_ERROR("Setting mute failed. Video sink is NULL"); - return; - } - if (m_glibWrapper->gObjectClassFindProperty(G_OBJECT_GET_CLASS(videoSink), "show-video-window")) - { - m_glibWrapper->gObjectSet(videoSink, "show-video-window", m_mute, nullptr); - } - else - { - RIALTO_SERVER_LOG_ERROR("Setting mute failed. Property does not exist"); - } - m_gstWrapper->gstObjectUnref(GST_OBJECT(videoSink)); + m_context.pendingShowVideoWindow = !m_mute; + m_player.setShowVideoWindow(); } else { RIALTO_SERVER_LOG_ERROR("Setting mute for type %s unsupported", common::convertMediaSourceType(m_mediaSourceType)); + return; } + RIALTO_SERVER_LOG_MIL("%s source %s", common::convertMediaSourceType(m_mediaSourceType), + (m_mute ? "muted" : "unmuted")); } } // namespace firebolt::rialto::server::tasks::generic diff --git a/media/server/gstplayer/source/tasks/generic/SetPlaybackRate.cpp b/media/server/gstplayer/source/tasks/generic/SetPlaybackRate.cpp index 803860985..f5f8f609c 100644 --- a/media/server/gstplayer/source/tasks/generic/SetPlaybackRate.cpp +++ b/media/server/gstplayer/source/tasks/generic/SetPlaybackRate.cpp @@ -93,7 +93,7 @@ void SetPlaybackRate::execute() const if (success) { - RIALTO_SERVER_LOG_INFO("Playback rate set to: %lf", m_rate); + RIALTO_SERVER_LOG_MIL("Playback rate set to: %lf", m_rate); m_context.playbackRate = m_rate; } diff --git a/media/server/gstplayer/source/tasks/generic/SetPosition.cpp b/media/server/gstplayer/source/tasks/generic/SetPosition.cpp index e37b206e0..df9d1b72b 100644 --- a/media/server/gstplayer/source/tasks/generic/SetPosition.cpp +++ b/media/server/gstplayer/source/tasks/generic/SetPosition.cpp @@ -84,13 +84,15 @@ void SetPosition::execute() const return; } + RIALTO_SERVER_LOG_MIL("Pipeline seek to: %" GST_TIME_FORMAT, GST_TIME_ARGS(m_position)); + // Reset Eos info m_context.endOfStreamInfo.clear(); m_context.eosNotified = false; m_gstPlayerClient->notifyPlaybackState(PlaybackState::SEEK_DONE); - // // Trigger NeedMediaData for all attached sources + // Trigger NeedMediaData for all attached sources for (const auto &streamInfo : m_context.streamInfo) { if (streamInfo.second.appSrc) diff --git a/media/server/gstplayer/source/tasks/generic/SetupElement.cpp b/media/server/gstplayer/source/tasks/generic/SetupElement.cpp index d4d1e79d9..57c14914a 100644 --- a/media/server/gstplayer/source/tasks/generic/SetupElement.cpp +++ b/media/server/gstplayer/source/tasks/generic/SetupElement.cpp @@ -255,6 +255,10 @@ void SetupElement::execute() const { m_player.setRenderFrame(); } + if (m_context.pendingShowVideoWindow.has_value()) + { + m_player.setShowVideoWindow(); + } } else if (isAudioDecoder(*m_gstWrapper, m_element)) { diff --git a/media/server/gstplayer/source/tasks/generic/Stop.cpp b/media/server/gstplayer/source/tasks/generic/Stop.cpp index 050c4a8a1..3f82478b5 100644 --- a/media/server/gstplayer/source/tasks/generic/Stop.cpp +++ b/media/server/gstplayer/source/tasks/generic/Stop.cpp @@ -43,5 +43,6 @@ void Stop::execute() const { streamInfo.second.isDataNeeded = false; } + RIALTO_SERVER_LOG_MIL("State change to NULL requested"); } } // namespace firebolt::rialto::server::tasks::generic diff --git a/media/server/gstplayer/source/tasks/generic/SwitchSource.cpp b/media/server/gstplayer/source/tasks/generic/SwitchSource.cpp index 5eb201471..22de55f5c 100644 --- a/media/server/gstplayer/source/tasks/generic/SwitchSource.cpp +++ b/media/server/gstplayer/source/tasks/generic/SwitchSource.cpp @@ -19,6 +19,7 @@ #include "SwitchSource.h" #include "RialtoServerLogging.h" +#include "TypeConverters.h" #include "Utils.h" namespace firebolt::rialto::server::tasks::generic @@ -40,6 +41,8 @@ void SwitchSource::execute() const if (!m_player.reattachSource(m_source)) { RIALTO_SERVER_LOG_WARN("Switch audio source failed"); + return; } + RIALTO_SERVER_LOG_MIL("%s source switched", common::convertMediaSourceType(m_source->getType())); } } // namespace firebolt::rialto::server::tasks::generic diff --git a/media/server/gstplayer/source/tasks/webAudio/Eos.cpp b/media/server/gstplayer/source/tasks/webAudio/Eos.cpp index 365f9b34d..be11e5405 100644 --- a/media/server/gstplayer/source/tasks/webAudio/Eos.cpp +++ b/media/server/gstplayer/source/tasks/webAudio/Eos.cpp @@ -42,5 +42,6 @@ void Eos::execute() const { RIALTO_SERVER_LOG_WARN("Set eos failed - Gstreamer error"); } + RIALTO_SERVER_LOG_MIL("EOS set for webaudio source"); } } // namespace firebolt::rialto::server::tasks::webaudio diff --git a/media/server/gstplayer/source/tasks/webAudio/HandleBusMessage.cpp b/media/server/gstplayer/source/tasks/webAudio/HandleBusMessage.cpp index f26146c8a..e8ffad051 100644 --- a/media/server/gstplayer/source/tasks/webAudio/HandleBusMessage.cpp +++ b/media/server/gstplayer/source/tasks/webAudio/HandleBusMessage.cpp @@ -52,10 +52,10 @@ void HandleBusMessage::execute() const { GstState oldState, newState, pending; m_gstWrapper->gstMessageParseStateChanged(m_message, &oldState, &newState, &pending); - RIALTO_SERVER_LOG_INFO("State changed (old: %s, new: %s, pending: %s)", - m_gstWrapper->gstElementStateGetName(oldState), - m_gstWrapper->gstElementStateGetName(newState), - m_gstWrapper->gstElementStateGetName(pending)); + RIALTO_SERVER_LOG_MIL("State changed (old: %s, new: %s, pending: %s)", + m_gstWrapper->gstElementStateGetName(oldState), + m_gstWrapper->gstElementStateGetName(newState), + m_gstWrapper->gstElementStateGetName(pending)); std::string filename = std::string(m_gstWrapper->gstElementStateGetName(oldState)) + "-" + std::string(m_gstWrapper->gstElementStateGetName(newState)); diff --git a/media/server/gstplayer/source/tasks/webAudio/Pause.cpp b/media/server/gstplayer/source/tasks/webAudio/Pause.cpp index 298cab286..a7acec661 100644 --- a/media/server/gstplayer/source/tasks/webAudio/Pause.cpp +++ b/media/server/gstplayer/source/tasks/webAudio/Pause.cpp @@ -41,5 +41,6 @@ void Pause::execute() const { RIALTO_SERVER_LOG_ERROR("Failed to pause the web audio player"); } + RIALTO_SERVER_LOG_MIL("State change to PAUSED requested for webaudio pipeline"); } } // namespace firebolt::rialto::server::tasks::webaudio diff --git a/media/server/gstplayer/source/tasks/webAudio/Play.cpp b/media/server/gstplayer/source/tasks/webAudio/Play.cpp index b1b8c529a..19605b457 100644 --- a/media/server/gstplayer/source/tasks/webAudio/Play.cpp +++ b/media/server/gstplayer/source/tasks/webAudio/Play.cpp @@ -41,5 +41,6 @@ void Play::execute() const { RIALTO_SERVER_LOG_ERROR("Failed to play the web audio player"); } + RIALTO_SERVER_LOG_MIL("State change to PLAYING requested for webaudio pipeline"); } } // namespace firebolt::rialto::server::tasks::webaudio diff --git a/media/server/gstplayer/source/tasks/webAudio/SetCaps.cpp b/media/server/gstplayer/source/tasks/webAudio/SetCaps.cpp index 03f92b1d2..5d42d4c31 100644 --- a/media/server/gstplayer/source/tasks/webAudio/SetCaps.cpp +++ b/media/server/gstplayer/source/tasks/webAudio/SetCaps.cpp @@ -154,6 +154,7 @@ void SetCaps::execute() const m_gstWrapper->gstCapsUnref(caps); setBytesPerSample(); + RIALTO_SERVER_LOG_MIL("New caps set for webaudio source: %s", strCaps.c_str()); } } diff --git a/media/server/gstplayer/source/tasks/webAudio/Stop.cpp b/media/server/gstplayer/source/tasks/webAudio/Stop.cpp index 906764d40..56d01b7ae 100644 --- a/media/server/gstplayer/source/tasks/webAudio/Stop.cpp +++ b/media/server/gstplayer/source/tasks/webAudio/Stop.cpp @@ -38,5 +38,6 @@ void Stop::execute() const { RIALTO_SERVER_LOG_DEBUG("Executing Stop"); m_player.changePipelineState(GST_STATE_NULL); + RIALTO_SERVER_LOG_MIL("State change to NULL requested for webaudio pipeline"); } } // namespace firebolt::rialto::server::tasks::webaudio diff --git a/media/server/ipc/include/MediaPipelineCapabilitiesModuleService.h b/media/server/ipc/include/MediaPipelineCapabilitiesModuleService.h index 8660f8373..51a19410c 100644 --- a/media/server/ipc/include/MediaPipelineCapabilitiesModuleService.h +++ b/media/server/ipc/include/MediaPipelineCapabilitiesModuleService.h @@ -59,6 +59,9 @@ class MediaPipelineCapabilitiesModuleService : public IMediaPipelineCapabilities const ::firebolt::rialto::GetSupportedPropertiesRequest *request, ::firebolt::rialto::GetSupportedPropertiesResponse *response, ::google::protobuf::Closure *done) override; + void isVideoMaster(::google::protobuf::RpcController *controller, + const ::firebolt::rialto::IsVideoMasterRequest *request, + ::firebolt::rialto::IsVideoMasterResponse *response, ::google::protobuf::Closure *done) override; private: service::IMediaPipelineService &m_mediaPipelineService; diff --git a/media/server/ipc/source/ApplicationManagementServer.cpp b/media/server/ipc/source/ApplicationManagementServer.cpp index 69ee05d91..dd7db2272 100644 --- a/media/server/ipc/source/ApplicationManagementServer.cpp +++ b/media/server/ipc/source/ApplicationManagementServer.cpp @@ -79,6 +79,7 @@ bool ApplicationManagementServer::initialize(int socket) return false; } m_ipcClient->exportService(m_service); + RIALTO_SERVER_LOG_MIL("ApplicationManagementServer initialized"); return true; } @@ -116,6 +117,6 @@ void ApplicationManagementServer::stop() void ApplicationManagementServer::onClientDisconnected(const std::shared_ptr<::firebolt::rialto::ipc::IClient> &client) { - RIALTO_SERVER_LOG_INFO("Rialto Server Manager disconnected"); + RIALTO_SERVER_LOG_WARN("Rialto Server Manager disconnected"); } } // namespace firebolt::rialto::server::ipc diff --git a/media/server/ipc/source/MediaPipelineCapabilitiesModuleService.cpp b/media/server/ipc/source/MediaPipelineCapabilitiesModuleService.cpp index 2feca2411..efed009cc 100644 --- a/media/server/ipc/source/MediaPipelineCapabilitiesModuleService.cpp +++ b/media/server/ipc/source/MediaPipelineCapabilitiesModuleService.cpp @@ -152,4 +152,32 @@ void MediaPipelineCapabilitiesModuleService::getSupportedProperties( done->Run(); } +void MediaPipelineCapabilitiesModuleService::isVideoMaster(::google::protobuf::RpcController *controller, + const ::firebolt::rialto::IsVideoMasterRequest *request, + ::firebolt::rialto::IsVideoMasterResponse *response, + ::google::protobuf::Closure *done) +{ + RIALTO_SERVER_LOG_DEBUG("entry:"); + auto ipcController = dynamic_cast(controller); + if (!ipcController) + { + RIALTO_SERVER_LOG_ERROR("ipc library provided incompatible controller object"); + controller->SetFailed("ipc library provided incompatible controller object"); + done->Run(); + return; + } + + bool isMaster{false}; + if (!m_mediaPipelineService.isVideoMaster(isMaster)) + { + RIALTO_SERVER_LOG_ERROR("isVideoMaster check failed"); + controller->SetFailed("isVideoMaster check failed"); + done->Run(); + return; + } + + response->set_is_video_master(isMaster); + + done->Run(); +} } // namespace firebolt::rialto::server::ipc diff --git a/media/server/ipc/source/SessionManagementServer.cpp b/media/server/ipc/source/SessionManagementServer.cpp index 80ae051b7..ab9954a92 100644 --- a/media/server/ipc/source/SessionManagementServer.cpp +++ b/media/server/ipc/source/SessionManagementServer.cpp @@ -99,6 +99,8 @@ bool SessionManagementServer::initialize(const std::string &socketName, unsigned common::setFilePermissions(socketName, socketPermissions); common::setFileOwnership(socketName, socketOwner, socketGroup); + RIALTO_SERVER_LOG_MIL("Session Management Server initialized"); + return true; } @@ -121,6 +123,9 @@ bool SessionManagementServer::initialize(int32_t socketFd) socketFd); return false; } + + RIALTO_SERVER_LOG_MIL("Session Management Server initialized"); + return true; } @@ -158,6 +163,7 @@ void SessionManagementServer::setLogLevels(RIALTO_DEBUG_LEVEL defaultLogLevels, void SessionManagementServer::onClientConnected(const std::shared_ptr<::firebolt::rialto::ipc::IClient> &client) { + RIALTO_SERVER_LOG_MIL("Client app connected"); m_controlModule->clientConnected(client); m_mediaPipelineModule->clientConnected(client); m_mediaPipelineCapabilitiesModule->clientConnected(client); @@ -169,6 +175,7 @@ void SessionManagementServer::onClientConnected(const std::shared_ptr<::firebolt void SessionManagementServer::onClientDisconnected(const std::shared_ptr<::firebolt::rialto::ipc::IClient> &client) { + RIALTO_SERVER_LOG_MIL("Client app disconnected"); m_setLogLevelsService.clientDisconnected(client); m_mediaKeysCapabilitiesModule->clientDisconnected(client); m_mediaKeysModule->clientDisconnected(client); diff --git a/media/server/main/include/ITextTrackAccessor.h b/media/server/main/include/ITextTrackAccessor.h index 57d55557a..d167b13cb 100644 --- a/media/server/main/include/ITextTrackAccessor.h +++ b/media/server/main/include/ITextTrackAccessor.h @@ -58,7 +58,7 @@ class ITextTrackAccessor virtual bool play(uint32_t sessionId) = 0; virtual bool mute(uint32_t sessionId, bool mute) = 0; virtual bool setPosition(uint32_t sessionId, uint64_t mediaTimestampMs) = 0; - virtual bool sendData(uint32_t sessionId, const std::string &data, DataType datatype, int32_t displayOffsetMs = 0) = 0; + virtual bool sendData(uint32_t sessionId, const std::string &data, DataType datatype, int64_t displayOffsetMs = 0) = 0; virtual bool setSessionWebVTTSelection(uint32_t sessionId) = 0; virtual bool setSessionTTMLSelection(uint32_t sessionId) = 0; virtual bool setSessionCCSelection(uint32_t sessionId, const std::string &service) = 0; diff --git a/media/server/main/include/MediaPipelineCapabilities.h b/media/server/main/include/MediaPipelineCapabilities.h index 008da32b0..be5a34451 100644 --- a/media/server/main/include/MediaPipelineCapabilities.h +++ b/media/server/main/include/MediaPipelineCapabilities.h @@ -66,6 +66,7 @@ class MediaPipelineCapabilities : public IMediaPipelineCapabilities bool isMimeTypeSupported(const std::string &mimeType) override; std::vector getSupportedProperties(MediaSourceType mediaType, const std::vector &propertyNames) override; + bool isVideoMaster(bool &isVideoMaster) override; private: /** diff --git a/media/server/main/include/TextTrackAccessor.h b/media/server/main/include/TextTrackAccessor.h index 14c788121..af2c4d533 100644 --- a/media/server/main/include/TextTrackAccessor.h +++ b/media/server/main/include/TextTrackAccessor.h @@ -51,7 +51,7 @@ class TextTrackAccessor : public ITextTrackAccessor bool play(uint32_t sessionId) override; bool mute(uint32_t sessionId, bool mute) override; bool setPosition(uint32_t sessionId, uint64_t mediaTimestampMs) override; - bool sendData(uint32_t sessionId, const std::string &data, DataType datatype, int32_t displayOffsetMs) override; + bool sendData(uint32_t sessionId, const std::string &data, DataType datatype, int64_t displayOffsetMs) override; bool setSessionWebVTTSelection(uint32_t sessionId) override; bool setSessionTTMLSelection(uint32_t sessionId) override; bool setSessionCCSelection(uint32_t sessionId, const std::string &service) override; diff --git a/media/server/main/include/TextTrackSession.h b/media/server/main/include/TextTrackSession.h index ce566d11b..6a344e289 100644 --- a/media/server/main/include/TextTrackSession.h +++ b/media/server/main/include/TextTrackSession.h @@ -44,7 +44,7 @@ class TextTrackSession : public ITextTrackSession bool play() override; bool mute(bool mute) override; bool setPosition(uint64_t mediaTimestampMs) override; - bool sendData(const std::string &data, int32_t displayOffsetMs = 0) override; + bool sendData(const std::string &data, int64_t displayOffsetMs = 0) override; bool setSessionWebVTTSelection() override; bool setSessionTTMLSelection() override; bool setSessionCCSelection(const std::string &service) override; diff --git a/media/server/main/interface/ITextTrackSession.h b/media/server/main/interface/ITextTrackSession.h index d198f156f..d5e86b2dc 100644 --- a/media/server/main/interface/ITextTrackSession.h +++ b/media/server/main/interface/ITextTrackSession.h @@ -46,7 +46,7 @@ class ITextTrackSession virtual bool play() = 0; virtual bool mute(bool mute) = 0; virtual bool setPosition(uint64_t mediaTimestampMs) = 0; - virtual bool sendData(const std::string &data, int32_t displayOffsetMs = 0) = 0; + virtual bool sendData(const std::string &data, int64_t displayOffsetMs = 0) = 0; virtual bool setSessionWebVTTSelection() = 0; virtual bool setSessionTTMLSelection() = 0; virtual bool setSessionCCSelection(const std::string &service) = 0; diff --git a/media/server/main/source/ControlServerInternal.cpp b/media/server/main/source/ControlServerInternal.cpp index 996124844..49ae2e78a 100644 --- a/media/server/main/source/ControlServerInternal.cpp +++ b/media/server/main/source/ControlServerInternal.cpp @@ -118,7 +118,7 @@ void ControlServerInternal::ack(int32_t ackId) void ControlServerInternal::setApplicationState(const ApplicationState &state) { - RIALTO_SERVER_LOG_INFO("Notify rialto client about state changed to: %s", convertApplicationState(state)); + RIALTO_SERVER_LOG_MIL("Notify rialto client about state changed to: %s", convertApplicationState(state)); auto task = [&]() { m_currentState = state; diff --git a/media/server/main/source/DataReaderV2.cpp b/media/server/main/source/DataReaderV2.cpp index 88a7b2722..5659045f0 100644 --- a/media/server/main/source/DataReaderV2.cpp +++ b/media/server/main/source/DataReaderV2.cpp @@ -187,6 +187,10 @@ createSegment(const firebolt::rialto::MediaSegmentMetadata &metadata, const fire { segment->setEncryptionPattern(metadata.crypt(), metadata.skip()); } + if (metadata.has_display_offset()) + { + segment->setDisplayOffset(metadata.display_offset()); + } for (const auto &info : metadata.sub_sample_info()) { diff --git a/media/server/main/source/MediaKeySession.cpp b/media/server/main/source/MediaKeySession.cpp index a45a977a1..414856cd8 100644 --- a/media/server/main/source/MediaKeySession.cpp +++ b/media/server/main/source/MediaKeySession.cpp @@ -81,6 +81,7 @@ MediaKeySession::MediaKeySession(const std::string &keySystem, int32_t keySessio { throw std::runtime_error("Ocdm session could not be created"); } + RIALTO_SERVER_LOG_MIL("New OCDM session created"); } MediaKeySession::~MediaKeySession() @@ -254,6 +255,7 @@ MediaKeyErrorStatus MediaKeySession::closeKeySession() RIALTO_SERVER_LOG_WARN("Failed to clean the decrypt context for the key session"); } status = MediaKeyErrorStatus::OK; + RIALTO_SERVER_LOG_MIL("OCDM session closed"); } else { diff --git a/media/server/main/source/MediaPipelineCapabilities.cpp b/media/server/main/source/MediaPipelineCapabilities.cpp index 184c3b0f2..67cd7c19a 100644 --- a/media/server/main/source/MediaPipelineCapabilities.cpp +++ b/media/server/main/source/MediaPipelineCapabilities.cpp @@ -94,4 +94,9 @@ std::vector MediaPipelineCapabilities::getSupportedProperties(Media return m_gstCapabilities->getSupportedProperties(mediaType, propertyNames); } +bool MediaPipelineCapabilities::isVideoMaster(bool &isVideoMaster) +{ + return m_gstCapabilities->isVideoMaster(isVideoMaster); +} + }; // namespace firebolt::rialto::server diff --git a/media/server/main/source/MediaPipelineServerInternal.cpp b/media/server/main/source/MediaPipelineServerInternal.cpp index 88ba70e12..e80808285 100644 --- a/media/server/main/source/MediaPipelineServerInternal.cpp +++ b/media/server/main/source/MediaPipelineServerInternal.cpp @@ -1151,8 +1151,7 @@ bool MediaPipelineServerInternal::flushInternal(int32_t sourceId, bool resetTime return false; } - async = m_gstPlayer->isAsync(sourceIter->first); - m_gstPlayer->flush(sourceIter->first, resetTime); + m_gstPlayer->flush(sourceIter->first, resetTime, async); // Reset Eos on flush auto it = m_isMediaTypeEosMap.find(sourceIter->first); diff --git a/media/server/main/source/TextTrackAccessor.cpp b/media/server/main/source/TextTrackAccessor.cpp index 2d41d644d..824735286 100644 --- a/media/server/main/source/TextTrackAccessor.cpp +++ b/media/server/main/source/TextTrackAccessor.cpp @@ -162,7 +162,7 @@ bool TextTrackAccessor::setPosition(uint32_t sessionId, uint64_t mediaTimestampM return false; } -bool TextTrackAccessor::sendData(uint32_t sessionId, const std::string &data, DataType datatype, int32_t displayOffsetMs) +bool TextTrackAccessor::sendData(uint32_t sessionId, const std::string &data, DataType datatype, int64_t displayOffsetMs) { firebolt::rialto::wrappers::ITextTrackWrapper::DataType wrapperDataType{}; if (datatype == DataType::WebVTT) @@ -182,7 +182,7 @@ bool TextTrackAccessor::sendData(uint32_t sessionId, const std::string &data, Da const uint32_t result = m_textTrackWrapper->sendSessionData(sessionId, wrapperDataType, displayOffsetMs, data); if (m_thunderWrapper->isSuccessful(result)) { - RIALTO_SERVER_LOG_DEBUG("Sending data to TextTrack session %u was successful", sessionId); + RIALTO_SERVER_LOG_DEBUG("Sending data to TextTrack session %u was successful; size %zu", sessionId, data.size()); return true; } diff --git a/media/server/main/source/TextTrackSession.cpp b/media/server/main/source/TextTrackSession.cpp index c5c969ead..3a68491b7 100644 --- a/media/server/main/source/TextTrackSession.cpp +++ b/media/server/main/source/TextTrackSession.cpp @@ -121,7 +121,7 @@ bool TextTrackSession::setPosition(uint64_t mediaTimestampMs) return m_textTrackAccessor->setPosition(m_sessionId, mediaTimestampMs); } -bool TextTrackSession::sendData(const std::string &data, int32_t displayOffsetMs) +bool TextTrackSession::sendData(const std::string &data, int64_t displayOffsetMs) { return m_textTrackAccessor->sendData(m_sessionId, data, m_dataType, displayOffsetMs); } diff --git a/media/server/service/include/IMediaPipelineService.h b/media/server/service/include/IMediaPipelineService.h index bdabb1b17..0a4336f36 100644 --- a/media/server/service/include/IMediaPipelineService.h +++ b/media/server/service/include/IMediaPipelineService.h @@ -89,6 +89,7 @@ class IMediaPipelineService const std::vector &propertyNames) = 0; virtual void ping(const std::shared_ptr &heartbeatProcedure) = 0; virtual bool switchSource(int sessionId, const std::unique_ptr &source) = 0; + virtual bool isVideoMaster(bool &isVideoMaster) = 0; }; } // namespace firebolt::rialto::server::service diff --git a/media/server/service/source/MediaPipelineService.cpp b/media/server/service/source/MediaPipelineService.cpp index 2031afdf5..608e0171e 100644 --- a/media/server/service/source/MediaPipelineService.cpp +++ b/media/server/service/source/MediaPipelineService.cpp @@ -620,6 +620,13 @@ bool MediaPipelineService::switchSource(int sessionId, const std::unique_ptrsecond->switchSource(source); } +bool MediaPipelineService::isVideoMaster(bool &isVideoMaster) +{ + RIALTO_SERVER_LOG_INFO("MediaPipelineService requested check if video is master"); + + return m_mediaPipelineCapabilities->isVideoMaster(isVideoMaster); +} + std::vector MediaPipelineService::getSupportedMimeTypes(MediaSourceType type) { return m_mediaPipelineCapabilities->getSupportedMimeTypes(type); diff --git a/media/server/service/source/MediaPipelineService.h b/media/server/service/source/MediaPipelineService.h index 86804d1d0..7ec49309b 100644 --- a/media/server/service/source/MediaPipelineService.h +++ b/media/server/service/source/MediaPipelineService.h @@ -95,6 +95,7 @@ class MediaPipelineService : public IMediaPipelineService bool setUseBuffering(int sessionId, bool useBuffering) override; bool getUseBuffering(int sessionId, bool &useBuffering) override; bool switchSource(int sessionId, const std::unique_ptr &source) override; + bool isVideoMaster(bool &isVideoMaster) override; std::vector getSupportedMimeTypes(MediaSourceType type) override; bool isMimeTypeSupported(const std::string &mimeType) override; std::vector getSupportedProperties(MediaSourceType mediaType, diff --git a/media/server/service/source/SessionServerManager.cpp b/media/server/service/source/SessionServerManager.cpp index 5e2ec150d..b63a7752f 100644 --- a/media/server/service/source/SessionServerManager.cpp +++ b/media/server/service/source/SessionServerManager.cpp @@ -212,6 +212,7 @@ bool SessionServerManager::switchToActive() { m_controlService.setApplicationState(ApplicationState::RUNNING); m_currentState.store(common::SessionServerState::ACTIVE); + RIALTO_SERVER_LOG_MIL("RialtoServer state is ACTIVE now"); return true; } m_playbackService.switchToInactive(); @@ -232,6 +233,7 @@ bool SessionServerManager::switchToInactive() { m_controlService.setApplicationState(ApplicationState::INACTIVE); m_currentState.store(common::SessionServerState::INACTIVE); + RIALTO_SERVER_LOG_MIL("RialtoServer state is INACTIVE now"); return true; } if (m_currentState.load() == common::SessionServerState::ACTIVE) @@ -250,6 +252,7 @@ bool SessionServerManager::switchToInactive() bool SessionServerManager::switchToNotRunning() { + RIALTO_SERVER_LOG_MIL("RialtoServer state switch to NOT_RUNNING requested"); if (m_currentState.load() == common::SessionServerState::NOT_RUNNING) { RIALTO_SERVER_LOG_DEBUG("Session server already in NotRunning state."); diff --git a/media/server/service/source/main.cpp b/media/server/service/source/main.cpp index 19e987d71..94c7e5138 100644 --- a/media/server/service/source/main.cpp +++ b/media/server/service/source/main.cpp @@ -17,10 +17,12 @@ * limitations under the License. */ +#include +#include + #include "IApplicationSessionServer.h" #include "IGstInitialiser.h" #include "RialtoServerLogging.h" -#include // NOLINT(build/filename_format) @@ -55,5 +57,11 @@ int main(int argc, char *argv[]) return EXIT_FAILURE; } appSessionServer->startService(); + +#ifdef FREE_MEM_BEFORE_EXIT + RIALTO_SERVER_LOG_INFO("Calling ShutdownProtobufLibrary"); + google::protobuf::ShutdownProtobufLibrary(); +#endif + return EXIT_SUCCESS; } diff --git a/proto/mediapipelinecapabilitiesmodule.proto b/proto/mediapipelinecapabilitiesmodule.proto index df3c47d73..1e18f9227 100644 --- a/proto/mediapipelinecapabilitiesmodule.proto +++ b/proto/mediapipelinecapabilitiesmodule.proto @@ -55,6 +55,21 @@ message IsMimeTypeSupportedResponse { optional bool is_supported = 1; } +/** + * @fn void isVideoMaster(bool &isVideoMaster) + * @brief Checks if the platform is video master. + * + * @param[out] is_video_master True if video is master otherwise false. + * + * @retval true on success false otherwise +*/ + +message IsVideoMasterRequest { +} +message IsVideoMasterResponse { + optional bool is_video_master = 1; +} + /** * @fn vector getSupportedProperties(MediaSourceType media_type, const vector &property_names) * @brief Has any gstreamer sink or decoder got a named property @@ -93,4 +108,11 @@ service MediaPipelineCapabilitiesModule { */ rpc getSupportedProperties(GetSupportedPropertiesRequest) returns (GetSupportedPropertiesResponse) { } + + /** + * @brief Checks if the platform is video master. + * @see IsVideoMasterRequest + */ + rpc isVideoMaster(IsVideoMasterRequest) returns (IsVideoMasterResponse) { + } } \ No newline at end of file diff --git a/proto/metadata.proto b/proto/metadata.proto index 2587fb5ec..59d68f231 100644 --- a/proto/metadata.proto +++ b/proto/metadata.proto @@ -78,4 +78,5 @@ message MediaSegmentMetadata { optional Fraction frame_rate = 20; /* Fractional frame rate of the video segments */ optional uint64 clipping_start = 21; /* The amount of audio to clip from start of buffer */ optional uint64 clipping_end = 22; /* The amount of audio to clip from end of buffer */ + optional uint64 display_offset = 23; /* The offset in the source file of the beginning of the media segment. */ } diff --git a/rialto.supp b/rialto.supp index 17a07d536..65e2603cc 100644 --- a/rialto.supp +++ b/rialto.supp @@ -134,6 +134,455 @@ fun:gst_debug_add_log_function ... } +{ + + Memcheck:Leak + match-leak-kinds: definite + fun:malloc + fun:__vasprintf_internal + fun:g_vasprintf + fun:g_strdup_vprintf + fun:g_strdup_printf + obj:*/libgstreamer-1.0.so* + obj:*/libgobject-2.0.so* + obj:*/libgobject-2.0.so* + fun:g_object_new_with_properties + fun:gst_element_factory_create_with_properties + obj:*/gstreamer-1.0/libgstplayback.so + obj:*/libffi.so* + obj:*/libffi.so* + fun:g_cclosure_marshal_generic + fun:g_closure_invoke + obj:*/libgobject-2.0.so* + fun:g_signal_emit_valist + fun:g_signal_emit + obj:*/gstreamer-1.0/libgstplayback.so + obj:*/libffi.so* + obj:*/libffi.so* + fun:g_cclosure_marshal_generic + fun:g_closure_invoke + obj:*/libgobject-2.0.so* + fun:g_signal_emit_valist + fun:g_signal_emit + obj:*/gstreamer-1.0/libgstplayback.so + obj:*/gstreamer-1.0/libgstplayback.so + obj:*/libffi.so* + obj:*/libffi.so* + fun:g_cclosure_marshal_generic + fun:g_closure_invoke + obj:*/libgobject-2.0.so* + fun:g_signal_emit_valist + fun:g_signal_emit + obj:*/gstreamer-1.0/libgstcoreelements.so + obj:*/libgstreamer-1.0.so* + obj:*/libgstreamer-1.0.so* + obj:*/libgstreamer-1.0.so* + obj:*/libgstreamer-1.0.so* + fun:gst_pad_push_event + obj:*/libgstreamer-1.0.so* + fun:gst_pad_forward + fun:gst_pad_event_default + obj:*/libgstreamer-1.0.so* + obj:*/libgstreamer-1.0.so* + obj:*/libgstreamer-1.0.so* + obj:*/libgstreamer-1.0.so* + fun:gst_pad_push_event + obj:*/libgstreamer-1.0.so* + fun:gst_pad_forward + fun:gst_pad_event_default + obj:*/libgstreamer-1.0.so* + obj:*/libgstreamer-1.0.so* + obj:*/libgstreamer-1.0.so* + obj:*/libgstreamer-1.0.so* + fun:gst_pad_push_event + obj:*/gstreamer-1.0/libgstcoreelements.so + obj:*/libgstreamer-1.0.so* + obj:*/libglib-2.0.so* + obj:*/libglib-2.0.so* + fun:start_thread + fun:clone +} +{ + + Memcheck:Leak + match-leak-kinds: possible + fun:calloc + fun:calloc + fun:allocate_dtv + fun:_dl_allocate_tls + fun:allocate_stack + fun:pthread_create* + obj:*/libglib-2.0.so* + obj:*/libglib-2.0.so* + fun:g_thread_pool_push + ... + fun:gst_element_change_state + fun:gst_element_change_state + obj:*/libgstreamer-1.0.so* + fun:gst_element_sync_state_with_parent + fun:_ZN8firebolt6rialto8wrappers10GstWrapper29gstElementSyncStateWithParentEP11_GstElement + fun:_ZN8firebolt6rialto6server6GstSrc17setupAndAddAppSrcEPNS1_18IDecryptionServiceEP11_GstElementRNS1_10StreamInfoEP18GstAppSrcCallbacksPvNS0_15MediaSourceTypeE +} +{ + + Memcheck:Leak + match-leak-kinds: definite + fun:malloc + fun:__vasprintf_internal + fun:g_vasprintf + fun:g_strdup_vprintf + fun:g_strdup_printf + obj:*/libgstreamer-1.0.so* + obj:*/libgobject-2.0.so* + obj:*/libgobject-2.0.so* + fun:g_object_new_with_properties + fun:gst_element_factory_create_with_properties + obj:*/gstreamer-1.0/libgstplayback.so + obj:*/libffi.so* + obj:*/libffi.so* + fun:g_cclosure_marshal_generic + fun:g_closure_invoke + obj:*/libgobject-2.0.so* + fun:g_signal_emit_valist + fun:g_signal_emit + obj:*/gstreamer-1.0/libgstplayback.so + obj:*/libffi.so* + obj:*/libffi.so* + fun:g_cclosure_marshal_generic + fun:g_closure_invoke + obj:*/libgobject-2.0.so* + fun:g_signal_emit_valist + fun:g_signal_emit + obj:*/gstreamer-1.0/libgstplayback.so + obj:*/gstreamer-1.0/libgstplayback.so + obj:*/libffi.so* + obj:*/libffi.so* + fun:g_cclosure_marshal_generic + fun:g_closure_invoke + obj:*/libgobject-2.0.so* + fun:g_signal_emit_valist + fun:g_signal_emit + obj:*/gstreamer-1.0/libgstcoreelements.so + obj:*/libgstreamer-1.0.so* + obj:*/libgstreamer-1.0.so* + obj:*/libgstreamer-1.0.so* + obj:*/libgstreamer-1.0.so* + fun:gst_pad_push_event + obj:*/libgstreamer-1.0.so* + fun:gst_pad_forward + fun:gst_pad_event_default + obj:*/libgstreamer-1.0.so* + obj:*/libgstreamer-1.0.so* + obj:*/libgstreamer-1.0.so* + obj:*/libgstreamer-1.0.so* + fun:gst_pad_push_event + obj:*/libgstreamer-1.0.so* + fun:gst_pad_forward + fun:gst_pad_event_default + obj:*/libgstreamer-1.0.so* + obj:*/libgstreamer-1.0.so* + obj:*/libgstreamer-1.0.so* + obj:*/libgstreamer-1.0.so* + fun:gst_pad_push_event + obj:*/gstreamer-1.0/libgstcoreelements.so + obj:*/libgstreamer-1.0.so* + obj:*/libglib-2.0.so* + obj:*/libglib-2.0.so* + fun:start_thread + fun:clone +} +{ + + Memcheck:Leak + match-leak-kinds: definite + fun:malloc + fun:g_malloc + obj:*/libglib-2.0.so* + obj:*/libgobject-2.0.so* + fun:g_object_unref + obj:*/gstreamer-1.0/libgstplayback.so + fun:g_object_unref + obj:*/libgstreamer-1.0.so* + fun:gst_bin_remove + obj:*/libgstreamer-1.0.so* + fun:g_object_unref + fun:_ZN8firebolt6rialto8wrappers10GstWrapper14gstObjectUnrefEPv + fun:_ZN8firebolt6rialto6server16GstGenericPlayer12termPipelineEv + ... + fun:_ZNKSt14default_deleteIN8firebolt6rialto6server17IGstGenericPlayerEEclEPS3_ + fun:_ZNSt10unique_ptrIN8firebolt6rialto6server17IGstGenericPlayerESt14default_deleteIS3_EED1Ev + ... + fun:_ZNKSt14default_deleteIN8firebolt6rialto6server28IMediaPipelineServerInternalEEclEPS3_ + fun:_ZNSt10unique_ptrIN8firebolt6rialto6server28IMediaPipelineServerInternalESt14default_deleteIS3_EED1Ev +} +{ + + Memcheck:Leak + match-leak-kinds: definite + fun:malloc + obj:*/libglib-2.0.so* + fun:g_rec_mutex_init + obj:*/libgstreamer-1.0.so* + fun:g_type_create_instance + obj:*/libgobject-2.0.so* + fun:g_object_new_with_properties + fun:gst_element_factory_create_with_properties + obj:*/gstreamer-1.0/libgstplayback.so + ... + fun:gst_pad_push_event + obj:*/libgstreamer-1.0.so* + fun:gst_pad_forward + fun:gst_pad_event_default + ... + fun:gst_pad_push_event + ... + fun:gst_pad_push_event + obj:*/gstreamer-1.0/libgstcoreelements.so + obj:*/libgstreamer-1.0.so* + obj:*/libglib-2.0.so* + obj:*/libglib-2.0.so* + fun:start_thread + fun:clone +} +{ + + Memcheck:Leak + match-leak-kinds: possible + fun:calloc + fun:calloc + fun:allocate_dtv + fun:_dl_allocate_tls + fun:allocate_stack + fun:pthread_create* + obj:*/libglib-2.0.so* + obj:*/libglib-2.0.so* + fun:g_thread_pool_push + obj:*/libgstreamer-1.0.so* + obj:*/libgstreamer-1.0.so* + fun:gst_task_set_state + fun:gst_pad_start_task + obj:*/gstreamer-1.0/libgstcoreelements.so + obj:*/libgstreamer-1.0.so* + fun:gst_pad_set_active + obj:*/libgstreamer-1.0.so* + fun:gst_iterator_fold + obj:*/libgstreamer-1.0.so* + obj:*/libgstreamer-1.0.so* + obj:*/libgstreamer-1.0.so* + fun:gst_element_change_state + obj:*/libgstreamer-1.0.so* + obj:*/libgstreamer-1.0.so* + fun:gst_element_change_state + fun:gst_element_change_state + obj:*/libgstreamer-1.0.so* + obj:*/gstreamer-1.0/libgstplayback.so + obj:*/libgstreamer-1.0.so* + fun:g_hook_list_marshal + obj:*/libgstreamer-1.0.so* + obj:*/libgstreamer-1.0.so* + obj:*/libgstreamer-1.0.so* + obj:*/libgstreamer-1.0.so* + fun:gst_pad_push_event + obj:*/libgstreamer-1.0.so* + fun:gst_pad_forward + fun:gst_pad_event_default + obj:*/libgstreamer-1.0.so* + obj:*/libgstreamer-1.0.so* + obj:*/libgstreamer-1.0.so* + obj:*/libgstreamer-1.0.so* + fun:gst_pad_push_event + obj:*/libgstreamer-1.0.so* + obj:*/libgstreamer-1.0.so* + obj:*/libgstreamer-1.0.so* + obj:*/libgstreamer-1.0.so* + fun:gst_pad_push_event + obj:*/libgstreamer-1.0.so* + fun:gst_pad_forward + fun:gst_pad_event_default + obj:*/libgstreamer-1.0.so* + obj:*/libgstreamer-1.0.so* + obj:*/libgstreamer-1.0.so* + obj:*/libgstreamer-1.0.so* + fun:gst_pad_push_event + obj:*/libgstreamer-1.0.so* + fun:gst_pad_forward + fun:gst_pad_event_default + ... + fun:gst_pad_push_event + obj:*/libffi.so* + obj:*/libffi.so* + fun:g_cclosure_marshal_generic + fun:g_closure_invoke + obj:*/libgobject-2.0.so* + fun:g_signal_emit_valist + fun:g_signal_emit + ... + fun:gst_pad_push_event + obj:*/libgstreamer-1.0.so* + fun:gst_pad_forward + fun:gst_pad_event_default + ... + fun:gst_pad_push_event + obj:*/libgstreamer-1.0.so* + fun:gst_pad_forward + fun:gst_pad_event_default + ... + fun:gst_pad_push_event + obj:*/gstreamer-1.0/libgstcoreelements.so + obj:*/libgstreamer-1.0.so* + obj:*/libglib-2.0.so* + obj:*/libglib-2.0.so* + fun:start_thread + fun:clone +} +{ + + Memcheck:Leak + match-leak-kinds: definite + fun:calloc + fun:g_malloc0 + obj:*/libgstreamer-1.0.so* + fun:gst_structure_new_id + fun:gst_event_new_seek + fun:gst_element_seek + fun:_ZN8firebolt6rialto8wrappers10GstWrapper14gstElementSeekEP11_GstElementd9GstFormat12GstSeekFlags11GstSeekTypelS7_l + fun:_ZNK8firebolt6rialto6server5tasks7generic15SetPlaybackRate7executeEv + fun:_ZN8firebolt6rialto6server12WorkerThread11taskHandlerEv + fun:_ZSt13__invoke_implIvMN8firebolt6rialto6server12WorkerThreadEFvvEPS3_JEET_St21__invoke_memfun_derefOT0_OT1_DpOT2_ + fun:_ZSt8__invokeIMN8firebolt6rialto6server12WorkerThreadEFvvEJPS3_EENSt15__invoke_resultIT_JDpT0_EE4typeEOS8_DpOS9_ + fun:_ZNSt6thread8_InvokerISt5tupleIJMN8firebolt6rialto6server12WorkerThreadEFvvEPS5_EEE9_M_invokeIJLm0ELm1EEEEvSt12_Index_tupleIJXspT_EEE + fun:_ZNSt6thread8_InvokerISt5tupleIJMN8firebolt6rialto6server12WorkerThreadEFvvEPS5_EEEclEv + fun:_ZNSt6thread11_State_implINS_8_InvokerISt5tupleIJMN8firebolt6rialto6server12WorkerThreadEFvvEPS6_EEEEE6_M_runEv + obj:*/libstdc++.so* + fun:start_thread + fun:clone +} +{ + + Memcheck:Leak + match-leak-kinds: definite + fun:malloc + fun:g_malloc + fun:g_slice_alloc + fun:gst_event_new_custom + fun:gst_element_seek + fun:_ZN8firebolt6rialto8wrappers10GstWrapper14gstElementSeekEP11_GstElementd9GstFormat12GstSeekFlags11GstSeekTypelS7_l + fun:_ZNK8firebolt6rialto6server5tasks7generic15SetPlaybackRate7executeEv + fun:_ZN8firebolt6rialto6server12WorkerThread11taskHandlerEv + fun:_ZSt13__invoke_implIvMN8firebolt6rialto6server12WorkerThreadEFvvEPS3_JEET_St21__invoke_memfun_derefOT0_OT1_DpOT2_ + fun:_ZSt8__invokeIMN8firebolt6rialto6server12WorkerThreadEFvvEJPS3_EENSt15__invoke_resultIT_JDpT0_EE4typeEOS8_DpOS9_ + fun:_ZNSt6thread8_InvokerISt5tupleIJMN8firebolt6rialto6server12WorkerThreadEFvvEPS5_EEE9_M_invokeIJLm0ELm1EEEEvSt12_Index_tupleIJXspT_EEE + fun:_ZNSt6thread8_InvokerISt5tupleIJMN8firebolt6rialto6server12WorkerThreadEFvvEPS5_EEEclEv + fun:_ZNSt6thread11_State_implINS_8_InvokerISt5tupleIJMN8firebolt6rialto6server12WorkerThreadEFvvEPS6_EEEEE6_M_runEv + obj:*/libstdc++.so* + fun:start_thread + fun:clone +} + + +{ + + Helgrind:Race + ... + fun:gst_* +} +{ + + Helgrind:Race + ... + fun:g_* +} +{ + + Helgrind:Race + ... + obj:*/libglib-2.0.so* +} +{ + + Helgrind:Race + ... + obj:*/libgstcoreelements.so +} +{ + + Helgrind:Race + ... + obj:*/libgstreamer-1.0.so* +} +{ + + Helgrind:Race + ... + obj:*/libgstapp-1.0.so* +} +{ + + Helgrind:Race + ... + obj:*/libgstbase-1.0.so* +} +{ + + Helgrind:LockOrder + ... + obj:*/libgstreamer-1.0.so* +} + + +{ + + Helgrind:Race + ... + fun:_ZNK6google8protobuf* +} + + +{ + + Helgrind:Misc + obj:*/libexec/valgrind/vgpreload_helgrind-amd64-linux.so + fun:_ZN8firebolt6rialto6server10MainThread11enqueueTaskEjSt8functionIFvvEE +} +{ + + Helgrind:Misc + obj:*/libexec/valgrind/vgpreload_helgrind-amd64-linux.so + fun:_ZN8firebolt6rialto6server10MainThread18enqueueTaskAndWaitEjSt8functionIFvvEE +} +{ + + Helgrind:Misc + obj:*/libexec/valgrind/vgpreload_helgrind-amd64-linux.so + fun:_ZN8firebolt6rialto6server12WorkerThread11enqueueTaskEOSt10unique_ptrINS1_11IPlayerTaskESt14default_deleteIS4_EE +} +{ + + Helgrind:Race + fun:_ZN8firebolt6rialto6server19GstDispatcherThread18gstBusEventHandlerEP11_GstElement +} +{ + + Helgrind:Race + fun:_ZNK8firebolt6rialto6server5tasks7generic16HandleBusMessage7executeEv +} +{ + + Helgrind:Misc + ... + fun:_ZN8firebolt6rialto6common5Timer6cancelEv +} +{ + + Memcheck:Leak + match-leak-kinds: definite + fun:malloc + fun:__vasprintf_internal + fun:g_vasprintf + fun:g_strdup_vprintf + fun:g_error_new_valist + fun:g_error_new +} { ignore_protobuf_internal_parse_possibly_lost Memcheck:Leak @@ -164,3 +613,604 @@ fun:gst_update_registry ... } +{ + + Memcheck:Leak + match-leak-kinds: possible + fun:malloc + fun:malloc + fun:allocate_dtv_entry + fun:allocate_and_init + fun:tls_get_addr_tail + fun:__tls_get_addr + obj:*/libgnutls.so* + fun:_dl_call_fini + fun:_dl_fini + fun:__run_exit_handlers + fun:exit + ... +} +{ + + Memcheck:Leak + match-leak-kinds: possible + fun:malloc + fun:malloc + fun:_dl_resize_dtv + fun:_dl_update_slotinfo + fun:update_get_addr + fun:__tls_get_addr + obj:*/libgnutls.so* + fun:_dl_call_fini + fun:_dl_fini + fun:__run_exit_handlers + fun:exit + ... +} +{ + + Memcheck:Leak + match-leak-kinds: possible + fun:malloc + fun:_dl_resize_dtv + fun:_dl_update_slotinfo + fun:update_get_addr + fun:__tls_get_addr + obj:*/libgnutls.so* + fun:_dl_call_fini + fun:_dl_fini + fun:__run_exit_handlers + fun:exit + ... +} +{ + + Memcheck:Leak + match-leak-kinds: possible + fun:calloc + fun:calloc + fun:allocate_dtv + fun:_dl_allocate_tls + fun:allocate_stack + fun:pthread_create* + obj:*/libglib-2.0.so* + obj:*/libglib-2.0.so* + obj:*/libglib-2.0.so* + fun:start_thread + fun:clone +} +{ + + Memcheck:Leak + match-leak-kinds: definite + fun:malloc + fun:__vasprintf_internal + fun:g_vasprintf + fun:g_strdup_vprintf + fun:g_strdup_printf + obj:*/libgstreamer-1.0.so* + obj:*/libgobject-2.0.so* + obj:*/libgobject-2.0.so* + fun:g_object_new_with_properties + fun:gst_element_factory_create_with_properties + ... +} +{ + + Memcheck:Leak + match-leak-kinds: definite + fun:malloc + fun:g_rec_mutex_init + obj:*/libgstreamer-1.0.so* + fun:g_type_create_instance + obj:*/libgobject-2.0.so* + fun:g_object_new_with_properties + fun:gst_element_factory_create_with_properties + ... +} +{ + + Memcheck:Leak + match-leak-kinds: definite + fun:malloc + fun:malloc + fun:resize_scopes + fun:dl_open_worker_begin + fun:_dl_catch_exception + fun:dl_open_worker + fun:_dl_catch_exception + fun:_dl_open + fun:dlopen_doit + fun:_dl_catch_exception + fun:_dl_catch_error + fun:_dlerror_run + fun:dlopen_implementation + fun:dlopen@@GLIBC_2.34 + fun:g_module_open_full + obj:*/libgstreamer-1.0.so* + fun:gst_plugin_load_by_name + fun:gst_plugin_feature_load + fun:gst_element_factory_create_with_properties + ... +} +{ + + Memcheck:Leak + match-leak-kinds: definite + fun:malloc + fun:g_malloc + obj:*/libglib-2.0.so* + obj:*/libglib-2.0.so* + obj:*/libgobject-2.0.so* + fun:g_object_unref + ... +} +{ + + Memcheck:Leak + match-leak-kinds: possible + fun:malloc + fun:g_malloc + fun:g_atomic_rc_box_alloc + obj:*/libgstreamer-1.0.so* + fun:g_type_create_instance + obj:*/libgobject-2.0.so* + fun:g_object_new_valist + fun:g_object_new + fun:gst_system_clock_obtain + obj:*/libgstreamer-1.0.so* + obj:*/libgstreamer-1.0.so* + obj:*/gstreamer-1.0/libgstplayback.so + fun:gst_element_change_state + obj:*/libgstreamer-1.0.so* + ... +} +{ + + Memcheck:Leak + match-leak-kinds: possible + fun:calloc + fun:calloc + fun:allocate_dtv + fun:_dl_allocate_tls + fun:allocate_stack + fun:pthread_create* + obj:*/libglib-2.0.so* + fun:g_thread_new + fun:g_thread_pool_new_full + obj:*/libgstreamer-1.0.so* + obj:*/libgstreamer-1.0.so* + fun:g_type_create_instance + obj:*/libgobject-2.0.so* + fun:g_object_new_with_properties + fun:g_object_new + fun:gst_task_new + fun:gst_pad_start_task + obj:*/gstreamer-1.0/libgstcoreelements.so + obj:*/libgstreamer-1.0.so* + fun:gst_pad_set_active + obj:*/libgstreamer-1.0.so* + fun:gst_iterator_fold + obj:*/libgstreamer-1.0.so* + obj:*/libgstreamer-1.0.so* + obj:*/libgstreamer-1.0.so* + fun:gst_element_change_state + fun:gst_element_change_state + obj:*/libgstreamer-1.0.so* + fun:gst_element_sync_state_with_parent + ... +} +{ + + Memcheck:Leak + match-leak-kinds: definite + ... + obj:*/gstreamer-1.0/libgstplayback.so + obj:*/gstreamer-1.0/libgstplayback.so + obj:*/gstreamer-1.0/libgstplayback.so + obj:*/libgstreamer-1.0.so* + fun:g_hook_list_marshal + obj:*/libgstreamer-1.0.so* + obj:*/libgstreamer-1.0.so* + obj:*/libgstreamer-1.0.so* + obj:*/libgstreamer-1.0.so* + fun:gst_pad_push_event + obj:*/libgstreamer-1.0.so* + fun:gst_pad_forward + fun:gst_pad_event_default + obj:*/libgstreamer-1.0.so* + obj:*/libgstreamer-1.0.so* + obj:*/libgstreamer-1.0.so* + obj:*/libgstreamer-1.0.so* + fun:gst_pad_push_event + obj:*/libgstreamer-1.0.so* + obj:*/libgstreamer-1.0.so* + obj:*/libgstreamer-1.0.so* + obj:*/libgstreamer-1.0.so* + fun:gst_pad_push_event + obj:*/libgstreamer-1.0.so* + fun:gst_pad_forward + fun:gst_pad_event_default + obj:*/libgstreamer-1.0.so* + obj:*/libgstreamer-1.0.so* + obj:*/libgstreamer-1.0.so* + obj:*/libgstreamer-1.0.so* + fun:gst_pad_push_event + obj:*/libgstreamer-1.0.so* + fun:gst_pad_forward + fun:gst_pad_event_default + obj:*/libgstreamer-1.0.so* + obj:*/libgstreamer-1.0.so* + obj:*/libgstreamer-1.0.so* + obj:*/libgstreamer-1.0.so* + fun:gst_pad_push_event + obj:*/libffi.so* + obj:*/libffi.so* + fun:ffi_call + fun:g_cclosure_marshal_generic + fun:g_closure_invoke + obj:*/libgobject-2.0.so* + obj:*/libgobject-2.0.so* + fun:g_signal_emit_valist + fun:g_signal_emit + obj:*/gstreamer-1.0/libgstcoreelements.so + obj:*/libgstreamer-1.0.so* + obj:*/libgstreamer-1.0.so* + obj:*/libgstreamer-1.0.so* + obj:*/libgstreamer-1.0.so* + fun:gst_pad_push_event + obj:*/libgstreamer-1.0.so* + fun:gst_pad_forward + fun:gst_pad_event_default + obj:*/libgstreamer-1.0.so* + obj:*/libgstreamer-1.0.so* + obj:*/libgstreamer-1.0.so* + obj:*/libgstreamer-1.0.so* + fun:gst_pad_push_event + obj:*/libgstreamer-1.0.so* + fun:gst_pad_forward + fun:gst_pad_event_default + obj:*/libgstreamer-1.0.so* + obj:*/libgstreamer-1.0.so* + obj:*/libgstreamer-1.0.so* + obj:*/libgstreamer-1.0.so* + fun:gst_pad_push_event + obj:*/gstreamer-1.0/libgstcoreelements.so + obj:*/libgstreamer-1.0.so* + obj:*/libglib-2.0.so* + obj:*/libglib-2.0.so* + fun:start_thread + fun:clone +} +{ + + Memcheck:Leak + match-leak-kinds: possible + ... + obj:*/gstreamer-1.0/libgstplayback.so + obj:*/gstreamer-1.0/libgstplayback.so + obj:*/gstreamer-1.0/libgstplayback.so + obj:*/libgstreamer-1.0.so* + fun:g_hook_list_marshal + obj:*/libgstreamer-1.0.so* + obj:*/libgstreamer-1.0.so* + obj:*/libgstreamer-1.0.so* + obj:*/libgstreamer-1.0.so* + fun:gst_pad_push_event + obj:*/libgstreamer-1.0.so* + fun:gst_pad_forward + fun:gst_pad_event_default + obj:*/libgstreamer-1.0.so* + obj:*/libgstreamer-1.0.so* + obj:*/libgstreamer-1.0.so* + obj:*/libgstreamer-1.0.so* + fun:gst_pad_push_event + obj:*/libgstreamer-1.0.so* + obj:*/libgstreamer-1.0.so* + obj:*/libgstreamer-1.0.so* + obj:*/libgstreamer-1.0.so* + fun:gst_pad_push_event + obj:*/libgstreamer-1.0.so* + fun:gst_pad_forward + fun:gst_pad_event_default + obj:*/libgstreamer-1.0.so* + obj:*/libgstreamer-1.0.so* + obj:*/libgstreamer-1.0.so* + obj:*/libgstreamer-1.0.so* + fun:gst_pad_push_event + obj:*/libgstreamer-1.0.so* + fun:gst_pad_forward + fun:gst_pad_event_default + obj:*/libgstreamer-1.0.so* + obj:*/libgstreamer-1.0.so* + obj:*/libgstreamer-1.0.so* + obj:*/libgstreamer-1.0.so* + fun:gst_pad_push_event + obj:*/libffi.so* + obj:*/libffi.so* + fun:ffi_call + fun:g_cclosure_marshal_generic + fun:g_closure_invoke + obj:*/libgobject-2.0.so* + obj:*/libgobject-2.0.so* + fun:g_signal_emit_valist + fun:g_signal_emit + obj:*/gstreamer-1.0/libgstcoreelements.so + obj:*/libgstreamer-1.0.so* + obj:*/libgstreamer-1.0.so* + obj:*/libgstreamer-1.0.so* + obj:*/libgstreamer-1.0.so* + fun:gst_pad_push_event + obj:*/libgstreamer-1.0.so* + fun:gst_pad_forward + fun:gst_pad_event_default + obj:*/libgstreamer-1.0.so* + obj:*/libgstreamer-1.0.so* + obj:*/libgstreamer-1.0.so* + obj:*/libgstreamer-1.0.so* + fun:gst_pad_push_event + obj:*/libgstreamer-1.0.so* + fun:gst_pad_forward + fun:gst_pad_event_default + obj:*/libgstreamer-1.0.so* + obj:*/libgstreamer-1.0.so* + obj:*/libgstreamer-1.0.so* + obj:*/libgstreamer-1.0.so* + fun:gst_pad_push_event + obj:*/gstreamer-1.0/libgstcoreelements.so + obj:*/libgstreamer-1.0.so* + obj:*/libglib-2.0.so* + obj:*/libglib-2.0.so* + fun:start_thread + fun:clone +} +{ + + Memcheck:Leak + match-leak-kinds: definite + fun:malloc + ... + obj:*/libgobject-2.0.so* + fun:g_object_new_with_properties + fun:gst_element_factory_create_with_properties + obj:*/gstreamer-1.0/libgstplayback.so + obj:*/libffi.so* + obj:*/libffi.so* + fun:ffi_call + fun:g_cclosure_marshal_generic + fun:g_closure_invoke + obj:*/libgobject-2.0.so* + obj:*/libgobject-2.0.so* + fun:g_signal_emit_valist + fun:g_signal_emit + obj:*/gstreamer-1.0/libgstplayback.so + obj:*/libffi.so* + obj:*/libffi.so* + fun:ffi_call + fun:g_cclosure_marshal_generic + fun:g_closure_invoke + obj:*/libgobject-2.0.so* + obj:*/libgobject-2.0.so* + fun:g_signal_emit_valist + fun:g_signal_emit + obj:*/gstreamer-1.0/libgstplayback.so + obj:*/gstreamer-1.0/libgstplayback.so + obj:*/libffi.so* + obj:*/libffi.so* + fun:ffi_call + fun:g_cclosure_marshal_generic + fun:g_closure_invoke + obj:*/libgobject-2.0.so* + obj:*/libgobject-2.0.so* + fun:g_signal_emit_valist + fun:g_signal_emit + obj:*/gstreamer-1.0/libgstcoreelements.so + obj:*/libgstreamer-1.0.so* + obj:*/libgstreamer-1.0.so* + obj:*/libgstreamer-1.0.so* + obj:*/libgstreamer-1.0.so* + fun:gst_pad_push_event + obj:*/libgstreamer-1.0.so* + fun:gst_pad_forward + fun:gst_pad_event_default + obj:*/libgstreamer-1.0.so* + obj:*/libgstreamer-1.0.so* + obj:*/libgstreamer-1.0.so* + obj:*/libgstreamer-1.0.so* + fun:gst_pad_push_event + obj:*/libgstreamer-1.0.so* + fun:gst_pad_forward + fun:gst_pad_event_default + obj:*/libgstreamer-1.0.so* + obj:*/libgstreamer-1.0.so* + obj:*/libgstreamer-1.0.so* + obj:*/libgstreamer-1.0.so* + fun:gst_pad_push_event + obj:*/gstreamer-1.0/libgstcoreelements.so + obj:*/libgstreamer-1.0.so* + obj:*/libglib-2.0.so* + obj:*/libglib-2.0.so* + fun:start_thread + fun:clone +} +{ + + Memcheck:Leak + match-leak-kinds: definite + fun:g_type_create_instance + obj:*/libgobject-2.0.so* + fun:g_object_new_with_properties + fun:gst_element_factory_create_with_properties + fun:gst_element_factory_create_valist + fun:gst_element_factory_make_valist + fun:gst_element_factory_make_full + obj:*/gstreamer-1.0/libgstplayback.so + obj:*/libgstreamer-1.0.so* + fun:g_hook_list_marshal + obj:*/libgstreamer-1.0.so* + fun:gst_pad_push_event + obj:*/libgstreamer-1.0.so* + fun:gst_pad_forward + fun:gst_pad_event_default + obj:*/libgstreamer-1.0.so* + fun:gst_pad_push_event + obj:*/libgstreamer-1.0.so* + fun:gst_pad_push_event + obj:*/libgstreamer-1.0.so* + fun:gst_pad_forward + fun:gst_pad_event_default + obj:*/libgstreamer-1.0.so* + fun:gst_pad_push_event + obj:*/libgstreamer-1.0.so* + fun:gst_pad_forward + fun:gst_pad_event_default + obj:*/libgstreamer-1.0.so* + fun:gst_pad_push_event + obj:*/libffi.so* + fun:ffi_call + fun:g_cclosure_marshal_generic + fun:g_closure_invoke + obj:*/libgobject-2.0.so* + fun:g_signal_emit_valist + fun:g_signal_emit + obj:*/gstreamer-1.0/libgstcoreelements.so + obj:*/libgstreamer-1.0.so* + fun:gst_pad_push_event + obj:*/libgstreamer-1.0.so* + fun:gst_pad_forward + fun:gst_pad_event_default + obj:*/libgstreamer-1.0.so* + fun:gst_pad_push_event + obj:*/libgstreamer-1.0.so* + fun:gst_pad_forward + fun:gst_pad_event_default + obj:*/libgstreamer-1.0.so* + fun:gst_pad_push_event + obj:*/gstreamer-1.0/libgstcoreelements.so + obj:*/libgstreamer-1.0.so* + obj:*/libglib-2.0.so* + fun:start_thread + fun:clone +} +{ + + Memcheck:Leak + match-leak-kinds: possible + ... + obj:*/gstreamer-1.0/libgstplayback.so + obj:*/libgstreamer-1.0.so* + obj:*/gstreamer-1.0/libgstplayback.so + obj:*/gstreamer-1.0/libgstplayback.so + obj:*/gstreamer-1.0/libgstplayback.so + obj:*/gstreamer-1.0/libgstplayback.so + fun:g_cclosure_marshal_VOID__OBJECTv + obj:*/libgobject-2.0.so* + fun:g_signal_emit_valist + fun:g_signal_emit + fun:gst_element_remove_pad + fun:g_cclosure_marshal_VOID__OBJECTv + obj:*/libgobject-2.0.so* + fun:g_signal_emit_valist + fun:g_signal_emit + fun:gst_element_remove_pad + obj:*/gstreamer-1.0/libgstplayback.so + obj:*/gstreamer-1.0/libgstplayback.so + fun:gst_element_change_state + obj:*/libgstreamer-1.0.so* + obj:*/libgstreamer-1.0.so* + obj:*/gstreamer-1.0/libgstplayback.so + fun:gst_element_change_state + obj:*/libgstreamer-1.0.so* + obj:*/libgstreamer-1.0.so* + obj:*/gstreamer-1.0/libgstplayback.so + fun:gst_element_change_state + ... +} +{ + + Memcheck:Leak + match-leak-kinds: definite + ... + obj:*/gstreamer-1.0/libgstplayback.so + obj:*/libgstreamer-1.0.so* + obj:*/gstreamer-1.0/libgstplayback.so + obj:*/gstreamer-1.0/libgstplayback.so + obj:*/gstreamer-1.0/libgstplayback.so + obj:*/gstreamer-1.0/libgstplayback.so + fun:g_cclosure_marshal_VOID__OBJECTv + obj:*/libgobject-2.0.so* + fun:g_signal_emit_valist + fun:g_signal_emit + fun:gst_element_remove_pad + fun:g_cclosure_marshal_VOID__OBJECTv + obj:*/libgobject-2.0.so* + fun:g_signal_emit_valist + fun:g_signal_emit + fun:gst_element_remove_pad + obj:*/gstreamer-1.0/libgstplayback.so + obj:*/gstreamer-1.0/libgstplayback.so + fun:gst_element_change_state + obj:*/libgstreamer-1.0.so* + obj:*/libgstreamer-1.0.so* + obj:*/gstreamer-1.0/libgstplayback.so + fun:gst_element_change_state + obj:*/libgstreamer-1.0.so* + obj:*/libgstreamer-1.0.so* + obj:*/gstreamer-1.0/libgstplayback.so + fun:gst_element_change_state + ... +} +{ + + Memcheck:Leak + match-leak-kinds: definite + fun:g_type_create_instance + fun:g_param_spec_internal + fun:* + fun:* + fun:ipatch_init + fun:new_fluid_synth + obj:*/gstreamer-1.0/libgstfluidsynthmidi.so + fun:g_type_create_instance + obj:*/libgobject-2.0.so* + fun:g_object_new_with_properties + fun:gst_element_factory_create_with_properties + ... +} +{ + + Memcheck:Leak + match-leak-kinds: definite + fun:malloc + obj:*/libglib-2.0.so* + fun:g_rec_mutex_init + obj:*/libgstreamer-1.0.so* + fun:g_type_create_instance + obj:*/libgobject-2.0.so* + fun:g_object_new_with_properties + fun:gst_element_factory_create_with_properties + ... +} +{ + + Memcheck:Leak + match-leak-kinds: definite + fun:malloc + fun:g_malloc + obj:*/libglib-2.0.so* + obj:*/libgobject-2.0.so* + fun:g_object_unref + ... +} +{ + + Memcheck:Leak + match-leak-kinds: possible + fun:calloc + fun:calloc + fun:allocate_dtv + fun:_dl_allocate_tls + fun:allocate_stack + fun:pthread_create* + ... +} diff --git a/scripts/gtest/generate_coverage.py b/scripts/gtest/generate_coverage.py index ce6356bc6..e73e2a397 100644 --- a/scripts/gtest/generate_coverage.py +++ b/scripts/gtest/generate_coverage.py @@ -27,10 +27,10 @@ from .utils import runcmd # Generates the coverage stats and produces html github pages for all files in the src tree -def generateCoverageReport(outputDir, resultsFile, suites): +def generateCoverageReport(baseDir, outputDir, resultsFile): lcovCommon = [] lcovCommon.extend(["--exclude", "/usr/*"]) - lcovCommon.extend(["--exclude", "*build/*", "--exclude", "*tests/*", "--exclude", "*wrappers/*", "--filter", "brace,function,trivial"]) + lcovCommon.extend(["--exclude", "*build*/*", "--exclude", "*tests/*", "--exclude", "*wrappers/*", "--filter", "brace,function,trivial"]) lcovCommon.extend(["--parallel", str(multiprocessing.cpu_count())]) # the following line tells lcov to ignore any errors caused by include/exclude/erase/omit/substitute pattern which did not match any file pathnames @@ -40,18 +40,18 @@ def generateCoverageReport(outputDir, resultsFile, suites): lcovBaseCmd.extend(lcovCommon) if resultsFile: - lcovBaseStatus = runcmd(lcovBaseCmd, cwd=os.getcwd() + '/' + outputDir, stdout=resultsFile, stderr=subprocess.STDOUT) + lcovBaseStatus = runcmd(lcovBaseCmd, cwd=baseDir + '/' + outputDir, stdout=resultsFile, stderr=subprocess.STDOUT) else: - lcovBaseStatus = runcmd(lcovBaseCmd, cwd=os.getcwd() + '/' + outputDir, stderr=subprocess.STDOUT) + lcovBaseStatus = runcmd(lcovBaseCmd, cwd=baseDir + '/' + outputDir, stderr=subprocess.STDOUT) if not lcovBaseStatus: return False lcovTestCmd = ["lcov", "-c", "-d", ".", "--output-file", "coverage_test.info"] lcovTestCmd.extend(lcovCommon) if resultsFile: - lcovTestStatus = runcmd(lcovTestCmd, cwd=os.getcwd() + '/' + outputDir, stdout=resultsFile, stderr=subprocess.STDOUT) + lcovTestStatus = runcmd(lcovTestCmd, cwd=baseDir + '/' + outputDir, stdout=resultsFile, stderr=subprocess.STDOUT) else: - lcovTestStatus = runcmd(lcovTestCmd, cwd=os.getcwd() + '/' + outputDir, stderr=subprocess.STDOUT) + lcovTestStatus = runcmd(lcovTestCmd, cwd=baseDir + '/' + outputDir, stderr=subprocess.STDOUT) if not lcovTestStatus: return False @@ -59,24 +59,24 @@ def generateCoverageReport(outputDir, resultsFile, suites): "brace,function,trivial"] lcovCombineCmd.extend(["--ignore-errors", "empty"]) if resultsFile: - lcovCombineStatus = runcmd(lcovCombineCmd, cwd=os.getcwd() + '/' + outputDir, stdout=resultsFile, stderr=subprocess.STDOUT) + lcovCombineStatus = runcmd(lcovCombineCmd, cwd=baseDir + '/' + outputDir, stdout=resultsFile, stderr=subprocess.STDOUT) else: - lcovCombineStatus = runcmd(lcovCombineCmd, cwd=os.getcwd() + '/' + outputDir, stderr=subprocess.STDOUT) + lcovCombineStatus = runcmd(lcovCombineCmd, cwd=baseDir + '/' + outputDir, stderr=subprocess.STDOUT) if not lcovCombineStatus: return False genHtmlCmd = ["genhtml", "coverage.info", "--output-directory", "gh_pages/coverage_report", "--filter", "brace,function,trivial"] genHtmlCmd.extend(["--ignore-errors", "empty"]) if resultsFile: - genHtmlStatus = runcmd(genHtmlCmd, cwd=os.getcwd() + '/' + outputDir, stdout=resultsFile, stderr=subprocess.STDOUT) + genHtmlStatus = runcmd(genHtmlCmd, cwd=baseDir + '/' + outputDir, stdout=resultsFile, stderr=subprocess.STDOUT) else: - genHtmlStatus = runcmd(genHtmlCmd, cwd=os.getcwd() + '/' + outputDir, stderr=subprocess.STDOUT) + genHtmlStatus = runcmd(genHtmlCmd, cwd=baseDir + '/' + outputDir, stderr=subprocess.STDOUT) genStatsCmd = ["lcov", "--summary", "coverage.info", "--filter", "brace,function,trivial"] genStatsCmd.extend(["--ignore-errors", "empty"]) - statsFile = open(os.getcwd() + '/' + outputDir + '/' + "coverage_statistics.txt", "w") + statsFile = open(baseDir + '/' + outputDir + '/' + "coverage_statistics.txt", "w") if statsFile: - genStatsStatus = runcmd(genStatsCmd, cwd=os.getcwd() + '/' + outputDir, stdout=statsFile, stderr=subprocess.STDOUT) + genStatsStatus = runcmd(genStatsCmd, cwd=baseDir + '/' + outputDir, stdout=statsFile, stderr=subprocess.STDOUT) else: genStatsStatus = False statsFile.close() @@ -84,16 +84,16 @@ def generateCoverageReport(outputDir, resultsFile, suites): return genHtmlStatus and genStatsStatus # Generates a stats file based on the file patterns given in includeFiles. generateCoverageReport must have been run first. -def generateSpecificCoverageStats(outputDir, resultsFile, includeFiles, statsFileName): +def generateSpecificCoverageStats(baseDir, outputDir, resultsFile, includeFiles, statsFileName): genStatsCmd = ["lcov", "--summary", "coverage.info", "--filter", "brace,function,trivial"] genStatsCmd.extend(["--ignore-errors", "empty"]) for file in includeFiles: genStatsCmd.extend(["--include", file]) - statsFile = open(os.getcwd() + '/' + outputDir + '/' + statsFileName + '.txt', "w") + statsFile = open(baseDir + '/' + outputDir + '/' + statsFileName + '.txt', "w") if statsFile: - genStatsStatus = runcmd(genStatsCmd, cwd=os.getcwd() + '/' + outputDir, stdout=statsFile, stderr=subprocess.STDOUT) + genStatsStatus = runcmd(genStatsCmd, cwd=baseDir + '/' + outputDir, stdout=statsFile, stderr=subprocess.STDOUT) else: genStatsStatus = False statsFile.close() diff --git a/serverManager/common/source/SessionServerApp.cpp b/serverManager/common/source/SessionServerApp.cpp index 8b69838f1..46363d9da 100644 --- a/serverManager/common/source/SessionServerApp.cpp +++ b/serverManager/common/source/SessionServerApp.cpp @@ -421,7 +421,7 @@ void SessionServerApp::waitForChildProcess() return; } auto killTimer = - m_timerFactory->createTimer(std::chrono::milliseconds{1000}, + m_timerFactory->createTimer(std::chrono::milliseconds{1500}, [this]() { RIALTO_SERVER_MANAGER_LOG_ERROR("Waitpid timeout. Killing: %d", m_kServerId); diff --git a/serverManager/serverManagerSim/commands/SetLog.cpp b/serverManager/serverManagerSim/commands/SetLog.cpp index 95d6615c9..cfe258957 100644 --- a/serverManager/serverManagerSim/commands/SetLog.cpp +++ b/serverManager/serverManagerSim/commands/SetLog.cpp @@ -59,12 +59,17 @@ rialto::servermanager::service::LoggingLevels convert(const std::string &compone auto loggingLevel{convert(level)}; if ("all" == component) { + levels.defaultLoggingLevel = loggingLevel; levels.clientLoggingLevel = loggingLevel; levels.sessionServerLoggingLevel = loggingLevel; levels.ipcLoggingLevel = loggingLevel; levels.serverManagerLoggingLevel = loggingLevel; levels.commonLoggingLevel = loggingLevel; } + else if ("default" == component) + { + levels.defaultLoggingLevel = loggingLevel; + } else if ("client" == component) { levels.clientLoggingLevel = loggingLevel; diff --git a/serverManager/service/CMakeLists.txt b/serverManager/service/CMakeLists.txt index dedb42e95..3f5004699 100644 --- a/serverManager/service/CMakeLists.txt +++ b/serverManager/service/CMakeLists.txt @@ -77,14 +77,6 @@ if( RIALTO_ENABLE_CONFIG_FILE ) ) endif() -if ( COVERAGE_ENABLED ) - target_link_libraries( - RialtoServerManager - PRIVATE - gcov - ) -endif() - if( NOT CMAKE_BUILD_TYPE STREQUAL "UnitTests" ) include( GNUInstallDirs ) install ( diff --git a/tests/common/externalLibraryMocks/GstWrapperMock.h b/tests/common/externalLibraryMocks/GstWrapperMock.h index 476bbdab6..10e76256a 100644 --- a/tests/common/externalLibraryMocks/GstWrapperMock.h +++ b/tests/common/externalLibraryMocks/GstWrapperMock.h @@ -33,6 +33,7 @@ class GstWrapperMock : public IGstWrapper virtual ~GstWrapperMock() = default; MOCK_METHOD(void, gstInit, (int *argc, char ***argv), (override)); + MOCK_METHOD(void, gstDeinit, (), (override)); MOCK_METHOD(GstPlugin *, gstRegistryFindPlugin, (GstRegistry * registry, const gchar *name), (override)); MOCK_METHOD(void, gstRegistryRemovePlugin, (GstRegistry * registry, GstPlugin *plugin), (override)); MOCK_METHOD(void, gstObjectUnref, (gpointer object), (override)); diff --git a/tests/common/externalLibraryMocks/TextTrackWrapperMock.h b/tests/common/externalLibraryMocks/TextTrackWrapperMock.h index f43d16592..101caeb84 100644 --- a/tests/common/externalLibraryMocks/TextTrackWrapperMock.h +++ b/tests/common/externalLibraryMocks/TextTrackWrapperMock.h @@ -41,7 +41,7 @@ class TextTrackWrapperMock : public ITextTrackWrapper MOCK_METHOD(std::uint32_t, sendSessionTimestamp, (std::uint32_t sessionId, std::uint64_t mediaTimestampMs), (const, override)); MOCK_METHOD(std::uint32_t, sendSessionData, - (std::uint32_t sessionId, ITextTrackWrapper::DataType type, std::int32_t displayOffsetMs, + (std::uint32_t sessionId, ITextTrackWrapper::DataType type, std::int64_t displayOffsetMs, const std::string &data), (const, override)); MOCK_METHOD(std::uint32_t, setSessionWebVTTSelection, (std::uint32_t sessionId), (const, override)); diff --git a/tests/componenttests/client/CMakeLists.txt b/tests/componenttests/client/CMakeLists.txt index ca850f953..35ac239f3 100644 --- a/tests/componenttests/client/CMakeLists.txt +++ b/tests/componenttests/client/CMakeLists.txt @@ -127,13 +127,3 @@ target_link_libraries( RialtoPlayerCommon RialtoProtobuf ) - -if ( COVERAGE_ENABLED ) - target_link_libraries( - RialtoClientComponentTests - - gcov - ) -endif() - - diff --git a/tests/componenttests/client/mocks/MediaPipelineCapabilitiesModuleMock.h b/tests/componenttests/client/mocks/MediaPipelineCapabilitiesModuleMock.h index 81cc315a1..958dc8be7 100644 --- a/tests/componenttests/client/mocks/MediaPipelineCapabilitiesModuleMock.h +++ b/tests/componenttests/client/mocks/MediaPipelineCapabilitiesModuleMock.h @@ -46,6 +46,11 @@ class MediaPipelineCapabilitiesModuleMock : public ::firebolt::rialto::MediaPipe ::firebolt::rialto::GetSupportedPropertiesResponse *response, ::google::protobuf::Closure *done), (override)); + MOCK_METHOD(void, isVideoMaster, + (::google::protobuf::RpcController * controller, const ::firebolt::rialto::IsVideoMasterRequest *request, + ::firebolt::rialto::IsVideoMasterResponse *response, ::google::protobuf::Closure *done), + (override)); + void defaultReturn(::google::protobuf::RpcController *controller, ::google::protobuf::Closure *done) { done->Run(); diff --git a/tests/componenttests/client/mocks/MediaPipelineModuleMock.h b/tests/componenttests/client/mocks/MediaPipelineModuleMock.h index 934934205..a6fc772c0 100644 --- a/tests/componenttests/client/mocks/MediaPipelineModuleMock.h +++ b/tests/componenttests/client/mocks/MediaPipelineModuleMock.h @@ -140,6 +140,9 @@ class MediaPipelineModuleMock : public ::firebolt::rialto::MediaPipelineModule MOCK_METHOD(void, processAudioGap, (::google::protobuf::RpcController * controller, const ::firebolt::rialto::ProcessAudioGapRequest *request, ::firebolt::rialto::ProcessAudioGapResponse *response, ::google::protobuf::Closure *done)); + MOCK_METHOD(void, isVideoMaster, + (::google::protobuf::RpcController * controller, const ::firebolt::rialto::IsVideoMasterRequest *request, + ::firebolt::rialto::IsVideoMasterResponse *response, ::google::protobuf::Closure *done)); void defaultReturn(::google::protobuf::RpcController *controller, ::google::protobuf::Closure *done) { diff --git a/tests/componenttests/client/tests/base/MediaPipelineTestMethods.cpp b/tests/componenttests/client/tests/base/MediaPipelineTestMethods.cpp index 2722564c1..0379384c8 100644 --- a/tests/componenttests/client/tests/base/MediaPipelineTestMethods.cpp +++ b/tests/componenttests/client/tests/base/MediaPipelineTestMethods.cpp @@ -1587,6 +1587,30 @@ void MediaPipelineTestMethods::switchSourceMpeg() EXPECT_EQ(m_mediaPipeline->switchSource(mediaSource), true); } +void MediaPipelineTestMethods::shouldCheckIsVideoMaster() +{ + EXPECT_CALL(*m_mediaPipelineCapabilitiesModuleMock, isVideoMaster(_, _, _, _)) + .WillOnce(WithArgs<0, 3>(Invoke(&(*m_mediaPipelineModuleMock), &MediaPipelineModuleMock::defaultReturn))); +} + +void MediaPipelineTestMethods::shouldFailToCheckIsVideoMaster() +{ + EXPECT_CALL(*m_mediaPipelineCapabilitiesModuleMock, isVideoMaster(_, _, _, _)) + .WillOnce(WithArgs<0, 3>(Invoke(&(*m_mediaPipelineModuleMock), &MediaPipelineModuleMock::failureReturn))); +} + +void MediaPipelineTestMethods::isVideoMaster() +{ + bool isMaster{false}; + EXPECT_TRUE(m_mediaPipelineCapabilities->isVideoMaster(isMaster)); +} + +void MediaPipelineTestMethods::isVideoMasterFailure() +{ + bool isMaster{false}; + EXPECT_FALSE(m_mediaPipelineCapabilities->isVideoMaster(isMaster)); +} + /*************************** Private methods ********************************/ void MediaPipelineTestMethods::resetWriteLocation(uint32_t partitionId) diff --git a/tests/componenttests/client/tests/base/MediaPipelineTestMethods.h b/tests/componenttests/client/tests/base/MediaPipelineTestMethods.h index 5a64b9e20..b2f007e84 100644 --- a/tests/componenttests/client/tests/base/MediaPipelineTestMethods.h +++ b/tests/componenttests/client/tests/base/MediaPipelineTestMethods.h @@ -139,6 +139,8 @@ class MediaPipelineTestMethods void shouldFailToProcessAudioGap(); void shouldSwitchSourceEacs(); void shouldSwitchSourceMpeg(); + void shouldCheckIsVideoMaster(); + void shouldFailToCheckIsVideoMaster(); // MediaPipelineClient Expect methods void shouldNotifyNetworkStateBuffering(); @@ -263,6 +265,8 @@ class MediaPipelineTestMethods void processAudioGapFailure(); void switchSourceEac(); void switchSourceMpeg(); + void isVideoMaster(); + void isVideoMasterFailure(); // Event methods void sendNotifyNetworkStateBuffering(); diff --git a/tests/componenttests/client/tests/mse/IsVideoMasterTest.cpp b/tests/componenttests/client/tests/mse/IsVideoMasterTest.cpp new file mode 100644 index 000000000..f7a3da184 --- /dev/null +++ b/tests/componenttests/client/tests/mse/IsVideoMasterTest.cpp @@ -0,0 +1,99 @@ +/* + * If not stated otherwise in this file or this component's LICENSE file the + * following copyright and licenses apply: + * + * Copyright 2025 Sky UK + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "ClientComponentTest.h" +#include + +namespace firebolt::rialto::client::ct +{ +class MuteTest : public ClientComponentTest +{ +public: + double m_isVideoMaster = false; + + MuteTest() : ClientComponentTest() + { + ClientComponentTest::startApplicationRunning(); + MediaPipelineTestMethods::startAudioVideoMediaSessionPrerollPaused(); + } + + ~MuteTest() + { + MediaPipelineTestMethods::endAudioVideoMediaSession(); + ClientComponentTest::stopApplication(); + } +}; + +/* + * Component Test: IsVideoMaster + * Test Objective: + * Test the IsVideoMaster API. + * + * Sequence Diagrams: + * IsVideoMaster - https://wiki.rdkcentral.com/display/ASP/Rialto+MSE+Misc+Sequence+Diagrams + * + * Test Setup: + * Language: C++ + * Testing Framework: Google Test + * Components: MediaPipeline + * + * Test Initialize: + * Create memory region for the shared buffer. + * Create a server that handles Control IPC requests. + * Initalise the control state to running for this test application. + * Initalise a audio video media session paused and prerolled. + * + * Test Steps: + * Step 1: Call IsVideoMaster + * Call IsVideoMaster + * Expect that IsVideoMaster propagated to the server and returns the IsVideoMaster status. + * + * Step 2: Call IsVideoMaster failure + * Call IsVideoMaster + * Expect that when IsVideoMaster fails, it returns the error status. + * + * Step 3: Call IsVideoMaster capability + * Call IsVideoMaster capability + * Expect that IsVideoMaster propagated to the server and returns the IsVideoMaster status. + * + * Step 4: Call IsVideoMaster capability failure + * Call IsVideoMaster capability + * Expect that when IsVideoMaster fails, it returns the error status. + * + * Test Teardown: + * Terminate the media session. + * Memory region created for the shared buffer is closed. + * Server is terminated. + * + * Expected Results: + * IsVideoMaster can be set and got multiple times without issue. + * + * Code: + */ +TEST_F(MuteTest, mute) +{ + // Step 1: Call IsVideoMaster + MediaPipelineTestMethods::shouldCheckIsVideoMaster(); + MediaPipelineTestMethods::isVideoMaster(); + + // Step 2: Call IsVideoMaster failure + MediaPipelineTestMethods::shouldFailToCheckIsVideoMaster(); + MediaPipelineTestMethods::isVideoMasterFailure(); +} +} // namespace firebolt::rialto::client::ct diff --git a/tests/componenttests/server/common/ActionTraits.h b/tests/componenttests/server/common/ActionTraits.h index a88293e3f..d601e8d9f 100644 --- a/tests/componenttests/server/common/ActionTraits.h +++ b/tests/componenttests/server/common/ActionTraits.h @@ -580,6 +580,14 @@ struct GetSupportedProperties static constexpr auto m_kFunction{&Stub::getSupportedProperties}; }; +struct IsVideoMaster +{ + using RequestType = ::firebolt::rialto::IsVideoMasterRequest; + using ResponseType = ::firebolt::rialto::IsVideoMasterResponse; + using Stub = ::firebolt::rialto::MediaPipelineCapabilitiesModule_Stub; + static constexpr auto m_kFunction{&Stub::isVideoMaster}; +}; + // web audio player module struct CreateWebAudioPlayer { diff --git a/tests/componenttests/server/common/MessageBuilders.cpp b/tests/componenttests/server/common/MessageBuilders.cpp index c2b4f868b..848b925f8 100644 --- a/tests/componenttests/server/common/MessageBuilders.cpp +++ b/tests/componenttests/server/common/MessageBuilders.cpp @@ -655,6 +655,12 @@ createGetSupportedPropertiesRequest(const ProtoMediaSourceType &mediaType, const return request; } +::firebolt::rialto::IsVideoMasterRequest createIsVideoMasterRequest() +{ + ::firebolt::rialto::IsVideoMasterRequest request; + return request; +} + ::firebolt::rialto::CreateWebAudioPlayerRequest createCreateWebAudioPlayerRequest(uint32 pcmRate, uint32 pcmChannels, uint32 pcmSampleSize, bool pcmIsBigEndian, bool pcmIsSigned, bool pcmIsFloat, const std::string &audioMimeType, uint32 priority) diff --git a/tests/componenttests/server/common/MessageBuilders.h b/tests/componenttests/server/common/MessageBuilders.h index 54fe2202b..dae4679ae 100644 --- a/tests/componenttests/server/common/MessageBuilders.h +++ b/tests/componenttests/server/common/MessageBuilders.h @@ -130,6 +130,7 @@ createGetSupportedMimeTypesRequest(const ProtoMediaSourceType &mediaSourceType); ::firebolt::rialto::IsMimeTypeSupportedRequest createIsMimeTypeSupportedRequest(const std::string &mimeType); ::firebolt::rialto::GetSupportedPropertiesRequest createGetSupportedPropertiesRequest(const ProtoMediaSourceType &mediaType, const std::vector &propertyNames); +::firebolt::rialto::IsVideoMasterRequest createIsVideoMasterRequest(); // web audio player module ::firebolt::rialto::CreateWebAudioPlayerRequest diff --git a/tests/componenttests/server/fixtures/MediaPipelineTest.cpp b/tests/componenttests/server/fixtures/MediaPipelineTest.cpp index ee022fee4..ea021e5d2 100644 --- a/tests/componenttests/server/fixtures/MediaPipelineTest.cpp +++ b/tests/componenttests/server/fixtures/MediaPipelineTest.cpp @@ -118,6 +118,8 @@ void MediaPipelineTest::audioSourceWillBeAttached() EXPECT_CALL(*m_gstWrapperMock, gstCapsSetSimpleIntStub(&m_audioCaps, StrEq("mpegversion"), G_TYPE_INT, 4)); EXPECT_CALL(*m_gstWrapperMock, gstCapsSetSimpleIntStub(&m_audioCaps, StrEq("channels"), G_TYPE_INT, kNumOfChannels)); EXPECT_CALL(*m_gstWrapperMock, gstCapsSetSimpleIntStub(&m_audioCaps, StrEq("rate"), G_TYPE_INT, kSampleRate)); + EXPECT_CALL(*m_gstWrapperMock, gstCapsToString(&m_audioCaps)).WillOnce(Return(&m_audioCapsStr)); + EXPECT_CALL(*m_glibWrapperMock, gFree(&m_audioCapsStr)); EXPECT_CALL(*m_gstWrapperMock, gstElementFactoryMake(StrEq("appsrc"), StrEq("audsrc"))) .WillOnce(Return(GST_ELEMENT(&m_audioAppSrc))); EXPECT_CALL(*m_gstWrapperMock, gstAppSrcSetCaps(&m_audioAppSrc, &m_audioCaps)); @@ -133,6 +135,8 @@ void MediaPipelineTest::videoSourceWillBeAttached() gstCapsSetSimpleStringStub(&m_videoCaps, StrEq("stream-format"), G_TYPE_STRING, StrEq("raw"))); EXPECT_CALL(*m_gstWrapperMock, gstCapsSetSimpleIntStub(&m_videoCaps, StrEq("width"), G_TYPE_INT, kWidth)); EXPECT_CALL(*m_gstWrapperMock, gstCapsSetSimpleIntStub(&m_videoCaps, StrEq("height"), G_TYPE_INT, kHeight)); + EXPECT_CALL(*m_gstWrapperMock, gstCapsToString(&m_videoCaps)).WillOnce(Return(&m_videoCapsStr)); + EXPECT_CALL(*m_glibWrapperMock, gFree(&m_videoCapsStr)); EXPECT_CALL(*m_gstWrapperMock, gstElementFactoryMake(StrEq("appsrc"), StrEq("vidsrc"))) .WillOnce(Return(GST_ELEMENT(&m_videoAppSrc))); EXPECT_CALL(*m_gstWrapperMock, gstAppSrcSetCaps(&m_videoAppSrc, &m_videoCaps)); diff --git a/tests/componenttests/server/tests/CMakeLists.txt b/tests/componenttests/server/tests/CMakeLists.txt index 04d368646..9fe1d15bb 100644 --- a/tests/componenttests/server/tests/CMakeLists.txt +++ b/tests/componenttests/server/tests/CMakeLists.txt @@ -98,11 +98,3 @@ target_link_libraries( RialtoServerComponentTestsFixtures RialtoTestCommonUtils ) - -if ( COVERAGE_ENABLED ) - target_link_libraries( - RialtoServerComponentTests - - gcov - ) -endif() diff --git a/tests/componenttests/server/tests/mediaPipeline/DualVideoPlaybackTest.cpp b/tests/componenttests/server/tests/mediaPipeline/DualVideoPlaybackTest.cpp index 7e3b90170..5b3efd9d9 100644 --- a/tests/componenttests/server/tests/mediaPipeline/DualVideoPlaybackTest.cpp +++ b/tests/componenttests/server/tests/mediaPipeline/DualVideoPlaybackTest.cpp @@ -141,6 +141,8 @@ class DualVideoPlaybackTest : public MediaPipelineTest .RetiresOnSaturation(); EXPECT_CALL(*m_gstWrapperMock, gstCapsSetSimpleIntStub(&m_videoCaps, StrEq("height"), G_TYPE_INT, kHeight)) .RetiresOnSaturation(); + EXPECT_CALL(*m_gstWrapperMock, gstCapsToString(&m_videoCaps)).WillOnce(Return(&m_videoCapsStr)); + EXPECT_CALL(*m_glibWrapperMock, gFree(&m_videoCapsStr)); EXPECT_CALL(*m_gstWrapperMock, gstElementFactoryMake(StrEq("appsrc"), StrEq("vidsrc"))) .WillOnce(Return(GST_ELEMENT(&m_secondaryVideoAppSrc))); EXPECT_CALL(*m_gstWrapperMock, gstAppSrcSetCaps(&m_secondaryVideoAppSrc, &m_videoCaps)); diff --git a/tests/componenttests/server/tests/mediaPipeline/PipelinePropertyTest.cpp b/tests/componenttests/server/tests/mediaPipeline/PipelinePropertyTest.cpp index 6ef30946e..2284fd8cd 100644 --- a/tests/componenttests/server/tests/mediaPipeline/PipelinePropertyTest.cpp +++ b/tests/componenttests/server/tests/mediaPipeline/PipelinePropertyTest.cpp @@ -402,6 +402,7 @@ class PipelinePropertyTest : public MediaPipelineTest GstIterator m_it{}; char m_dummy{0}; GstElementFactory *m_factory = reinterpret_cast(&m_dummy); + GstRegistry m_registry{}; }; /* @@ -587,7 +588,7 @@ TEST_F(PipelinePropertyTest, pipelinePropertyGetAndSetSuccess) willStop(); stop(); - // Step 18: Destroy media session + // Step 19: Destroy media session gstPlayerWillBeDestructed(); destroySession(); } diff --git a/tests/componenttests/server/tests/mediaPipelineCapabilities/MediaPipelineCapabilitiesTest.cpp b/tests/componenttests/server/tests/mediaPipelineCapabilities/MediaPipelineCapabilitiesTest.cpp index 2ebc6ec14..acfcef40b 100644 --- a/tests/componenttests/server/tests/mediaPipelineCapabilities/MediaPipelineCapabilitiesTest.cpp +++ b/tests/componenttests/server/tests/mediaPipelineCapabilities/MediaPipelineCapabilitiesTest.cpp @@ -91,6 +91,12 @@ class MediaPipelineCapabilitiesTest : public RialtoServerComponentTest m_listOfFactories = nullptr; } + void willCheckIfVideoIsMaster() + { + EXPECT_CALL(*m_gstWrapperMock, gstRegistryGet()).WillOnce(Return(&m_registry)); + EXPECT_CALL(*m_gstWrapperMock, gstRegistryLookupFeature(&m_registry, StrEq("amlhalasink"))).WillOnce(Return(nullptr)); + } + private: GList *m_listOfFactories{nullptr}; GParamSpec m_dummyParams[kNumPropertiesOnSink]; @@ -98,6 +104,7 @@ class MediaPipelineCapabilitiesTest : public RialtoServerComponentTest std::vector m_kParamNames{kPropertyName1, kPropertyName3, kPropertyName2, kAudioFade}; GstElement m_object; GstElementFactory *m_elementFactory; + GstRegistry m_registry{}; }; /* @@ -372,4 +379,45 @@ TEST_F(MediaPipelineCapabilitiesTest, checkGetSupportedProperties) willCallGetSupportedProperties(); callGetSupportedProperties(); } + +/* + * Component Test: Check, if video is master + * Test Objective: + * Test if video is master in Rialto Server + * + * Sequence Diagrams: + * Capabilities + * https://wiki.rdkcentral.com/display/ASP/Rialto+MSE+Misc+Sequence+Diagrams#RialtoMSEMiscSequenceDiagrams + * + * Test Setup: + * Language: C++ + * Testing Framework: Google Test + * Components: MediaPipelineCapabilities + * + * Test Initialize: + * Set Rialto Server to Active + * Connect Rialto Client Stub + * + * Test Steps: + * Step 1: Check is video master + * Client stub requests the server to check, if video is master + * Expect that server returns, that video is master + * + * Test Teardown: + * Server is terminated. + * + * Expected Results: + * Rialto server checks, if mime types are supported. + * + * Code: + */ +TEST_F(MediaPipelineCapabilitiesTest, checkIsVideoMaster) +{ + // Step 1: Check is video master + willCheckIfVideoIsMaster(); + ConfigureAction{m_clientStub} + .send(createIsVideoMasterRequest()) + .expectSuccess() + .matchResponse([](const auto &resp) { EXPECT_TRUE(resp.is_video_master()); }); +}; } // namespace firebolt::rialto::server::ct diff --git a/tests/componenttests/server/tests/webAudio/WebAudioTestMethods.cpp b/tests/componenttests/server/tests/webAudio/WebAudioTestMethods.cpp index d7876715e..1d34fe7e3 100644 --- a/tests/componenttests/server/tests/webAudio/WebAudioTestMethods.cpp +++ b/tests/componenttests/server/tests/webAudio/WebAudioTestMethods.cpp @@ -199,15 +199,19 @@ void WebAudioTestMethods::willCreateWebAudioPlayer() EXPECT_CALL(*m_gstWrapperMock, gstElementFactoryMake(StrEq("audioconvert"), _)).WillOnce(Return(&m_convert)); EXPECT_CALL(*m_gstWrapperMock, gstElementFactoryMake(StrEq("audioresample"), _)).WillOnce(Return(&m_resample)); EXPECT_CALL(*m_gstWrapperMock, gstElementFactoryMake(StrEq("volume"), _)).WillOnce(Return(&m_volume)); + EXPECT_CALL(*m_gstWrapperMock, gstElementFactoryMake(StrEq("queue"), _)).WillOnce(Return(&m_queue)); + EXPECT_CALL(*m_glibWrapperMock, gObjectSetStub(&m_queue, StrEq("max-size-bytes"))); EXPECT_CALL(*m_gstWrapperMock, gstBinAdd(GST_BIN(&m_pipeline), GST_ELEMENT(&m_appSrc))).WillOnce(Return(TRUE)); EXPECT_CALL(*m_gstWrapperMock, gstBinAdd(GST_BIN(&m_pipeline), &m_convert)).WillOnce(Return(TRUE)); EXPECT_CALL(*m_gstWrapperMock, gstBinAdd(GST_BIN(&m_pipeline), &m_resample)).WillOnce(Return(TRUE)); EXPECT_CALL(*m_gstWrapperMock, gstBinAdd(GST_BIN(&m_pipeline), &m_volume)).WillOnce(Return(TRUE)); + EXPECT_CALL(*m_gstWrapperMock, gstBinAdd(GST_BIN(&m_pipeline), &m_queue)).WillOnce(Return(TRUE)); EXPECT_CALL(*m_gstWrapperMock, gstBinAdd(GST_BIN(&m_pipeline), &m_sink)).WillOnce(Return(TRUE)); EXPECT_CALL(*m_gstWrapperMock, gstElementLink(GST_ELEMENT(&m_appSrc), &m_convert)).WillOnce(Return(TRUE)); EXPECT_CALL(*m_gstWrapperMock, gstElementLink(&m_convert, &m_resample)).WillOnce(Return(TRUE)); EXPECT_CALL(*m_gstWrapperMock, gstElementLink(&m_resample, &m_volume)).WillOnce(Return(TRUE)); - EXPECT_CALL(*m_gstWrapperMock, gstElementLink(&m_volume, &m_sink)).WillOnce(Return(TRUE)); + EXPECT_CALL(*m_gstWrapperMock, gstElementLink(&m_volume, &m_queue)).WillOnce(Return(TRUE)); + EXPECT_CALL(*m_gstWrapperMock, gstElementLink(&m_queue, &m_sink)).WillOnce(Return(TRUE)); EXPECT_CALL(*m_gstWrapperMock, gstCapsNewEmptySimple(StrEq(kAudioMimeType))).WillOnce(Return(&m_gstCaps1)); EXPECT_CALL(*m_gstWrapperMock, gstCapsSetSimpleIntStub(&m_gstCaps1, StrEq("channels"), G_TYPE_INT, kPcmChannels)); diff --git a/tests/componenttests/server/tests/webAudio/WebAudioTestMethods.h b/tests/componenttests/server/tests/webAudio/WebAudioTestMethods.h index 166b47ea8..cd3cc7f32 100644 --- a/tests/componenttests/server/tests/webAudio/WebAudioTestMethods.h +++ b/tests/componenttests/server/tests/webAudio/WebAudioTestMethods.h @@ -109,6 +109,7 @@ class WebAudioTestMethods : public RialtoServerComponentTest GstElement m_convert; GstElement m_resample; GstElement m_volume; + GstElement m_queue; GstBuffer m_buffer; gchar m_capsStr; diff --git a/tests/unittests/common/unittests/CMakeLists.txt b/tests/unittests/common/unittests/CMakeLists.txt index 63df0a217..b9d1ab2a8 100644 --- a/tests/unittests/common/unittests/CMakeLists.txt +++ b/tests/unittests/common/unittests/CMakeLists.txt @@ -18,7 +18,8 @@ # if ( COVERAGE_ENABLED ) - add_compile_options(-coverage) + add_compile_options(--coverage) + add_link_options(--coverage) endif() add_gtests ( @@ -41,11 +42,3 @@ target_link_libraries( RialtoCommonUnitTests RialtoCommon ) - -if ( COVERAGE_ENABLED ) - target_link_libraries( - RialtoCommonUnitTests - - gcov - ) -endif() diff --git a/tests/unittests/ipc/CMakeLists.txt b/tests/unittests/ipc/CMakeLists.txt index ec517eec4..a170c44d0 100644 --- a/tests/unittests/ipc/CMakeLists.txt +++ b/tests/unittests/ipc/CMakeLists.txt @@ -64,13 +64,3 @@ target_link_libraries( RialtoIpcStub RialtoProtobuf ) - -if ( COVERAGE_ENABLED ) - target_link_libraries( - RialtoIpcUnitTests - - gcov - ) -endif() - - diff --git a/tests/unittests/logging/CMakeLists.txt b/tests/unittests/logging/CMakeLists.txt index 2811f5836..57bdc177a 100644 --- a/tests/unittests/logging/CMakeLists.txt +++ b/tests/unittests/logging/CMakeLists.txt @@ -40,12 +40,3 @@ target_link_libraries( # # Link application source RialtoLogging ) - -if ( COVERAGE_ENABLED ) - target_link_libraries( - RialtoLoggingUnitTests - - gcov - ) -endif() - diff --git a/tests/unittests/media/client/ipc/CMakeLists.txt b/tests/unittests/media/client/ipc/CMakeLists.txt index a2fcca219..d00f5d6cf 100644 --- a/tests/unittests/media/client/ipc/CMakeLists.txt +++ b/tests/unittests/media/client/ipc/CMakeLists.txt @@ -145,11 +145,3 @@ target_link_libraries( RialtoIpcClient RialtoProtobuf ) - -if ( COVERAGE_ENABLED ) - target_link_libraries( - RialtoClientIpcUnitTests - - gcov - ) -endif() diff --git a/tests/unittests/media/client/ipc/mediaPipelineCapabilitiesIpc/MediaPipelineCapabilitiesIpcTest.cpp b/tests/unittests/media/client/ipc/mediaPipelineCapabilitiesIpc/MediaPipelineCapabilitiesIpcTest.cpp index 1fba66ab9..13cbffe06 100644 --- a/tests/unittests/media/client/ipc/mediaPipelineCapabilitiesIpc/MediaPipelineCapabilitiesIpcTest.cpp +++ b/tests/unittests/media/client/ipc/mediaPipelineCapabilitiesIpc/MediaPipelineCapabilitiesIpcTest.cpp @@ -66,6 +66,13 @@ class MediaPipelineCapabilitiesIpcTest : public IpcModuleBase, public ::testing: dynamic_cast(response); getSupportedPropertiesResponse->add_supported_properties(kPropertyName); } + + void setIsVideoMasterResponse(google::protobuf::Message *response) + { + firebolt::rialto::IsVideoMasterResponse *isVideoMasterResponse = + dynamic_cast(response); + isVideoMasterResponse->set_is_video_master(true); + } }; TEST_F(MediaPipelineCapabilitiesIpcTest, createMediaPipelineCapabilitiesIpc) @@ -217,3 +224,53 @@ TEST_F(MediaPipelineCapabilitiesIpcTest, GetSupportedSubtitlesMimeTypesSuccess) EXPECT_EQ(m_sut->getSupportedMimeTypes(MediaSourceType::SUBTITLE), m_mimeTypes); } + +TEST_F(MediaPipelineCapabilitiesIpcTest, IsVideoMasterSuccess) +{ + bool isMaster{false}; + + createMediaPipelineCapabilitiesIpc(); + expectIpcApiCallSuccess(); + + EXPECT_CALL(*m_channelMock, + CallMethod(methodMatcher("isVideoMaster"), m_controllerMock.get(), _, _, m_blockingClosureMock.get())) + .WillOnce(WithArgs<3>(Invoke(this, &MediaPipelineCapabilitiesIpcTest::setIsVideoMasterResponse))); + + EXPECT_TRUE(m_sut->isVideoMaster(isMaster)); +} + +TEST_F(MediaPipelineCapabilitiesIpcTest, IsVideoMastersDisconnected) +{ + bool isMaster{false}; + + createMediaPipelineCapabilitiesIpc(); + expectIpcApiCallDisconnected(); + + EXPECT_FALSE(m_sut->isVideoMaster(isMaster)); +} + +TEST_F(MediaPipelineCapabilitiesIpcTest, IsVideoMasterDisconnectedReconnectChannel) +{ + bool isMaster{false}; + + createMediaPipelineCapabilitiesIpc(); + expectIpcApiCallReconnected(); + + EXPECT_CALL(*m_channelMock, + CallMethod(methodMatcher("isVideoMaster"), m_controllerMock.get(), _, _, m_blockingClosureMock.get())) + .WillOnce(WithArgs<3>(Invoke(this, &MediaPipelineCapabilitiesIpcTest::setIsVideoMasterResponse))); + + EXPECT_TRUE(m_sut->isVideoMaster(isMaster)); +} + +TEST_F(MediaPipelineCapabilitiesIpcTest, IsVideoMasterFailure) +{ + bool isMaster{false}; + + createMediaPipelineCapabilitiesIpc(); + expectIpcApiCallFailure(); + + EXPECT_CALL(*m_channelMock, CallMethod(methodMatcher("isVideoMaster"), _, _, _, _)); + + EXPECT_FALSE(m_sut->isVideoMaster(isMaster)); +} diff --git a/tests/unittests/media/client/main/CMakeLists.txt b/tests/unittests/media/client/main/CMakeLists.txt index acb66b743..d0ae9c218 100644 --- a/tests/unittests/media/client/main/CMakeLists.txt +++ b/tests/unittests/media/client/main/CMakeLists.txt @@ -121,13 +121,3 @@ target_link_libraries( # # Link application source RialtoClient ) - -if ( COVERAGE_ENABLED ) - target_link_libraries( - RialtoClientUnitTests - - gcov - ) -endif() - - diff --git a/tests/unittests/media/client/main/mediaPipelineCapabilities/MediaPipelineCapabilitiesTest.cpp b/tests/unittests/media/client/main/mediaPipelineCapabilities/MediaPipelineCapabilitiesTest.cpp index b48532202..6b77b620c 100644 --- a/tests/unittests/media/client/main/mediaPipelineCapabilities/MediaPipelineCapabilitiesTest.cpp +++ b/tests/unittests/media/client/main/mediaPipelineCapabilities/MediaPipelineCapabilitiesTest.cpp @@ -102,6 +102,15 @@ TEST_F(MediaPipelineCapabilitiesTest, getSupportedProperties) EXPECT_EQ(supportedProperties, kProperties); } +TEST_F(MediaPipelineCapabilitiesTest, isVideoMaster) +{ + bool isMaster{false}; + createMediaPipelineCapabilitiesIpcSucceeds(); + + EXPECT_CALL(*m_mediaPipelineCapabilitiesIpcMock, isVideoMaster(isMaster)).WillOnce(Return(true)); + EXPECT_TRUE(m_sut->isVideoMaster(isMaster)); +} + /** * Test the factory failure */ diff --git a/tests/unittests/media/client/mocks/ipc/MediaPipelineCapabilitiesIpcMock.h b/tests/unittests/media/client/mocks/ipc/MediaPipelineCapabilitiesIpcMock.h index 7e6ac845a..4b90da019 100644 --- a/tests/unittests/media/client/mocks/ipc/MediaPipelineCapabilitiesIpcMock.h +++ b/tests/unittests/media/client/mocks/ipc/MediaPipelineCapabilitiesIpcMock.h @@ -38,6 +38,7 @@ class MediaPipelineCapabilitiesIpcMock : public IMediaPipelineCapabilities MOCK_METHOD(bool, isMimeTypeSupported, (const std::string &mimeType), (override)); MOCK_METHOD(std::vector, getSupportedProperties, (MediaSourceType mediaType, const std::vector &propertyNames), (override)); + MOCK_METHOD(bool, isVideoMaster, (bool &isVideoMaster), (override)); }; } // namespace firebolt::rialto::client diff --git a/tests/unittests/media/common/CMakeLists.txt b/tests/unittests/media/common/CMakeLists.txt index 88726d5e7..c129e0d3e 100644 --- a/tests/unittests/media/common/CMakeLists.txt +++ b/tests/unittests/media/common/CMakeLists.txt @@ -53,12 +53,3 @@ target_link_libraries( RialtoPlayerCommon RialtoProtobuf ) - -if ( COVERAGE_ENABLED ) - target_link_libraries( - RialtoPlayerCommonUnitTests - - gcov - ) -endif() - diff --git a/tests/unittests/media/common/mediaFrameWriterV2/WriteFrameTest.cpp b/tests/unittests/media/common/mediaFrameWriterV2/WriteFrameTest.cpp index cae30412b..ff83078c2 100644 --- a/tests/unittests/media/common/mediaFrameWriterV2/WriteFrameTest.cpp +++ b/tests/unittests/media/common/mediaFrameWriterV2/WriteFrameTest.cpp @@ -50,6 +50,7 @@ const std::vector kInitVector{34, 53, 54, 62, 56}; constexpr size_t kNumClearBytes{2}; constexpr size_t kNumEncryptedBytes{7}; constexpr uint32_t kInitWithLast15{1}; +constexpr uint64_t kDisplayOffset{35}; uint32_t readLEUint32(const uint8_t *buffer) { @@ -78,6 +79,7 @@ void addOptionalData(std::unique_ptr &segment) segment->setSegmentAlignment(SegmentAlignment::NAL); segment->setExtraData(kExtraData); segment->setCodecData(std::make_shared(CodecData{kCodecDataVector, CodecDataType::BUFFER})); + segment->setDisplayOffset(kDisplayOffset); } void addEncryptionData(std::unique_ptr &segment) @@ -133,6 +135,7 @@ void checkOptionalMetadataPresent(const MediaSegmentMetadata &metadata) EXPECT_TRUE(metadata.has_codec_data()); EXPECT_EQ(metadata.codec_data().data(), std::string(kCodecDataVector.begin(), kCodecDataVector.end())); EXPECT_EQ(metadata.codec_data().type(), MediaSegmentMetadata_CodecData_Type_BUFFER); + EXPECT_EQ(metadata.display_offset(), kDisplayOffset); } void checkEncryptionMetadataNotPresent(const MediaSegmentMetadata &metadata) diff --git a/tests/unittests/media/server/gstplayer/CMakeLists.txt b/tests/unittests/media/server/gstplayer/CMakeLists.txt index 94e79529c..f3da20901 100644 --- a/tests/unittests/media/server/gstplayer/CMakeLists.txt +++ b/tests/unittests/media/server/gstplayer/CMakeLists.txt @@ -147,12 +147,4 @@ target_link_libraries(RialtoServerGstPlayerUnitTests RialtoTestCommonUtils ) -if ( COVERAGE_ENABLED ) - target_link_libraries( - RialtoServerGstPlayerUnitTests - - gcov - ) -endif() - set_target_properties(RialtoServerGstPlayerUnitTests PROPERTIES COMPILE_FLAGS "-Wno-write-strings") diff --git a/tests/unittests/media/server/gstplayer/flushWatcher/FlushWatcherTests.cpp b/tests/unittests/media/server/gstplayer/flushWatcher/FlushWatcherTests.cpp index dae7893d3..2d93ba441 100644 --- a/tests/unittests/media/server/gstplayer/flushWatcher/FlushWatcherTests.cpp +++ b/tests/unittests/media/server/gstplayer/flushWatcher/FlushWatcherTests.cpp @@ -30,17 +30,21 @@ TEST(FlushWatcherTests, ShouldReturnCorrectValue) EXPECT_FALSE(watcher.isFlushOngoing()); // Flushing when flushing set for at least one source - watcher.setFlushing(MediaSourceType::AUDIO); + watcher.setFlushing(MediaSourceType::AUDIO, false); EXPECT_TRUE(watcher.isFlushOngoing()); + EXPECT_FALSE(watcher.isAsyncFlushOngoing()); - watcher.setFlushing(MediaSourceType::VIDEO); + watcher.setFlushing(MediaSourceType::VIDEO, true); EXPECT_TRUE(watcher.isFlushOngoing()); + EXPECT_TRUE(watcher.isAsyncFlushOngoing()); // Not flushing when all flush flags cleared watcher.setFlushed(MediaSourceType::AUDIO); EXPECT_TRUE(watcher.isFlushOngoing()); + EXPECT_TRUE(watcher.isAsyncFlushOngoing()); watcher.setFlushed(MediaSourceType::VIDEO); EXPECT_FALSE(watcher.isFlushOngoing()); + EXPECT_FALSE(watcher.isAsyncFlushOngoing()); } } // namespace firebolt::rialto::server diff --git a/tests/unittests/media/server/gstplayer/genericPlayer/GstCapabilitiesTest.cpp b/tests/unittests/media/server/gstplayer/genericPlayer/GstCapabilitiesTest.cpp index a9fd3a7dc..9d9940488 100644 --- a/tests/unittests/media/server/gstplayer/genericPlayer/GstCapabilitiesTest.cpp +++ b/tests/unittests/media/server/gstplayer/genericPlayer/GstCapabilitiesTest.cpp @@ -74,6 +74,7 @@ class GstCapabilitiesTest : public testing::Test GstCapabilitiesTest() // valid values of GstCaps are not needed, only addresses will be used : m_capsMap{{"audio/mpeg, mpegversion=(int)4", {}}, + {"audio/mpeg, mpegversion=(int)1, layer=(int)3", {}}, {"audio/x-eac3", {}}, {"audio/x-opus", {}}, {"audio/x-opus, channel-mapping-family=(int)0", {}}, @@ -584,6 +585,9 @@ TEST_F(GstCapabilitiesTest, CreateGstCapabilities_OneDecoderWithOneSinkPad_Parse .WillOnce(Return(true)); EXPECT_CALL(*m_gstWrapperMock, gstCapsCanIntersect(&m_capsMap["audio/x-raw"], &m_sinkTemplateCaps)) .WillOnce(Return(true)); + EXPECT_CALL(*m_gstWrapperMock, + gstCapsCanIntersect(&m_capsMap["audio/mpeg, mpegversion=(int)1, layer=(int)3"], &m_sinkTemplateCaps)) + .WillOnce(Return(true)); EXPECT_CALL(m_gstInitialiserMock, waitForInitialisation()); m_sut = std::make_unique(m_gstWrapperMock, m_glibWrapperMock, m_rdkGstreamerUtilsWrapperMock, @@ -593,6 +597,7 @@ TEST_F(GstCapabilitiesTest, CreateGstCapabilities_OneDecoderWithOneSinkPad_Parse EXPECT_TRUE(m_sut->isMimeTypeSupported("video/h264")); EXPECT_TRUE(m_sut->isMimeTypeSupported("audio/x-raw")); + EXPECT_TRUE(m_sut->isMimeTypeSupported("audio/mp3")); EXPECT_FALSE(m_sut->isMimeTypeSupported("video/x-av1")); EXPECT_FALSE(m_sut->isMimeTypeSupported("audio/x-opus")); } @@ -878,3 +883,39 @@ TEST_F(GstCapabilitiesTest, CreateGstCapabilities_GetSubtitlesMimeTypes) EXPECT_EQ(m_sut->getSupportedMimeTypes(MediaSourceType::SUBTITLE), kSubtitleMimeTypes); } + +TEST_F(GstCapabilitiesTest, shouldFailToCheckIfVideoIsMasterWhenRegistryIsNull) +{ + createSutWithNoDecoderAndNoSink(); + + EXPECT_CALL(*m_gstWrapperMock, gstRegistryGet()).WillOnce(Return(nullptr)); + bool isVideoMaster{false}; + EXPECT_FALSE(m_sut->isVideoMaster(isVideoMaster)); +} + +TEST_F(GstCapabilitiesTest, shouldCheckIfVideoIsMasterAndReturnTrue) +{ + createSutWithNoDecoderAndNoSink(); + + GstRegistry registry{}; + EXPECT_CALL(*m_gstWrapperMock, gstRegistryGet()).WillOnce(Return(®istry)); + EXPECT_CALL(*m_gstWrapperMock, gstRegistryLookupFeature(®istry, StrEq("amlhalasink"))).WillOnce(Return(nullptr)); + bool isVideoMaster{false}; + EXPECT_TRUE(m_sut->isVideoMaster(isVideoMaster)); + EXPECT_TRUE(isVideoMaster); +} + +TEST_F(GstCapabilitiesTest, shouldCheckIfVideoIsMasterAndReturnFalse) +{ + createSutWithNoDecoderAndNoSink(); + + GstRegistry registry{}; + GstObject feature{}; + EXPECT_CALL(*m_gstWrapperMock, gstRegistryGet()).WillOnce(Return(®istry)); + EXPECT_CALL(*m_gstWrapperMock, gstRegistryLookupFeature(®istry, StrEq("amlhalasink"))) + .WillOnce(Return(GST_PLUGIN_FEATURE(&feature))); + EXPECT_CALL(*m_gstWrapperMock, gstObjectUnref(GST_PLUGIN_FEATURE(&feature))); + bool isVideoMaster{false}; + EXPECT_TRUE(m_sut->isVideoMaster(isVideoMaster)); + EXPECT_FALSE(isVideoMaster); +} diff --git a/tests/unittests/media/server/gstplayer/genericPlayer/GstDispatcherThreadClientTest.cpp b/tests/unittests/media/server/gstplayer/genericPlayer/GstDispatcherThreadClientTest.cpp index 617e4ba92..ed883ce93 100644 --- a/tests/unittests/media/server/gstplayer/genericPlayer/GstDispatcherThreadClientTest.cpp +++ b/tests/unittests/media/server/gstplayer/genericPlayer/GstDispatcherThreadClientTest.cpp @@ -55,14 +55,12 @@ class GstDispatcherThreadClientTest : public GstGenericPlayerTestCommon TEST_F(GstDispatcherThreadClientTest, shouldHandleBusMessage) { - constexpr bool kIsFlushing{false}; GstMessage message{}; std::unique_ptr messageTask{std::make_unique>()}; - EXPECT_CALL(m_flushWatcherMock, isFlushOngoing()).WillOnce(Return(kIsFlushing)); EXPECT_CALL(dynamic_cast &>(*messageTask), execute()); EXPECT_CALL(m_workerThreadMock, enqueueTask(_)) .WillRepeatedly(Invoke([](std::unique_ptr &&task) { task->execute(); })); - EXPECT_CALL(m_taskFactoryMock, createHandleBusMessage(_, _, &message, kIsFlushing)) + EXPECT_CALL(m_taskFactoryMock, createHandleBusMessage(_, _, &message, _)) .WillOnce(Return(ByMove(std::move(messageTask)))); m_sut->handleBusMessage(&message); diff --git a/tests/unittests/media/server/gstplayer/genericPlayer/GstGenericPlayerPrivateTest.cpp b/tests/unittests/media/server/gstplayer/genericPlayer/GstGenericPlayerPrivateTest.cpp index ead4576bd..b9ea88135 100644 --- a/tests/unittests/media/server/gstplayer/genericPlayer/GstGenericPlayerPrivateTest.cpp +++ b/tests/unittests/media/server/gstplayer/genericPlayer/GstGenericPlayerPrivateTest.cpp @@ -79,6 +79,7 @@ const std::string kSyncModeStreamingStr{"syncmode-streaming"}; const std::string kBufferingLimitStr{"limit-buffering-ms"}; const std::string kUseBufferingStr{"use-buffering"}; const std::string kFrameStepOnPrerollStr{"frame-step-on-preroll"}; +constexpr bool kShowVideoWindow{true}; } // namespace bool operator==(const GstRialtoProtectionData &lhs, const GstRialtoProtectionData &rhs) @@ -97,6 +98,7 @@ class GstGenericPlayerPrivateTest : public GstGenericPlayerTestCommon GstElement *m_realElement; GstElement m_element{}; GParamSpec m_rectangleSpec{}; + GParamSpec m_showVideoWindowSpec{}; GstEvent m_event{}; GstGenericPlayerPrivateTest() @@ -1989,3 +1991,36 @@ TEST_F(GstGenericPlayerPrivateTest, shouldSetSourceFlushed) EXPECT_CALL(m_flushWatcherMock, setFlushed(MediaSourceType::AUDIO)); m_sut->setSourceFlushed(MediaSourceType::AUDIO); } + +TEST_F(GstGenericPlayerPrivateTest, failToSetShowVideoWindowNoValue) +{ + EXPECT_FALSE(m_sut->setShowVideoWindow()); +} + +TEST_F(GstGenericPlayerPrivateTest, failToSetShowVideoWindowNoSink) +{ + modifyContext([&](GenericPlayerContext &context) { context.pendingShowVideoWindow = true; }); + EXPECT_CALL(*m_glibWrapperMock, gObjectGetStub(_, StrEq(kVideoSinkStr.c_str()), _)); + EXPECT_FALSE(m_sut->setShowVideoWindow()); +} + +TEST_F(GstGenericPlayerPrivateTest, failToSetShowVideoWindowNoProperty) +{ + modifyContext([&](GenericPlayerContext &context) { context.pendingShowVideoWindow = true; }); + expectGetSink(kVideoSinkStr, m_realElement); + EXPECT_CALL(*m_glibWrapperMock, gObjectClassFindProperty(_, StrEq("show-video-window"))).WillOnce(Return(nullptr)); + EXPECT_CALL(*m_gstWrapperMock, gstObjectUnref(m_realElement)); + EXPECT_FALSE(m_sut->setShowVideoWindow()); +} + +TEST_F(GstGenericPlayerPrivateTest, shouldSetShowVideoWindow) +{ + modifyContext([&](GenericPlayerContext &context) { context.pendingShowVideoWindow = true; }); + + expectGetSink(kVideoSinkStr, m_realElement); + EXPECT_CALL(*m_glibWrapperMock, gObjectClassFindProperty(_, StrEq("show-video-window"))) + .WillOnce(Return(&m_showVideoWindowSpec)); + EXPECT_CALL(*m_glibWrapperMock, gObjectSetStub(m_realElement, StrEq("show-video-window"))); + EXPECT_CALL(*m_gstWrapperMock, gstObjectUnref(m_realElement)); + EXPECT_TRUE(m_sut->setShowVideoWindow()); +} diff --git a/tests/unittests/media/server/gstplayer/genericPlayer/GstGenericPlayerTest.cpp b/tests/unittests/media/server/gstplayer/genericPlayer/GstGenericPlayerTest.cpp index 7e0c3c54c..e3ae84101 100644 --- a/tests/unittests/media/server/gstplayer/genericPlayer/GstGenericPlayerTest.cpp +++ b/tests/unittests/media/server/gstplayer/genericPlayer/GstGenericPlayerTest.cpp @@ -843,13 +843,23 @@ TEST_F(GstGenericPlayerTest, shouldPing) TEST_F(GstGenericPlayerTest, shouldFlush) { constexpr bool kResetTime{true}; + bool isAsync{true}; std::unique_ptr task{std::make_unique>()}; - EXPECT_CALL(m_flushWatcherMock, setFlushing(MediaSourceType::AUDIO)); + EXPECT_CALL(m_flushWatcherMock, setFlushing(MediaSourceType::VIDEO, isAsync)); + expectGetSink(kVideoSinkStr, m_element); + EXPECT_CALL(*m_glibWrapperMock, gObjectGetStub(_, StrEq("async"), _)) + .WillOnce(Invoke( + [&](gpointer object, const gchar *first_property_name, void *val) + { + gboolean *returnVal = reinterpret_cast(val); + *returnVal = TRUE; + })); + EXPECT_CALL(*m_gstWrapperMock, gstObjectUnref(m_element)); EXPECT_CALL(dynamic_cast &>(*task), execute()); - EXPECT_CALL(m_taskFactoryMock, createFlush(_, _, MediaSourceType::AUDIO, kResetTime)) + EXPECT_CALL(m_taskFactoryMock, createFlush(_, _, MediaSourceType::VIDEO, kResetTime)) .WillOnce(Return(ByMove(std::move(task)))); - m_sut->flush(MediaSourceType::AUDIO, kResetTime); + m_sut->flush(MediaSourceType::VIDEO, kResetTime, isAsync); } TEST_F(GstGenericPlayerTest, shouldSetSourcePosition) @@ -1043,18 +1053,3 @@ TEST_F(GstGenericPlayerTest, shouldSwitchSource) m_sut->switchSource(source); } - -TEST_F(GstGenericPlayerTest, shouldCheckIfSinkIsAsync) -{ - expectGetSink(kVideoSinkStr, m_element); - EXPECT_CALL(*m_glibWrapperMock, gObjectGetStub(_, StrEq("async"), _)) - .WillOnce(Invoke( - [&](gpointer object, const gchar *first_property_name, void *val) - { - gboolean *returnVal = reinterpret_cast(val); - *returnVal = TRUE; - })); - EXPECT_CALL(*m_gstWrapperMock, gstObjectUnref(m_element)); - - EXPECT_TRUE(m_sut->isAsync(MediaSourceType::VIDEO)); -} diff --git a/tests/unittests/media/server/gstplayer/genericPlayer/common/GenericTasksTestsBase.cpp b/tests/unittests/media/server/gstplayer/genericPlayer/common/GenericTasksTestsBase.cpp index ffac46908..852abf977 100644 --- a/tests/unittests/media/server/gstplayer/genericPlayer/common/GenericTasksTestsBase.cpp +++ b/tests/unittests/media/server/gstplayer/genericPlayer/common/GenericTasksTestsBase.cpp @@ -137,6 +137,7 @@ constexpr bool kIsAudioAac{false}; constexpr uint64_t kStopPosition{4523}; const std::vector kStreamHeaderVector{1, 2, 3, 4}; constexpr bool kFramed{true}; +constexpr uint64_t kDisplayOffset{35}; firebolt::rialto::IMediaPipeline::MediaSegmentVector buildAudioSamples() { @@ -173,10 +174,12 @@ firebolt::rialto::IMediaPipeline::MediaSegmentVector buildSubtitleSamples() std::make_unique(kSubtitleSourceId, firebolt::rialto::MediaSourceType::SUBTITLE, kItHappenedInThePast, kDuration)); + dataVec.back()->setDisplayOffset(kDisplayOffset); dataVec.emplace_back( std::make_unique(kSubtitleSourceId, firebolt::rialto::MediaSourceType::SUBTITLE, kItWillHappenInTheFuture, kDuration)); + dataVec.back()->setDisplayOffset(kDisplayOffset); return dataVec; } @@ -798,6 +801,21 @@ void GenericTasksTestsBase::shouldSetupVideoSinkElementWithPendingRenderFrame() expectSetupVideoSinkElement(); } +void GenericTasksTestsBase::shouldSetupVideoSinkElementWithPendingShowVideoWindow() +{ + testContext->m_context.pendingShowVideoWindow = true; + EXPECT_CALL(*testContext->m_glibWrapper, gTypeName(G_OBJECT_TYPE(testContext->m_element))) + .WillOnce(Return(kElementTypeName.c_str())); + EXPECT_CALL(*testContext->m_glibWrapper, gStrHasPrefix(_, StrEq("amlhalasink"))).WillOnce(Return(FALSE)); + EXPECT_CALL(*testContext->m_glibWrapper, gStrHasPrefix(_, StrEq("brcmaudiosink"))).WillOnce(Return(FALSE)); + EXPECT_CALL(*testContext->m_glibWrapper, gStrHasPrefix(_, StrEq("rialtotexttracksink"))).WillOnce(Return(FALSE)); + EXPECT_CALL(*testContext->m_gstWrapper, gstIsBaseParse(_)).WillOnce(Return(FALSE)); + + // This is the extra EXPECT caused by setting pendingShowVideoWindow... + EXPECT_CALL(testContext->m_gstPlayer, setShowVideoWindow()).WillOnce(Return(true)); + expectSetupVideoSinkElement(); +} + void GenericTasksTestsBase::shouldSetupAudioElementAmlhalasinkWhenVideoExists() { setContextStreamInfo(firebolt::rialto::MediaSourceType::VIDEO); @@ -1522,6 +1540,30 @@ void GenericTasksTestsBase::triggerAttachFlacAudioSource() task.execute(); } +void GenericTasksTestsBase::shouldAttachMp3AudioSource() +{ + EXPECT_CALL(*testContext->m_gstWrapper, gstCapsNewEmptySimple(StrEq("audio/mpeg"))) + .WillOnce(Return(&testContext->m_gstCaps1)); + EXPECT_CALL(*testContext->m_gstWrapper, + gstCapsSetSimpleIntStub(&testContext->m_gstCaps1, StrEq("mpegversion"), G_TYPE_INT, 1)); + EXPECT_CALL(*testContext->m_gstWrapper, + gstCapsSetSimpleIntStub(&testContext->m_gstCaps1, StrEq("layer"), G_TYPE_INT, 3)); + expectSetCaps(); +} + +void GenericTasksTestsBase::triggerAttachMp3AudioSource() +{ + std::unique_ptr source = + std::make_unique("audio/mp3", false); + firebolt::rialto::server::tasks::generic::AttachSource task{testContext->m_context, + testContext->m_gstWrapper, + testContext->m_glibWrapper, + testContext->m_gstTextTrackSinkFactoryMock, + testContext->m_gstPlayer, + source}; + task.execute(); +} + void GenericTasksTestsBase::expectAddChannelAndRateAudioToCaps() { EXPECT_CALL(*testContext->m_gstWrapper, @@ -1566,6 +1608,9 @@ void GenericTasksTestsBase::expectAddFramedToCaps() void GenericTasksTestsBase::expectSetCaps() { + EXPECT_CALL(*testContext->m_gstWrapper, gstCapsToString(&testContext->m_gstCaps1)) + .WillOnce(Return(&testContext->m_capsStr)); + EXPECT_CALL(*testContext->m_glibWrapper, gFree(&testContext->m_capsStr)); EXPECT_CALL(*testContext->m_gstWrapper, gstElementFactoryMake(_, StrEq(kAudName.c_str()))) .WillOnce(Return(&testContext->m_appSrcAudio)); EXPECT_CALL(*testContext->m_gstWrapper, @@ -1624,6 +1669,9 @@ void GenericTasksTestsBase::triggerAttachUnknownSource() void GenericTasksTestsBase::shouldAttachSubtitleSource() { EXPECT_CALL(*testContext->m_gstWrapper, gstCapsNewEmpty()).WillOnce(Return(&testContext->m_gstCaps2)); + EXPECT_CALL(*testContext->m_gstWrapper, gstCapsToString(&testContext->m_gstCaps2)) + .WillOnce(Return(&testContext->m_capsStr)); + EXPECT_CALL(*testContext->m_glibWrapper, gFree(&testContext->m_capsStr)); EXPECT_CALL(*testContext->m_gstWrapper, gstElementFactoryMake(_, StrEq(kSubtitleName.c_str()))) .WillOnce(Return(&testContext->m_appSrcSubtitle)); EXPECT_CALL(*testContext->m_gstTextTrackSinkFactoryMock, createGstTextTrackSink()) @@ -1726,6 +1774,9 @@ void GenericTasksTestsBase::shouldAttachVideoSourceWithEmptyCodecData() EXPECT_CALL(*testContext->m_gstWrapper, gstBufferUnref(&(testContext->m_videoBuffer))); EXPECT_CALL(*testContext->m_gstWrapper, gstCapsSetSimpleStringStub(&testContext->m_gstCaps1, StrEq("stream-format"), _, StrEq("avc"))); + EXPECT_CALL(*testContext->m_gstWrapper, gstCapsToString(&testContext->m_gstCaps1)) + .WillOnce(Return(&testContext->m_capsStr)); + EXPECT_CALL(*testContext->m_glibWrapper, gFree(&testContext->m_capsStr)); EXPECT_CALL(*testContext->m_gstWrapper, gstElementFactoryMake(_, StrEq(kVidName.c_str()))) .WillOnce(Return(&testContext->m_appSrcVideo)); EXPECT_CALL(*testContext->m_gstWrapper, @@ -1795,6 +1846,9 @@ void GenericTasksTestsBase::expectSetGenericVideoCaps() gstCapsSetSimpleIntStub(&testContext->m_gstCaps1, StrEq("width"), G_TYPE_INT, kWidth)); EXPECT_CALL(*testContext->m_gstWrapper, gstCapsSetSimpleIntStub(&testContext->m_gstCaps1, StrEq("height"), G_TYPE_INT, kHeight)); + EXPECT_CALL(*testContext->m_gstWrapper, gstCapsToString(&testContext->m_gstCaps1)) + .WillOnce(Return(&testContext->m_capsStr)); + EXPECT_CALL(*testContext->m_glibWrapper, gFree(&testContext->m_capsStr)); EXPECT_CALL(*testContext->m_gstWrapper, gstElementFactoryMake(_, StrEq(kVidName.c_str()))) .WillOnce(Return(&testContext->m_appSrcVideo)); EXPECT_CALL(*testContext->m_gstWrapper, @@ -2368,28 +2422,7 @@ void GenericTasksTestsBase::triggerShutdown() void GenericTasksTestsBase::shouldSetVideoMute() { - EXPECT_CALL(testContext->m_gstPlayer, getSink(firebolt::rialto::MediaSourceType::VIDEO)) - .WillOnce(Return(&testContext->m_videoSink)); - EXPECT_CALL(*testContext->m_glibWrapper, - gObjectClassFindProperty(G_OBJECT_GET_CLASS(&testContext->m_videoSink), StrEq("show-video-window"))) - .WillOnce(Return(&testContext->m_paramSpec)); - EXPECT_CALL(*testContext->m_glibWrapper, gObjectSetStub(&testContext->m_videoSink, StrEq("show-video-window"))); - EXPECT_CALL(*testContext->m_gstWrapper, gstObjectUnref(&testContext->m_videoSink)); -} - -void GenericTasksTestsBase::shouldFailToSetVideoMuteNoSink() -{ - EXPECT_CALL(testContext->m_gstPlayer, getSink(firebolt::rialto::MediaSourceType::VIDEO)).WillOnce(Return(nullptr)); -} - -void GenericTasksTestsBase::shouldFailToSetVideoMuteNoProperty() -{ - EXPECT_CALL(testContext->m_gstPlayer, getSink(firebolt::rialto::MediaSourceType::VIDEO)) - .WillOnce(Return(&testContext->m_videoSink)); - EXPECT_CALL(*testContext->m_glibWrapper, - gObjectClassFindProperty(G_OBJECT_GET_CLASS(&testContext->m_videoSink), StrEq("show-video-window"))) - .WillOnce(Return(nullptr)); - EXPECT_CALL(*testContext->m_gstWrapper, gstObjectUnref(&testContext->m_videoSink)); + EXPECT_CALL(testContext->m_gstPlayer, setShowVideoWindow()).WillOnce(Return(true)); } void GenericTasksTestsBase::triggerSetAudioMute() @@ -2417,6 +2450,7 @@ void GenericTasksTestsBase::triggerSetVideoMute() testContext->m_gstWrapper, testContext->m_glibWrapper, MediaSourceType::VIDEO, kMute}; task.execute(); + EXPECT_EQ(testContext->m_context.pendingShowVideoWindow, !kMute); } void GenericTasksTestsBase::triggerSetSubtitleMute() @@ -2627,7 +2661,7 @@ void GenericTasksTestsBase::shouldFailToReportPosition() void GenericTasksTestsBase::shouldFinishSetupSource() { EXPECT_CALL(*testContext->m_gstSrc, - setupAndAddAppArc(std::dynamic_pointer_cast( + setupAndAddAppSrc(std::dynamic_pointer_cast( testContext->m_decryptionServiceMock) .get(), testContext->m_element, testContext->m_streamInfoAudio, _, &testContext->m_gstPlayer, @@ -2642,7 +2676,7 @@ void GenericTasksTestsBase::shouldFinishSetupSource() })); EXPECT_CALL(testContext->m_gstPlayer, notifyNeedMediaData(MediaSourceType::AUDIO)); EXPECT_CALL(*testContext->m_gstSrc, - setupAndAddAppArc(std::dynamic_pointer_cast( + setupAndAddAppSrc(std::dynamic_pointer_cast( testContext->m_decryptionServiceMock) .get(), testContext->m_element, testContext->m_streamInfoVideo, _, &testContext->m_gstPlayer, diff --git a/tests/unittests/media/server/gstplayer/genericPlayer/common/GenericTasksTestsBase.h b/tests/unittests/media/server/gstplayer/genericPlayer/common/GenericTasksTestsBase.h index 9ccae0315..0681bcfba 100644 --- a/tests/unittests/media/server/gstplayer/genericPlayer/common/GenericTasksTestsBase.h +++ b/tests/unittests/media/server/gstplayer/genericPlayer/common/GenericTasksTestsBase.h @@ -88,6 +88,7 @@ class GenericTasksTestsBase : public ::testing::Test void shouldSetupVideoParserElementWithPendingStreamSyncMode(); void shouldSetupAudioDecoderElementWithPendingBufferingLimit(); void shouldSetupVideoSinkElementWithPendingRenderFrame(); + void shouldSetupVideoSinkElementWithPendingShowVideoWindow(); void shouldSetupAudioElementAmlhalasinkWhenNoVideo(); void shouldSetupAudioElementAmlhalasinkWhenVideoExists(); void shouldSetupAudioElementBrcmAudioSink(); @@ -167,6 +168,8 @@ class GenericTasksTestsBase : public ::testing::Test void triggerAttachXrawAudioSource(); void shouldAttachFlacAudioSource(); void triggerAttachFlacAudioSource(); + void shouldAttachMp3AudioSource(); + void triggerAttachMp3AudioSource(); void shouldAttachVideoSource(const std::string &mime, const std::string &alignment, const std::string &format); void triggerAttachVideoSource(const std::string &mimeType, firebolt::rialto::SegmentAlignment segmentAligment, firebolt::rialto::StreamFormat streamFormat); @@ -269,8 +272,6 @@ class GenericTasksTestsBase : public ::testing::Test void triggerSetUnknownMute(); void setContextSubtitleSink(); void shouldSetAudioMute(); - void shouldFailToSetVideoMuteNoSink(); - void shouldFailToSetVideoMuteNoProperty(); void shouldSetVideoMute(); void shouldSetSubtitleMute(); diff --git a/tests/unittests/media/server/gstplayer/genericPlayer/tasksTests/AttachSourceTest.cpp b/tests/unittests/media/server/gstplayer/genericPlayer/tasksTests/AttachSourceTest.cpp index 3842d1bdc..2b241b9fd 100644 --- a/tests/unittests/media/server/gstplayer/genericPlayer/tasksTests/AttachSourceTest.cpp +++ b/tests/unittests/media/server/gstplayer/genericPlayer/tasksTests/AttachSourceTest.cpp @@ -65,6 +65,13 @@ TEST_F(AttachSourceTest, shouldAttachFlacAudioSource) checkAudioSourceAttachedWithDrm(); } +TEST_F(AttachSourceTest, shouldAttachMp3AudioSource) +{ + shouldAttachMp3AudioSource(); + triggerAttachMp3AudioSource(); + checkAudioSourceAttached(); +} + TEST_F(AttachSourceTest, shouldAttachVideoSourceAuAvc) { std::string mimeType = "video/h264"; diff --git a/tests/unittests/media/server/gstplayer/genericPlayer/tasksTests/GenericPlayerTaskFactoryTest.cpp b/tests/unittests/media/server/gstplayer/genericPlayer/tasksTests/GenericPlayerTaskFactoryTest.cpp index 64b628ac5..45d0fd48d 100644 --- a/tests/unittests/media/server/gstplayer/genericPlayer/tasksTests/GenericPlayerTaskFactoryTest.cpp +++ b/tests/unittests/media/server/gstplayer/genericPlayer/tasksTests/GenericPlayerTaskFactoryTest.cpp @@ -19,6 +19,7 @@ #include +#include "FlushWatcherMock.h" #include "GenericPlayerContext.h" #include "GlibWrapperMock.h" #include "GstGenericPlayerClientMock.h" @@ -87,6 +88,7 @@ class GenericPlayerTaskFactoryTest : public testing::Test std::make_shared>()}; std::shared_ptr m_gstTextTrackSinkFactoryMock{ std::make_shared>()}; + StrictMock m_flushWatcherMock; firebolt::rialto::server::GenericPlayerTaskFactory m_sut{&m_gstPlayerClient, m_gstWrapper, m_glibWrapper, m_rdkGstreamerUtilsWrapper, m_gstTextTrackSinkFactoryMock}; }; @@ -141,7 +143,11 @@ TEST_F(GenericPlayerTaskFactoryTest, ShouldCreateFinishSetupSource) TEST_F(GenericPlayerTaskFactoryTest, ShouldCreateHandleBusMessage) { - auto task = m_sut.createHandleBusMessage(m_context, m_gstPlayer, nullptr, false); + constexpr bool kNoFlushOngoing{false}; + EXPECT_CALL(m_flushWatcherMock, isFlushOngoing()).WillRepeatedly(Return(kNoFlushOngoing)); + EXPECT_CALL(m_flushWatcherMock, isAsyncFlushOngoing()).WillRepeatedly(Return(kNoFlushOngoing)); + + auto task = m_sut.createHandleBusMessage(m_context, m_gstPlayer, nullptr, m_flushWatcherMock); EXPECT_NE(task, nullptr); EXPECT_NO_THROW(dynamic_cast(*task)); } diff --git a/tests/unittests/media/server/gstplayer/genericPlayer/tasksTests/HandleBusMessageTest.cpp b/tests/unittests/media/server/gstplayer/genericPlayer/tasksTests/HandleBusMessageTest.cpp index 6f5086de3..c06b47abe 100644 --- a/tests/unittests/media/server/gstplayer/genericPlayer/tasksTests/HandleBusMessageTest.cpp +++ b/tests/unittests/media/server/gstplayer/genericPlayer/tasksTests/HandleBusMessageTest.cpp @@ -18,6 +18,7 @@ */ #include "tasks/generic/HandleBusMessage.h" +#include "FlushWatcherMock.h" #include "GenericPlayerContext.h" #include "GlibWrapperMock.h" #include "GstGenericPlayerClientMock.h" @@ -54,6 +55,7 @@ class HandleBusMessageTest : public testing::Test std::make_shared>()}; std::shared_ptr m_glibWrapper{ std::make_shared>()}; + StrictMock m_flushWatcherMock; GstElement m_pipeline{}; GstAppSrc m_audioSrc{}; GstAppSrc m_videoSrc{}; @@ -84,9 +86,12 @@ TEST_F(HandleBusMessageTest, shouldNotHandleMessageWithUnknownType) { GST_MESSAGE_SRC(&m_message) = GST_OBJECT(&m_pipeline); EXPECT_CALL(*m_gstWrapper, gstMessageUnref(&m_message)); - firebolt::rialto::server::tasks::generic::HandleBusMessage task{m_context, m_gstPlayer, &m_gstPlayerClient, - m_gstWrapper, m_glibWrapper, &m_message, - kNoFlushOngoing}; + EXPECT_CALL(m_flushWatcherMock, isFlushOngoing()).WillRepeatedly(Return(kNoFlushOngoing)); + EXPECT_CALL(m_flushWatcherMock, isAsyncFlushOngoing()).WillRepeatedly(Return(kNoFlushOngoing)); + firebolt::rialto::server::tasks::generic::HandleBusMessage task{m_context, m_gstPlayer, + &m_gstPlayerClient, m_gstWrapper, + m_glibWrapper, &m_message, + m_flushWatcherMock}; task.execute(); } @@ -94,9 +99,12 @@ TEST_F(HandleBusMessageTest, shouldNotHandleEosMessageForAnotherPipeline) { EXPECT_CALL(*m_gstWrapper, gstMessageUnref(&m_message)); GST_MESSAGE_TYPE(&m_message) = GST_MESSAGE_EOS; - firebolt::rialto::server::tasks::generic::HandleBusMessage task{m_context, m_gstPlayer, &m_gstPlayerClient, - m_gstWrapper, m_glibWrapper, &m_message, - kNoFlushOngoing}; + EXPECT_CALL(m_flushWatcherMock, isFlushOngoing()).WillRepeatedly(Return(kNoFlushOngoing)); + EXPECT_CALL(m_flushWatcherMock, isAsyncFlushOngoing()).WillRepeatedly(Return(kNoFlushOngoing)); + firebolt::rialto::server::tasks::generic::HandleBusMessage task{m_context, m_gstPlayer, + &m_gstPlayerClient, m_gstWrapper, + m_glibWrapper, &m_message, + m_flushWatcherMock}; task.execute(); } @@ -106,9 +114,12 @@ TEST_F(HandleBusMessageTest, shouldNotHandleMessageEosWhenPipelineIsNull) GST_MESSAGE_SRC(&m_message) = GST_OBJECT(&m_pipeline); GST_MESSAGE_TYPE(&m_message) = GST_MESSAGE_EOS; EXPECT_CALL(*m_gstWrapper, gstMessageUnref(&m_message)); - firebolt::rialto::server::tasks::generic::HandleBusMessage task{m_context, m_gstPlayer, &m_gstPlayerClient, - m_gstWrapper, m_glibWrapper, &m_message, - kNoFlushOngoing}; + EXPECT_CALL(m_flushWatcherMock, isFlushOngoing()).WillRepeatedly(Return(kNoFlushOngoing)); + EXPECT_CALL(m_flushWatcherMock, isAsyncFlushOngoing()).WillRepeatedly(Return(kNoFlushOngoing)); + firebolt::rialto::server::tasks::generic::HandleBusMessage task{m_context, m_gstPlayer, + &m_gstPlayerClient, m_gstWrapper, + m_glibWrapper, &m_message, + m_flushWatcherMock}; task.execute(); } @@ -118,21 +129,44 @@ TEST_F(HandleBusMessageTest, shouldNotHandleMessageEosWhenEosAlreadyNotified) GST_MESSAGE_SRC(&m_message) = GST_OBJECT(&m_pipeline); GST_MESSAGE_TYPE(&m_message) = GST_MESSAGE_EOS; EXPECT_CALL(*m_gstWrapper, gstMessageUnref(&m_message)); - firebolt::rialto::server::tasks::generic::HandleBusMessage task{m_context, m_gstPlayer, &m_gstPlayerClient, - m_gstWrapper, m_glibWrapper, &m_message, - kNoFlushOngoing}; + EXPECT_CALL(m_flushWatcherMock, isFlushOngoing()).WillRepeatedly(Return(kNoFlushOngoing)); + EXPECT_CALL(m_flushWatcherMock, isAsyncFlushOngoing()).WillRepeatedly(Return(kNoFlushOngoing)); + firebolt::rialto::server::tasks::generic::HandleBusMessage task{m_context, m_gstPlayer, + &m_gstPlayerClient, m_gstWrapper, + m_glibWrapper, &m_message, + m_flushWatcherMock}; task.execute(); } -TEST_F(HandleBusMessageTest, shouldNotHandleEosMessageWhenFlushing) +TEST_F(HandleBusMessageTest, shouldNotHandleEosMessageWhenFlushRequestedBeforeTaskCreation) { constexpr bool kFlushOngoing{true}; GST_MESSAGE_SRC(&m_message) = GST_OBJECT(&m_pipeline); GST_MESSAGE_TYPE(&m_message) = GST_MESSAGE_EOS; EXPECT_CALL(*m_gstWrapper, gstMessageUnref(&m_message)); - firebolt::rialto::server::tasks::generic::HandleBusMessage task{m_context, m_gstPlayer, &m_gstPlayerClient, - m_gstWrapper, m_glibWrapper, &m_message, - kFlushOngoing}; + EXPECT_CALL(m_flushWatcherMock, isFlushOngoing()).WillOnce(Return(kFlushOngoing)); + EXPECT_CALL(m_flushWatcherMock, isAsyncFlushOngoing()).WillOnce(Return(kFlushOngoing)); + firebolt::rialto::server::tasks::generic::HandleBusMessage task{m_context, m_gstPlayer, + &m_gstPlayerClient, m_gstWrapper, + m_glibWrapper, &m_message, + m_flushWatcherMock}; + task.execute(); + + EXPECT_FALSE(m_context.eosNotified); +} + +TEST_F(HandleBusMessageTest, shouldNotHandleEosMessageWhenFlushRequestedAfterTaskCreation) +{ + constexpr bool kFlushOngoing{true}; + GST_MESSAGE_SRC(&m_message) = GST_OBJECT(&m_pipeline); + GST_MESSAGE_TYPE(&m_message) = GST_MESSAGE_EOS; + EXPECT_CALL(*m_gstWrapper, gstMessageUnref(&m_message)); + EXPECT_CALL(m_flushWatcherMock, isFlushOngoing()).WillOnce(Return(kNoFlushOngoing)).WillOnce(Return(kFlushOngoing)); + EXPECT_CALL(m_flushWatcherMock, isAsyncFlushOngoing()).WillOnce(Return(kNoFlushOngoing)); + firebolt::rialto::server::tasks::generic::HandleBusMessage task{m_context, m_gstPlayer, + &m_gstPlayerClient, m_gstWrapper, + m_glibWrapper, &m_message, + m_flushWatcherMock}; task.execute(); EXPECT_FALSE(m_context.eosNotified); @@ -144,9 +178,12 @@ TEST_F(HandleBusMessageTest, shouldHandleEosMessage) GST_MESSAGE_TYPE(&m_message) = GST_MESSAGE_EOS; EXPECT_CALL(m_gstPlayerClient, notifyPlaybackState(firebolt::rialto::PlaybackState::END_OF_STREAM)); EXPECT_CALL(*m_gstWrapper, gstMessageUnref(&m_message)); - firebolt::rialto::server::tasks::generic::HandleBusMessage task{m_context, m_gstPlayer, &m_gstPlayerClient, - m_gstWrapper, m_glibWrapper, &m_message, - kNoFlushOngoing}; + EXPECT_CALL(m_flushWatcherMock, isFlushOngoing()).WillRepeatedly(Return(kNoFlushOngoing)); + EXPECT_CALL(m_flushWatcherMock, isAsyncFlushOngoing()).WillRepeatedly(Return(kNoFlushOngoing)); + firebolt::rialto::server::tasks::generic::HandleBusMessage task{m_context, m_gstPlayer, + &m_gstPlayerClient, m_gstWrapper, + m_glibWrapper, &m_message, + m_flushWatcherMock}; task.execute(); EXPECT_TRUE(m_context.eosNotified); @@ -156,9 +193,12 @@ TEST_F(HandleBusMessageTest, shouldNotHandleStateChangedMessageForAnotherPipelin { EXPECT_CALL(*m_gstWrapper, gstMessageUnref(&m_message)); GST_MESSAGE_TYPE(&m_message) = GST_MESSAGE_STATE_CHANGED; - firebolt::rialto::server::tasks::generic::HandleBusMessage task{m_context, m_gstPlayer, &m_gstPlayerClient, - m_gstWrapper, m_glibWrapper, &m_message, - kNoFlushOngoing}; + EXPECT_CALL(m_flushWatcherMock, isFlushOngoing()).WillRepeatedly(Return(kNoFlushOngoing)); + EXPECT_CALL(m_flushWatcherMock, isAsyncFlushOngoing()).WillRepeatedly(Return(kNoFlushOngoing)); + firebolt::rialto::server::tasks::generic::HandleBusMessage task{m_context, m_gstPlayer, + &m_gstPlayerClient, m_gstWrapper, + m_glibWrapper, &m_message, + m_flushWatcherMock}; task.execute(); } @@ -168,9 +208,12 @@ TEST_F(HandleBusMessageTest, shouldNotHandleMessageStateChangedWhenPipelineIsNul GST_MESSAGE_SRC(&m_message) = GST_OBJECT(&m_pipeline); GST_MESSAGE_TYPE(&m_message) = GST_MESSAGE_STATE_CHANGED; EXPECT_CALL(*m_gstWrapper, gstMessageUnref(&m_message)); - firebolt::rialto::server::tasks::generic::HandleBusMessage task{m_context, m_gstPlayer, &m_gstPlayerClient, - m_gstWrapper, m_glibWrapper, &m_message, - kNoFlushOngoing}; + EXPECT_CALL(m_flushWatcherMock, isFlushOngoing()).WillRepeatedly(Return(kNoFlushOngoing)); + EXPECT_CALL(m_flushWatcherMock, isAsyncFlushOngoing()).WillRepeatedly(Return(kNoFlushOngoing)); + firebolt::rialto::server::tasks::generic::HandleBusMessage task{m_context, m_gstPlayer, + &m_gstPlayerClient, m_gstWrapper, + m_glibWrapper, &m_message, + m_flushWatcherMock}; task.execute(); } @@ -189,9 +232,11 @@ TEST_F(HandleBusMessageTest, shouldNotHandleStateChangedMessageWhenGstPlayerClie EXPECT_CALL(*m_gstWrapper, gstElementStateGetName(pending)).WillOnce(Return("Void")); EXPECT_CALL(*m_gstWrapper, gstDebugBinToDotFileWithTs(GST_BIN(&m_pipeline), _, _)); EXPECT_CALL(*m_gstWrapper, gstMessageUnref(&m_message)); - firebolt::rialto::server::tasks::generic::HandleBusMessage task{m_context, m_gstPlayer, nullptr, - m_gstWrapper, m_glibWrapper, &m_message, - kNoFlushOngoing}; + EXPECT_CALL(m_flushWatcherMock, isFlushOngoing()).WillRepeatedly(Return(kNoFlushOngoing)); + EXPECT_CALL(m_flushWatcherMock, isAsyncFlushOngoing()).WillRepeatedly(Return(kNoFlushOngoing)); + firebolt::rialto::server::tasks::generic::HandleBusMessage task{m_context, m_gstPlayer, nullptr, + m_gstWrapper, m_glibWrapper, &m_message, + m_flushWatcherMock}; task.execute(); } @@ -211,9 +256,12 @@ TEST_F(HandleBusMessageTest, shouldHandleStateChangedToNullMessage) EXPECT_CALL(*m_gstWrapper, gstDebugBinToDotFileWithTs(GST_BIN(&m_pipeline), _, _)); EXPECT_CALL(m_gstPlayerClient, notifyPlaybackState(firebolt::rialto::PlaybackState::STOPPED)); EXPECT_CALL(*m_gstWrapper, gstMessageUnref(&m_message)); - firebolt::rialto::server::tasks::generic::HandleBusMessage task{m_context, m_gstPlayer, &m_gstPlayerClient, - m_gstWrapper, m_glibWrapper, &m_message, - kNoFlushOngoing}; + EXPECT_CALL(m_flushWatcherMock, isFlushOngoing()).WillRepeatedly(Return(kNoFlushOngoing)); + EXPECT_CALL(m_flushWatcherMock, isAsyncFlushOngoing()).WillRepeatedly(Return(kNoFlushOngoing)); + firebolt::rialto::server::tasks::generic::HandleBusMessage task{m_context, m_gstPlayer, + &m_gstPlayerClient, m_gstWrapper, + m_glibWrapper, &m_message, + m_flushWatcherMock}; task.execute(); } @@ -233,9 +281,91 @@ TEST_F(HandleBusMessageTest, shouldHandleStateChangedToPausedMessage) EXPECT_CALL(*m_gstWrapper, gstDebugBinToDotFileWithTs(GST_BIN(&m_pipeline), _, _)); EXPECT_CALL(m_gstPlayerClient, notifyPlaybackState(firebolt::rialto::PlaybackState::PAUSED)); EXPECT_CALL(*m_gstWrapper, gstMessageUnref(&m_message)); - firebolt::rialto::server::tasks::generic::HandleBusMessage task{m_context, m_gstPlayer, &m_gstPlayerClient, - m_gstWrapper, m_glibWrapper, &m_message, - kNoFlushOngoing}; + EXPECT_CALL(m_flushWatcherMock, isFlushOngoing()).WillRepeatedly(Return(kNoFlushOngoing)); + EXPECT_CALL(m_flushWatcherMock, isAsyncFlushOngoing()).WillRepeatedly(Return(kNoFlushOngoing)); + firebolt::rialto::server::tasks::generic::HandleBusMessage task{m_context, m_gstPlayer, + &m_gstPlayerClient, m_gstWrapper, + m_glibWrapper, &m_message, + m_flushWatcherMock}; + task.execute(); +} + +TEST_F(HandleBusMessageTest, shouldHandleStateChangedToPausedMessageWhenSyncFlushIsOngoing) +{ + constexpr bool kFlushOngoing{true}; + + GST_MESSAGE_SRC(&m_message) = GST_OBJECT(&m_pipeline); + GST_MESSAGE_TYPE(&m_message) = GST_MESSAGE_STATE_CHANGED; + GstState oldState = GST_STATE_READY; + GstState newState = GST_STATE_PAUSED; + GstState pending = GST_STATE_VOID_PENDING; + + EXPECT_CALL(*m_gstWrapper, gstMessageParseStateChanged(&m_message, _, _, _)) + .WillRepeatedly(DoAll(SetArgPointee<1>(oldState), SetArgPointee<2>(newState), SetArgPointee<3>(pending))); + EXPECT_CALL(*m_gstWrapper, gstElementStateGetName(oldState)).Times(2).WillRepeatedly(Return("Ready")); + EXPECT_CALL(*m_gstWrapper, gstElementStateGetName(newState)).Times(2).WillRepeatedly(Return("Paused")); + EXPECT_CALL(*m_gstWrapper, gstElementStateGetName(pending)).WillOnce(Return("Void")); + EXPECT_CALL(*m_gstWrapper, gstDebugBinToDotFileWithTs(GST_BIN(&m_pipeline), _, _)); + EXPECT_CALL(m_gstPlayerClient, notifyPlaybackState(firebolt::rialto::PlaybackState::PAUSED)); + EXPECT_CALL(*m_gstWrapper, gstMessageUnref(&m_message)); + EXPECT_CALL(m_flushWatcherMock, isFlushOngoing()).WillRepeatedly(Return(kFlushOngoing)); + EXPECT_CALL(m_flushWatcherMock, isAsyncFlushOngoing()).WillRepeatedly(Return(kNoFlushOngoing)); + firebolt::rialto::server::tasks::generic::HandleBusMessage task{m_context, m_gstPlayer, + &m_gstPlayerClient, m_gstWrapper, + m_glibWrapper, &m_message, + m_flushWatcherMock}; + task.execute(); +} + +TEST_F(HandleBusMessageTest, shouldSkipHandlingStateChangedToPausedMessageWhenAsyncFlushWasQueuedBeforeHandleBusMessage) +{ + constexpr bool kFlushOngoing{true}; + + GST_MESSAGE_SRC(&m_message) = GST_OBJECT(&m_pipeline); + GST_MESSAGE_TYPE(&m_message) = GST_MESSAGE_STATE_CHANGED; + GstState oldState = GST_STATE_READY; + GstState newState = GST_STATE_PAUSED; + GstState pending = GST_STATE_VOID_PENDING; + + EXPECT_CALL(*m_gstWrapper, gstMessageParseStateChanged(&m_message, _, _, _)) + .WillRepeatedly(DoAll(SetArgPointee<1>(oldState), SetArgPointee<2>(newState), SetArgPointee<3>(pending))); + EXPECT_CALL(*m_gstWrapper, gstElementStateGetName(oldState)).Times(2).WillRepeatedly(Return("Ready")); + EXPECT_CALL(*m_gstWrapper, gstElementStateGetName(newState)).Times(2).WillRepeatedly(Return("Paused")); + EXPECT_CALL(*m_gstWrapper, gstElementStateGetName(pending)).WillOnce(Return("Void")); + EXPECT_CALL(*m_gstWrapper, gstDebugBinToDotFileWithTs(GST_BIN(&m_pipeline), _, _)); + EXPECT_CALL(*m_gstWrapper, gstMessageUnref(&m_message)); + EXPECT_CALL(m_flushWatcherMock, isFlushOngoing()).WillOnce(Return(kFlushOngoing)); + EXPECT_CALL(m_flushWatcherMock, isAsyncFlushOngoing()).WillOnce(Return(kFlushOngoing)); + firebolt::rialto::server::tasks::generic::HandleBusMessage task{m_context, m_gstPlayer, + &m_gstPlayerClient, m_gstWrapper, + m_glibWrapper, &m_message, + m_flushWatcherMock}; + task.execute(); +} + +TEST_F(HandleBusMessageTest, shouldSkipHandlingStateChangedToPausedMessageWhenAsyncFlushWasQueuedAfterHandleBusMessage) +{ + constexpr bool kFlushOngoing{true}; + + GST_MESSAGE_SRC(&m_message) = GST_OBJECT(&m_pipeline); + GST_MESSAGE_TYPE(&m_message) = GST_MESSAGE_STATE_CHANGED; + GstState oldState = GST_STATE_READY; + GstState newState = GST_STATE_PAUSED; + GstState pending = GST_STATE_VOID_PENDING; + + EXPECT_CALL(*m_gstWrapper, gstMessageParseStateChanged(&m_message, _, _, _)) + .WillRepeatedly(DoAll(SetArgPointee<1>(oldState), SetArgPointee<2>(newState), SetArgPointee<3>(pending))); + EXPECT_CALL(*m_gstWrapper, gstElementStateGetName(oldState)).Times(2).WillRepeatedly(Return("Ready")); + EXPECT_CALL(*m_gstWrapper, gstElementStateGetName(newState)).Times(2).WillRepeatedly(Return("Paused")); + EXPECT_CALL(*m_gstWrapper, gstElementStateGetName(pending)).WillOnce(Return("Void")); + EXPECT_CALL(*m_gstWrapper, gstDebugBinToDotFileWithTs(GST_BIN(&m_pipeline), _, _)); + EXPECT_CALL(*m_gstWrapper, gstMessageUnref(&m_message)); + EXPECT_CALL(m_flushWatcherMock, isFlushOngoing()).WillOnce(Return(kFlushOngoing)); + EXPECT_CALL(m_flushWatcherMock, isAsyncFlushOngoing()).WillOnce(Return(kNoFlushOngoing)).WillOnce(Return(kFlushOngoing)); + firebolt::rialto::server::tasks::generic::HandleBusMessage task{m_context, m_gstPlayer, + &m_gstPlayerClient, m_gstWrapper, + m_glibWrapper, &m_message, + m_flushWatcherMock}; task.execute(); } @@ -252,9 +382,12 @@ TEST_F(HandleBusMessageTest, shouldHandleStateChangedToPausedAndPendingPausedMes EXPECT_CALL(*m_gstWrapper, gstElementStateGetName(GST_STATE_PAUSED)).WillRepeatedly(Return("Paused")); EXPECT_CALL(*m_gstWrapper, gstDebugBinToDotFileWithTs(GST_BIN(&m_pipeline), _, _)); EXPECT_CALL(*m_gstWrapper, gstMessageUnref(&m_message)); - firebolt::rialto::server::tasks::generic::HandleBusMessage task{m_context, m_gstPlayer, &m_gstPlayerClient, - m_gstWrapper, m_glibWrapper, &m_message, - kNoFlushOngoing}; + EXPECT_CALL(m_flushWatcherMock, isFlushOngoing()).WillRepeatedly(Return(kNoFlushOngoing)); + EXPECT_CALL(m_flushWatcherMock, isAsyncFlushOngoing()).WillRepeatedly(Return(kNoFlushOngoing)); + firebolt::rialto::server::tasks::generic::HandleBusMessage task{m_context, m_gstPlayer, + &m_gstPlayerClient, m_gstWrapper, + m_glibWrapper, &m_message, + m_flushWatcherMock}; task.execute(); } @@ -276,14 +409,102 @@ TEST_F(HandleBusMessageTest, shouldHandleStateChangedToPlayingMessage) EXPECT_CALL(m_gstPlayer, startPositionReportingAndCheckAudioUnderflowTimer()); EXPECT_CALL(m_gstPlayerClient, notifyPlaybackState(firebolt::rialto::PlaybackState::PLAYING)); EXPECT_CALL(*m_gstWrapper, gstMessageUnref(&m_message)); - firebolt::rialto::server::tasks::generic::HandleBusMessage task{m_context, m_gstPlayer, &m_gstPlayerClient, - m_gstWrapper, m_glibWrapper, &m_message, - kNoFlushOngoing}; + EXPECT_CALL(m_flushWatcherMock, isFlushOngoing()).WillRepeatedly(Return(kNoFlushOngoing)); + EXPECT_CALL(m_flushWatcherMock, isAsyncFlushOngoing()).WillRepeatedly(Return(kNoFlushOngoing)); + firebolt::rialto::server::tasks::generic::HandleBusMessage task{m_context, m_gstPlayer, + &m_gstPlayerClient, m_gstWrapper, + m_glibWrapper, &m_message, + m_flushWatcherMock}; task.execute(); EXPECT_TRUE(m_context.isPlaying); } +TEST_F(HandleBusMessageTest, shouldHandleStateChangedToPlayingMessageWhenSyncFlushIsOngoing) +{ + constexpr bool kIsFlushOngoing{true}; + + m_context.isPlaying = false; + GST_MESSAGE_SRC(&m_message) = GST_OBJECT(&m_pipeline); + GST_MESSAGE_TYPE(&m_message) = GST_MESSAGE_STATE_CHANGED; + GstState oldState = GST_STATE_READY; + GstState newState = GST_STATE_PLAYING; + GstState pending = GST_STATE_VOID_PENDING; + + EXPECT_CALL(*m_gstWrapper, gstMessageParseStateChanged(&m_message, _, _, _)) + .WillRepeatedly(DoAll(SetArgPointee<1>(oldState), SetArgPointee<2>(newState), SetArgPointee<3>(pending))); + EXPECT_CALL(*m_gstWrapper, gstElementStateGetName(oldState)).Times(2).WillRepeatedly(Return("Ready")); + EXPECT_CALL(*m_gstWrapper, gstElementStateGetName(newState)).Times(2).WillRepeatedly(Return("Playing")); + EXPECT_CALL(*m_gstWrapper, gstElementStateGetName(pending)).WillOnce(Return("Void")); + EXPECT_CALL(*m_gstWrapper, gstDebugBinToDotFileWithTs(GST_BIN(&m_pipeline), _, _)); + EXPECT_CALL(m_gstPlayer, startPositionReportingAndCheckAudioUnderflowTimer()); + EXPECT_CALL(m_gstPlayerClient, notifyPlaybackState(firebolt::rialto::PlaybackState::PLAYING)); + EXPECT_CALL(*m_gstWrapper, gstMessageUnref(&m_message)); + EXPECT_CALL(m_flushWatcherMock, isFlushOngoing()).WillRepeatedly(Return(kIsFlushOngoing)); + EXPECT_CALL(m_flushWatcherMock, isAsyncFlushOngoing()).WillRepeatedly(Return(kNoFlushOngoing)); + firebolt::rialto::server::tasks::generic::HandleBusMessage task{m_context, m_gstPlayer, + &m_gstPlayerClient, m_gstWrapper, + m_glibWrapper, &m_message, + m_flushWatcherMock}; + task.execute(); + + EXPECT_TRUE(m_context.isPlaying); +} + +TEST_F(HandleBusMessageTest, shouldSkipHandlingStateChangedToPlayingMessageWhenAsyncFlushIsQueuedBeforeHandleBusMessage) +{ + constexpr bool kIsFlushOngoing{true}; + + m_context.isPlaying = false; + GST_MESSAGE_SRC(&m_message) = GST_OBJECT(&m_pipeline); + GST_MESSAGE_TYPE(&m_message) = GST_MESSAGE_STATE_CHANGED; + GstState oldState = GST_STATE_READY; + GstState newState = GST_STATE_PLAYING; + GstState pending = GST_STATE_VOID_PENDING; + + EXPECT_CALL(*m_gstWrapper, gstMessageParseStateChanged(&m_message, _, _, _)) + .WillRepeatedly(DoAll(SetArgPointee<1>(oldState), SetArgPointee<2>(newState), SetArgPointee<3>(pending))); + EXPECT_CALL(*m_gstWrapper, gstElementStateGetName(oldState)).Times(2).WillRepeatedly(Return("Ready")); + EXPECT_CALL(*m_gstWrapper, gstElementStateGetName(newState)).Times(2).WillRepeatedly(Return("Playing")); + EXPECT_CALL(*m_gstWrapper, gstElementStateGetName(pending)).WillOnce(Return("Void")); + EXPECT_CALL(*m_gstWrapper, gstDebugBinToDotFileWithTs(GST_BIN(&m_pipeline), _, _)); + EXPECT_CALL(*m_gstWrapper, gstMessageUnref(&m_message)); + EXPECT_CALL(m_flushWatcherMock, isFlushOngoing()).WillOnce(Return(kIsFlushOngoing)); + EXPECT_CALL(m_flushWatcherMock, isAsyncFlushOngoing()).WillOnce(Return(kIsFlushOngoing)); + firebolt::rialto::server::tasks::generic::HandleBusMessage task{m_context, m_gstPlayer, + &m_gstPlayerClient, m_gstWrapper, + m_glibWrapper, &m_message, + m_flushWatcherMock}; + task.execute(); +} + +TEST_F(HandleBusMessageTest, shouldSkipHandlingStateChangedToPlayingMessageWhenAsyncFlushIsQueuedAfterHandleBusMessage) +{ + constexpr bool kIsFlushOngoing{true}; + + m_context.isPlaying = false; + GST_MESSAGE_SRC(&m_message) = GST_OBJECT(&m_pipeline); + GST_MESSAGE_TYPE(&m_message) = GST_MESSAGE_STATE_CHANGED; + GstState oldState = GST_STATE_READY; + GstState newState = GST_STATE_PLAYING; + GstState pending = GST_STATE_VOID_PENDING; + + EXPECT_CALL(*m_gstWrapper, gstMessageParseStateChanged(&m_message, _, _, _)) + .WillRepeatedly(DoAll(SetArgPointee<1>(oldState), SetArgPointee<2>(newState), SetArgPointee<3>(pending))); + EXPECT_CALL(*m_gstWrapper, gstElementStateGetName(oldState)).Times(2).WillRepeatedly(Return("Ready")); + EXPECT_CALL(*m_gstWrapper, gstElementStateGetName(newState)).Times(2).WillRepeatedly(Return("Playing")); + EXPECT_CALL(*m_gstWrapper, gstElementStateGetName(pending)).WillOnce(Return("Void")); + EXPECT_CALL(*m_gstWrapper, gstDebugBinToDotFileWithTs(GST_BIN(&m_pipeline), _, _)); + EXPECT_CALL(*m_gstWrapper, gstMessageUnref(&m_message)); + EXPECT_CALL(m_flushWatcherMock, isFlushOngoing()).WillOnce(Return(kIsFlushOngoing)); + EXPECT_CALL(m_flushWatcherMock, isAsyncFlushOngoing()).WillOnce(Return(kNoFlushOngoing)).WillOnce(Return(kIsFlushOngoing)); + firebolt::rialto::server::tasks::generic::HandleBusMessage task{m_context, m_gstPlayer, + &m_gstPlayerClient, m_gstWrapper, + m_glibWrapper, &m_message, + m_flushWatcherMock}; + task.execute(); +} + TEST_F(HandleBusMessageTest, shouldHandleStateChangedToPlayingMessageAndSetPendingPlaybackRate) { m_context.pendingPlaybackRate = 1.25; @@ -303,9 +524,12 @@ TEST_F(HandleBusMessageTest, shouldHandleStateChangedToPlayingMessageAndSetPendi EXPECT_CALL(m_gstPlayerClient, notifyPlaybackState(firebolt::rialto::PlaybackState::PLAYING)); EXPECT_CALL(m_gstPlayer, setPendingPlaybackRate()); EXPECT_CALL(*m_gstWrapper, gstMessageUnref(&m_message)); - firebolt::rialto::server::tasks::generic::HandleBusMessage task{m_context, m_gstPlayer, &m_gstPlayerClient, - m_gstWrapper, m_glibWrapper, &m_message, - kNoFlushOngoing}; + EXPECT_CALL(m_flushWatcherMock, isFlushOngoing()).WillRepeatedly(Return(kNoFlushOngoing)); + EXPECT_CALL(m_flushWatcherMock, isAsyncFlushOngoing()).WillRepeatedly(Return(kNoFlushOngoing)); + firebolt::rialto::server::tasks::generic::HandleBusMessage task{m_context, m_gstPlayer, + &m_gstPlayerClient, m_gstWrapper, + m_glibWrapper, &m_message, + m_flushWatcherMock}; task.execute(); } @@ -324,10 +548,12 @@ TEST_F(HandleBusMessageTest, shouldNotHandleQosMessageForUnsupportedFormat) .WillOnce(DoAll(SetArgPointee<1>(format), SetArgPointee<2>(processed), SetArgPointee<3>(dropped))); EXPECT_CALL(*m_gstWrapper, gstFormatGetName(format)).WillOnce(Return("Undefined")); EXPECT_CALL(*m_gstWrapper, gstMessageUnref(&m_message)); - - firebolt::rialto::server::tasks::generic::HandleBusMessage task{m_context, m_gstPlayer, &m_gstPlayerClient, - m_gstWrapper, m_glibWrapper, &m_message, - kNoFlushOngoing}; + EXPECT_CALL(m_flushWatcherMock, isFlushOngoing()).WillRepeatedly(Return(kNoFlushOngoing)); + EXPECT_CALL(m_flushWatcherMock, isAsyncFlushOngoing()).WillRepeatedly(Return(kNoFlushOngoing)); + firebolt::rialto::server::tasks::generic::HandleBusMessage task{m_context, m_gstPlayer, + &m_gstPlayerClient, m_gstWrapper, + m_glibWrapper, &m_message, + m_flushWatcherMock}; task.execute(); } @@ -348,10 +574,12 @@ TEST_F(HandleBusMessageTest, shouldNotHandleQosMessageForUnknownSourceType) StrEq(GST_ELEMENT_METADATA_KLASS))) .WillOnce(Return("Unknown")); EXPECT_CALL(*m_gstWrapper, gstMessageUnref(&m_message)); - - firebolt::rialto::server::tasks::generic::HandleBusMessage task{m_context, m_gstPlayer, &m_gstPlayerClient, - m_gstWrapper, m_glibWrapper, &m_message, - kNoFlushOngoing}; + EXPECT_CALL(m_flushWatcherMock, isFlushOngoing()).WillRepeatedly(Return(kNoFlushOngoing)); + EXPECT_CALL(m_flushWatcherMock, isAsyncFlushOngoing()).WillRepeatedly(Return(kNoFlushOngoing)); + firebolt::rialto::server::tasks::generic::HandleBusMessage task{m_context, m_gstPlayer, + &m_gstPlayerClient, m_gstWrapper, + m_glibWrapper, &m_message, + m_flushWatcherMock}; task.execute(); } @@ -374,9 +602,12 @@ TEST_F(HandleBusMessageTest, shouldHandleQosMessageForVideo) EXPECT_CALL(m_gstPlayerClient, notifyQos(firebolt::rialto::MediaSourceType::VIDEO, QosInfoMatcher(processed, dropped))); EXPECT_CALL(*m_gstWrapper, gstMessageUnref(&m_message)); - firebolt::rialto::server::tasks::generic::HandleBusMessage task{m_context, m_gstPlayer, &m_gstPlayerClient, - m_gstWrapper, m_glibWrapper, &m_message, - kNoFlushOngoing}; + EXPECT_CALL(m_flushWatcherMock, isFlushOngoing()).WillRepeatedly(Return(kNoFlushOngoing)); + EXPECT_CALL(m_flushWatcherMock, isAsyncFlushOngoing()).WillRepeatedly(Return(kNoFlushOngoing)); + firebolt::rialto::server::tasks::generic::HandleBusMessage task{m_context, m_gstPlayer, + &m_gstPlayerClient, m_gstWrapper, + m_glibWrapper, &m_message, + m_flushWatcherMock}; task.execute(); } @@ -399,9 +630,12 @@ TEST_F(HandleBusMessageTest, shouldHandleQosMessageForAudio) EXPECT_CALL(m_gstPlayerClient, notifyQos(firebolt::rialto::MediaSourceType::AUDIO, QosInfoMatcher(processed, dropped))); EXPECT_CALL(*m_gstWrapper, gstMessageUnref(&m_message)); - firebolt::rialto::server::tasks::generic::HandleBusMessage task{m_context, m_gstPlayer, &m_gstPlayerClient, - m_gstWrapper, m_glibWrapper, &m_message, - kNoFlushOngoing}; + EXPECT_CALL(m_flushWatcherMock, isFlushOngoing()).WillRepeatedly(Return(kNoFlushOngoing)); + EXPECT_CALL(m_flushWatcherMock, isAsyncFlushOngoing()).WillRepeatedly(Return(kNoFlushOngoing)); + firebolt::rialto::server::tasks::generic::HandleBusMessage task{m_context, m_gstPlayer, + &m_gstPlayerClient, m_gstWrapper, + m_glibWrapper, &m_message, + m_flushWatcherMock}; task.execute(); } @@ -413,15 +647,17 @@ TEST_F(HandleBusMessageTest, shouldHandleErrorMessageNoEos) GST_MESSAGE_TYPE(&m_message) = GST_MESSAGE_ERROR; GST_MESSAGE_SRC(&m_message) = GST_OBJECT_CAST(&m_videoSrc); m_err.domain = GST_CORE_ERROR; - + EXPECT_CALL(m_flushWatcherMock, isFlushOngoing()).WillRepeatedly(Return(kNoFlushOngoing)); + EXPECT_CALL(m_flushWatcherMock, isAsyncFlushOngoing()).WillRepeatedly(Return(kNoFlushOngoing)); EXPECT_CALL(*m_gstWrapper, gstMessageParseError(&m_message, _, _)) .WillRepeatedly(DoAll(SetArgPointee<1>(&m_err), SetArgPointee<2>(m_debug))); EXPECT_CALL(m_gstPlayerClient, notifyPlaybackState(firebolt::rialto::PlaybackState::FAILURE)); expectFreeErrorMessage(); - firebolt::rialto::server::tasks::generic::HandleBusMessage task{m_context, m_gstPlayer, &m_gstPlayerClient, - m_gstWrapper, m_glibWrapper, &m_message, - kNoFlushOngoing}; + firebolt::rialto::server::tasks::generic::HandleBusMessage task{m_context, m_gstPlayer, + &m_gstPlayerClient, m_gstWrapper, + m_glibWrapper, &m_message, + m_flushWatcherMock}; task.execute(); } @@ -436,15 +672,17 @@ TEST_F(HandleBusMessageTest, shouldHandleErrorMessageWhenEosAllSources) m_context.endOfStreamInfo.emplace(firebolt::rialto::MediaSourceType::AUDIO, firebolt::rialto::server::EosState::SET); m_context.endOfStreamInfo.emplace(firebolt::rialto::MediaSourceType::VIDEO, firebolt::rialto::server::EosState::SET); - + EXPECT_CALL(m_flushWatcherMock, isFlushOngoing()).WillRepeatedly(Return(kNoFlushOngoing)); + EXPECT_CALL(m_flushWatcherMock, isAsyncFlushOngoing()).WillRepeatedly(Return(kNoFlushOngoing)); EXPECT_CALL(*m_gstWrapper, gstMessageParseError(&m_message, _, _)) .WillRepeatedly(DoAll(SetArgPointee<1>(&m_err), SetArgPointee<2>(m_debug))); EXPECT_CALL(m_gstPlayerClient, notifyPlaybackState(firebolt::rialto::PlaybackState::FAILURE)); expectFreeErrorMessage(); - firebolt::rialto::server::tasks::generic::HandleBusMessage task{m_context, m_gstPlayer, &m_gstPlayerClient, - m_gstWrapper, m_glibWrapper, &m_message, - kNoFlushOngoing}; + firebolt::rialto::server::tasks::generic::HandleBusMessage task{m_context, m_gstPlayer, + &m_gstPlayerClient, m_gstWrapper, + m_glibWrapper, &m_message, + m_flushWatcherMock}; task.execute(); } @@ -456,15 +694,17 @@ TEST_F(HandleBusMessageTest, shouldHandleStreamErrorMessageNoEos) GST_MESSAGE_TYPE(&m_message) = GST_MESSAGE_ERROR; GST_MESSAGE_SRC(&m_message) = GST_OBJECT_CAST(&m_videoSrc); m_err.domain = GST_STREAM_ERROR; - + EXPECT_CALL(m_flushWatcherMock, isFlushOngoing()).WillRepeatedly(Return(kNoFlushOngoing)); + EXPECT_CALL(m_flushWatcherMock, isAsyncFlushOngoing()).WillRepeatedly(Return(kNoFlushOngoing)); EXPECT_CALL(*m_gstWrapper, gstMessageParseError(&m_message, _, _)) .WillRepeatedly(DoAll(SetArgPointee<1>(&m_err), SetArgPointee<2>(m_debug))); EXPECT_CALL(m_gstPlayerClient, notifyPlaybackState(firebolt::rialto::PlaybackState::FAILURE)); expectFreeErrorMessage(); - firebolt::rialto::server::tasks::generic::HandleBusMessage task{m_context, m_gstPlayer, &m_gstPlayerClient, - m_gstWrapper, m_glibWrapper, &m_message, - kNoFlushOngoing}; + firebolt::rialto::server::tasks::generic::HandleBusMessage task{m_context, m_gstPlayer, + &m_gstPlayerClient, m_gstWrapper, + m_glibWrapper, &m_message, + m_flushWatcherMock}; task.execute(); } @@ -478,15 +718,17 @@ TEST_F(HandleBusMessageTest, shouldHandleStreamErrorMessageWhenEosSingleSource) m_err.domain = GST_STREAM_ERROR; m_context.endOfStreamInfo.emplace(firebolt::rialto::MediaSourceType::AUDIO, firebolt::rialto::server::EosState::SET); - + EXPECT_CALL(m_flushWatcherMock, isFlushOngoing()).WillRepeatedly(Return(kNoFlushOngoing)); + EXPECT_CALL(m_flushWatcherMock, isAsyncFlushOngoing()).WillRepeatedly(Return(kNoFlushOngoing)); EXPECT_CALL(*m_gstWrapper, gstMessageParseError(&m_message, _, _)) .WillRepeatedly(DoAll(SetArgPointee<1>(&m_err), SetArgPointee<2>(m_debug))); EXPECT_CALL(m_gstPlayerClient, notifyPlaybackState(firebolt::rialto::PlaybackState::FAILURE)); expectFreeErrorMessage(); - firebolt::rialto::server::tasks::generic::HandleBusMessage task{m_context, m_gstPlayer, &m_gstPlayerClient, - m_gstWrapper, m_glibWrapper, &m_message, - kNoFlushOngoing}; + firebolt::rialto::server::tasks::generic::HandleBusMessage task{m_context, m_gstPlayer, + &m_gstPlayerClient, m_gstWrapper, + m_glibWrapper, &m_message, + m_flushWatcherMock}; task.execute(); } @@ -501,15 +743,17 @@ TEST_F(HandleBusMessageTest, shouldHandleStreamErrorMessageWhenEosAllSources) m_context.endOfStreamInfo.emplace(firebolt::rialto::MediaSourceType::AUDIO, firebolt::rialto::server::EosState::SET); m_context.endOfStreamInfo.emplace(firebolt::rialto::MediaSourceType::VIDEO, firebolt::rialto::server::EosState::SET); - + EXPECT_CALL(m_flushWatcherMock, isFlushOngoing()).WillRepeatedly(Return(kNoFlushOngoing)); + EXPECT_CALL(m_flushWatcherMock, isAsyncFlushOngoing()).WillRepeatedly(Return(kNoFlushOngoing)); EXPECT_CALL(*m_gstWrapper, gstMessageParseError(&m_message, _, _)) .WillRepeatedly(DoAll(SetArgPointee<1>(&m_err), SetArgPointee<2>(m_debug))); EXPECT_CALL(m_gstPlayerClient, notifyPlaybackState(firebolt::rialto::PlaybackState::END_OF_STREAM)); expectFreeErrorMessage(); - firebolt::rialto::server::tasks::generic::HandleBusMessage task{m_context, m_gstPlayer, &m_gstPlayerClient, - m_gstWrapper, m_glibWrapper, &m_message, - kNoFlushOngoing}; + firebolt::rialto::server::tasks::generic::HandleBusMessage task{m_context, m_gstPlayer, + &m_gstPlayerClient, m_gstWrapper, + m_glibWrapper, &m_message, + m_flushWatcherMock}; task.execute(); EXPECT_TRUE(m_context.eosNotified); @@ -528,14 +772,16 @@ TEST_F(HandleBusMessageTest, shouldHandleStreamErrorMessageWhenEosAllSourcesAndE m_context.endOfStreamInfo.emplace(firebolt::rialto::MediaSourceType::AUDIO, firebolt::rialto::server::EosState::SET); m_context.endOfStreamInfo.emplace(firebolt::rialto::MediaSourceType::VIDEO, firebolt::rialto::server::EosState::SET); m_context.eosNotified = true; - + EXPECT_CALL(m_flushWatcherMock, isFlushOngoing()).WillRepeatedly(Return(kNoFlushOngoing)); + EXPECT_CALL(m_flushWatcherMock, isAsyncFlushOngoing()).WillRepeatedly(Return(kNoFlushOngoing)); EXPECT_CALL(*m_gstWrapper, gstMessageParseError(&m_message, _, _)) .WillRepeatedly(DoAll(SetArgPointee<1>(&m_err), SetArgPointee<2>(m_debug))); expectFreeErrorMessage(); - firebolt::rialto::server::tasks::generic::HandleBusMessage task{m_context, m_gstPlayer, &m_gstPlayerClient, - m_gstWrapper, m_glibWrapper, &m_message, - kNoFlushOngoing}; + firebolt::rialto::server::tasks::generic::HandleBusMessage task{m_context, m_gstPlayer, + &m_gstPlayerClient, m_gstWrapper, + m_glibWrapper, &m_message, + m_flushWatcherMock}; task.execute(); } @@ -552,16 +798,18 @@ TEST_F(HandleBusMessageTest, shouldHandleWarningMessageForAudioDecryption) GST_MESSAGE_SRC(&m_message) = decryptor; m_err.domain = GST_STREAM_ERROR; m_err.code = GST_STREAM_ERROR_DECRYPT; - + EXPECT_CALL(m_flushWatcherMock, isFlushOngoing()).WillRepeatedly(Return(kNoFlushOngoing)); + EXPECT_CALL(m_flushWatcherMock, isAsyncFlushOngoing()).WillRepeatedly(Return(kNoFlushOngoing)); EXPECT_CALL(*m_gstWrapper, gstMessageParseWarning(&m_message, _, _)) .WillOnce(DoAll(SetArgPointee<1>(&m_err), SetArgPointee<2>(m_debug))); EXPECT_CALL(m_gstPlayerClient, notifyPlaybackError(firebolt::rialto::MediaSourceType::AUDIO, firebolt::rialto::PlaybackError::DECRYPTION)); expectFreeErrorMessage(); - firebolt::rialto::server::tasks::generic::HandleBusMessage task{m_context, m_gstPlayer, &m_gstPlayerClient, - m_gstWrapper, m_glibWrapper, &m_message, - kNoFlushOngoing}; + firebolt::rialto::server::tasks::generic::HandleBusMessage task{m_context, m_gstPlayer, + &m_gstPlayerClient, m_gstWrapper, + m_glibWrapper, &m_message, + m_flushWatcherMock}; task.execute(); g_object_unref(decryptor); @@ -580,16 +828,18 @@ TEST_F(HandleBusMessageTest, shouldHandleWarningMessageForVideoDecryption) GST_MESSAGE_SRC(&m_message) = decryptor; m_err.domain = GST_STREAM_ERROR; m_err.code = GST_STREAM_ERROR_DECRYPT; - + EXPECT_CALL(m_flushWatcherMock, isFlushOngoing()).WillRepeatedly(Return(kNoFlushOngoing)); + EXPECT_CALL(m_flushWatcherMock, isAsyncFlushOngoing()).WillRepeatedly(Return(kNoFlushOngoing)); EXPECT_CALL(*m_gstWrapper, gstMessageParseWarning(&m_message, _, _)) .WillOnce(DoAll(SetArgPointee<1>(&m_err), SetArgPointee<2>(m_debug))); EXPECT_CALL(m_gstPlayerClient, notifyPlaybackError(firebolt::rialto::MediaSourceType::VIDEO, firebolt::rialto::PlaybackError::DECRYPTION)); expectFreeErrorMessage(); - firebolt::rialto::server::tasks::generic::HandleBusMessage task{m_context, m_gstPlayer, &m_gstPlayerClient, - m_gstWrapper, m_glibWrapper, &m_message, - kNoFlushOngoing}; + firebolt::rialto::server::tasks::generic::HandleBusMessage task{m_context, m_gstPlayer, + &m_gstPlayerClient, m_gstWrapper, + m_glibWrapper, &m_message, + m_flushWatcherMock}; task.execute(); g_object_unref(decryptor); @@ -607,14 +857,16 @@ TEST_F(HandleBusMessageTest, shouldHandleWarningMessageGeneric) GST_MESSAGE_TYPE(&m_message) = GST_MESSAGE_WARNING; GST_MESSAGE_SRC(&m_message) = element; m_err.domain = GST_CORE_ERROR; - + EXPECT_CALL(m_flushWatcherMock, isFlushOngoing()).WillRepeatedly(Return(kNoFlushOngoing)); + EXPECT_CALL(m_flushWatcherMock, isAsyncFlushOngoing()).WillRepeatedly(Return(kNoFlushOngoing)); EXPECT_CALL(*m_gstWrapper, gstMessageParseWarning(&m_message, _, _)) .WillOnce(DoAll(SetArgPointee<1>(&m_err), SetArgPointee<2>(m_debug))); expectFreeErrorMessage(); - firebolt::rialto::server::tasks::generic::HandleBusMessage task{m_context, m_gstPlayer, &m_gstPlayerClient, - m_gstWrapper, m_glibWrapper, &m_message, - kNoFlushOngoing}; + firebolt::rialto::server::tasks::generic::HandleBusMessage task{m_context, m_gstPlayer, + &m_gstPlayerClient, m_gstWrapper, + m_glibWrapper, &m_message, + m_flushWatcherMock}; task.execute(); g_object_unref(element); @@ -633,14 +885,16 @@ TEST_F(HandleBusMessageTest, shouldHandleWarningMessageForUnknownSrcTypeDecrypti GST_MESSAGE_SRC(&m_message) = element; m_err.domain = GST_STREAM_ERROR; m_err.code = GST_STREAM_ERROR_DECRYPT; - + EXPECT_CALL(m_flushWatcherMock, isFlushOngoing()).WillRepeatedly(Return(kNoFlushOngoing)); + EXPECT_CALL(m_flushWatcherMock, isAsyncFlushOngoing()).WillRepeatedly(Return(kNoFlushOngoing)); EXPECT_CALL(*m_gstWrapper, gstMessageParseWarning(&m_message, _, _)) .WillOnce(DoAll(SetArgPointee<1>(&m_err), SetArgPointee<2>(m_debug))); expectFreeErrorMessage(); - firebolt::rialto::server::tasks::generic::HandleBusMessage task{m_context, m_gstPlayer, &m_gstPlayerClient, - m_gstWrapper, m_glibWrapper, &m_message, - kNoFlushOngoing}; + firebolt::rialto::server::tasks::generic::HandleBusMessage task{m_context, m_gstPlayer, + &m_gstPlayerClient, m_gstWrapper, + m_glibWrapper, &m_message, + m_flushWatcherMock}; task.execute(); g_object_unref(element); diff --git a/tests/unittests/media/server/gstplayer/genericPlayer/tasksTests/SetMuteTest.cpp b/tests/unittests/media/server/gstplayer/genericPlayer/tasksTests/SetMuteTest.cpp index 7ea55907a..5bccd8bb0 100644 --- a/tests/unittests/media/server/gstplayer/genericPlayer/tasksTests/SetMuteTest.cpp +++ b/tests/unittests/media/server/gstplayer/genericPlayer/tasksTests/SetMuteTest.cpp @@ -34,18 +34,6 @@ TEST_F(SetMuteTest, shouldSetVideoMute) triggerSetVideoMute(); } -TEST_F(SetMuteTest, shouldFailToSetVideoMuteNoSink) -{ - shouldFailToSetVideoMuteNoSink(); - triggerSetVideoMute(); -} - -TEST_F(SetMuteTest, shouldFailToSetVideoMuteNoProperty) -{ - shouldFailToSetVideoMuteNoProperty(); - triggerSetVideoMute(); -} - TEST_F(SetMuteTest, shouldFailToSetAudioMuteWhenPipelineIsNull) { setContextPipelineNull(); diff --git a/tests/unittests/media/server/gstplayer/genericPlayer/tasksTests/SetupElementTest.cpp b/tests/unittests/media/server/gstplayer/genericPlayer/tasksTests/SetupElementTest.cpp index 6eec00361..d572a59d0 100644 --- a/tests/unittests/media/server/gstplayer/genericPlayer/tasksTests/SetupElementTest.cpp +++ b/tests/unittests/media/server/gstplayer/genericPlayer/tasksTests/SetupElementTest.cpp @@ -83,6 +83,12 @@ TEST_F(SetupElementTest, shouldSetupVideoElementWithPendingRenderFrame) triggerSetupElement(); } +TEST_F(SetupElementTest, shouldSetupVideoElementWithPendingShowVideoWindow) +{ + shouldSetupVideoSinkElementWithPendingShowVideoWindow(); + triggerSetupElement(); +} + TEST_F(SetupElementTest, shouldSetupAudioElementAmlhalasinkWhenNoVideo) { shouldSetupAudioElementAmlhalasinkWhenNoVideo(); diff --git a/tests/unittests/media/server/gstplayer/rialtoSrc/AppSrcTest.cpp b/tests/unittests/media/server/gstplayer/rialtoSrc/AppSrcTest.cpp index 64af525f7..48e126df8 100644 --- a/tests/unittests/media/server/gstplayer/rialtoSrc/AppSrcTest.cpp +++ b/tests/unittests/media/server/gstplayer/rialtoSrc/AppSrcTest.cpp @@ -227,7 +227,7 @@ TEST_F(RialtoServerAppSrcGstSrcTest, SetupVideo) expectLinkQueue(&m_payloader); expectSetupPad(&m_queue); - m_gstSrc->setupAndAddAppArc(m_decryptionServiceMock.get(), GST_ELEMENT(&m_rialtoSrc), m_streamInfo, &m_callbacks, + m_gstSrc->setupAndAddAppSrc(m_decryptionServiceMock.get(), GST_ELEMENT(&m_rialtoSrc), m_streamInfo, &m_callbacks, this, MediaSourceType::VIDEO); } @@ -247,7 +247,7 @@ TEST_F(RialtoServerAppSrcGstSrcTest, SetupVideoH264WithoutStreamFormat) expectLinkQueue(&m_payloader); expectSetupPad(&m_queue); - m_gstSrc->setupAndAddAppArc(m_decryptionServiceMock.get(), GST_ELEMENT(&m_rialtoSrc), m_streamInfo, &m_callbacks, + m_gstSrc->setupAndAddAppSrc(m_decryptionServiceMock.get(), GST_ELEMENT(&m_rialtoSrc), m_streamInfo, &m_callbacks, this, MediaSourceType::VIDEO); } @@ -273,7 +273,7 @@ TEST_F(RialtoServerAppSrcGstSrcTest, SetupVideoWithStreamFormat) expectLinkQueue(&m_payloader); expectSetupPad(&m_queue); - m_gstSrc->setupAndAddAppArc(m_decryptionServiceMock.get(), GST_ELEMENT(&m_rialtoSrc), m_streamInfo, &m_callbacks, + m_gstSrc->setupAndAddAppSrc(m_decryptionServiceMock.get(), GST_ELEMENT(&m_rialtoSrc), m_streamInfo, &m_callbacks, this, MediaSourceType::VIDEO); } @@ -299,7 +299,7 @@ TEST_F(RialtoServerAppSrcGstSrcTest, SetupVideoWithCodecData) expectLinkQueue(&m_payloader); expectSetupPad(&m_queue); - m_gstSrc->setupAndAddAppArc(m_decryptionServiceMock.get(), GST_ELEMENT(&m_rialtoSrc), m_streamInfo, &m_callbacks, + m_gstSrc->setupAndAddAppSrc(m_decryptionServiceMock.get(), GST_ELEMENT(&m_rialtoSrc), m_streamInfo, &m_callbacks, this, MediaSourceType::VIDEO); } @@ -328,7 +328,7 @@ TEST_F(RialtoServerAppSrcGstSrcTest, SetupAudio) expectLinkQueue(&m_decryptor); expectSetupPad(&m_queue); - m_gstSrc->setupAndAddAppArc(m_decryptionServiceMock.get(), GST_ELEMENT(&m_rialtoSrc), m_streamInfo, &m_callbacks, + m_gstSrc->setupAndAddAppSrc(m_decryptionServiceMock.get(), GST_ELEMENT(&m_rialtoSrc), m_streamInfo, &m_callbacks, this, MediaSourceType::AUDIO); } @@ -354,7 +354,7 @@ TEST_F(RialtoServerAppSrcGstSrcTest, DecryptorFailure) expectLinkQueue(&m_payloader); expectSetupPad(&m_queue); - m_gstSrc->setupAndAddAppArc(m_decryptionServiceMock.get(), GST_ELEMENT(&m_rialtoSrc), m_streamInfo, &m_callbacks, + m_gstSrc->setupAndAddAppSrc(m_decryptionServiceMock.get(), GST_ELEMENT(&m_rialtoSrc), m_streamInfo, &m_callbacks, this, MediaSourceType::VIDEO); } @@ -379,7 +379,7 @@ TEST_F(RialtoServerAppSrcGstSrcTest, PayloaderFailure) expectLinkQueue(&m_decryptor); expectSetupPad(&m_queue); - m_gstSrc->setupAndAddAppArc(m_decryptionServiceMock.get(), GST_ELEMENT(&m_rialtoSrc), m_streamInfo, &m_callbacks, + m_gstSrc->setupAndAddAppSrc(m_decryptionServiceMock.get(), GST_ELEMENT(&m_rialtoSrc), m_streamInfo, &m_callbacks, this, MediaSourceType::VIDEO); } @@ -400,7 +400,7 @@ TEST_F(RialtoServerAppSrcGstSrcTest, QueueFailure) expectAddDefaultStreamFormat(); expectSetupPad(&m_payloader); - m_gstSrc->setupAndAddAppArc(m_decryptionServiceMock.get(), GST_ELEMENT(&m_rialtoSrc), m_streamInfo, &m_callbacks, + m_gstSrc->setupAndAddAppSrc(m_decryptionServiceMock.get(), GST_ELEMENT(&m_rialtoSrc), m_streamInfo, &m_callbacks, this, MediaSourceType::VIDEO); } @@ -417,7 +417,7 @@ TEST_F(RialtoServerAppSrcGstSrcTest, NotDrm) expectSyncElement(m_streamInfo.appSrc); expectSetupPad(m_streamInfo.appSrc); - m_gstSrc->setupAndAddAppArc(m_decryptionServiceMock.get(), GST_ELEMENT(&m_rialtoSrc), m_streamInfo, &m_callbacks, + m_gstSrc->setupAndAddAppSrc(m_decryptionServiceMock.get(), GST_ELEMENT(&m_rialtoSrc), m_streamInfo, &m_callbacks, this, MediaSourceType::VIDEO); } diff --git a/tests/unittests/media/server/gstplayer/webAudioPlayer/CreateTest.cpp b/tests/unittests/media/server/gstplayer/webAudioPlayer/CreateTest.cpp index ccfb2a55a..0a61ceeb5 100644 --- a/tests/unittests/media/server/gstplayer/webAudioPlayer/CreateTest.cpp +++ b/tests/unittests/media/server/gstplayer/webAudioPlayer/CreateTest.cpp @@ -369,6 +369,46 @@ TEST_F(RialtoServerCreateGstWebAudioPlayerTest, createAudioResampleFailure) EXPECT_EQ(m_gstPlayer, nullptr); } +/** + * Test that a GstWebAudioPlayer throws an exception if there is a failure to create queue. + */ +TEST_F(RialtoServerCreateGstWebAudioPlayerTest, createAudioQueueFailure) +{ + EXPECT_CALL(m_gstInitialiserMock, waitForInitialisation()); + expectInitRialtoSrc(); + expectMakeRtkAudioSink(); + expectCreatePipeline(); + expectInitAppSrc(); + expectInitWorkerThread(); + EXPECT_CALL(*m_glibWrapperMock, gObjectSetStub(G_OBJECT(&m_sink), StrEq("media-tunnel"))); + EXPECT_CALL(*m_glibWrapperMock, gObjectSetStub(G_OBJECT(&m_sink), StrEq("audio-service"))); + + GstElement convert{}; + GstElement resample{}; + GstElement volume{}; + + EXPECT_CALL(*m_gstWrapperMock, gstElementFactoryMake(StrEq("audioconvert"), _)).WillOnce(Return(&convert)); + EXPECT_CALL(*m_gstWrapperMock, gstElementFactoryMake(StrEq("audioresample"), _)).WillOnce(Return(&resample)); + EXPECT_CALL(*m_gstWrapperMock, gstElementFactoryMake(StrEq("volume"), _)).WillOnce(Return(&volume)); + EXPECT_CALL(*m_gstWrapperMock, gstElementFactoryMake(StrEq("queue"), _)).WillOnce(Return(nullptr)); + EXPECT_CALL(*m_gstWrapperMock, gstObjectUnref(&convert)); + + // Reset worker thread and pipeline on failure + gstPlayerWillBeDestroyed(); + EXPECT_CALL(*m_gstWrapperMock, gstObjectUnref(&resample)); + EXPECT_CALL(*m_gstWrapperMock, gstObjectUnref(&volume)); + EXPECT_CALL(*m_gstWrapperMock, gstObjectUnref(&m_sink)); + EXPECT_CALL(*m_gstWrapperMock, gstObjectUnref(&m_appSrc)); + + EXPECT_THROW(m_gstPlayer = std::make_unique(&m_gstPlayerClient, m_priority, m_gstWrapperMock, + m_glibWrapperMock, m_gstInitialiserMock, + m_gstSrcFactoryMock, std::move(m_taskFactory), + std::move(workerThreadFactory), + std::move(gstDispatcherThreadFactory)), + std::runtime_error); + EXPECT_EQ(m_gstPlayer, nullptr); +} + /** * Test that a GstWebAudioPlayer throws an exception if there is a failure to add the audio sink elements to the bin. */ diff --git a/tests/unittests/media/server/gstplayer/webAudioPlayer/common/GstWebAudioPlayerTestCommon.cpp b/tests/unittests/media/server/gstplayer/webAudioPlayer/common/GstWebAudioPlayerTestCommon.cpp index b6b50076d..96980db37 100644 --- a/tests/unittests/media/server/gstplayer/webAudioPlayer/common/GstWebAudioPlayerTestCommon.cpp +++ b/tests/unittests/media/server/gstplayer/webAudioPlayer/common/GstWebAudioPlayerTestCommon.cpp @@ -197,19 +197,24 @@ void GstWebAudioPlayerTestCommon::expectLinkElements() GstElement convert{}; GstElement resample{}; memset(&m_volume, 0x00, sizeof(m_volume)); + GstElement queue{}; EXPECT_CALL(*m_gstWrapperMock, gstElementFactoryMake(StrEq("audioconvert"), _)).WillOnce(Return(&convert)); EXPECT_CALL(*m_gstWrapperMock, gstElementFactoryMake(StrEq("audioresample"), _)).WillOnce(Return(&resample)); EXPECT_CALL(*m_gstWrapperMock, gstElementFactoryMake(StrEq("volume"), _)).WillOnce(Return(&m_volume)); + EXPECT_CALL(*m_gstWrapperMock, gstElementFactoryMake(StrEq("queue"), _)).WillOnce(Return(&queue)); + EXPECT_CALL(*m_glibWrapperMock, gObjectSetStub(G_OBJECT(&queue), StrEq("max-size-bytes"))); EXPECT_CALL(*m_gstWrapperMock, gstBinAdd(GST_BIN(&m_pipeline), &m_appSrc)).WillOnce(Return(TRUE)); EXPECT_CALL(*m_gstWrapperMock, gstBinAdd(GST_BIN(&m_pipeline), &convert)).WillOnce(Return(TRUE)); EXPECT_CALL(*m_gstWrapperMock, gstBinAdd(GST_BIN(&m_pipeline), &resample)).WillOnce(Return(TRUE)); EXPECT_CALL(*m_gstWrapperMock, gstBinAdd(GST_BIN(&m_pipeline), &m_volume)).WillOnce(Return(TRUE)); + EXPECT_CALL(*m_gstWrapperMock, gstBinAdd(GST_BIN(&m_pipeline), &queue)).WillOnce(Return(TRUE)); EXPECT_CALL(*m_gstWrapperMock, gstBinAdd(GST_BIN(&m_pipeline), &m_sink)).WillOnce(Return(TRUE)); EXPECT_CALL(*m_gstWrapperMock, gstElementLink(&m_appSrc, &convert)).WillOnce(Return(TRUE)); EXPECT_CALL(*m_gstWrapperMock, gstElementLink(&convert, &resample)).WillOnce(Return(TRUE)); EXPECT_CALL(*m_gstWrapperMock, gstElementLink(&resample, &m_volume)).WillOnce(Return(TRUE)); - EXPECT_CALL(*m_gstWrapperMock, gstElementLink(&m_volume, &m_sink)).WillOnce(Return(TRUE)); + EXPECT_CALL(*m_gstWrapperMock, gstElementLink(&m_volume, &queue)).WillOnce(Return(TRUE)); + EXPECT_CALL(*m_gstWrapperMock, gstElementLink(&queue, &m_sink)).WillOnce(Return(TRUE)); } void GstWebAudioPlayerTestCommon::expectLinkElementsExceptVolume() @@ -231,14 +236,18 @@ void GstWebAudioPlayerTestCommon::expectAddBinFailure() GstElement convert{}; GstElement resample{}; memset(&m_volume, 0x00, sizeof(m_volume)); + GstElement queue{}; EXPECT_CALL(*m_gstWrapperMock, gstElementFactoryMake(StrEq("audioconvert"), _)).WillOnce(Return(&convert)); EXPECT_CALL(*m_gstWrapperMock, gstElementFactoryMake(StrEq("audioresample"), _)).WillOnce(Return(&resample)); EXPECT_CALL(*m_gstWrapperMock, gstElementFactoryMake(StrEq("volume"), _)).WillOnce(Return(&m_volume)); + EXPECT_CALL(*m_gstWrapperMock, gstElementFactoryMake(StrEq("queue"), _)).WillOnce(Return(&queue)); + EXPECT_CALL(*m_glibWrapperMock, gObjectSetStub(G_OBJECT(&queue), StrEq("max-size-bytes"))); EXPECT_CALL(*m_gstWrapperMock, gstBinAdd(GST_BIN(&m_pipeline), &m_appSrc)).WillOnce(Return(TRUE)); EXPECT_CALL(*m_gstWrapperMock, gstBinAdd(GST_BIN(&m_pipeline), &convert)).WillOnce(Return(TRUE)); EXPECT_CALL(*m_gstWrapperMock, gstBinAdd(GST_BIN(&m_pipeline), &resample)).WillOnce(Return(TRUE)); EXPECT_CALL(*m_gstWrapperMock, gstBinAdd(GST_BIN(&m_pipeline), &m_volume)).WillOnce(Return(TRUE)); + EXPECT_CALL(*m_gstWrapperMock, gstBinAdd(GST_BIN(&m_pipeline), &queue)).WillOnce(Return(TRUE)); EXPECT_CALL(*m_gstWrapperMock, gstBinAdd(GST_BIN(&m_pipeline), &m_sink)).WillOnce(Return(FALSE)); EXPECT_CALL(*m_gstWrapperMock, gstObjectUnref(&m_sink)); } @@ -248,14 +257,18 @@ void GstWebAudioPlayerTestCommon::expectLinkElementFailure() GstElement convert{}; GstElement resample{}; memset(&m_volume, 0x00, sizeof(m_volume)); + GstElement queue{}; EXPECT_CALL(*m_gstWrapperMock, gstElementFactoryMake(StrEq("audioconvert"), _)).WillOnce(Return(&convert)); EXPECT_CALL(*m_gstWrapperMock, gstElementFactoryMake(StrEq("audioresample"), _)).WillOnce(Return(&resample)); EXPECT_CALL(*m_gstWrapperMock, gstElementFactoryMake(StrEq("volume"), _)).WillOnce(Return(&m_volume)); + EXPECT_CALL(*m_gstWrapperMock, gstElementFactoryMake(StrEq("queue"), _)).WillOnce(Return(&queue)); + EXPECT_CALL(*m_glibWrapperMock, gObjectSetStub(G_OBJECT(&queue), StrEq("max-size-bytes"))); EXPECT_CALL(*m_gstWrapperMock, gstBinAdd(GST_BIN(&m_pipeline), &m_appSrc)).WillOnce(Return(TRUE)); EXPECT_CALL(*m_gstWrapperMock, gstBinAdd(GST_BIN(&m_pipeline), &convert)).WillOnce(Return(TRUE)); EXPECT_CALL(*m_gstWrapperMock, gstBinAdd(GST_BIN(&m_pipeline), &resample)).WillOnce(Return(TRUE)); EXPECT_CALL(*m_gstWrapperMock, gstBinAdd(GST_BIN(&m_pipeline), &m_volume)).WillOnce(Return(TRUE)); + EXPECT_CALL(*m_gstWrapperMock, gstBinAdd(GST_BIN(&m_pipeline), &queue)).WillOnce(Return(TRUE)); EXPECT_CALL(*m_gstWrapperMock, gstBinAdd(GST_BIN(&m_pipeline), &m_sink)).WillOnce(Return(TRUE)); EXPECT_CALL(*m_gstWrapperMock, gstElementLink(&m_appSrc, &convert)).WillOnce(Return(FALSE)); } diff --git a/tests/unittests/media/server/ipc/CMakeLists.txt b/tests/unittests/media/server/ipc/CMakeLists.txt index d08cb21bf..ac1d8856c 100644 --- a/tests/unittests/media/server/ipc/CMakeLists.txt +++ b/tests/unittests/media/server/ipc/CMakeLists.txt @@ -99,15 +99,6 @@ target_link_libraries( RialtoProtobuf ) -if ( COVERAGE_ENABLED ) - target_link_libraries( - RialtoServerIpcUnitTests - - gcov - ) -endif() - - set_target_properties( RialtoServerIpcUnitTests PROPERTIES COMPILE_FLAGS "-Wno-write-strings" diff --git a/tests/unittests/media/server/ipc/mediaPipelineCapabilitiesModule/MediaPipelineCapabilitiesModuleServiceTests.cpp b/tests/unittests/media/server/ipc/mediaPipelineCapabilitiesModule/MediaPipelineCapabilitiesModuleServiceTests.cpp index 17c38161f..75d8697dc 100644 --- a/tests/unittests/media/server/ipc/mediaPipelineCapabilitiesModule/MediaPipelineCapabilitiesModuleServiceTests.cpp +++ b/tests/unittests/media/server/ipc/mediaPipelineCapabilitiesModule/MediaPipelineCapabilitiesModuleServiceTests.cpp @@ -65,3 +65,15 @@ TEST_F(MediaPipelineCapabilitiesModuleServiceTests, shouldConvertMediaType) { expectCorrectMediaTypeConversion(); } + +TEST_F(MediaPipelineCapabilitiesModuleServiceTests, shouldCheckIfVideoIsMaster) +{ + mediaPipelineWillCheckIfVideoIsMaster(); + sendIsVideoMasterRequestWithSuccess(); +} + +TEST_F(MediaPipelineCapabilitiesModuleServiceTests, shouldFailToCheckIfVideoIsMaster) +{ + expectInvalidControlFailure(); + sendIsVideoMasterRequestAndExpectFailure(); +} diff --git a/tests/unittests/media/server/ipc/mediaPipelineCapabilitiesModule/MediaPipelineCapabilitiesModuleServiceTestsFixture.cpp b/tests/unittests/media/server/ipc/mediaPipelineCapabilitiesModule/MediaPipelineCapabilitiesModuleServiceTestsFixture.cpp index ff47788a6..cd5f796b2 100644 --- a/tests/unittests/media/server/ipc/mediaPipelineCapabilitiesModule/MediaPipelineCapabilitiesModuleServiceTestsFixture.cpp +++ b/tests/unittests/media/server/ipc/mediaPipelineCapabilitiesModule/MediaPipelineCapabilitiesModuleServiceTestsFixture.cpp @@ -40,6 +40,7 @@ const std::vector kMimeTypes{"video/h264", "video/h265"}; const firebolt::rialto::MediaSourceType kSourceType{firebolt::rialto::MediaSourceType::VIDEO}; const firebolt::rialto::ProtoMediaSourceType kMediaSourceType{firebolt::rialto::ProtoMediaSourceType::VIDEO}; const std::vector kPropertyNames{"test-property", "another-property"}; +constexpr bool kIsVideoMaster{true}; } // namespace MediaPipelineCapabilitiesModuleServiceTests::MediaPipelineCapabilitiesModuleServiceTests() @@ -80,6 +81,13 @@ void MediaPipelineCapabilitiesModuleServiceTests::mediaPipelineWillGetSupportedP .WillOnce(Return(kPropertyNames)); } +void MediaPipelineCapabilitiesModuleServiceTests::mediaPipelineWillCheckIfVideoIsMaster() +{ + expectRequestSuccess(); + EXPECT_CALL(m_mediaPipelineServiceMock, isVideoMaster(_)) + .WillOnce(DoAll(SetArgReferee<0>(kIsVideoMaster), Return(true))); +} + void MediaPipelineCapabilitiesModuleServiceTests::expectRequestSuccess() { EXPECT_CALL(*m_closureMock, Run()); @@ -170,6 +178,23 @@ void MediaPipelineCapabilitiesModuleServiceTests::sendGetSupportedPropertiesRequ EXPECT_TRUE(supportedProperties.empty()); } +void MediaPipelineCapabilitiesModuleServiceTests::sendIsVideoMasterRequestWithSuccess() +{ + firebolt::rialto::IsVideoMasterRequest request; + firebolt::rialto::IsVideoMasterResponse response; + + m_service->isVideoMaster(m_controllerMock.get(), &request, &response, m_closureMock.get()); + + EXPECT_EQ(response.is_video_master(), kIsVideoMaster); +} + +void MediaPipelineCapabilitiesModuleServiceTests::sendIsVideoMasterRequestAndExpectFailure() +{ + firebolt::rialto::IsVideoMasterRequest request; + firebolt::rialto::IsVideoMasterResponse response; + m_service->isVideoMaster(m_invalidControllerMock.get(), &request, &response, m_closureMock.get()); +} + void MediaPipelineCapabilitiesModuleServiceTests::expectCorrectMediaTypeConversion() { EXPECT_EQ(firebolt::rialto::server::ipc::convertMediaSourceType(firebolt::rialto::ProtoMediaSourceType::UNKNOWN), diff --git a/tests/unittests/media/server/ipc/mediaPipelineCapabilitiesModule/MediaPipelineCapabilitiesModuleServiceTestsFixture.h b/tests/unittests/media/server/ipc/mediaPipelineCapabilitiesModule/MediaPipelineCapabilitiesModuleServiceTestsFixture.h index beb677c97..cd4583972 100644 --- a/tests/unittests/media/server/ipc/mediaPipelineCapabilitiesModule/MediaPipelineCapabilitiesModuleServiceTestsFixture.h +++ b/tests/unittests/media/server/ipc/mediaPipelineCapabilitiesModule/MediaPipelineCapabilitiesModuleServiceTestsFixture.h @@ -42,6 +42,7 @@ class MediaPipelineCapabilitiesModuleServiceTests : public testing::Test void mediaPipelineServiceWillGetSupportedMimeTypes(); void mediaPipelineWillCheckIfMimeTypeIsSupported(); void mediaPipelineWillGetSupportedProperties(); + void mediaPipelineWillCheckIfVideoIsMaster(); void sendClientConnected(); void sendClientDisconnected(); @@ -51,6 +52,8 @@ class MediaPipelineCapabilitiesModuleServiceTests : public testing::Test void sendIsMimeTypeSupportedRequestAndExpectFailure(); void sendGetSupportedPropertiesRequestWithSuccess(); void sendGetSupportedPropertiesRequestAndExpectFailure(); + void sendIsVideoMasterRequestWithSuccess(); + void sendIsVideoMasterRequestAndExpectFailure(); void expectInvalidControlFailure(); void expectCorrectMediaTypeConversion(); diff --git a/tests/unittests/media/server/ipc/mediaPipelineModuleService/MediaPipelineModuleServiceTestsFixture.cpp b/tests/unittests/media/server/ipc/mediaPipelineModuleService/MediaPipelineModuleServiceTestsFixture.cpp index ee28f9233..80ed6c280 100644 --- a/tests/unittests/media/server/ipc/mediaPipelineModuleService/MediaPipelineModuleServiceTestsFixture.cpp +++ b/tests/unittests/media/server/ipc/mediaPipelineModuleService/MediaPipelineModuleServiceTestsFixture.cpp @@ -91,6 +91,7 @@ constexpr uint32_t kBufferingLimit{12341}; constexpr bool kUseBuffering{true}; constexpr uint64_t kStopPosition{2423}; constexpr bool kFramed{true}; +constexpr bool kIsVideoMaster{true}; } // namespace MATCHER_P(AttachedSourceMatcher, source, "") diff --git a/tests/unittests/media/server/main/CMakeLists.txt b/tests/unittests/media/server/main/CMakeLists.txt index 995e79ea8..ec242bc4f 100644 --- a/tests/unittests/media/server/main/CMakeLists.txt +++ b/tests/unittests/media/server/main/CMakeLists.txt @@ -143,11 +143,3 @@ target_link_libraries( RialtoPlayerCommon RialtoCommonMisc ) - -if ( COVERAGE_ENABLED ) - target_link_libraries( - RialtoServerMainUnitTests - - gcov - ) -endif() diff --git a/tests/unittests/media/server/main/dataReader/DataReaderV2Tests.cpp b/tests/unittests/media/server/main/dataReader/DataReaderV2Tests.cpp index 001f6b0de..c2824b425 100644 --- a/tests/unittests/media/server/main/dataReader/DataReaderV2Tests.cpp +++ b/tests/unittests/media/server/main/dataReader/DataReaderV2Tests.cpp @@ -64,6 +64,7 @@ constexpr SegmentAlignment kSegmentAlignment{SegmentAlignment::AU}; constexpr uint32_t kCryptBlocks{131}; constexpr uint32_t kSkipBlocks{242}; +constexpr uint64_t kDisplayOffset{35}; class Check { @@ -115,6 +116,7 @@ class Check EXPECT_TRUE(m_segment->getCodecData()); EXPECT_EQ(m_segment->getCodecData()->data, kCodecData.data); EXPECT_EQ(m_segment->getCodecData()->type, kCodecData.type); + EXPECT_EQ(m_segment->getDisplayOffset().value(), kDisplayOffset); return *this; } @@ -230,6 +232,7 @@ class Build m_segment->setExtraData(kExtraData); m_segment->setSegmentAlignment(kSegmentAlignment); m_segment->setCodecData(std::make_shared(kCodecData)); + m_segment->setDisplayOffset(kDisplayOffset); return *this; } diff --git a/tests/unittests/media/server/main/mediaPipeline/FlushTest.cpp b/tests/unittests/media/server/main/mediaPipeline/FlushTest.cpp index 65762329d..a9ca62986 100644 --- a/tests/unittests/media/server/main/mediaPipeline/FlushTest.cpp +++ b/tests/unittests/media/server/main/mediaPipeline/FlushTest.cpp @@ -29,7 +29,6 @@ class RialtoServerMediaPipelineFlushTest : public MediaPipelineTestBase const char *m_kMimeType{"video/mpeg"}; const bool m_kResetTime{true}; const int m_kDummySourceId{123}; - const bool m_kIsAsync{true}; RialtoServerMediaPipelineFlushTest() { createMediaPipeline(); } @@ -53,10 +52,8 @@ TEST_F(RialtoServerMediaPipelineFlushTest, FlushSuccess) bool async{false}; mainThreadWillEnqueueTaskAndWait(); - EXPECT_CALL(*m_gstPlayerMock, isAsync(m_kType)).WillOnce(Return(m_kIsAsync)); - EXPECT_CALL(*m_gstPlayerMock, flush(m_kType, m_kResetTime)); + EXPECT_CALL(*m_gstPlayerMock, flush(m_kType, m_kResetTime, async)); EXPECT_TRUE(m_mediaPipeline->flush(sourceId, m_kResetTime, async)); - EXPECT_EQ(async, m_kIsAsync); } /** @@ -99,10 +96,8 @@ TEST_F(RialtoServerMediaPipelineFlushTest, FlushResetEos) setEos(firebolt::rialto::MediaSourceType::VIDEO); mainThreadWillEnqueueTaskAndWait(); - EXPECT_CALL(*m_gstPlayerMock, isAsync(m_kType)).WillOnce(Return(m_kIsAsync)); - EXPECT_CALL(*m_gstPlayerMock, flush(m_kType, m_kResetTime)); + EXPECT_CALL(*m_gstPlayerMock, flush(m_kType, m_kResetTime, async)); EXPECT_TRUE(m_mediaPipeline->flush(sourceId, m_kResetTime, async)); - EXPECT_EQ(async, m_kIsAsync); // Expect need data notified to client expectNotifyNeedData(firebolt::rialto::MediaSourceType::VIDEO, sourceId, 3); diff --git a/tests/unittests/media/server/main/mediaPipelineCapabilities/MediaPipelineCapabilitiesTest.cpp b/tests/unittests/media/server/main/mediaPipelineCapabilities/MediaPipelineCapabilitiesTest.cpp index 784004fd3..a7e0396d7 100644 --- a/tests/unittests/media/server/main/mediaPipelineCapabilities/MediaPipelineCapabilitiesTest.cpp +++ b/tests/unittests/media/server/main/mediaPipelineCapabilities/MediaPipelineCapabilitiesTest.cpp @@ -149,3 +149,13 @@ TEST_F(MediaPipelineCapabilitiesTest, getSupportedProperties) std::vector supportedProperties{m_sut->getSupportedProperties(kMediaType, kProperties)}; EXPECT_EQ(kProperties, supportedProperties); } + +TEST_F(MediaPipelineCapabilitiesTest, isVideoMaster) +{ + bool isMaster{false}; + + EXPECT_CALL(*m_gstCapabilities, isVideoMaster(isMaster)).WillOnce(Return(true)); + + createMediaPipelineCapabilities(); + EXPECT_TRUE(m_sut->isVideoMaster(isMaster)); +} diff --git a/tests/unittests/media/server/mocks/gstplayer/FlushWatcherMock.h b/tests/unittests/media/server/mocks/gstplayer/FlushWatcherMock.h index 27d16a2bb..b3d0390f3 100644 --- a/tests/unittests/media/server/mocks/gstplayer/FlushWatcherMock.h +++ b/tests/unittests/media/server/mocks/gstplayer/FlushWatcherMock.h @@ -28,9 +28,10 @@ namespace firebolt::rialto::server class FlushWatcherMock : public IFlushWatcher { public: - MOCK_METHOD(void, setFlushing, (const MediaSourceType &type), (override)); + MOCK_METHOD(void, setFlushing, (const MediaSourceType &type, bool async), (override)); MOCK_METHOD(void, setFlushed, (const MediaSourceType &type), (override)); MOCK_METHOD(bool, isFlushOngoing, (), (const, override)); + MOCK_METHOD(bool, isAsyncFlushOngoing, (), (const, override)); }; } // namespace firebolt::rialto::server #endif // FIREBOLT_RIALTO_SERVER_FLUSH_WATCHER_MOCK_H_ diff --git a/tests/unittests/media/server/mocks/gstplayer/GenericPlayerTaskFactoryMock.h b/tests/unittests/media/server/mocks/gstplayer/GenericPlayerTaskFactoryMock.h index 815ed0520..656416104 100644 --- a/tests/unittests/media/server/mocks/gstplayer/GenericPlayerTaskFactoryMock.h +++ b/tests/unittests/media/server/mocks/gstplayer/GenericPlayerTaskFactoryMock.h @@ -50,7 +50,8 @@ class GenericPlayerTaskFactoryMock : public IGenericPlayerTaskFactory MOCK_METHOD(std::unique_ptr, createFinishSetupSource, (GenericPlayerContext & context, IGstGenericPlayerPrivate &player), (const, override)); MOCK_METHOD(std::unique_ptr, createHandleBusMessage, - (GenericPlayerContext & context, IGstGenericPlayerPrivate &player, GstMessage *message, bool isFlushing), + (GenericPlayerContext & context, IGstGenericPlayerPrivate &player, GstMessage *message, + const IFlushWatcher &flushWatcher), (const, override)); MOCK_METHOD(std::unique_ptr, createNeedData, (GenericPlayerContext & context, IGstGenericPlayerPrivate &player, GstAppSrc *src), (const, override)); diff --git a/tests/unittests/media/server/mocks/gstplayer/GstCapabilitiesMock.h b/tests/unittests/media/server/mocks/gstplayer/GstCapabilitiesMock.h index 345705d48..dcc8bacaa 100644 --- a/tests/unittests/media/server/mocks/gstplayer/GstCapabilitiesMock.h +++ b/tests/unittests/media/server/mocks/gstplayer/GstCapabilitiesMock.h @@ -34,6 +34,7 @@ class GstCapabilitiesMock : public IGstCapabilities MOCK_METHOD(bool, isMimeTypeSupported, (const std::string &mimeType), (override)); MOCK_METHOD(std::vector, getSupportedProperties, (MediaSourceType mediaType, const std::vector &propertyNames), (override)); + MOCK_METHOD(bool, isVideoMaster, (bool &isVideoMaster), (override)); }; } // namespace firebolt::rialto::server diff --git a/tests/unittests/media/server/mocks/gstplayer/GstGenericPlayerMock.h b/tests/unittests/media/server/mocks/gstplayer/GstGenericPlayerMock.h index b03de8f81..224147f1d 100644 --- a/tests/unittests/media/server/mocks/gstplayer/GstGenericPlayerMock.h +++ b/tests/unittests/media/server/mocks/gstplayer/GstGenericPlayerMock.h @@ -56,7 +56,6 @@ class GstGenericPlayerMock : public IGstGenericPlayer MOCK_METHOD(bool, getVolume, (double &volume), (override)); MOCK_METHOD(void, setMute, (const MediaSourceType &mediaSourceType, bool mute), (override)); MOCK_METHOD(bool, getMute, (const MediaSourceType &mediaSourceType, bool &mute), (override)); - MOCK_METHOD(bool, isAsync, (const MediaSourceType &mediaSourceType), (const, override)); MOCK_METHOD(void, setTextTrackIdentifier, (const std::string &textTrackIdentifier), (override)); MOCK_METHOD(bool, getTextTrackIdentifier, (std::string & textTrackIdentifier), (override)); MOCK_METHOD(bool, setLowLatency, (bool lowLatency), (override)); @@ -66,7 +65,7 @@ class GstGenericPlayerMock : public IGstGenericPlayer MOCK_METHOD(bool, setStreamSyncMode, (const MediaSourceType &mediaSourceType, int32_t streamSyncMode), (override)); MOCK_METHOD(bool, getStreamSyncMode, (int32_t & streamSyncMode), (override)); MOCK_METHOD(void, ping, (std::unique_ptr && heartbeatHandler), (override)); - MOCK_METHOD(void, flush, (const MediaSourceType &mediaSourceType, bool resetTime), (override)); + MOCK_METHOD(void, flush, (const MediaSourceType &mediaSourceType, bool resetTime, bool &async), (override)); MOCK_METHOD(void, setSourcePosition, (const MediaSourceType &mediaSourceType, int64_t position, bool resetTime, double appliedRate, uint64_t stopPosition), diff --git a/tests/unittests/media/server/mocks/gstplayer/GstGenericPlayerPrivateMock.h b/tests/unittests/media/server/mocks/gstplayer/GstGenericPlayerPrivateMock.h index 3697e3deb..f54f53988 100644 --- a/tests/unittests/media/server/mocks/gstplayer/GstGenericPlayerPrivateMock.h +++ b/tests/unittests/media/server/mocks/gstplayer/GstGenericPlayerPrivateMock.h @@ -46,6 +46,7 @@ class GstGenericPlayerPrivateMock : public IGstGenericPlayerPrivate MOCK_METHOD(bool, setRenderFrame, (), (override)); MOCK_METHOD(bool, setBufferingLimit, (), (override)); MOCK_METHOD(bool, setUseBuffering, (), (override)); + MOCK_METHOD(bool, setShowVideoWindow, (), (override)); MOCK_METHOD(void, notifyNeedMediaData, (const MediaSourceType mediaSource), (override)); MOCK_METHOD(GstBuffer *, createBuffer, (const IMediaPipeline::MediaSegment &mediaSegment), (const, override)); MOCK_METHOD(void, attachData, (const firebolt::rialto::MediaSourceType mediaType), (override)); diff --git a/tests/unittests/media/server/mocks/gstplayer/GstSrcMock.h b/tests/unittests/media/server/mocks/gstplayer/GstSrcMock.h index b9554a5ad..774cb8e2d 100644 --- a/tests/unittests/media/server/mocks/gstplayer/GstSrcMock.h +++ b/tests/unittests/media/server/mocks/gstplayer/GstSrcMock.h @@ -32,7 +32,7 @@ class GstSrcMock : public IGstSrc virtual ~GstSrcMock() = default; MOCK_METHOD(void, initSrc, (), (override)); - MOCK_METHOD(void, setupAndAddAppArc, + MOCK_METHOD(void, setupAndAddAppSrc, (IDecryptionService * decryptionService, GstElement *element, StreamInfo &streamInfo, GstAppSrcCallbacks *callbacks, gpointer userData, firebolt::rialto::MediaSourceType type), (override)); diff --git a/tests/unittests/media/server/mocks/main/MediaPipelineCapabilitiesMock.h b/tests/unittests/media/server/mocks/main/MediaPipelineCapabilitiesMock.h index 87a295f42..d317b39ca 100644 --- a/tests/unittests/media/server/mocks/main/MediaPipelineCapabilitiesMock.h +++ b/tests/unittests/media/server/mocks/main/MediaPipelineCapabilitiesMock.h @@ -35,6 +35,7 @@ class MediaPipelineCapabilitiesMock : public IMediaPipelineCapabilities MOCK_METHOD(bool, isMimeTypeSupported, (const std::string &mimeType), (override)); MOCK_METHOD(std::vector, getSupportedProperties, (MediaSourceType mediaType, const std::vector &propertyNames), (override)); + MOCK_METHOD(bool, isVideoMaster, (bool &isVideoMaster), (override)); }; } // namespace firebolt::rialto::server diff --git a/tests/unittests/media/server/mocks/main/TextTrackAccessorMock.h b/tests/unittests/media/server/mocks/main/TextTrackAccessorMock.h index 9f80bd05f..8b1688f31 100644 --- a/tests/unittests/media/server/mocks/main/TextTrackAccessorMock.h +++ b/tests/unittests/media/server/mocks/main/TextTrackAccessorMock.h @@ -37,7 +37,7 @@ class TextTrackAccessorMock : public ITextTrackAccessor MOCK_METHOD(bool, mute, (uint32_t sessionId, bool mute), (override)); MOCK_METHOD(bool, setPosition, (uint32_t sessionId, uint64_t mediaTimestampMs), (override)); MOCK_METHOD(bool, sendData, - (uint32_t sessionId, const std::string &data, DataType datatype, int32_t displayOffsetMs), (override)); + (uint32_t sessionId, const std::string &data, DataType datatype, int64_t displayOffsetMs), (override)); MOCK_METHOD(bool, setSessionWebVTTSelection, (uint32_t sessionId), (override)); MOCK_METHOD(bool, setSessionTTMLSelection, (uint32_t sessionId), (override)); MOCK_METHOD(bool, setSessionCCSelection, (uint32_t sessionId, const std::string &service), (override)); diff --git a/tests/unittests/media/server/mocks/service/MediaPipelineServiceMock.h b/tests/unittests/media/server/mocks/service/MediaPipelineServiceMock.h index 136d89f66..47022425f 100644 --- a/tests/unittests/media/server/mocks/service/MediaPipelineServiceMock.h +++ b/tests/unittests/media/server/mocks/service/MediaPipelineServiceMock.h @@ -78,6 +78,7 @@ class MediaPipelineServiceMock : public IMediaPipelineService MOCK_METHOD(bool, setUseBuffering, (int sessionId, bool useBuffering), (override)); MOCK_METHOD(bool, getUseBuffering, (int sessionId, bool &useBuffering), (override)); MOCK_METHOD(bool, switchSource, (int, const std::unique_ptr &), (override)); + MOCK_METHOD(bool, isVideoMaster, (bool &isVideoMaster), (override)); MOCK_METHOD(std::vector, getSupportedMimeTypes, (MediaSourceType type), (override)); MOCK_METHOD(bool, isMimeTypeSupported, (const std::string &mimeType), (override)); MOCK_METHOD(std::vector, getSupportedProperties, diff --git a/tests/unittests/media/server/service/CMakeLists.txt b/tests/unittests/media/server/service/CMakeLists.txt index 87710b501..e2fab6d94 100644 --- a/tests/unittests/media/server/service/CMakeLists.txt +++ b/tests/unittests/media/server/service/CMakeLists.txt @@ -64,11 +64,3 @@ target_link_libraries( # # Link application source RialtoServerService ) - -if ( COVERAGE_ENABLED ) - target_link_libraries( - RialtoServerServiceUnitTests - - gcov - ) -endif() diff --git a/tests/unittests/media/server/service/mediaPipelineService/MediaPipelineServiceTests.cpp b/tests/unittests/media/server/service/mediaPipelineService/MediaPipelineServiceTests.cpp index 32f0c0b2e..4cd1f95d1 100644 --- a/tests/unittests/media/server/service/mediaPipelineService/MediaPipelineServiceTests.cpp +++ b/tests/unittests/media/server/service/mediaPipelineService/MediaPipelineServiceTests.cpp @@ -819,6 +819,20 @@ TEST_F(MediaPipelineServiceTests, shouldSwitchSource) switchSourceShouldSucceed(); } +TEST_F(MediaPipelineServiceTests, shouldFailToCheckIfVideoIsMaster) +{ + initSession(); + mediaPipelineWillFailToCheckIfVideoIsMaster(); + isVideoMasterShouldFail(); +} + +TEST_F(MediaPipelineServiceTests, shouldCheckIfVideoIsMaster) +{ + initSession(); + mediaPipelineWillCheckIfVideoIsMaster(); + isVideoMasterShouldSucceed(); +} + TEST_F(MediaPipelineServiceTests, shouldPing) { initSession(); diff --git a/tests/unittests/media/server/service/mediaPipelineService/MediaPipelineServiceTestsFixture.cpp b/tests/unittests/media/server/service/mediaPipelineService/MediaPipelineServiceTestsFixture.cpp index dedf20042..9b9e441dd 100644 --- a/tests/unittests/media/server/service/mediaPipelineService/MediaPipelineServiceTestsFixture.cpp +++ b/tests/unittests/media/server/service/mediaPipelineService/MediaPipelineServiceTestsFixture.cpp @@ -486,6 +486,16 @@ void MediaPipelineServiceTests::mediaPipelineWillFailToSwitchSource() EXPECT_CALL(m_mediaPipelineMock, switchSource(_)).WillOnce(Return(false)); } +void MediaPipelineServiceTests::mediaPipelineWillCheckIfVideoIsMaster() +{ + EXPECT_CALL(m_mediaPipelineCapabilitiesMock, isVideoMaster(_)).WillOnce(Return(true)); +} + +void MediaPipelineServiceTests::mediaPipelineWillFailToCheckIfVideoIsMaster() +{ + EXPECT_CALL(m_mediaPipelineCapabilitiesMock, isVideoMaster(_)).WillOnce(Return(false)); +} + void MediaPipelineServiceTests::mediaPipelineWillPing() { EXPECT_CALL(*m_heartbeatProcedureMock, createHandler()) @@ -995,6 +1005,18 @@ void MediaPipelineServiceTests::switchSourceShouldFail() EXPECT_FALSE(m_sut->switchSource(kSessionId, mediaSource)); } +void MediaPipelineServiceTests::isVideoMasterShouldSucceed() +{ + bool isMaster{false}; + EXPECT_TRUE(m_sut->isVideoMaster(isMaster)); +} + +void MediaPipelineServiceTests::isVideoMasterShouldFail() +{ + bool isMaster{false}; + EXPECT_FALSE(m_sut->isVideoMaster(isMaster)); +} + void MediaPipelineServiceTests::clearMediaPipelines() { m_sut->clearMediaPipelines(); diff --git a/tests/unittests/media/server/service/mediaPipelineService/MediaPipelineServiceTestsFixture.h b/tests/unittests/media/server/service/mediaPipelineService/MediaPipelineServiceTestsFixture.h index e766bbd69..ead87a642 100644 --- a/tests/unittests/media/server/service/mediaPipelineService/MediaPipelineServiceTestsFixture.h +++ b/tests/unittests/media/server/service/mediaPipelineService/MediaPipelineServiceTestsFixture.h @@ -112,6 +112,8 @@ class MediaPipelineServiceTests : public testing::Test void mediaPipelineWillFailToGetUseBuffering(); void mediaPipelineWillSwitchSource(); void mediaPipelineWillFailToSwitchSource(); + void mediaPipelineWillCheckIfVideoIsMaster(); + void mediaPipelineWillFailToCheckIfVideoIsMaster(); void mediaPipelineWillPing(); @@ -205,6 +207,8 @@ class MediaPipelineServiceTests : public testing::Test void getUseBufferingShouldFail(); void switchSourceShouldSucceed(); void switchSourceShouldFail(); + void isVideoMasterShouldSucceed(); + void isVideoMasterShouldFail(); void clearMediaPipelines(); void initSession(); diff --git a/tests/unittests/serverManager/CMakeLists.txt b/tests/unittests/serverManager/CMakeLists.txt index 3bdc94aa9..7a6c930ef 100644 --- a/tests/unittests/serverManager/CMakeLists.txt +++ b/tests/unittests/serverManager/CMakeLists.txt @@ -83,11 +83,3 @@ target_link_libraries( RialtoServerManager Threads::Threads ) - -if ( COVERAGE_ENABLED ) - target_link_libraries( - RialtoServerManagerUnitTests - - gcov - ) -endif() diff --git a/tests/unittests/serverManager/unittests/common/SessionServerAppTestsFixture.cpp b/tests/unittests/serverManager/unittests/common/SessionServerAppTestsFixture.cpp index cf843d8b2..01d487eb4 100644 --- a/tests/unittests/serverManager/unittests/common/SessionServerAppTestsFixture.cpp +++ b/tests/unittests/serverManager/unittests/common/SessionServerAppTestsFixture.cpp @@ -28,7 +28,7 @@ const std::list kEnvironmentVariablesWithLogPath{"var1", "RIALTO_LO const std::list kEnvironmentVariables{"var1", "var2"}; const std::string kSessionServerPath{"/usr/bin/RialtoServer"}; constexpr std::chrono::milliseconds kSessionServerStartupTimeout{100}; -constexpr std::chrono::milliseconds kKillTimeout{1000}; +constexpr std::chrono::milliseconds kKillTimeout{1500}; constexpr unsigned int kSocketPermissions{0777}; // Empty strings for kSocketOwner and kSocketGroup means that chown() won't be called. This will leave the created // socket being owned by the user executing the code (and the group would be their primary group) diff --git a/tests/unittests/serverManager/unittests/service/ConfigReaderTests.cpp b/tests/unittests/serverManager/unittests/service/ConfigReaderTests.cpp index a876dd59b..eff8204dc 100644 --- a/tests/unittests/serverManager/unittests/service/ConfigReaderTests.cpp +++ b/tests/unittests/serverManager/unittests/service/ConfigReaderTests.cpp @@ -129,7 +129,7 @@ TEST_F(ConfigReaderTests, thereWillBeNothing) EXPECT_CALL(*m_rootJsonValueMock, isMember(_)).WillRepeatedly(Return(false)); EXPECT_TRUE(m_sut->read()); - EXPECT_EQ(m_sut->getEnvironmentVariables().size(), 0); + EXPECT_EQ(m_sut->getEnvironmentVariables().size(), 0u); EXPECT_EQ(m_sut->getSessionServerPath().has_value(), false); EXPECT_EQ(m_sut->getSessionServerStartupTimeout().has_value(), false); EXPECT_EQ(m_sut->getHealthcheckInterval().has_value(), false); @@ -150,7 +150,7 @@ TEST_F(ConfigReaderTests, envVariablesNotArray) EXPECT_CALL(*m_rootJsonValueMock, isMember(StrNe("environmentVariables"))).WillRepeatedly(Return(false)); EXPECT_TRUE(m_sut->read()); - EXPECT_EQ(m_sut->getEnvironmentVariables().size(), 0); + EXPECT_EQ(m_sut->getEnvironmentVariables().size(), 0u); } TEST_F(ConfigReaderTests, envVariablesEmptyArray) @@ -165,7 +165,7 @@ TEST_F(ConfigReaderTests, envVariablesEmptyArray) EXPECT_CALL(*m_rootJsonValueMock, isMember(StrNe("environmentVariables"))).WillRepeatedly(Return(false)); EXPECT_TRUE(m_sut->read()); - EXPECT_EQ(m_sut->getEnvironmentVariables().size(), 0); + EXPECT_EQ(m_sut->getEnvironmentVariables().size(), 0u); } TEST_F(ConfigReaderTests, envVariablesOneElementArrayNotString) @@ -185,7 +185,7 @@ TEST_F(ConfigReaderTests, envVariablesOneElementArrayNotString) EXPECT_CALL(*m_rootJsonValueMock, isMember(StrNe("environmentVariables"))).WillRepeatedly(Return(false)); EXPECT_TRUE(m_sut->read()); - EXPECT_EQ(m_sut->getEnvironmentVariables().size(), 0); + EXPECT_EQ(m_sut->getEnvironmentVariables().size(), 0u); } TEST_F(ConfigReaderTests, envVariablesMultipleElementArray) @@ -431,7 +431,7 @@ TEST_F(ConfigReaderTests, extraEnvVariablesNotArray) EXPECT_CALL(*m_rootJsonValueMock, isMember(StrNe("extraEnvVariables"))).WillRepeatedly(Return(false)); EXPECT_TRUE(m_sut->read()); - EXPECT_EQ(m_sut->getExtraEnvVariables().size(), 0); + EXPECT_EQ(m_sut->getExtraEnvVariables().size(), 0u); } TEST_F(ConfigReaderTests, extraEnvVariablesEmptyArray) @@ -446,7 +446,7 @@ TEST_F(ConfigReaderTests, extraEnvVariablesEmptyArray) EXPECT_CALL(*m_rootJsonValueMock, isMember(StrNe("extraEnvVariables"))).WillRepeatedly(Return(false)); EXPECT_TRUE(m_sut->read()); - EXPECT_EQ(m_sut->getExtraEnvVariables().size(), 0); + EXPECT_EQ(m_sut->getExtraEnvVariables().size(), 0u); } TEST_F(ConfigReaderTests, extraEnvVariablesOneElementArrayNotString) @@ -466,7 +466,7 @@ TEST_F(ConfigReaderTests, extraEnvVariablesOneElementArrayNotString) EXPECT_CALL(*m_rootJsonValueMock, isMember(StrNe("extraEnvVariables"))).WillRepeatedly(Return(false)); EXPECT_TRUE(m_sut->read()); - EXPECT_EQ(m_sut->getExtraEnvVariables().size(), 0); + EXPECT_EQ(m_sut->getExtraEnvVariables().size(), 0u); } TEST_F(ConfigReaderTests, extraEnvVariablesMultipleElementArray) diff --git a/wrappers/CMakeLists.txt b/wrappers/CMakeLists.txt index 37a472e23..3be841fd1 100644 --- a/wrappers/CMakeLists.txt +++ b/wrappers/CMakeLists.txt @@ -130,11 +130,3 @@ if( RIALTO_ENABLE_CONFIG_FILE ) JsonCpp::JsonCpp ) endif() - -if ( COVERAGE_ENABLED ) - target_link_libraries( - RialtoWrappers - PRIVATE - gcov - ) -endif() diff --git a/wrappers/include/GstWrapper.h b/wrappers/include/GstWrapper.h index 275a056c9..05e829417 100644 --- a/wrappers/include/GstWrapper.h +++ b/wrappers/include/GstWrapper.h @@ -73,6 +73,8 @@ class GstWrapper : public IGstWrapper void gstInit(int *argc, char ***argv) override { gst_init(argc, argv); } + void gstDeinit() override { gst_deinit(); } + GstPlugin *gstRegistryFindPlugin(GstRegistry *registry, const gchar *name) override { return gst_registry_find_plugin(registry, name); diff --git a/wrappers/include/TextTrackWrapper.h b/wrappers/include/TextTrackWrapper.h index 392a48120..bc2d5e297 100644 --- a/wrappers/include/TextTrackWrapper.h +++ b/wrappers/include/TextTrackWrapper.h @@ -43,7 +43,7 @@ class TextTrackWrapper : public ITextTrackWrapper std::uint32_t resetSession(std::uint32_t sessionId) const override; std::uint32_t sendSessionTimestamp(std::uint32_t sessionId, std::uint64_t mediaTimestampMs) const override; std::uint32_t sendSessionData(std::uint32_t sessionId, ITextTrackWrapper::DataType type, - std::int32_t displayOffsetMs, const std::string &data) const override; + std::int64_t displayOffsetMs, const std::string &data) const override; std::uint32_t setSessionWebVTTSelection(std::uint32_t sessionId) const override; std::uint32_t setSessionTTMLSelection(std::uint32_t sessionId) const override; std::uint32_t setSessionClosedCaptionsService(std::uint32_t sessionId, const std::string &service) const override; diff --git a/wrappers/interface/IGstWrapper.h b/wrappers/interface/IGstWrapper.h index 6237e792d..847128d54 100644 --- a/wrappers/interface/IGstWrapper.h +++ b/wrappers/interface/IGstWrapper.h @@ -78,6 +78,12 @@ class IGstWrapper */ virtual void gstInit(int *argc, char ***argv) = 0; + /** + * @brief Deinitalise gstreamer. + * + */ + virtual void gstDeinit() = 0; + /** * @brief Finds the plugin with the given name. * diff --git a/wrappers/interface/ITextTrackWrapper.h b/wrappers/interface/ITextTrackWrapper.h index 699fca875..3699e7d67 100644 --- a/wrappers/interface/ITextTrackWrapper.h +++ b/wrappers/interface/ITextTrackWrapper.h @@ -129,7 +129,7 @@ class ITextTrackWrapper * * @retval the error code */ - virtual std::uint32_t sendSessionData(std::uint32_t sessionId, DataType type, std::int32_t displayOffsetMs, + virtual std::uint32_t sendSessionData(std::uint32_t sessionId, DataType type, std::int64_t displayOffsetMs, const std::string &data) const = 0; /** diff --git a/wrappers/source/TextTrackWrapper.cpp b/wrappers/source/TextTrackWrapper.cpp index 295cc3f57..174f66922 100644 --- a/wrappers/source/TextTrackWrapper.cpp +++ b/wrappers/source/TextTrackWrapper.cpp @@ -91,7 +91,7 @@ std::uint32_t TextTrackWrapper::sendSessionTimestamp(std::uint32_t sessionId, st } std::uint32_t TextTrackWrapper::sendSessionData(std::uint32_t sessionId, ITextTrackWrapper::DataType type, - std::int32_t displayOffsetMs, const std::string &data) const + std::int64_t displayOffsetMs, const std::string &data) const { return m_textTrackControlInterface->SendSessionData(sessionId, convertDataType(type), displayOffsetMs, data); }