From 519c81330ff51c96c06546cb72089e2b17e3cd7a Mon Sep 17 00:00:00 2001 From: zhanhang Date: Thu, 11 Jan 2024 14:48:24 +0800 Subject: [PATCH] add GetAudioPosition Signed-off-by: zhanhang --- .../include/audio_renderer_private.h | 1 + .../audiorenderer/src/audio_renderer.cpp | 5 +++ .../native/audiostream/include/audio_stream.h | 4 +- .../audiostream/include/fast_audio_stream.h | 1 + .../audiostream/include/i_audio_stream.h | 1 + frameworks/native/ohaudio/OHAudioRenderer.cpp | 2 +- .../audiorenderer/include/audio_renderer.h | 11 +++++ .../client/include/audio_service_client.h | 4 ++ .../client/src/audio_service_client.cpp | 45 +++++++++++++------ .../audio_service/client/src/audio_stream.cpp | 9 ++-- .../client/src/capturer_in_client.cpp | 6 +++ .../client/src/fast_audio_stream.cpp | 5 +++ .../client/src/renderer_in_client.cpp | 6 +++ 13 files changed, 76 insertions(+), 24 deletions(-) diff --git a/frameworks/native/audiorenderer/include/audio_renderer_private.h b/frameworks/native/audiorenderer/include/audio_renderer_private.h index 2fd013e65d..5ec686c45d 100644 --- a/frameworks/native/audiorenderer/include/audio_renderer_private.h +++ b/frameworks/native/audiorenderer/include/audio_renderer_private.h @@ -43,6 +43,7 @@ public: int32_t Write(uint8_t *pcmBuffer, size_t pcmSize, uint8_t *metaBuffer, size_t metaSize) override; RendererState GetStatus() const override; bool GetAudioTime(Timestamp ×tamp, Timestamp::Timestampbase base) const override; + bool GetAudioPosition(Timestamp ×tamp, Timestamp::Timestampbase base) const override; bool Drain() const override; bool PauseTransitent(StateChangeCmdType cmdType = CMD_FROM_CLIENT) const override; bool Pause(StateChangeCmdType cmdType = CMD_FROM_CLIENT) const override; diff --git a/frameworks/native/audiorenderer/src/audio_renderer.cpp b/frameworks/native/audiorenderer/src/audio_renderer.cpp index fbb2e53f0c..43e93e6c3e 100644 --- a/frameworks/native/audiorenderer/src/audio_renderer.cpp +++ b/frameworks/native/audiorenderer/src/audio_renderer.cpp @@ -580,6 +580,11 @@ bool AudioRendererPrivate::GetAudioTime(Timestamp ×tamp, Timestamp::Timesta return audioStream_->GetAudioTime(timestamp, base); } +bool AudioRendererPrivate::GetAudioPosition(Timestamp ×tamp, Timestamp::Timestampbase base) const +{ + return audioStream_->GetAudioPosition(timestamp, base); +} + bool AudioRendererPrivate::Drain() const { return audioStream_->DrainAudioStream(); diff --git a/frameworks/native/audiostream/include/audio_stream.h b/frameworks/native/audiostream/include/audio_stream.h index 6980139605..4661be4aa5 100644 --- a/frameworks/native/audiostream/include/audio_stream.h +++ b/frameworks/native/audiostream/include/audio_stream.h @@ -50,8 +50,8 @@ public: int32_t GetAudioStreamInfo(AudioStreamParams &info) override; int32_t GetAudioSessionID(uint32_t &sessionID) override; State GetState() override; - bool GetAudioTimeForDev(Timestamp ×tamp, Timestamp::Timestampbase base); bool GetAudioTime(Timestamp ×tamp, Timestamp::Timestampbase base) override; + bool GetAudioPosition(Timestamp ×tamp, Timestamp::Timestampbase base) override; int32_t GetBufferSize(size_t &bufferSize) override; int32_t GetFrameCount(uint32_t &frameCount) override; int32_t GetLatency(uint64_t &latency) override; @@ -185,8 +185,6 @@ private: std::shared_ptr audioStreamPolicyServiceDiedCB_ = nullptr; std::shared_ptr proxyObj_ = nullptr; - - bool hdiPositionSwitch = true; }; class AudioStreamPolicyServiceDiedCallbackImpl : public AudioStreamPolicyServiceDiedCallback { diff --git a/frameworks/native/audiostream/include/fast_audio_stream.h b/frameworks/native/audiostream/include/fast_audio_stream.h index b82d30df0c..acb1c85d89 100644 --- a/frameworks/native/audiostream/include/fast_audio_stream.h +++ b/frameworks/native/audiostream/include/fast_audio_stream.h @@ -77,6 +77,7 @@ public: int32_t GetAudioSessionID(uint32_t &sessionID) override; State GetState() override; bool GetAudioTime(Timestamp ×tamp, Timestamp::Timestampbase base) override; + bool GetAudioPosition(Timestamp ×tamp, Timestamp::Timestampbase base) override; int32_t GetBufferSize(size_t &bufferSize) override; int32_t GetFrameCount(uint32_t &frameCount) override; int32_t GetLatency(uint64_t &latency) override; diff --git a/frameworks/native/audiostream/include/i_audio_stream.h b/frameworks/native/audiostream/include/i_audio_stream.h index 6888bb6a5a..c3111314a7 100644 --- a/frameworks/native/audiostream/include/i_audio_stream.h +++ b/frameworks/native/audiostream/include/i_audio_stream.h @@ -123,6 +123,7 @@ public: virtual int32_t GetAudioSessionID(uint32_t &sessionID) = 0; virtual State GetState() = 0; virtual bool GetAudioTime(Timestamp ×tamp, Timestamp::Timestampbase base) = 0; + virtual bool GetAudioPosition(Timestamp ×tamp, Timestamp::Timestampbase base) = 0; virtual int32_t GetBufferSize(size_t &bufferSize) = 0; virtual int32_t GetFrameCount(uint32_t &frameCount) = 0; virtual int32_t GetLatency(uint64_t &latency) = 0; diff --git a/frameworks/native/ohaudio/OHAudioRenderer.cpp b/frameworks/native/ohaudio/OHAudioRenderer.cpp index 9b5847125a..d07f2d2634 100644 --- a/frameworks/native/ohaudio/OHAudioRenderer.cpp +++ b/frameworks/native/ohaudio/OHAudioRenderer.cpp @@ -341,7 +341,7 @@ int64_t OHAudioRenderer::GetFramesWritten() bool OHAudioRenderer::GetAudioTime(Timestamp ×tamp, Timestamp::Timestampbase base) { CHECK_AND_RETURN_RET_LOG(audioRenderer_ != nullptr, false, "renderer client is nullptr"); - return audioRenderer_->GetAudioTime(timestamp, base); + return audioRenderer_->GetAudioPosition(timestamp, base); } int32_t OHAudioRenderer::GetFrameSizeInCallback() diff --git a/interfaces/inner_api/native/audiorenderer/include/audio_renderer.h b/interfaces/inner_api/native/audiorenderer/include/audio_renderer.h index 5c3b46b293..8104338f5a 100644 --- a/interfaces/inner_api/native/audiorenderer/include/audio_renderer.h +++ b/interfaces/inner_api/native/audiorenderer/include/audio_renderer.h @@ -368,6 +368,17 @@ public: */ virtual bool GetAudioTime(Timestamp ×tamp, Timestamp::Timestampbase base) const = 0; + /** + * @brief Obtains the position info. + * + * @param timestamp Indicates a {@link Timestamp} instance reference provided by the caller. + * @param base Indicates the time base, which can be {@link Timestamp.Timestampbase#BOOTTIME} or + * {@link Timestamp.Timestampbase#MONOTONIC}. + * @return Returns true if the timestamp is successfully obtained; returns false otherwise. + * @since 11 + */ + virtual bool GetAudioPosition(Timestamp ×tamp, Timestamp::Timestampbase base) const = 0; + /** * @brief Obtains the latency in microseconds. * diff --git a/services/audio_service/client/include/audio_service_client.h b/services/audio_service/client/include/audio_service_client.h index d49165d7ef..d01a07123b 100644 --- a/services/audio_service/client/include/audio_service_client.h +++ b/services/audio_service/client/include/audio_service_client.h @@ -752,6 +752,8 @@ private: uint64_t lastPositionTimestamp_ = 0; uint64_t lastHdiPosition_ = 0; uint64_t lastOffloadStreamCorkedPosition_ = 0; + uint64_t preFrameNum_ = 0; + int32_t ConnectStreamToPA(); std::pair GetDeviceNameForConnect(); int32_t UpdatePAProbListOffload(AudioOffloadType statePolicy); @@ -775,6 +777,8 @@ private: void HandleCapturePositionCallbacks(size_t bytesRead); void WriteStateChangedSysEvents(); + int32_t UpdateOffloadStreamPosition(UpdatePositionTimeNode node, uint64_t& frames, + int64_t& timeSec, int64_t& timeNanoSec); int32_t SetPaProplist(pa_proplist *propList, pa_channel_map &map, AudioStreamParams &audioParams, const std::string &streamName, const std::string &streamStartTime); diff --git a/services/audio_service/client/src/audio_service_client.cpp b/services/audio_service/client/src/audio_service_client.cpp index 82728e97b0..6f3b9fc85a 100644 --- a/services/audio_service/client/src/audio_service_client.cpp +++ b/services/audio_service/client/src/audio_service_client.cpp @@ -186,7 +186,6 @@ void AudioServiceClient::PAStreamStartSuccessCb(pa_stream *stream, int32_t succe AudioServiceClient *asClient = static_cast(userdata); pa_threaded_mainloop *mainLoop = static_cast(asClient->mainLoop); - asClient->UpdateStreamPosition(UpdatePositionTimeNode::START_NODE); asClient->state_ = RUNNING; asClient->breakingWritePa_ = false; asClient->offloadTsLast_ = 0; @@ -1747,6 +1746,8 @@ int32_t AudioServiceClient::RenderPrebuf(uint32_t writeLen) prebufStream.bufferLen = writeLen; } + preFrameNum_ = prebufStream.bufferLen / mFrameSize; + size_t bytesWritten {0}; AUDIO_INFO_LOG("RenderPrebuf start"); while (true) { @@ -2168,6 +2169,19 @@ int32_t AudioServiceClient::GetAudioLatencyOffload(uint64_t &latency) return AUDIO_CLIENT_SUCCESS; } +int32_t AudioServiceClient::UpdateOffloadStreamPosition(UpdatePositionTimeNode node, uint64_t& frames, + int64_t& timeSec, int64_t& timeNanoSec) +{ + if (node == UpdatePositionTimeNode::CORKED_NODE) { + lastOffloadStreamCorkedPosition_ = mTotalBytesWritten / mFrameSize; + return AUDIO_CLIENT_SUCCESS; + } + frames = frames * HDI_OFFLOAD_SAMPLE_RATE / SECOND_TO_MICROSECOND; + lastStreamPosition_ = lastOffloadStreamCorkedPosition_ + frames; + lastPositionTimestamp_ = timeSec * AUDIO_S_TO_NS + timeNanoSec; + return AUDIO_CLIENT_SUCCESS; +} + int32_t AudioServiceClient::UpdateStreamPosition(UpdatePositionTimeNode node) { uint64_t frames; @@ -2177,15 +2191,9 @@ int32_t AudioServiceClient::UpdateStreamPosition(UpdatePositionTimeNode node) if (eAudioClientType == AUDIO_SERVICE_CLIENT_PLAYBACK && audioSystemManager_->GetRenderPresentationPosition(deviceClass, frames, timeSec, timeNanoSec) == 0) { if (offloadEnable_) { - if (node == UpdatePositionTimeNode::CORKED_NODE) { - lastOffloadStreamCorkedPosition_ = mTotalBytesWritten / mFrameSize; - return AUDIO_CLIENT_SUCCESS; - } - frames = frames * HDI_OFFLOAD_SAMPLE_RATE / SECOND_TO_MICROSECOND; - lastStreamPosition_ = lastOffloadStreamCorkedPosition_ + frames; - lastPositionTimestamp_ = timeSec * AUDIO_S_TO_NS + timeNanoSec; - return AUDIO_CLIENT_SUCCESS; + return UpdateOffloadStreamPosition(node, frames, timeSec, timeNanoSec); } + frames = frames * sampleSpec.rate / HDI_OFFLOAD_SAMPLE_RATE; // revert hdi frame size to client size if (frames < lastHdiPosition_) { AUDIO_ERR_LOG("The frame position should be continuously increasing"); return AUDIO_CLIENT_ERR; @@ -2212,10 +2220,6 @@ int32_t AudioServiceClient::UpdateStreamPosition(UpdatePositionTimeNode node) return AUDIO_CLIENT_SUCCESS; } else { AUDIO_ERR_LOG("UpdateStreamPosition from hdi failed!"); - if (eAudioClientType == AUDIO_SERVICE_CLIENT_PLAYBACK && - !offloadEnable_ && node == UpdatePositionTimeNode::RUNNING_NODE) { - lastHdiPosition_ += 240000; // 240000 frame size for 5s,the state from suspend to running - } return AUDIO_CLIENT_ERR; } } @@ -2227,7 +2231,19 @@ int32_t AudioServiceClient::GetCurrentPosition(uint64_t &framePosition, uint64_t // This time will get an exception value, here will not return the exception to the application.Return the // last frame information instead UpdateStreamPosition(UpdatePositionTimeNode::USER_NODE); - framePosition = lastStreamPosition_; + if (lastStreamPosition_ > preFrameNum_) { + framePosition = lastStreamPosition_ - preFrameNum_; + } else { + framePosition = 0; + } + uint64_t latency = 0; + GetAudioLatency(latency); + latency = latency * sampleSpec.rate / SECOND_TO_MICROSECOND; + if (framePosition > latency) { + framePosition -= latency; + } else { + framePosition = 0; + } timeStamp = lastPositionTimestamp_; return AUDIO_CLIENT_SUCCESS; } @@ -2330,6 +2346,7 @@ int32_t AudioServiceClient::SetRendererFirstFrameWritingCallback( void AudioServiceClient::OnFirstFrameWriting() { + UpdateStreamPosition(UpdatePositionTimeNode::START_NODE); hasFirstFrameWrited_ = true; CHECK_AND_RETURN_LOG(firstFrameWritingCb_!= nullptr, "firstFrameWritingCb_ is null."); uint64_t latency = AUDIO_FIRST_FRAME_LATENCY; diff --git a/services/audio_service/client/src/audio_stream.cpp b/services/audio_service/client/src/audio_stream.cpp index eb01d58ca5..f1bc89d938 100644 --- a/services/audio_service/client/src/audio_stream.cpp +++ b/services/audio_service/client/src/audio_stream.cpp @@ -188,7 +188,7 @@ int32_t AudioStream::GetAudioSessionID(uint32_t &sessionID) return SUCCESS; } -bool AudioStream::GetAudioTimeForDev(Timestamp ×tamp, Timestamp::Timestampbase base) +bool AudioStream::GetAudioTime(Timestamp ×tamp, Timestamp::Timestampbase base) { if (state_ == STOPPED) { return false; @@ -221,12 +221,9 @@ bool AudioStream::GetAudioTimeForDev(Timestamp ×tamp, Timestamp::Timestampb return false; } -bool AudioStream::GetAudioTime(Timestamp ×tamp, Timestamp::Timestampbase base) +bool AudioStream::GetAudioPosition(Timestamp ×tamp, Timestamp::Timestampbase base) { - if (hdiPositionSwitch) { - return GetAudioTimeForDev(timestamp, base); - } - if (state_ == STOPPED) { + if (state_ != RUNNING) { return false; } uint64_t framePosition = 0; diff --git a/services/audio_service/client/src/capturer_in_client.cpp b/services/audio_service/client/src/capturer_in_client.cpp index 83c72663ef..8496c2d554 100644 --- a/services/audio_service/client/src/capturer_in_client.cpp +++ b/services/audio_service/client/src/capturer_in_client.cpp @@ -82,6 +82,7 @@ public: State GetState() override; int32_t GetAudioSessionID(uint32_t &sessionID) override; bool GetAudioTime(Timestamp ×tamp, Timestamp::Timestampbase base) override; + bool GetAudioPosition(Timestamp ×tamp, Timestamp::Timestampbase base) override; int32_t GetBufferSize(size_t &bufferSize) override; int32_t GetFrameCount(uint32_t &frameCount) override; int32_t GetLatency(uint64_t &latency) override; @@ -798,6 +799,11 @@ bool CapturerInClientInner::GetAudioTime(Timestamp ×tamp, Timestamp::Timest return true; } +bool CapturerInClientInner::GetAudioPosition(Timestamp ×tamp, Timestamp::Timestampbase base) +{ + return GetAudioTime(timestamp, base); +} + int32_t CapturerInClientInner::GetBufferSize(size_t &bufferSize) { CHECK_AND_RETURN_RET_LOG(state_ != RELEASED, ERR_ILLEGAL_STATE, "Capturer stream is released"); diff --git a/services/audio_service/client/src/fast_audio_stream.cpp b/services/audio_service/client/src/fast_audio_stream.cpp index 2caa997e86..c196d48ec2 100644 --- a/services/audio_service/client/src/fast_audio_stream.cpp +++ b/services/audio_service/client/src/fast_audio_stream.cpp @@ -166,6 +166,11 @@ bool FastAudioStream::GetAudioTime(Timestamp ×tamp, Timestamp::Timestampbas return true; } +bool FastAudioStream::GetAudioPosition(Timestamp ×tamp, Timestamp::Timestampbase base) +{ + return GetAudioTime(timestamp, base); +} + int32_t FastAudioStream::GetBufferSize(size_t &bufferSize) { CHECK_AND_RETURN_RET_LOG(processClient_ != nullptr, ERR_OPERATION_FAILED, "GetBufferSize failed: null process"); diff --git a/services/audio_service/client/src/renderer_in_client.cpp b/services/audio_service/client/src/renderer_in_client.cpp index b862a1f705..856eb582af 100644 --- a/services/audio_service/client/src/renderer_in_client.cpp +++ b/services/audio_service/client/src/renderer_in_client.cpp @@ -88,6 +88,7 @@ public: int32_t GetAudioSessionID(uint32_t &sessionID) override; State GetState() override; bool GetAudioTime(Timestamp ×tamp, Timestamp::Timestampbase base) override; + bool GetAudioPosition(Timestamp ×tamp, Timestamp::Timestampbase base) override; int32_t GetBufferSize(size_t &bufferSize) override; int32_t GetFrameCount(uint32_t &frameCount) override; int32_t GetLatency(uint64_t &latency) override; @@ -762,6 +763,11 @@ bool RendererInClientInner::GetAudioTime(Timestamp ×tamp, Timestamp::Timest return true; } +bool RendererInClientInner::GetAudioPosition(Timestamp ×tamp, Timestamp::Timestampbase base) +{ + return GetAudioTime(timestamp, base); +} + int32_t RendererInClientInner::GetBufferSize(size_t &bufferSize) { CHECK_AND_RETURN_RET_LOG(state_ != RELEASED, ERR_ILLEGAL_STATE, "Capturer stream is released"); -- Gitee