summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRicardo Cerqueira <cyanogenmod@cerqueira.org>2013-01-09 12:42:17 -0800
committerGerrit Code Review <gerrit@review.cyanogenmod.com>2013-01-09 12:42:17 -0800
commit87e95973043c3d85774972447425b182d535bbaa (patch)
treef6d47fca300f75797d68ab3ed533049be8884dc5
parent6dcc59e51c11819d668aee09a3265c3cd2717791 (diff)
parentceb8b69d4a71a32375a8a957d087621638dec50b (diff)
downloadandroid_frameworks_base-87e95973043c3d85774972447425b182d535bbaa.tar.gz
android_frameworks_base-87e95973043c3d85774972447425b182d535bbaa.tar.bz2
android_frameworks_base-87e95973043c3d85774972447425b182d535bbaa.zip
Merge "ST_ERICSSON: support for latency" into ics
-rw-r--r--include/media/AudioParameter.h3
-rw-r--r--include/media/AudioSystem.h19
-rw-r--r--include/media/AudioTrack.h12
-rw-r--r--include/media/MediaPlayerInterface.h8
-rw-r--r--include/media/stagefright/AudioPlayer.h4
-rw-r--r--media/libmedia/AudioParameter.cpp3
-rw-r--r--media/libmedia/AudioSystem.cpp48
-rw-r--r--media/libmedia/AudioTrack.cpp32
-rw-r--r--media/libmediaplayerservice/MediaPlayerService.cpp46
-rw-r--r--media/libmediaplayerservice/MediaPlayerService.h16
-rw-r--r--media/libstagefright/AudioPlayer.cpp27
-rw-r--r--services/audioflinger/AudioFlinger.cpp13
12 files changed, 229 insertions, 2 deletions
diff --git a/include/media/AudioParameter.h b/include/media/AudioParameter.h
index 79d5d82ddb8..7c9536e2c82 100644
--- a/include/media/AudioParameter.h
+++ b/include/media/AudioParameter.h
@@ -46,6 +46,9 @@ public:
static const char *keyChannels;
static const char *keyFrameCount;
static const char *keyInputSource;
+#ifdef STE_HARDWARE
+ static const char *keyLatency;
+#endif
String8 toString();
diff --git a/include/media/AudioSystem.h b/include/media/AudioSystem.h
index ff401f7ad94..89825257edd 100644
--- a/include/media/AudioSystem.h
+++ b/include/media/AudioSystem.h
@@ -31,6 +31,9 @@ namespace android {
typedef void (*audio_error_callback)(status_t err);
+#ifdef STE_HARDWARE
+typedef void (*latency_update_callback)(void *cookie, audio_io_handle_t output, uint32_t latency);
+#endif
class IAudioPolicyService;
class String8;
@@ -110,6 +113,10 @@ public:
static int newAudioSessionId();
static void acquireAudioSessionId(int audioSession);
static void releaseAudioSessionId(int audioSession);
+#ifdef STE_HARDWARE
+ static int registerLatencyNotificationClient(latency_update_callback cb, void *cookie);
+ static void unregisterLatencyNotificationClient(int clientId);
+#endif
// types of io configuration change events received with ioConfigChanged()
enum io_config_event {
@@ -239,6 +246,13 @@ private:
virtual void binderDied(const wp<IBinder>& who);
};
+#ifdef STE_HARDWARE
+ struct NotificationClient : public RefBase {
+ latency_update_callback mCb;
+ void * mCookie;
+ };
+#endif
+
static sp<AudioFlingerClient> gAudioFlingerClient;
static sp<AudioPolicyServiceClient> gAudioPolicyServiceClient;
friend class AudioFlingerClient;
@@ -261,6 +275,11 @@ private:
// list of output descriptors containing cached parameters
// (sampling rate, framecount, channel count...)
static DefaultKeyedVector<audio_io_handle_t, OutputDescriptor *> gOutputs;
+#ifdef STE_HARDWARE
+ static Mutex gLatencyLock;
+ static int gNextUniqueLatencyId;
+ static DefaultKeyedVector<int, sp<AudioSystem::NotificationClient> > gLatencyNotificationClients;
+#endif
};
}; // namespace android
diff --git a/include/media/AudioTrack.h b/include/media/AudioTrack.h
index f518198885b..1208adad182 100644
--- a/include/media/AudioTrack.h
+++ b/include/media/AudioTrack.h
@@ -55,7 +55,12 @@ public:
EVENT_LOOP_END = 2, // Sample loop end was reached; playback restarted from loop start if loop count was not 0.
EVENT_MARKER = 3, // Playback head is at the specified marker position (See setMarkerPosition()).
EVENT_NEW_POS = 4, // Playback head is at a new position (See setPositionUpdatePeriod()).
+#ifdef STE_HARDWARE
+ EVENT_BUFFER_END = 5, // Playback head is at the end of the buffer.
+ EVENT_LATENCY_CHANGED = 6 // Audio output has been reconfigured and latency has changed.
+#else
EVENT_BUFFER_END = 5 // Playback head is at the end of the buffer.
+#endif
};
/* Create Buffer on the stack and pass it to obtainBuffer()
@@ -480,6 +485,10 @@ private:
status_t setLoop_l(uint32_t loopStart, uint32_t loopEnd, int loopCount);
audio_io_handle_t getOutput_l();
status_t restoreTrack_l(audio_track_cblk_t*& cblk, bool fromStart);
+#ifdef STE_HARDWARE
+ static void LatencyCallbackWrapper(void *cookie, audio_io_handle_t output, uint32_t latency);
+ void latencyCallback(audio_io_handle_t output, uint32_t latency);
+#endif
sp<IAudioTrack> mAudioTrack;
sp<IMemory> mCblkMemory;
@@ -521,6 +530,9 @@ private:
int mAuxEffectId;
Mutex mLock;
status_t mRestoreStatus;
+#ifdef STE_HARDWARE
+ int mLatencyClientId;
+#endif
};
diff --git a/include/media/MediaPlayerInterface.h b/include/media/MediaPlayerInterface.h
index d23d2c44303..9088a869a12 100644
--- a/include/media/MediaPlayerInterface.h
+++ b/include/media/MediaPlayerInterface.h
@@ -68,6 +68,9 @@ public:
// Callback returns the number of bytes actually written to the buffer.
typedef size_t (*AudioCallback)(
AudioSink *audioSink, void *buffer, size_t size, void *cookie);
+#ifdef STE_HARDWARE
+ typedef void (*LatencyCallback)(uint32_t latency, void *cookie);
+#endif
virtual ~AudioSink() {}
virtual bool ready() const = 0; // audio output is open and ready
@@ -88,7 +91,12 @@ public:
int format=AUDIO_FORMAT_PCM_16_BIT,
int bufferCount=DEFAULT_AUDIOSINK_BUFFERCOUNT,
AudioCallback cb = NULL,
+#ifdef STE_HARDWARE
+ void *cookie = NULL,
+ LatencyCallback latencyCb = NULL) = 0;
+#else
void *cookie = NULL) = 0;
+#endif
#ifdef WITH_QCOM_LPA
// API to open a routing session for tunneled audio playback
diff --git a/include/media/stagefright/AudioPlayer.h b/include/media/stagefright/AudioPlayer.h
index bb05ba3cc03..dd09f187506 100644
--- a/include/media/stagefright/AudioPlayer.h
+++ b/include/media/stagefright/AudioPlayer.h
@@ -104,6 +104,10 @@ private:
MediaPlayerBase::AudioSink *audioSink,
void *data, size_t size, void *me);
+#ifdef STE_HARDWARE
+ static void LatencyCallback(uint32_t latency, void *cookie);
+#endif
+
size_t fillBuffer(void *data, size_t size);
int64_t getRealTimeUsLocked() const;
diff --git a/media/libmedia/AudioParameter.cpp b/media/libmedia/AudioParameter.cpp
index 59ccfd00f3c..60046e407f5 100644
--- a/media/libmedia/AudioParameter.cpp
+++ b/media/libmedia/AudioParameter.cpp
@@ -29,6 +29,9 @@ const char *AudioParameter::keyFormat = "format";
const char *AudioParameter::keyChannels = "channels";
const char *AudioParameter::keyFrameCount = "frame_count";
const char *AudioParameter::keyInputSource = "input_source";
+#ifdef STE_HARDWARE
+const char *AudioParameter::keyLatency = "latency";
+#endif
AudioParameter::AudioParameter(const String8& keyValuePairs)
{
diff --git a/media/libmedia/AudioSystem.cpp b/media/libmedia/AudioSystem.cpp
index 98959b85ac2..dc4ad4df9ab 100644
--- a/media/libmedia/AudioSystem.cpp
+++ b/media/libmedia/AudioSystem.cpp
@@ -45,6 +45,13 @@ int AudioSystem::gPrevInChannelCount = 1;
size_t AudioSystem::gInBuffSize = 0;
+#ifdef STE_HARDWARE
+// Clients for receiving latency update notifications
+Mutex AudioSystem::gLatencyLock;
+int AudioSystem::gNextUniqueLatencyId = 0;
+DefaultKeyedVector<int, sp<AudioSystem::NotificationClient> > AudioSystem::gLatencyNotificationClients(0);
+#endif
+
// establish binder interface to AudioFlinger service
const sp<IAudioFlinger>& AudioSystem::get_audio_flinger()
{
@@ -370,9 +377,32 @@ void AudioSystem::releaseAudioSessionId(int audioSession) {
}
}
+#ifdef STE_HARDWARE
+int AudioSystem::registerLatencyNotificationClient(latency_update_callback cb, void *cookie) {
+ Mutex::Autolock _l(gLatencyLock);
+
+ sp<NotificationClient> notificationClient = new NotificationClient();
+ notificationClient->mCb = cb;
+ notificationClient->mCookie = cookie;
+
+ gNextUniqueLatencyId++;
+ gLatencyNotificationClients.add(gNextUniqueLatencyId, notificationClient);
+ return gNextUniqueLatencyId;
+}
+
+void AudioSystem::unregisterLatencyNotificationClient(int clientId) {
+ Mutex::Autolock _l(gLatencyLock);
+ gLatencyNotificationClients.removeItem(clientId);
+}
// ---------------------------------------------------------------------------
+#endif
void AudioSystem::AudioFlingerClient::binderDied(const wp<IBinder>& who) {
+#ifdef STE_HARDWARE
+ gLatencyLock.lock();
+ AudioSystem::gLatencyNotificationClients.clear();
+ gLatencyLock.unlock();
+#endif
Mutex::Autolock _l(AudioSystem::gLock);
AudioSystem::gAudioFlinger.clear();
@@ -445,9 +475,27 @@ void AudioSystem::AudioFlingerClient::ioConfigChanged(int event, int ioHandle, v
ioHandle, desc->samplingRate, desc->format,
desc->channels, desc->frameCount, desc->latency);
OutputDescriptor *outputDesc = gOutputs.valueAt(index);
+#ifdef STE_HARDWARE
+ uint32_t oldLatency = outputDesc->latency;
+#endif
delete outputDesc;
outputDesc = new OutputDescriptor(*desc);
gOutputs.replaceValueFor(ioHandle, outputDesc);
+#ifdef STE_HARDWARE
+ if (oldLatency == outputDesc->latency) {
+ break;
+ }
+ uint32_t newLatency = outputDesc->latency;
+ gLock.unlock();
+ gLatencyLock.lock();
+ size_t size = gLatencyNotificationClients.size();
+ for (size_t i = 0; i < size; i++) {
+ sp<NotificationClient> client = gLatencyNotificationClients.valueAt(i);
+ (*client->mCb)(client->mCookie, ioHandle, newLatency);
+ }
+ gLatencyLock.unlock();
+ gLock.lock();
+#endif
} break;
case INPUT_OPENED:
case INPUT_CLOSED:
diff --git a/media/libmedia/AudioTrack.cpp b/media/libmedia/AudioTrack.cpp
index a9ab9828cdc..938aea8a774 100644
--- a/media/libmedia/AudioTrack.cpp
+++ b/media/libmedia/AudioTrack.cpp
@@ -78,7 +78,6 @@ status_t AudioTrack::getMinFrameCount(
if (AudioSystem::getOutputLatency(&afLatency, streamType) != NO_ERROR) {
return NO_INIT;
}
-
// Ensure that buffer depth covers at least audio hardware latency
uint32_t minBufCount = afLatency / ((1000 * afFrameCount) / afSampleRate);
if (minBufCount < 2) minBufCount = 2;
@@ -215,6 +214,9 @@ AudioTrack::~AudioTrack()
AudioSystem::releaseAudioSessionId(mSessionId);
#endif
}
+#ifdef STE_HARDWARE
+ AudioSystem::unregisterLatencyNotificationClient(mLatencyClientId);
+#endif
}
status_t AudioTrack::set(
@@ -345,6 +347,10 @@ status_t AudioTrack::set(
#endif
AudioSystem::acquireAudioSessionId(mSessionId);
mRestoreStatus = NO_ERROR;
+#ifdef STE_HARDWARE
+ mLatencyClientId = AudioSystem::registerLatencyNotificationClient(
+ &AudioTrack::LatencyCallbackWrapper, this);
+#endif
return NO_ERROR;
}
@@ -1479,6 +1485,30 @@ status_t AudioTrack::dump(int fd, const Vector<String16>& args) const
return NO_ERROR;
}
+#ifdef STE_HARDWARE
+// static
+void AudioTrack::LatencyCallbackWrapper(void *cookie, audio_io_handle_t output, uint32_t latency)
+{
+ static_cast<AudioTrack *>(cookie)->latencyCallback(output, latency);
+}
+
+void AudioTrack::latencyCallback(audio_io_handle_t output, uint32_t latency)
+{
+ audio_io_handle_t myOutput = getOutput();
+ if (output != myOutput) {
+ return;
+ }
+
+ uint32_t oldLatency = mLatency;
+ mLatency = latency + (1000*mCblk->frameCount) / mCblk->sampleRate;
+ LOGV("new latency for output %d (old latency %d, new latency %d)", output, oldLatency, mLatency);
+
+ if (mCbf != NULL) {
+ mCbf(EVENT_LATENCY_CHANGED, mUserData, &mLatency);
+ }
+}
+#endif
+
// =========================================================================
AudioTrack::AudioTrackThread::AudioTrackThread(AudioTrack& receiver, bool bCanCallJava)
diff --git a/media/libmediaplayerservice/MediaPlayerService.cpp b/media/libmediaplayerservice/MediaPlayerService.cpp
index 2888888bb5a..17216d024d5 100644
--- a/media/libmediaplayerservice/MediaPlayerService.cpp
+++ b/media/libmediaplayerservice/MediaPlayerService.cpp
@@ -321,7 +321,11 @@ status_t MediaPlayerService::AudioOutput::dump(int fd, const Vector<String16>& a
mStreamType, mLeftVolume, mRightVolume);
result.append(buffer);
snprintf(buffer, 255, " msec per frame(%f), latency (%d)\n",
+#ifdef STE_HARDWARE
+ mMsecsPerFrame, mLatency);
+#else
mMsecsPerFrame, (mTrack != 0) ? mTrack->latency() : -1);
+#endif
result.append(buffer);
snprintf(buffer, 255, " aux effect id(%d), send level (%f)\n",
mAuxEffectId, mSendLevel);
@@ -1269,6 +1273,9 @@ MediaPlayerService::AudioOutput::AudioOutput(int sessionId)
mStreamType = AUDIO_STREAM_MUSIC;
mLeftVolume = 1.0;
mRightVolume = 1.0;
+#ifdef STE_HARDWARE
+ mLatency = 0;
+#endif
mMsecsPerFrame = 0;
mAuxEffectId = 0;
mSendLevel = 0.0;
@@ -1330,8 +1337,12 @@ ssize_t MediaPlayerService::AudioOutput::frameSize() const
uint32_t MediaPlayerService::AudioOutput::latency () const
{
+#ifdef STE_HARDWARE
+ return mLatency;
+#else
if (mTrack == 0) return 0;
return mTrack->latency();
+#endif
}
float MediaPlayerService::AudioOutput::msecsPerFrame() const
@@ -1380,10 +1391,17 @@ status_t MediaPlayerService::AudioOutput::openSession(
status_t MediaPlayerService::AudioOutput::open(
uint32_t sampleRate, int channelCount, int format, int bufferCount,
+#ifdef STE_HARDWARE
+ AudioCallback cb, void *cookie, LatencyCallback latencyCb)
+#else
AudioCallback cb, void *cookie)
+#endif
{
mCallback = cb;
mCallbackCookie = cookie;
+#ifdef STE_HARDWARE
+ mLatencyCallback = latencyCb;
+#endif
// Check argument "bufferCount" against the mininum buffer count
if (bufferCount < mMinBufferCount) {
@@ -1443,6 +1461,9 @@ status_t MediaPlayerService::AudioOutput::open(
t->setVolume(mLeftVolume, mRightVolume);
mMsecsPerFrame = 1.e3 / (float) sampleRate;
+#ifdef STE_HARDWARE
+ mLatency = t->latency();
+#endif
mTrack = t;
t->setAuxEffectSendLevel(mSendLevel);
@@ -1494,10 +1515,15 @@ void MediaPlayerService::AudioOutput::pause()
void MediaPlayerService::AudioOutput::close()
{
LOGV("close");
+#ifdef STE_HARDWARE
+ delete mTrack;
+ mTrack = 0;
+#else
if(mTrack != NULL) {
delete mTrack;
mTrack = 0;
}
+#endif
}
#ifdef WITH_QCOM_LPA
void MediaPlayerService::AudioOutput::closeSession()
@@ -1568,10 +1594,13 @@ status_t MediaPlayerService::AudioOutput::attachAuxEffect(int effectId)
void MediaPlayerService::AudioOutput::CallbackWrapper(
int event, void *cookie, void *info) {
//LOGV("callbackwrapper");
+#ifdef STE_HARDWARE
+ if (event == AudioTrack::EVENT_MORE_DATA) {
+#else
if (event != AudioTrack::EVENT_MORE_DATA) {
return;
}
-
+#endif
AudioOutput *me = (AudioOutput *)cookie;
AudioTrack::Buffer *buffer = (AudioTrack::Buffer *)info;
@@ -1587,6 +1616,17 @@ void MediaPlayerService::AudioOutput::CallbackWrapper(
}
buffer->size = actualSize;
+#ifdef STE_HARDWARE
+ } else if (event == AudioTrack::EVENT_LATENCY_CHANGED) {
+ AudioOutput *me = (AudioOutput *)cookie;
+
+ uint32_t *newLatency = (uint32_t *)info;
+ me->mLatency = *newLatency;
+ if (me->mLatencyCallback != NULL) {
+ (*me->mLatencyCallback)(*newLatency, me->mCallbackCookie);
+ }
+ }
+#endif
}
int MediaPlayerService::AudioOutput::getSessionId()
@@ -1687,7 +1727,11 @@ bool CallbackThread::threadLoop() {
status_t MediaPlayerService::AudioCache::open(
uint32_t sampleRate, int channelCount, int format, int bufferCount,
+#ifdef STE_HARDWARE
+ AudioCallback cb, void *cookie, LatencyCallback latencyCb)
+#else
AudioCallback cb, void *cookie)
+#endif
{
LOGV("open(%u, %d, %d, %d)", sampleRate, channelCount, format, bufferCount);
if (mHeap->getHeapID() < 0) {
diff --git a/media/libmediaplayerservice/MediaPlayerService.h b/media/libmediaplayerservice/MediaPlayerService.h
index 24a8d09b3c5..4bde518557c 100644
--- a/media/libmediaplayerservice/MediaPlayerService.h
+++ b/media/libmediaplayerservice/MediaPlayerService.h
@@ -84,7 +84,12 @@ class MediaPlayerService : public BnMediaPlayerService
virtual status_t open(
uint32_t sampleRate, int channelCount,
int format, int bufferCount,
+#ifdef STE_HARDWARE
+ AudioCallback cb, void *cookie,
+ LatencyCallback latencyCb = NULL);
+#else
AudioCallback cb, void *cookie);
+#endif
#ifdef WITH_QCOM_LPA
virtual status_t openSession(
int format, int sessionId, uint32_t sampleRate, int channels);
@@ -124,10 +129,16 @@ class MediaPlayerService : public BnMediaPlayerService
#endif
AudioCallback mCallback;
void * mCallbackCookie;
+#ifdef STE_HARDWARE
+ LatencyCallback mLatencyCallback;
+#endif
int mStreamType;
float mLeftVolume;
float mRightVolume;
float mMsecsPerFrame;
+#ifdef STE_HARDWARE
+ uint32_t mLatency;
+#endif
int mSessionId;
float mSendLevel;
int mAuxEffectId;
@@ -156,7 +167,12 @@ class MediaPlayerService : public BnMediaPlayerService
virtual status_t open(
uint32_t sampleRate, int channelCount, int format,
int bufferCount = 1,
+#ifdef STE_HARDWARE
+ AudioCallback cb = NULL, void *cookie = NULL,
+ LatencyCallback latencyCb = NULL);
+#else
AudioCallback cb = NULL, void *cookie = NULL);
+#endif
virtual void start();
virtual ssize_t write(const void* buffer, size_t size);
diff --git a/media/libstagefright/AudioPlayer.cpp b/media/libstagefright/AudioPlayer.cpp
index ea04288f888..290e562b824 100644
--- a/media/libstagefright/AudioPlayer.cpp
+++ b/media/libstagefright/AudioPlayer.cpp
@@ -124,7 +124,12 @@ status_t AudioPlayer::start(bool sourceAlreadyStarted) {
status_t err = mAudioSink->open(
mSampleRate, numChannels, AUDIO_FORMAT_PCM_16_BIT,
DEFAULT_AUDIOSINK_BUFFERCOUNT,
+#ifdef STE_HARDWARE
+ &AudioPlayer::AudioSinkCallback, this,
+ &AudioPlayer::LatencyCallback);
+#else
&AudioPlayer::AudioSinkCallback, this);
+#endif
if (err != OK) {
if (mFirstBuffer != NULL) {
mFirstBuffer->release();
@@ -275,6 +280,16 @@ void AudioPlayer::AudioCallback(int event, void *user, void *info) {
static_cast<AudioPlayer *>(user)->AudioCallback(event, info);
}
+#ifdef STE_HARDWARE
+// static
+void AudioPlayer::LatencyCallback(uint32_t latency, void *cookie) {
+ AudioPlayer *me = (AudioPlayer *)cookie;
+ int64_t oldLatency = me->mLatencyUs;
+ me->mLatencyUs = (int64_t)latency * 1000;
+ LOGI("Audio output latency updated from %lldus to %lldus", oldLatency, me->mLatencyUs);
+}
+#endif
+
bool AudioPlayer::isSeeking() {
Mutex::Autolock autoLock(mLock);
return mSeeking;
@@ -298,14 +313,26 @@ size_t AudioPlayer::AudioSinkCallback(
}
void AudioPlayer::AudioCallback(int event, void *info) {
+#ifdef STE_HARDWARE
+ if (event == AudioTrack::EVENT_MORE_DATA) {
+#else
if (event != AudioTrack::EVENT_MORE_DATA) {
return;
}
+#endif
AudioTrack::Buffer *buffer = (AudioTrack::Buffer *)info;
size_t numBytesWritten = fillBuffer(buffer->raw, buffer->size);
buffer->size = numBytesWritten;
+#ifdef STE_HARDWARE
+ } else if (event == AudioTrack::EVENT_LATENCY_CHANGED) {
+ uint32_t *newLatency = (uint32_t *)info;
+ int64_t oldLatency = mLatencyUs;
+ mLatencyUs = (int64_t)*newLatency * 1000;
+ LOGI("Audio output latency updated from %lldus to %lldus", oldLatency, mLatencyUs);
+ }
+#endif
}
uint32_t AudioPlayer::getNumFramesPendingPlayout() const {
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index 6bd7245cc42..e0e17f6194a 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -2748,6 +2748,9 @@ void AudioFlinger::MixerThread::deleteTrackName_l(int name)
bool AudioFlinger::MixerThread::checkForNewParameters_l()
{
bool reconfig = false;
+#ifdef STE_HARDWARE
+ bool updateLatency = false;
+#endif
while (!mNewParameters.isEmpty()) {
status_t status = NO_ERROR;
@@ -2811,6 +2814,11 @@ bool AudioFlinger::MixerThread::checkForNewParameters_l()
mEffectChains[i]->setDevice_l(mDevice);
}
}
+#ifdef STE_HARDWARE
+ if (param.getInt(String8(AudioParameter::keyLatency), value) == NO_ERROR) {
+ updateLatency = true;
+#endif
+ }
if (status == NO_ERROR) {
status = mOutput->stream->common.set_parameters(&mOutput->stream->common,
@@ -2837,6 +2845,11 @@ bool AudioFlinger::MixerThread::checkForNewParameters_l()
}
sendConfigEvent_l(AudioSystem::OUTPUT_CONFIG_CHANGED);
}
+#ifdef STE_HARDWARE
+ if (status == NO_ERROR && updateLatency) {
+ sendConfigEvent_l(AudioSystem::OUTPUT_CONFIG_CHANGED);
+ }
+#endif
}
mNewParameters.removeAt(0);