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/PlaybackTracks.h b/services/audioflinger/PlaybackTracks.h
index ea01a25..a78be99 100644
--- a/services/audioflinger/PlaybackTracks.h
+++ b/services/audioflinger/PlaybackTracks.h
@@ -93,6 +93,23 @@
const sp<media::VolumeShaper::Operation>& operation);
sp<media::VolumeShaper::State> getVolumeShaperState(int id);
sp<media::VolumeHandler> getVolumeHandler() { return mVolumeHandler; }
+ /** Set the computed normalized final volume of the track.
+ * !masterMute * masterVolume * streamVolume * averageLRVolume */
+ void setFinalVolume(float volume);
+ float getFinalVolume() const { return mFinalVolume; }
+
+ /** @return true if the track has changed (metadata or volume) since
+ * the last time this function was called,
+ * true if this function was never called since the track creation,
+ * false otherwise.
+ * Thread safe.
+ */
+ bool readAndClearHasChanged() { return !mChangeNotified.test_and_set(); }
+
+ using SourceMetadatas = std::vector<playback_track_metadata_t>;
+ using MetadataInserter = std::back_insert_iterator<SourceMetadatas>;
+ /** Copy the track metadata in the provided iterator. Thread safe. */
+ virtual void copyMetadataTo(MetadataInserter& backInserter) const;
protected:
// for numerous
@@ -133,6 +150,8 @@
bool presentationComplete(int64_t framesWritten, size_t audioHalFrames);
void signalClientFlag(int32_t flag);
+ /** Set that a metadata has changed and needs to be notified to backend. Thread safe. */
+ void setMetadataHasChanged() { mChangeNotified.clear(); }
public:
void triggerEvents(AudioSystem::sync_event_t type);
virtual void invalidate();
@@ -182,10 +201,13 @@
volatile float mCachedVolume; // combined master volume and stream type volume;
// 'volatile' means accessed without lock or
// barrier, but is read/written atomically
+ float mFinalVolume; // combine master volume, stream type volume and track volume
sp<AudioTrackServerProxy> mAudioTrackServerProxy;
bool mResumeToStopping; // track was paused in stopping state.
bool mFlushHwPending; // track requests for thread flush
audio_output_flags_t mFlags;
+ // If the last track change was notified to the client with readAndClearHasChanged
+ std::atomic_flag mChangeNotified = ATOMIC_FLAG_INIT;
}; // end of Track
@@ -216,8 +238,11 @@
bool isActive() const { return mActive; }
const wp<ThreadBase>& thread() const { return mThread; }
-private:
+ void copyMetadataTo(MetadataInserter& backInserter) const override;
+ /** Set the metadatas of the upstream tracks. Thread safe. */
+ void setMetadatas(const SourceMetadatas& metadatas);
+private:
status_t obtainBuffer(AudioBufferProvider::Buffer* buffer,
uint32_t waitTimeMs);
void clearBufferQueue();
@@ -232,6 +257,20 @@
bool mActive;
DuplicatingThread* const mSourceThread; // for waitTimeMs() in write()
sp<AudioTrackClientProxy> mClientProxy;
+ /** Attributes of the source tracks.
+ *
+ * This member must be accessed with mTrackMetadatasMutex taken.
+ * There is one writer (duplicating thread) and one reader (downstream mixer).
+ *
+ * That means that the duplicating thread can block the downstream mixer
+ * thread and vice versa for the time of the copy.
+ * If this becomes an issue, the metadata could be stored in an atomic raw pointer,
+ * and a exchange with nullptr and delete can be used.
+ * Alternatively a read-copy-update might be implemented.
+ */
+ SourceMetadatas mTrackMetadatas;
+ /** Protects mTrackMetadatas against concurrent access. */
+ mutable std::mutex mTrackMetadatasMutex;
}; // end of OutputTrack
// playback track, used by PatchPanel