Add callback for codec format change.
When creating native audio track, a IAudioTrackCallback will be created
systematically. All callbacks will be cached in Threads and protected by
a lock. Whenever there is a callback event from audio HAL, it will
finally trigger callback to native audio track. Currently, there is only
one callback event, which is codec format change.
Bug: 150301890
Test: manual
Change-Id: I32293627ed923b17dd25f11f0ee0a0c35cd7c01f
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index 2833525..f24dcd7 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -42,6 +42,7 @@
#include <private/media/AudioTrackShared.h>
#include <private/android_filesystem_config.h>
#include <audio_utils/Balance.h>
+#include <audio_utils/Metadata.h>
#include <audio_utils/channels.h>
#include <audio_utils/mono_blend.h>
#include <audio_utils/primitives.h>
@@ -1921,6 +1922,16 @@
void AudioFlinger::PlaybackThread::onFirstRef()
{
+ if (mOutput == nullptr || mOutput->stream == nullptr) {
+ ALOGE("The stream is not open yet"); // This should not happen.
+ } else {
+ // setEventCallback will need a strong pointer as a parameter. Calling it
+ // here instead of constructor of PlaybackThread so that the onFirstRef
+ // callback would not be made on an incompletely constructed object.
+ if (mOutput->stream->setEventCallback(this) != OK) {
+ ALOGE("Failed to add event callback");
+ }
+ }
run(mThreadName, ANDROID_PRIORITY_URGENT_AUDIO);
}
@@ -2050,7 +2061,8 @@
pid_t tid,
uid_t uid,
status_t *status,
- audio_port_handle_t portId)
+ audio_port_handle_t portId,
+ const sp<media::IAudioTrackCallback>& callback)
{
size_t frameCount = *pFrameCount;
size_t notificationFrameCount = *pNotificationFrameCount;
@@ -2340,6 +2352,12 @@
goto Exit;
}
mTracks.add(track);
+ {
+ Mutex::Autolock _atCbL(mAudioTrackCbLock);
+ if (callback.get() != nullptr) {
+ mAudioTrackCallbacks.emplace(callback);
+ }
+ }
sp<EffectChain> chain = getEffectChain_l(sessionId);
if (chain != 0) {
@@ -2642,6 +2660,29 @@
mCallbackThread->setAsyncError();
}
+void AudioFlinger::PlaybackThread::onCodecFormatChanged(
+ const std::basic_string<uint8_t>& metadataBs)
+{
+ std::thread([this, metadataBs]() {
+ audio_utils::metadata::Data metadata =
+ audio_utils::metadata::dataFromByteString(metadataBs);
+ if (metadata.empty()) {
+ ALOGW("Can not transform the buffer to audio metadata, %s, %d",
+ reinterpret_cast<char*>(const_cast<uint8_t*>(metadataBs.data())),
+ (int)metadataBs.size());
+ return;
+ }
+
+ audio_utils::metadata::ByteString metaDataStr =
+ audio_utils::metadata::byteStringFromData(metadata);
+ std::vector metadataVec(metaDataStr.begin(), metaDataStr.end());
+ Mutex::Autolock _l(mAudioTrackCbLock);
+ for (const auto& callback : mAudioTrackCallbacks) {
+ callback->onCodecFormatChanged(metadataVec);
+ }
+ }).detach();
+}
+
void AudioFlinger::PlaybackThread::resetWriteBlocked(uint32_t sequence)
{
Mutex::Autolock _l(mLock);