From f38973266f70610a6186194da81bf19f64a4a8b2 Mon Sep 17 00:00:00 2001 From: Anurup M Date: Fri, 30 Jul 2021 23:43:09 +0530 Subject: [PATCH] add renderer pause and flush apis Signed-off-by: sulav --- .../include/audio_renderer_private.h | 2 ++ .../audiorenderer/src/audio_renderer.cpp | 10 ++++++ .../audiorenderer/include/audio_renderer.h | 18 +++++++++- .../native/audiostream/include/audio_stream.h | 5 ++- .../include/client/audio_service_client.h | 5 ++- services/src/client/audio_service_client.cpp | 8 +++-- services/src/client/audio_stream.cpp | 26 ++++++++++++-- services/test/audio_renderer_test.cpp | 35 ++++++++++++++++++- 8 files changed, 98 insertions(+), 11 deletions(-) diff --git a/frameworks/innerkitsimpl/audiorenderer/include/audio_renderer_private.h b/frameworks/innerkitsimpl/audiorenderer/include/audio_renderer_private.h index 78ea1b596c..997439e025 100644 --- a/frameworks/innerkitsimpl/audiorenderer/include/audio_renderer_private.h +++ b/frameworks/innerkitsimpl/audiorenderer/include/audio_renderer_private.h @@ -32,7 +32,9 @@ public: RendererState GetStatus() const override; bool GetAudioTime(Timestamp ×tamp, Timestamp::Timestampbase base) const override; bool Drain() const override; + bool Pause() const override; bool Stop() const override; + bool Flush() const override; bool Release() const override; int32_t GetBufferSize(size_t &bufferSize) const override; diff --git a/frameworks/innerkitsimpl/audiorenderer/src/audio_renderer.cpp b/frameworks/innerkitsimpl/audiorenderer/src/audio_renderer.cpp index 87c8fdc339..df37e8ca53 100644 --- a/frameworks/innerkitsimpl/audiorenderer/src/audio_renderer.cpp +++ b/frameworks/innerkitsimpl/audiorenderer/src/audio_renderer.cpp @@ -95,6 +95,16 @@ bool AudioRendererPrivate::Drain() const return audioRenderer->DrainAudioStream(); } +bool AudioRendererPrivate::Flush() const +{ + return audioRenderer->FlushAudioStream(); +} + +bool AudioRendererPrivate::Pause() const +{ + return audioRenderer->PauseAudioStream(); +} + bool AudioRendererPrivate::Stop() const { return audioRenderer->StopAudioStream(); diff --git a/interfaces/innerkits/native/audiorenderer/include/audio_renderer.h b/interfaces/innerkits/native/audiorenderer/include/audio_renderer.h index ce6d9e8de6..649f795212 100644 --- a/interfaces/innerkits/native/audiorenderer/include/audio_renderer.h +++ b/interfaces/innerkits/native/audiorenderer/include/audio_renderer.h @@ -53,7 +53,9 @@ enum RendererState { /** Renderer Released state */ RENDERER_RELEASED, /** INVALID state */ - RENDERER_INVALID + RENDERER_INVALID, + /** Renderer Paused state */ + RENDERER_PAUSED }; /** @@ -154,6 +156,20 @@ public: */ virtual bool Drain() const = 0; + /** + * @brief flush renderer stream. + * + * @return Returns true if the object is successfully flushed; returns false otherwise. + */ + virtual bool Flush() const = 0; + + /** + * @brief Pauses audio rendering. + * + * @return Returns true if the rendering is successfully Paused; returns false otherwise. + */ + virtual bool Pause() const = 0; + /** * @brief Stops audio rendering. * diff --git a/interfaces/innerkits/native/audiostream/include/audio_stream.h b/interfaces/innerkits/native/audiostream/include/audio_stream.h index d24838e832..66694d6f6e 100644 --- a/interfaces/innerkits/native/audiostream/include/audio_stream.h +++ b/interfaces/innerkits/native/audiostream/include/audio_stream.h @@ -43,7 +43,9 @@ enum State { /** Released */ RELEASED, /** INVALID */ - INVALID + INVALID, + /** Paused */ + PAUSED }; class AudioStream : public AudioSession { @@ -68,6 +70,7 @@ public: // Common APIs bool StartAudioStream(); + bool PauseAudioStream(); bool StopAudioStream(); bool ReleaseAudioStream(); bool FlushAudioStream(); diff --git a/services/include/client/audio_service_client.h b/services/include/client/audio_service_client.h index d8b39f7463..a9374d1df2 100644 --- a/services/include/client/audio_service_client.h +++ b/services/include/client/audio_service_client.h @@ -132,12 +132,11 @@ public: int32_t DrainStream(); /** - * Pauses the stream using the session ID + * Pauses the stream * - * @param sessionID indicates the ID for the active stream to be controlled * @return Returns {@code 0} if success; returns {@code -1} otherwise. */ - int32_t PauseStream(uint32_t sessionID); + int32_t PauseStream(); /** * Sets the volume of the stream associated with session ID diff --git a/services/src/client/audio_service_client.cpp b/services/src/client/audio_service_client.cpp index cc63a15612..a14230a128 100644 --- a/services/src/client/audio_service_client.cpp +++ b/services/src/client/audio_service_client.cpp @@ -560,10 +560,9 @@ int32_t AudioServiceClient::StartStream() } } -int32_t AudioServiceClient::PauseStream(uint32_t sessionID) +int32_t AudioServiceClient::PauseStream() { - CHECK_PA_STATUS_RET_IF_FAIL(mainLoop, context, paStream, AUDIO_CLIENT_PA_ERR); - return AUDIO_CLIENT_SUCCESS; + return StopStream(); } int32_t AudioServiceClient::StopStream() @@ -628,6 +627,9 @@ int32_t AudioServiceClient::FlushStream() return AUDIO_CLIENT_ERR; } else { MEDIA_INFO_LOG("Stream Flushed Successfully"); + acache.readIndex = 0; + acache.writeIndex = 0; + acache.isFull = false; return AUDIO_CLIENT_SUCCESS; } } diff --git a/services/src/client/audio_stream.cpp b/services/src/client/audio_stream.cpp index 22f6c473b3..7eb856689e 100644 --- a/services/src/client/audio_stream.cpp +++ b/services/src/client/audio_stream.cpp @@ -207,7 +207,7 @@ int32_t AudioStream::SetAudioStreamInfo(const AudioStreamParams info) bool AudioStream::StartAudioStream() { - if ((state_ != PREPARED) && (state_ != STOPPED)) { + if ((state_ != PREPARED) && (state_ != STOPPED) && (state_ != PAUSED)) { MEDIA_ERR_LOG("StartAudioStream Illegal state:%{public}u", state_); return false; } @@ -279,6 +279,28 @@ size_t AudioStream::Write(uint8_t *buffer, size_t buffer_size) return bytesWritten; } +bool AudioStream::PauseAudioStream() +{ + if (state_ != RUNNING) { + MEDIA_ERR_LOG("PauseAudioStream: State is not RUNNING. Illegal state:%{public}u", state_); + return false; + } + State oldState = state_; + state_ = PAUSED; // Set it before stopping as Read/Write and Stop can be called from different threads + while (isReadInProgress_ || isWriteInProgress_) { + } + + int32_t ret = PauseStream(); + if (ret != SUCCESS) { + MEDIA_DEBUG_LOG("StreamPause fail,ret:0x%{public}x", ret); + state_ = oldState; + return false; + } + MEDIA_INFO_LOG("PauseAudioStream SUCCESS"); + + return true; +} + bool AudioStream::StopAudioStream() { if (state_ != RUNNING) { @@ -303,7 +325,7 @@ bool AudioStream::StopAudioStream() bool AudioStream::FlushAudioStream() { - if (state_ != RUNNING) { + if ((state_ != RUNNING) && (state_ != PAUSED)) { MEDIA_ERR_LOG("FlushAudioStream: State is not RUNNING. Illegal state:%{public}u", state_); return false; } diff --git a/services/test/audio_renderer_test.cpp b/services/test/audio_renderer_test.cpp index 7e8418e770..9deecb7c9c 100644 --- a/services/test/audio_renderer_test.cpp +++ b/services/test/audio_renderer_test.cpp @@ -26,6 +26,10 @@ namespace AudioTestConstants { constexpr int32_t ARGS_INDEX_TWO = 2; constexpr int32_t ARGS_COUNT_TWO = 2; constexpr int32_t SUCCESS = 0; + constexpr int32_t STOP_BUFFER_POSITION = 700000; + constexpr int32_t PAUSE_BUFFER_POSITION = 1400000; + constexpr int32_t PAUSE_RENDER_TIME_SECONDS = 1; + constexpr int32_t STOP_RENDER_TIME_SECONDS = 1; } class AudioRendererTest { @@ -115,12 +119,41 @@ public: size_t bytesWritten = 0; size_t minBytes = 4; uint64_t latency; + bool stopTested = false; + bool pauseTested = false; while (!feof(wavFile)) { bytesToWrite = fread(buffer, 1, bufferLen, wavFile); bytesWritten = 0; MEDIA_INFO_LOG("AudioRendererTest: Bytes to write: %{public}d", bytesToWrite); + uint64_t currFilePos = ftell(wavFile); + MEDIA_INFO_LOG("AudioRendererTest: Current file position: %{public}llu", currFilePos); + if (!stopTested && (currFilePos > AudioTestConstants::STOP_BUFFER_POSITION) && audioRenderer->Stop()) { + MEDIA_INFO_LOG("Audio render stopping for 1 second"); + stopTested = true; + sleep(AudioTestConstants::STOP_RENDER_TIME_SECONDS); + MEDIA_INFO_LOG("Audio render resume"); + if (!audioRenderer->Start()) { + MEDIA_ERR_LOG("resume stream failed"); + break; + } + } else if (!pauseTested && (currFilePos > AudioTestConstants::PAUSE_BUFFER_POSITION) + && audioRenderer->Pause()) { + MEDIA_INFO_LOG("Audio render pausing for 1 second"); + pauseTested = true; + sleep(AudioTestConstants::PAUSE_RENDER_TIME_SECONDS); + MEDIA_INFO_LOG("Audio render resume"); + if (!audioRenderer->Flush()) { + MEDIA_ERR_LOG("AudioRendererTest: flush failed"); + break; + } + if (!audioRenderer->Start()) { + MEDIA_ERR_LOG("resume stream failed"); + break; + } + } + if (audioRenderer->GetLatency(latency)) { MEDIA_ERR_LOG("AudioRendererTest: GetLatency failed"); break; @@ -183,7 +216,7 @@ public: return false; } - if (StartRender(audioRenderer, wavFile)) { + if (!StartRender(audioRenderer, wavFile)) { MEDIA_ERR_LOG("AudioRendererTest: Start render failed"); return false; } -- Gitee