diff options
| author | 2022-03-01 23:45:51 +0000 | |
|---|---|---|
| committer | 2022-03-01 23:45:51 +0000 | |
| commit | 9350158d4e4f52b66cc709353ad694192d22fd02 (patch) | |
| tree | 1f526ec242c7f30a287a010bce65be09e70121f3 | |
| parent | 0a69364a40a95d1fdd00c84b2901ffd2cce3c363 (diff) | |
| parent | 81fb57f59b19c921b897757f40610109114e5e3d (diff) | |
Merge "Update Soundpool callback interface" into tm-dev
| -rw-r--r-- | media/jni/soundpool/Stream.cpp | 94 | ||||
| -rw-r--r-- | media/jni/soundpool/Stream.h | 33 |
2 files changed, 86 insertions, 41 deletions
diff --git a/media/jni/soundpool/Stream.cpp b/media/jni/soundpool/Stream.cpp index 50bb79ccaa0b..9ed8770a455c 100644 --- a/media/jni/soundpool/Stream.cpp +++ b/media/jni/soundpool/Stream.cpp @@ -15,6 +15,7 @@ */ //#define LOG_NDEBUG 0 +#include <utility> #define LOG_TAG "SoundPool::Stream" #include <utils/Log.h> #include <android/content/AttributionSourceState.h> @@ -309,13 +310,11 @@ void Stream::play_l(const std::shared_ptr<Sound>& sound, int32_t nextStreamID, } if (mAudioTrack == nullptr) { // mToggle toggles each time a track is started on a given stream. - // The toggle is concatenated with the Stream address and passed to AudioTrack - // as callback user data. This enables the detection of callbacks received from the old + // This enables the detection of callbacks received from the old // audio track while the new one is being started and avoids processing them with // wrong audio audio buffer size (mAudioBufferSize) auto toggle = mToggle ^ 1; // NOLINTNEXTLINE(performance-no-int-to-ptr) - void* userData = reinterpret_cast<void*>((uintptr_t)this | toggle); audio_channel_mask_t soundChannelMask = sound->getChannelMask(); // When sound contains a valid channel mask, use it as is. // Otherwise, use stream count to calculate channel mask. @@ -327,10 +326,11 @@ void Stream::play_l(const std::shared_ptr<Sound>& sound, int32_t nextStreamID, android::content::AttributionSourceState attributionSource; attributionSource.packageName = mStreamManager->getOpPackageName(); attributionSource.token = sp<BBinder>::make(); + mCallback = sp<StreamCallback>::make(this, toggle), // TODO b/182469354 make consistent with AudioRecord, add util for native source mAudioTrack = new AudioTrack(streamType, sampleRate, sound->getFormat(), channelMask, sound->getIMemory(), AUDIO_OUTPUT_FLAG_FAST, - staticCallback, userData, + mCallback, 0 /*default notification frames*/, AUDIO_SESSION_ALLOCATE, AudioTrack::TRANSFER_DEFAULT, nullptr /*offloadInfo*/, attributionSource, @@ -375,16 +375,55 @@ void Stream::play_l(const std::shared_ptr<Sound>& sound, int32_t nextStreamID, mStreamID = nextStreamID; // prefer this to be the last, as it is an atomic sync point } -/* static */ -void Stream::staticCallback(int event, void* user, void* info) -{ - const auto userAsInt = (uintptr_t)user; - // NOLINTNEXTLINE(performance-no-int-to-ptr) - auto stream = reinterpret_cast<Stream*>(userAsInt & ~1); - stream->callback(event, info, int(userAsInt & 1), 0 /* tries */); +int Stream::getCorrespondingStreamID() { + std::lock_guard lock(mLock); + return static_cast<int>(mAudioTrack ? mStreamID : getPairStream()->mStreamID); +} +size_t Stream::StreamCallback::onMoreData(const AudioTrack::Buffer&) { + ALOGW("%s streamID %d Unexpected EVENT_MORE_DATA for static track", + __func__, mStream->getCorrespondingStreamID()); + return 0; +} + +void Stream::StreamCallback::onUnderrun() { + ALOGW("%s streamID %d Unexpected EVENT_UNDERRUN for static track", + __func__, mStream->getCorrespondingStreamID()); +} + +void Stream::StreamCallback::onLoopEnd(int32_t) { + ALOGV("%s streamID %d EVENT_LOOP_END", __func__, mStream->getCorrespondingStreamID()); +} + +void Stream::StreamCallback::onMarker(uint32_t) { + ALOGW("%s streamID %d Unexpected EVENT_MARKER for static track", + __func__, mStream->getCorrespondingStreamID()); +} + +void Stream::StreamCallback::onNewPos(uint32_t) { + ALOGW("%s streamID %d Unexpected EVENT_NEW_POS for static track", + __func__, mStream->getCorrespondingStreamID()); } -void Stream::callback(int event, void* info, int toggle, int tries) +void Stream::StreamCallback::onBufferEnd() { + mStream->onBufferEnd(mToggle, 0); +} + +void Stream::StreamCallback::onNewIAudioTrack() { + ALOGV("%s streamID %d NEW_IAUDIOTRACK", __func__, mStream->getCorrespondingStreamID()); +} + +void Stream::StreamCallback::onStreamEnd() { + ALOGW("%s streamID %d Unexpected EVENT_STREAM_END for static track", + __func__, mStream->getCorrespondingStreamID()); +} + +size_t Stream::StreamCallback::onCanWriteMoreData(const AudioTrack::Buffer&) { + ALOGW("%s streamID %d Unexpected EVENT_CAN_WRITE_MORE_DATA for static track", + __func__, mStream->getCorrespondingStreamID()); + return 0; +} + +void Stream::onBufferEnd(int toggle, int tries) { int32_t activeStreamIDToRestart = 0; { @@ -400,7 +439,7 @@ void Stream::callback(int event, void* info, int toggle, int tries) if (tries < 3) { lock.unlock(); ALOGV("%s streamID %d going to pair stream", __func__, (int)mStreamID); - getPairStream()->callback(event, info, toggle, tries + 1); + getPairStream()->onBufferEnd(toggle, tries + 1); } else { ALOGW("%s streamID %d cannot find track", __func__, (int)mStreamID); } @@ -410,31 +449,10 @@ void Stream::callback(int event, void* info, int toggle, int tries) ALOGD("%s streamID %d wrong toggle", __func__, (int)mStreamID); return; } - switch (event) { - case AudioTrack::EVENT_MORE_DATA: - ALOGW("%s streamID %d Invalid EVENT_MORE_DATA for static track", - __func__, (int)mStreamID); - break; - case AudioTrack::EVENT_UNDERRUN: - ALOGW("%s streamID %d Invalid EVENT_UNDERRUN for static track", - __func__, (int)mStreamID); - break; - case AudioTrack::EVENT_BUFFER_END: - ALOGV("%s streamID %d EVENT_BUFFER_END", __func__, (int)mStreamID); - if (mState != IDLE) { - activeStreamIDToRestart = mStreamID; - mStopTimeNs = systemTime(); - } - break; - case AudioTrack::EVENT_LOOP_END: - ALOGV("%s streamID %d EVENT_LOOP_END", __func__, (int)mStreamID); - break; - case AudioTrack::EVENT_NEW_IAUDIOTRACK: - ALOGV("%s streamID %d NEW_IAUDIOTRACK", __func__, (int)mStreamID); - break; - default: - ALOGW("%s streamID %d Invalid event %d", __func__, (int)mStreamID, event); - break; + ALOGV("%s streamID %d EVENT_BUFFER_END", __func__, (int)mStreamID); + if (mState != IDLE) { + activeStreamIDToRestart = mStreamID; + mStopTimeNs = systemTime(); } } // lock ends here. This is on the callback thread, no need to be precise. if (activeStreamIDToRestart > 0) { diff --git a/media/jni/soundpool/Stream.h b/media/jni/soundpool/Stream.h index aa0eef5bc66e..0054eeca529a 100644 --- a/media/jni/soundpool/Stream.h +++ b/media/jni/soundpool/Stream.h @@ -124,6 +124,35 @@ public: // This never changes. See top of header. Stream* getPairStream() const; + // Stream ID of ourselves, or the pair depending on who holds the AudioTrack + int getCorrespondingStreamID(); + +protected: + // AudioTrack callback interface implementation + class StreamCallback : public AudioTrack::IAudioTrackCallback { + public: + StreamCallback(Stream * stream, bool toggle) : mStream(stream), mToggle(toggle) {} + size_t onMoreData(const AudioTrack::Buffer& buffer) override; + void onUnderrun() override; + void onLoopEnd(int32_t loopsRemaining) override; + void onMarker(uint32_t markerPosition) override; + void onNewPos(uint32_t newPos) override; + void onBufferEnd() override; + void onNewIAudioTrack() override; + void onStreamEnd() override; + size_t onCanWriteMoreData(const AudioTrack::Buffer& buffer) override; + + // Holding a raw ptr is technically unsafe, but, Stream objects persist + // through the lifetime of the StreamManager through the use of a + // unique_ptr<Stream[]>. Ensuring lifetime will cause us to give up + // locality as well as pay RefBase/sp performance cost, which we are + // unwilling to do. Non-owning refs to unique_ptrs are idiomatically raw + // ptrs, as below. + Stream * const mStream; + const bool mToggle; + }; + + sp<StreamCallback> mCallback; private: // garbage is used to release tracks and data outside of any lock. void play_l(const std::shared_ptr<Sound>& sound, int streamID, @@ -133,9 +162,7 @@ private: void setVolume_l(float leftVolume, float rightVolume) REQUIRES(mLock); // For use with AudioTrack callback. - static void staticCallback(int event, void* user, void* info); - void callback(int event, void* info, int toggle, int tries) - NO_THREAD_SAFETY_ANALYSIS; // uses unique_lock + void onBufferEnd(int toggle, int tries) NO_THREAD_SAFETY_ANALYSIS; // StreamManager should be set on construction and not changed. // release mLock before calling into StreamManager |