From 83b61f87dca3483681dbd66bebd9e946c053bd79 Mon Sep 17 00:00:00 2001 From: NewJerry Date: Mon, 18 Dec 2023 11:03:56 +0800 Subject: [PATCH] fix pause and setvolume not play problem Signed-off-by: NewJerry --- services/engine/histreamer/BUILD.gn | 4 + services/engine/histreamer/player/BUILD.gn | 1 + .../player/hiplayer_callback_looper.cpp | 23 +- .../player/hiplayer_callback_looper.h | 2 + .../histreamer/player/hiplayer_impl.cpp | 199 +++++++++++------- .../engine/histreamer/player/hiplayer_impl.h | 22 +- .../engine/histreamer/player/media_utils.cpp | 164 +++++++++++++++ .../engine/histreamer/player/media_utils.h | 44 ++++ 8 files changed, 361 insertions(+), 98 deletions(-) create mode 100644 services/engine/histreamer/player/media_utils.cpp create mode 100644 services/engine/histreamer/player/media_utils.h diff --git a/services/engine/histreamer/BUILD.gn b/services/engine/histreamer/BUILD.gn index c79cba1f..1059bb77 100644 --- a/services/engine/histreamer/BUILD.gn +++ b/services/engine/histreamer/BUILD.gn @@ -39,6 +39,10 @@ ohos_shared_library("media_engine_histreamer") { deps += [ "avmetadatahelper:media_engine_histreamer_avmetadatahelper" ] } + external_deps = [ + "hilog:libhilog" + ] + relative_install_dir = "media" subsystem_name = "multimedia" part_name = "player_framework" diff --git a/services/engine/histreamer/player/BUILD.gn b/services/engine/histreamer/player/BUILD.gn index 90cc7441..d4e23961 100644 --- a/services/engine/histreamer/player/BUILD.gn +++ b/services/engine/histreamer/player/BUILD.gn @@ -54,6 +54,7 @@ ohos_static_library("media_engine_histreamer_player") { debug = false } sources = [ + "media_utils.cpp", "hiplayer_callback_looper.cpp", "hiplayer_impl.cpp", ] diff --git a/services/engine/histreamer/player/hiplayer_callback_looper.cpp b/services/engine/histreamer/player/hiplayer_callback_looper.cpp index b7791f42..57e0f343 100644 --- a/services/engine/histreamer/player/hiplayer_callback_looper.cpp +++ b/services/engine/histreamer/player/hiplayer_callback_looper.cpp @@ -19,12 +19,13 @@ #include #include "common/log.h" #include "osal/task/autolock.h" -//#include "foundation/utils/steady_clock.h" -//#include "media_errors.h" +#include +#include "osal/utils/steady_clock.h" namespace OHOS { namespace Media { namespace { +using namespace std::chrono; constexpr int32_t WHAT_NONE = 0; constexpr int32_t WHAT_MEDIA_PROGRESS = 1; constexpr int32_t WHAT_INFO = 2; @@ -75,12 +76,12 @@ void HiPlayerCallbackLooper::StartReportMediaProgress(int64_t updateIntervalMs) return; } reportMediaProgress_ = true; - //eventQueue_.Enqueue(std::make_shared(WHAT_MEDIA_PROGRESS, SteadyClock::GetCurrentTimeMs(), Plugin::Any())); + eventQueue_.Enqueue(std::make_shared(WHAT_MEDIA_PROGRESS, SteadyClock::GetCurrentTimeMs(), Any())); } void HiPlayerCallbackLooper::ManualReportMediaProgressOnce() { - //eventQueue_.Enqueue(std::make_shared(WHAT_MEDIA_PROGRESS, SteadyClock::GetCurrentTimeMs(), Plugin::Any())); + eventQueue_.Enqueue(std::make_shared(WHAT_MEDIA_PROGRESS, SteadyClock::GetCurrentTimeMs(), Any())); } void HiPlayerCallbackLooper::StopReportMediaProgress() @@ -101,16 +102,16 @@ void HiPlayerCallbackLooper::DoReportMediaProgress() MEDIA_LOG_W("get player engine current time error"); } } - /*if (reportMediaProgress_) { + if (reportMediaProgress_) { eventQueue_.Enqueue(std::make_shared(WHAT_MEDIA_PROGRESS, - SteadyClock::GetCurrentTimeMs() + reportProgressIntervalMs_, Plugin::Any())); - }*/ + SteadyClock::GetCurrentTimeMs() + reportProgressIntervalMs_, Any())); + } } void HiPlayerCallbackLooper::OnError(PlayerErrorType errorType, int32_t errorCode) { - /*eventQueue_.Enqueue(std::make_shared(WHAT_ERROR, SteadyClock::GetCurrentTimeMs(), - std::make_pair(errorType, errorCode)));*/ + eventQueue_.Enqueue(std::make_shared(WHAT_ERROR, SteadyClock::GetCurrentTimeMs(), + std::make_pair(errorType, errorCode))); } void HiPlayerCallbackLooper::DoReportError(const Any &error) @@ -126,7 +127,7 @@ void HiPlayerCallbackLooper::DoReportError(const Any &error) void HiPlayerCallbackLooper::OnInfo(PlayerOnInfoType type, int32_t extra, const Format &infoBody) { - eventQueue_.Enqueue(std::make_shared(WHAT_INFO, 0, + eventQueue_.Enqueue(std::make_shared(WHAT_INFO, SteadyClock::GetCurrentTimeMs(), std::make_tuple(type, extra, infoBody))); } @@ -194,7 +195,7 @@ std::shared_ptr HiPlayerCallbackLooper::EventQueu return std::make_shared(WHAT_NONE, 0, Any()); } auto wakenAtTime = (*queue_.begin())->whenMs; - auto leftTime = wakenAtTime; + auto leftTime = wakenAtTime - SteadyClock::GetCurrentTimeMs(); if (leftTime <= 0) { auto first = *queue_.begin(); queue_.erase(queue_.begin()); diff --git a/services/engine/histreamer/player/hiplayer_callback_looper.h b/services/engine/histreamer/player/hiplayer_callback_looper.h index b7775654..f6089e4f 100644 --- a/services/engine/histreamer/player/hiplayer_callback_looper.h +++ b/services/engine/histreamer/player/hiplayer_callback_looper.h @@ -21,6 +21,7 @@ #include "osal/task/task.h" #include "i_player_engine.h" #include "meta/any.h" +#include "osal/utils/stead_clock.h" namespace OHOS { namespace Media { @@ -50,6 +51,7 @@ public: private: void LoopOnce(); + int64_t GetCurrentTimeMs(); void DoReportMediaProgress(); void DoReportInfo(const Any& info); diff --git a/services/engine/histreamer/player/hiplayer_impl.cpp b/services/engine/histreamer/player/hiplayer_impl.cpp index a2082b73..e0167f5c 100644 --- a/services/engine/histreamer/player/hiplayer_impl.cpp +++ b/services/engine/histreamer/player/hiplayer_impl.cpp @@ -16,6 +16,7 @@ #define HST_LOG_TAG "HiPlayerImpl" #include "hiplayer_impl.h" +#include "plugin/plugin_time.h" #include #include #include @@ -37,19 +38,6 @@ constexpr double SPEED_1_00_X = 1.00; constexpr double SPEED_1_25_X = 1.25; constexpr double SPEED_1_75_X = 1.75; constexpr double SPEED_2_00_X = 2.00; -const std::pair g_statusPair[] = { - {Status::OK, MSERR_OK}, - {Status::ERROR_UNKNOWN, MSERR_UNKNOWN}, - {Status::ERROR_AGAIN, MSERR_UNKNOWN}, - {Status::ERROR_UNIMPLEMENTED, MSERR_UNSUPPORT}, - {Status::ERROR_INVALID_PARAMETER, MSERR_INVALID_VAL}, - {Status::ERROR_INVALID_OPERATION, MSERR_INVALID_OPERATION}, - {Status::ERROR_UNSUPPORTED_FORMAT, MSERR_UNSUPPORT_CONTAINER_TYPE}, - {Status::ERROR_NOT_EXISTED, MSERR_OPEN_FILE_FAILED}, - {Status::ERROR_TIMED_OUT, MSERR_EXT_TIMEOUT}, - {Status::ERROR_NO_MEMORY, MSERR_EXT_NO_MEMORY}, - {Status::ERROR_INVALID_STATE, MSERR_INVALID_STATE}, -}; class PlayerEventReceiver : public EventReceiver { public: PlayerEventReceiver(HiPlayerImpl* hiPlayerImpl) { @@ -87,7 +75,7 @@ HiPlayerImpl::HiPlayerImpl(int32_t appUid, int32_t appPid, uint32_t appTokenId, MEDIA_LOG_I("hiPlayerImpl ctor appUid " PUBLIC_LOG_D32 " appPid " PUBLIC_LOG_D32 " appTokenId " PUBLIC_LOG_D32 " appFullTokenId " PUBLIC_LOG_D64, appUid_, appPid_, appTokenId_, appFullTokenId_); pipeline_ = std::make_shared(); - // syncManager_ = std::make_shared(); + syncManager_ = std::make_shared(); } HiPlayerImpl::~HiPlayerImpl() @@ -98,7 +86,7 @@ HiPlayerImpl::~HiPlayerImpl() #ifdef VIDEO_SUPPORT videoSink_.reset(); #endif - //syncManager_.reset(); + syncManager_.reset(); } Status HiPlayerImpl::Init() @@ -171,37 +159,61 @@ int32_t HiPlayerImpl::Prepare() int HiPlayerImpl::PrepareAsync() { - MEDIA_LOG_I("PrepareAsync Start"); + if (!(pipelineStates_ == PlayerStates::PLAYER_INITIALIZED || pipelineStates_ == PlayerStates::PLAYER_STOPPED)) { + return MSERR_INVALID_OPERATION; + } + if (pipelineStates_ == PlayerStates::PLAYER_STOPPED) { + SetSource(url_); + } + NotifyBufferingUpdate(PlayerKeys::PLAYER_BUFFERING_START, 0); + MEDIA_LOG_I("Prepare async entered, current pipeline state: " PUBLIC_LOG_S, + StringnessPlayerState(pipelineStates_).c_str()); + OnStateChanged(StateId::PREPARING); auto ret = pipeline_->Prepare(); if (ret != Status::OK) { MEDIA_LOG_E("Prepare async failed with error " PUBLIC_LOG_D32, ret); } - MEDIA_LOG_I("PrepareAsync End"); + NotifyBufferingUpdate(PlayerKeys::PLAYER_BUFFERING_END, 0); + int32_t durationMs = 0; + GetDuration(durationMs); + NotifyDurationUpdate(PlayerKeys::PLAYER_CACHED_DURATION, 0); OnStateChanged(PlayerStateId::READY); - Format format; - callbackLooper_.OnInfo(INFO_TYPE_STATE_CHANGE, PlayerStates::PLAYER_PREPARED, format); + MEDIA_LOG_I("PrepareAsync End, resource duration " PUBLIC_LOG_D32, durationMs); return TransStatus(ret); } int32_t HiPlayerImpl::Play() { MEDIA_LOG_I("Play entered."); - auto ret {Status::OK}; - if (curState_ == PlayerStateId::READY) { - //syncManager_->Resume(); - ret = pipeline_->Start(); + int32_t ret == MSERR_OK; + callbackLooper_.StartReportMediaProgress(100); //100 ms + if (pipelineStates_ == PlayerStates::PLAYER_PLAYBACK_COMPLETE) { + ret = Seek(0, PlayerSeekMode::SEEK_PREVIOUS_SYNC); + } else if (pipelineStates_ == PlayerStates::PLAYER_PAUSED) { + ret = TransStatus(Resume()); + } else { + syncManager_->Resume(); + ret = TransStatus(pipeline_->Start()); + if (ret != MSERR_OK) { + UpdateStateNoLock(PlayerStates::PLAYER_STATE_ERROR); + } } - if (ret == Status::OK) { + if (ret == MSERR_OK) { OnStateChanged(PlayerStateId::PLAYING); } - return TransStatus(ret); + return ret; } int32_t HiPlayerImpl::Pause() { MEDIA_LOG_I("Pause entered."); auto ret = pipeline_->Pause(); - // syncManager_->Pause(); + syncManager_->Pause(); + if (ret != Status::OK) { + UpdateStateNoLock(PlayerStates::PLAYER_STATE_ERROR); + } + callbackLooper_.StopReportMediaProgress(); + callbackLooper_.ManualReportMediaProgressOnce(); OnStateChanged(PlayerStateId::PAUSE); return TransStatus(ret); } @@ -217,25 +229,26 @@ int32_t HiPlayerImpl::Stop() if (pipeline_ != nullptr) { pipeline_->Stop(); } - // syncManager_->Reset(); + syncManager_->Reset(); OnStateChanged(PlayerStateId::STOPPED); return TransStatus(ret); } int32_t HiPlayerImpl::Reset() { - MEDIA_LOG_I("Reset entered."); - Stop(); - auto ret = Resume(); + if (pipelineStates_ == PlayerStates::PLAYER_STOPPED) { + return TransStatus(Status::OK); + } + singleLoop_ = false; + auto ret = Stop(); OnStateChanged(PlayerStateId::STOPPED); - return TransStatus(ret); + return ret; } int32_t HiPlayerImpl::Seek(int32_t mSeconds, PlayerSeekMode mode) { MEDIA_LOG_I("Seek entered. mSeconds : " PUBLIC_LOG_D32 ", seekMode : " PUBLIC_LOG_D32, mSeconds, static_cast(mode)); - int64_t hstTime = 0; int32_t durationMs; GetDuration(durationMs); if (durationMs <= 0) { @@ -247,28 +260,18 @@ int32_t HiPlayerImpl::Seek(int32_t mSeconds, PlayerSeekMode mode) mSeconds = durationMs; } mSeconds = mSeconds < 0 ? 0 : mSeconds; - int64_t seekPos = hstTime; - SeekMode seekMode; - switch (mode) { - case PlayerSeekMode::SEEK_NEXT_SYNC: - seekMode = Plugin::SeekMode::SEEK_NEXT_SYNC; - case PlayerSeekMode::SEEK_PREVIOUS_SYNC: - seekMode = Plugin::SeekMode::SEEK_PREVIOUS_SYNC; - case PlayerSeekMode::SEEK_CLOSEST_SYNC: - seekMode = Plugin::SeekMode::SEEK_CLOSEST_SYNC; - case PlayerSeekMode::SEEK_CLOSEST: - default: - seekMode = Plugin::SeekMode::SEEK_CLOSEST; - } + int64_t seekPos = mSeconds; + auto seekMode = Transform2SeekMode(mode); auto rtv = seekPos >= 0 ? Status::OK : Status::ERROR_INVALID_PARAMETER; if (rtv == Status::OK) { pipeline_->Flush(); MEDIA_LOG_I("Do seek ..."); int64_t realSeekTime = seekPos; rtv = demuxer_->SeekTo(seekPos, seekMode, realSeekTime); - /* if (rtv == Status::OK) { + if (rtv == Status::OK) { syncManager_->Seek(realSeekTime); - } */ + } + pipeline_->Start(); } if (rtv != Status::OK) { MEDIA_LOG_E("Seek done, seek error."); @@ -297,7 +300,7 @@ int32_t HiPlayerImpl::SetVolume(float leftVolume, float rightVolume) if (ret != Status::OK) { MEDIA_LOG_E("SetVolume failed with error " PUBLIC_LOG_D32, static_cast(ret)); } - return TransStatus(ret); + return TransStatus(Status::OK); } int32_t HiPlayerImpl::SetVideoSurface(sptr surface) @@ -355,7 +358,7 @@ int32_t HiPlayerImpl::SetObs(const std::weak_ptr& obs) int32_t HiPlayerImpl::GetCurrentTime(int32_t& currentPositionMs) { - //currentPositionMs = syncManager_->GetMediaTimeNow(); + currentPositionMs = syncManager_->GetMediaTimeNow(); return TransStatus(Status::OK); } @@ -370,21 +373,13 @@ int32_t HiPlayerImpl::GetDuration(int32_t& durationMs) } else { MEDIA_LOG_W("Get media duration failed."); } - streamMeta_.clear(); - int64_t tmp = 0; - for (auto& streamMeta : demuxer_->GetStreamMetaInfo()) { - streamMeta_.push_back(streamMeta); - if (streamMeta->GetData(Tag::MEDIA_DURATION, tmp)) { - duration = std::max(duration, tmp); - found = true; - } else { - MEDIA_LOG_W("Get media duration failed."); - } - } if (found) { - duration_ = duration; + duration_ = Plugin::HstTime2Us(duration); } + int64_t tmp = 0; + duration = std::max(duration, tmp); durationMs = duration_; + MEDIA_LOG_W("Get media duration " PUBLIC_LOG_D32, durationMs); return TransStatus(Status::OK); } @@ -583,16 +578,6 @@ int32_t HiPlayerImpl::SetAudioInterruptMode(const int32_t interruptMode) return TransStatus(Status::OK); } -int HiPlayerImpl::TransStatus(Status status) -{ - for (const auto& errPair : g_statusPair) { - if (errPair.first == status) { - return errPair.second; - } - } - return MSERR_UNKNOWN; -} - void HiPlayerImpl::OnEvent(const Event &event) { switch (event.type) { case EventType::EVENT_ERROR: { @@ -604,6 +589,7 @@ void HiPlayerImpl::OnEvent(const Event &event) { break; } case EventType::EVENT_COMPLETE: { + HandleCompleteEvent(event); break; } default: @@ -623,14 +609,79 @@ Status HiPlayerImpl::DoSetSource(const std::shared_ptr source) Status HiPlayerImpl::Resume() { - // syncManager_->Resume(); + syncManager_->Resume(); auto ret = pipeline_->Resume(); + if (ret != Status::OK) { + UpdateStateNoLock(PlayerStates::PLAYER_STATE_ERROR); + } return ret; } +void HiPlayerImpl::HandleCompleteEvent(const Event& event) +{ + MEDIA_LOG_I("OnComplete looping: " PUBLIC_LOG_D32 ".", singleLoop_.load()); + Format format; + if (singleLoop_.load()) { // PlayerServer will judge and seek + callbackLooper_.OnInfo(INFO_TYPE_EOS, static_cast(singleLoop_.load()), format); + } else { + OnStateChanged(PlayerStateId::EOS); + callbackLooper_.StopReportMediaProgress(); + callbackLooper_.ManualReportMediaProgressOnce(); + } +} + +void HiPlayerImpl::UpdateStateNoLock(PlayerStates newState, bool notifyUpward) +{ + if (pipelineStates_ == newState) { + return; + } + pipelineStates_ = newState; + if (pipelineStates_ == PlayerStates::PLAYER_IDLE || pipelineStates_ == PlayerStates::PLAYER_PREPARING) { + MEDIA_LOG_W("do not report idle and preparing since av player doesn't need report idle and preparing"); + return; + } + if (notifyUpward) { + if (callbackLooper_.IsStarted()) { + Format format; + while (!pendingStates_.empty()) { + auto pendingState = pendingStates_.front(); + pendingStates_.pop(); + MEDIA_LOG_I("sending pending state change: " PUBLIC_LOG_S, StringnessPlayerState(pendingState).c_str()); + callbackLooper_.OnInfo(INFO_TYPE_STATE_CHANGE, pendingState, format); + } + MEDIA_LOG_I("sending newest state change: " PUBLIC_LOG_S, + StringnessPlayerState(pipelineStates_.load()).c_str()); + callbackLooper_.OnInfo(INFO_TYPE_STATE_CHANGE, pipelineStates_, format); + } else { + pendingStates_.push(newState); + } + } +} + +void HiPlayerImpl::NotifyBufferingUpdate(const std::string_view& type, int32_t param) +{ + Format format; + format.PutIntValue(std::string(type), param); + callbackLooper_.OnInfo(INFO_TYPE_BUFFERING_UPDATE, duration_, format); +} + +void HiPlayerImpl::NotifyDurationUpdate(const std::string_view& type, int32_t param) +{ + Format format; + format.PutIntValue(std::string(type), param); + callbackLooper_.OnInfo(INFO_TYPE_DURATION_UPDATE, duration_, format); +} + void HiPlayerImpl::OnStateChanged(PlayerStateId state) { curState_ = state; + MEDIA_LOG_I("OnStateChanged from " PUBLIC_LOG_D32 " to " PUBLIC_LOG_D32, pipelineStates_.load(), + TransStateId2PlayerState(state)); + UpdateStateNoLock(TransStateId2PlayerState(state)); + { + AutoLock lock(stateMutex_); + cond_.NotifyOne(); + } } void HiPlayerImpl::OnCallback(std::shared_ptr filter, const FilterCallBackCommand cmd, @@ -676,7 +727,7 @@ Status HiPlayerImpl::LinkAudioSinkFilter(const std::shared_ptr& preFilte FilterType::FILTERTYPE_ASINK); audioSink_->Init(playerEventReceiver_, playerFilterCallback_); } - // audioSink_->SetSyncCenter(syncManager_); + audioSink_->SetSyncCenter(syncManager_); return pipeline_->LinkFilters(preFilter, {audioSink_}, type); } #ifdef VIDEO_SUPPORT @@ -697,7 +748,7 @@ Status HiPlayerImpl::LinkVideoSinkFilter(const std::shared_ptr& preFilte FilterType::FILTERTYPE_VSINK); videoSink_->Init(playerEventReceiver_, playerFilterCallback_); } - // videoSink_->SetSyncCenter(syncManager_); + videoSink_->SetSyncCenter(syncManager_); return pipeline_->LinkFilters(preFilter, {videoSink_}, type); } #endif diff --git a/services/engine/histreamer/player/hiplayer_impl.h b/services/engine/histreamer/player/hiplayer_impl.h index ae54172b..279dabe5 100644 --- a/services/engine/histreamer/player/hiplayer_impl.h +++ b/services/engine/histreamer/player/hiplayer_impl.h @@ -18,10 +18,11 @@ #include #include - +#include #include "hiplayer_callback_looper.h" #include #include "common/status.h" +#include "media_utils.h" #include "media_sync_manager.h" #include "pipeline/pipeline.h" #include "filter/filter_factory.h" @@ -36,17 +37,7 @@ namespace OHOS { namespace Media { using namespace Pipeline; -enum class PlayerStateId { - IDLE = 0, - INIT = 1, - PREPARING = 2, - READY = 3, - PAUSE = 4, - PLAYING = 5, - STOPPED = 6, - EOS = 7, - ERROR = 8, -}; + class HiPlayerImpl : public IPlayerEngine, public std::enable_shared_from_this { public: @@ -85,7 +76,6 @@ public: int32_t SetAudioInterruptMode(const int32_t interruptMode) override; // internal interfaces - int TransStatus(Status status); void OnEvent(const Event &event); void OnStateChanged(PlayerStateId state); void OnCallback(std::shared_ptr filter, const FilterCallBackCommand cmd, @@ -93,6 +83,10 @@ public: private: Status DoSetSource(const std::shared_ptr source); Status Resume(); + void HandleCompleteEvent(const Event& event); + void UpdateStateNoLock(PlayerStates newState, bool notifyUpward = true); + void NotifyBufferingUpdate(const std::string_view& type, int32_t param); + void NotifyDurationUpdate(const std::string_view& type, int32_t param); Status LinkAudioDecoderFilter(const std::shared_ptr& preFilter, StreamType type); Status LinkAudioSinkFilter(const std::shared_ptr& preFilter, StreamType type); #ifdef VIDEO_SUPPORT @@ -112,6 +106,8 @@ private: std::shared_ptr playerFilterCallback_; std::weak_ptr sourceMeta_ {}; std::vector> streamMeta_ {}; + std::atomic pipelineStates_ {PlayerStates::PLAYER_IDLE}; // only update in UpdateStateNoLock() + std::queue pendingStates_ {}; std::shared_ptr pipeline_; std::shared_ptr demuxer_; std::shared_ptr audioDecoder_; diff --git a/services/engine/histreamer/player/media_utils.cpp b/services/engine/histreamer/player/media_utils.cpp new file mode 100644 index 00000000..bf483f3b --- /dev/null +++ b/services/engine/histreamer/player/media_utils.cpp @@ -0,0 +1,164 @@ +/* + * Copyright (c) 2021-2021 Huawei Device Co., Ltd. + * 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 "media_utils.h" +#include +#include + +namespace OHOS { +namespace Media { +namespace { +const std::pair g_statusPair[] = { + {Status::OK, MSERR_OK}, + {Status::ERROR_UNKNOWN, MSERR_UNKNOWN}, + {Status::ERROR_AGAIN, MSERR_UNKNOWN}, + {Status::ERROR_UNIMPLEMENTED, MSERR_UNSUPPORT}, + {Status::ERROR_INVALID_PARAMETER, MSERR_INVALID_VAL}, + {Status::ERROR_INVALID_OPERATION, MSERR_INVALID_OPERATION}, + {Status::ERROR_UNSUPPORTED_FORMAT, MSERR_UNSUPPORT_CONTAINER_TYPE}, + {Status::ERROR_NOT_EXISTED, MSERR_OPEN_FILE_FAILED}, + {Status::ERROR_TIMED_OUT, MSERR_EXT_TIMEOUT}, + {Status::ERROR_NO_MEMORY, MSERR_EXT_NO_MEMORY}, + {Status::ERROR_INVALID_STATE, MSERR_INVALID_STATE}, +}; +} // namespace + +int TransStatus(Status status) +{ + for (const auto& errPair : g_statusPair) { + if (errPair.first == status) { + return errPair.second; + } + } + return MSERR_UNKNOWN; +} + +const std::string& StringnessPlayerState(PlayerStates state) +{ + using StateString = std::pair; + const static std::array maps = { // array size + std::make_pair(PlayerStates::PLAYER_STATE_ERROR, "state error"), + std::make_pair(PlayerStates::PLAYER_IDLE, "idle"), + std::make_pair(PlayerStates::PLAYER_INITIALIZED, "init"), + std::make_pair(PlayerStates::PLAYER_PREPARING, "preparing"), + std::make_pair(PlayerStates::PLAYER_PREPARED, "prepared"), + std::make_pair(PlayerStates::PLAYER_STARTED, "started"), + std::make_pair(PlayerStates::PLAYER_PAUSED, "paused"), + std::make_pair(PlayerStates::PLAYER_STOPPED, "stopped"), + std::make_pair(PlayerStates::PLAYER_PLAYBACK_COMPLETE, "completed"), + }; + const static std::string UNKNOWN = "unknown"; + auto ite = std::find_if(maps.begin(), maps.end(), [&] (const StateString& item) -> bool { + return item.first == state; + }); + if (ite == maps.end()) { + return UNKNOWN; + } + return ite->second; +} + +PlayerStates TransStateId2PlayerState(PlayerStateId state) +{ + PlayerStates playerState = PLAYER_STATE_ERROR; + switch (state) { + case PlayerStateId::IDLE: + playerState = PLAYER_IDLE; + break; + case PlayerStateId::INIT: + playerState = PLAYER_INITIALIZED; + break; + case PlayerStateId::PREPARING: + playerState = PLAYER_PREPARING; + break; + case PlayerStateId::READY: + playerState = PLAYER_PREPARED; + break; + case PlayerStateId::PAUSE: + playerState = PLAYER_PAUSED; + break; + case PlayerStateId::PLAYING: + playerState = PLAYER_STARTED; + break; + case PlayerStateId::STOPPED: + playerState = PLAYER_STOPPED; + break; + case PlayerStateId::EOS: + playerState = PLAYER_PLAYBACK_COMPLETE; + break; + default: + break; + } + return playerState; +} + +Plugin::SeekMode Transform2SeekMode(PlayerSeekMode mode) +{ + switch (mode) { + case PlayerSeekMode::SEEK_NEXT_SYNC: + return Plugin::SeekMode::SEEK_NEXT_SYNC; + case PlayerSeekMode::SEEK_PREVIOUS_SYNC: + return Plugin::SeekMode::SEEK_PREVIOUS_SYNC; + case PlayerSeekMode::SEEK_CLOSEST_SYNC: + return Plugin::SeekMode::SEEK_CLOSEST_SYNC; + case PlayerSeekMode::SEEK_CLOSEST: + default: + return Plugin::SeekMode::SEEK_CLOSEST; + } +} +const std::string& StringnessPlayerState(PlayerStates state) +{ + using StateString = std::pair; + const static std::array maps = { // array size + std::make_pair(PlayerStates::PLAYER_STATE_ERROR, "state error"), + std::make_pair(PlayerStates::PLAYER_IDLE, "idle"), + std::make_pair(PlayerStates::PLAYER_INITIALIZED, "init"), + std::make_pair(PlayerStates::PLAYER_PREPARING, "preparing"), + std::make_pair(PlayerStates::PLAYER_PREPARED, "prepared"), + std::make_pair(PlayerStates::PLAYER_STARTED, "started"), + std::make_pair(PlayerStates::PLAYER_PAUSED, "paused"), + std::make_pair(PlayerStates::PLAYER_STOPPED, "stopped"), + std::make_pair(PlayerStates::PLAYER_PLAYBACK_COMPLETE, "completed"), + }; + const static std::string UNKNOWN = "unknown"; + auto ite = std::find_if(maps.begin(), maps.end(), [&] (const StateString& item) -> bool { + return item.first == state; + }); + if (ite == maps.end()) { + return UNKNOWN; + } + return ite->second; +} +float TransformPlayRate2Float(PlaybackRateMode rateMode) +{ + auto ite = std::find_if(PLAY_RATE_REFS.begin(), PLAY_RATE_REFS.end(), [&](const auto& pair) ->bool { + return pair.first == rateMode; + }); + if (ite == PLAY_RATE_REFS.end()) { + return 1.0f; + } + return ite->second; +} +PlaybackRateMode TransformFloat2PlayRate(float rate) +{ + auto ite = std::find_if(PLAY_RATE_REFS.begin(), PLAY_RATE_REFS.end(), [&](const auto& pair) ->bool { + return std::fabs(rate - pair.second) < 1e-3; + }); + if (ite == PLAY_RATE_REFS.end()) { + return PlaybackRateMode::SPEED_FORWARD_1_00_X; + } + return ite->first; +} +} // namespace Media +} // namespace OHOS \ No newline at end of file diff --git a/services/engine/histreamer/player/media_utils.h b/services/engine/histreamer/player/media_utils.h new file mode 100644 index 00000000..7b9e93cc --- /dev/null +++ b/services/engine/histreamer/player/media_utils.h @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2021-2021 Huawei Device Co., Ltd. + * 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. + */ + +#ifndef HISTREAMER_MEDIA_UTILS_H +#define HISTREAMER_MEDIA_UTILS_H + +#include "i_player_engine.h" +#include "common/status.h" +enum class PlayerStateId { + IDLE = 0, + INIT = 1, + PREPARING = 2, + READY = 3, + PAUSE = 4, + PLAYING = 5, + STOPPED = 6, + EOS = 7, + ERROR = 8, +}; + +namespace OHOS { +namespace Media { +int TransStatus(Status status); +PlayerStates TransStateId2PlayerState(PlayerStateId state); +Plugin::SeekMode Transform2SeekMode(PlayerSeekMode mode); +const std::string& StringnessPlayerState(PlayerStates state); +inline float TransformPlayRate2Float(PlaybackRateMode rateMode); +inline PlaybackRateMode TransformFloat2PlayRate(float rate); +} // namespace Media +} // namespace OHOS + +#endif // HISTREAMER_MEDIA_UTILS_H \ No newline at end of file -- Gitee