Audio V4: Send volume and duplicated track attr in update metadata
Only the volume of MMAP thread was previously sent and
the attributes of duplicated tracks were skipped.
Bug: 38184704
Bug: 69623109
Test: check that the HAL receives correct track metadata volume
Test: check that the HAL receives correct duplicated track metadata
Signed-off-by: Kevin Rocard <krocard@google.com>
Change-Id: I1e3b14edd8c9a5a65d2b9f4cf8660997c81c701c
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index 160aa45..43a8b50 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -2623,27 +2623,33 @@
void AudioFlinger::PlaybackThread::updateMetadata_l()
{
- // TODO: add volume support
- if (mOutput == nullptr || mOutput->stream == nullptr ||
- !mActiveTracks.readAndClearHasChanged()) {
- return;
+ if (mOutput == nullptr || mOutput->stream == nullptr ) {
+ return; // That should not happen
+ }
+ bool hasChanged = mActiveTracks.readAndClearHasChanged();
+ for (const sp<Track> &track : mActiveTracks) {
+ // Do not short-circuit as all hasChanged states must be reset
+ // as all the metadata are going to be sent
+ hasChanged |= track->readAndClearHasChanged();
+ }
+ if (!hasChanged) {
+ return; // nothing to do
}
StreamOutHalInterface::SourceMetadata metadata;
+ auto backInserter = std::back_inserter(metadata.tracks);
for (const sp<Track> &track : mActiveTracks) {
// No track is invalid as this is called after prepareTrack_l in the same critical section
- if (track->isOutputTrack()) {
- // TODO: OutputTrack (used for duplication) are currently not supported
- continue;
- }
- metadata.tracks.push_back({
- .usage = track->attributes().usage,
- .content_type = track->attributes().content_type,
- .gain = 1,
- });
+ track->copyMetadataTo(backInserter);
}
- mOutput->stream->updateSourceMetadata(metadata);
+ sendMetadataToBackend_l(metadata);
}
+void AudioFlinger::PlaybackThread::sendMetadataToBackend_l(
+ const StreamOutHalInterface::SourceMetadata& metadata)
+{
+ mOutput->stream->updateSourceMetadata(metadata);
+};
+
status_t AudioFlinger::PlaybackThread::getRenderPosition(uint32_t *halFrames, uint32_t *dspFrames)
{
if (halFrames == NULL || dspFrames == NULL) {
@@ -4381,13 +4387,19 @@
didModify = true;
// no acknowledgement required for newly active tracks
}
+ sp<AudioTrackServerProxy> proxy = track->mAudioTrackServerProxy;
// cache the combined master volume and stream type volume for fast mixer; this
// lacks any synchronization or barrier so VolumeProvider may read a stale value
const float vh = track->getVolumeHandler()->getVolume(
- track->mAudioTrackServerProxy->framesReleased()).first;
- track->mCachedVolume = masterVolume
+ proxy->framesReleased()).first;
+ float volume = masterVolume
* mStreamTypes[track->streamType()].volume
* vh;
+ track->mCachedVolume = masterVolume;
+ gain_minifloat_packed_t vlr = proxy->getVolumeLR();
+ float vlf = volume * float_from_gain(gain_minifloat_unpack_left(vlr));
+ float vrf = volume * float_from_gain(gain_minifloat_unpack_right(vlr));
+ track->setFinalVolume((vlf + vrf) / 2.f);
++fastTracks;
} else {
// was it previously active?
@@ -4564,6 +4576,8 @@
vaf = v * sendLevel * (1. / MAX_GAIN_INT);
}
+ track->setFinalVolume((vrf + vlf) / 2.f);
+
// Delegate volume control to effect in track effect chain if needed
if (chain != 0 && chain->setVolume_l(&vl, &vr)) {
// Do not ramp volume if volume is controlled by effect
@@ -5096,6 +5110,7 @@
}
if (lastTrack) {
+ track->setFinalVolume((left + right) / 2.f);
if (left != mLeftVolFloat || right != mRightVolFloat) {
mLeftVolFloat = left;
mRightVolFloat = right;
@@ -6153,14 +6168,12 @@
return true;
}
-void AudioFlinger::DuplicatingThread::updateMetadata_l()
+void AudioFlinger::DuplicatingThread::sendMetadataToBackend_l(
+ const StreamOutHalInterface::SourceMetadata& metadata)
{
- // TODO: The duplicated track metadata needs to be pushed to downstream
- // but this information can be read at any time by the downstream threads.
- // Taking the lock of any downstream threads is no possible due to cross deadlock risks
- // (eg: during effect move).
- // A lock-free structure needs to be used to shared the metadata, probably an atomic
- // pointer to a metadata vector in each output tracks.
+ for (auto& outputTrack : outputTracks) { // not mOutputTracks
+ outputTrack->setMetadatas(metadata.tracks);
+ }
}
uint32_t AudioFlinger::DuplicatingThread::activeSleepTimeUs() const