Take latency and current time into account for visualization
Buffer more data, and return the data that is currently being
output from the audio output, to ensure that visualizations are
smooth and responsive even when the audio output has a large
latency and/or large buffers.
b/6522728
Change-Id: I401637f01be7600b3c594a55c869036c13b206c0
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index 2cfc3e8..e7ababa 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -1818,6 +1818,10 @@
uint32_t AudioFlinger::PlaybackThread::latency() const
{
Mutex::Autolock _l(mLock);
+ return latency_l();
+}
+uint32_t AudioFlinger::PlaybackThread::latency_l() const
+{
if (initCheck() == NO_ERROR) {
return correctLatency(mOutput->stream->get_latency(mOutput->stream));
} else {
@@ -8187,6 +8191,31 @@
status = cmdStatus;
}
+ if (status == 0 &&
+ (memcmp(&mDescriptor.type, SL_IID_VISUALIZATION, sizeof(effect_uuid_t)) == 0)) {
+ uint32_t buf32[sizeof(effect_param_t) / sizeof(uint32_t) + 2];
+ effect_param_t *p = (effect_param_t *)buf32;
+
+ p->psize = sizeof(uint32_t);
+ p->vsize = sizeof(uint32_t);
+ size = sizeof(int);
+ *(int32_t *)p->data = VISUALIZER_PARAM_LATENCY;
+
+ uint32_t latency = 0;
+ PlaybackThread *pbt = thread->mAudioFlinger->checkPlaybackThread_l(thread->mId);
+ if (pbt != NULL) {
+ latency = pbt->latency_l();
+ }
+
+ *((int32_t *)p->data + 1)= latency;
+ (*mEffectInterface)->command(mEffectInterface,
+ EFFECT_CMD_SET_PARAM,
+ sizeof(effect_param_t) + 8,
+ &buf32,
+ &size,
+ &cmdStatus);
+ }
+
mMaxDisableWaitCnt = (MAX_DISABLE_TIME_MS * mConfig.outputCfg.samplingRate) /
(1000 * mConfig.outputCfg.buffer.frameCount);