summaryrefslogtreecommitdiffstats
path: root/libs
diff options
context:
space:
mode:
authorEric Laurent <elaurent@google.com>2010-01-19 17:37:09 -0800
committerEric Laurent <elaurent@google.com>2010-01-26 18:40:39 -0800
commit0986e7907ffc8387b04fb201e285784bcd11b9b7 (patch)
tree96733235d1e92e0f329ded11b9b55c0d67a4ca83 /libs
parent7d3a558b9ebf2256517ec99cd09c066cc7dbc92c (diff)
downloadframeworks_base-0986e7907ffc8387b04fb201e285784bcd11b9b7.zip
frameworks_base-0986e7907ffc8387b04fb201e285784bcd11b9b7.tar.gz
frameworks_base-0986e7907ffc8387b04fb201e285784bcd11b9b7.tar.bz2
Fix issue 2285561: New AudioFlinger and audio driver API needed for A/V sync
Added getRenderPosition() API to IAudioFlinger to retreive number of audio frames written by AudioFlinger to audio HAL and by DSP to DAC. Added getRenderPosition() API to AudioHardwareInterface to retreive number of audio frames written by DSP to DAC. Exposed AudioTrack::getPosition() to AudioSink() to make it available to media player. Removed excessive log in AudioHardwareGeneric.
Diffstat (limited to 'libs')
-rw-r--r--libs/audioflinger/A2dpAudioInterface.cpp6
-rw-r--r--libs/audioflinger/A2dpAudioInterface.h1
-rw-r--r--libs/audioflinger/AudioDumpInterface.cpp6
-rw-r--r--libs/audioflinger/AudioDumpInterface.h3
-rw-r--r--libs/audioflinger/AudioFlinger.cpp33
-rw-r--r--libs/audioflinger/AudioFlinger.h3
-rw-r--r--libs/audioflinger/AudioHardwareGeneric.cpp12
-rw-r--r--libs/audioflinger/AudioHardwareGeneric.h1
-rw-r--r--libs/audioflinger/AudioHardwareStub.cpp5
-rw-r--r--libs/audioflinger/AudioHardwareStub.h1
10 files changed, 62 insertions, 9 deletions
diff --git a/libs/audioflinger/A2dpAudioInterface.cpp b/libs/audioflinger/A2dpAudioInterface.cpp
index c07bbfe..747d0e4 100644
--- a/libs/audioflinger/A2dpAudioInterface.cpp
+++ b/libs/audioflinger/A2dpAudioInterface.cpp
@@ -457,4 +457,10 @@ status_t A2dpAudioInterface::A2dpAudioStreamOut::dump(int fd, const Vector<Strin
return NO_ERROR;
}
+status_t A2dpAudioInterface::A2dpAudioStreamOut::getRenderPosition(uint32_t *driverFrames)
+{
+ //TODO: enable when supported by driver
+ return INVALID_OPERATION;
+}
+
}; // namespace android
diff --git a/libs/audioflinger/A2dpAudioInterface.h b/libs/audioflinger/A2dpAudioInterface.h
index 530e432..48154f9 100644
--- a/libs/audioflinger/A2dpAudioInterface.h
+++ b/libs/audioflinger/A2dpAudioInterface.h
@@ -93,6 +93,7 @@ private:
virtual status_t dump(int fd, const Vector<String16>& args);
virtual status_t setParameters(const String8& keyValuePairs);
virtual String8 getParameters(const String8& keys);
+ virtual status_t getRenderPosition(uint32_t *dspFrames);
private:
friend class A2dpAudioInterface;
diff --git a/libs/audioflinger/AudioDumpInterface.cpp b/libs/audioflinger/AudioDumpInterface.cpp
index 858e5aa..30e2bc9 100644
--- a/libs/audioflinger/AudioDumpInterface.cpp
+++ b/libs/audioflinger/AudioDumpInterface.cpp
@@ -379,6 +379,12 @@ void AudioStreamOutDump::Close()
}
}
+status_t AudioStreamOutDump::getRenderPosition(uint32_t *dspFrames)
+{
+ if (mFinalStream != 0 ) return mFinalStream->getRenderPosition(dspFrames);
+ return INVALID_OPERATION;
+}
+
// ----------------------------------------------------------------------------
AudioStreamInDump::AudioStreamInDump(AudioDumpInterface *interface,
diff --git a/libs/audioflinger/AudioDumpInterface.h b/libs/audioflinger/AudioDumpInterface.h
index 1136ce1..5b9a6b1 100644
--- a/libs/audioflinger/AudioDumpInterface.h
+++ b/libs/audioflinger/AudioDumpInterface.h
@@ -56,8 +56,9 @@ public:
void Close(void);
AudioStreamOut* finalStream() { return mFinalStream; }
uint32_t device() { return mDevice; }
-
int getId() { return mId; }
+ virtual status_t getRenderPosition(uint32_t *dspFrames);
+
private:
AudioDumpInterface *mInterface;
int mId;
diff --git a/libs/audioflinger/AudioFlinger.cpp b/libs/audioflinger/AudioFlinger.cpp
index 5c58603..cad420a 100644
--- a/libs/audioflinger/AudioFlinger.cpp
+++ b/libs/audioflinger/AudioFlinger.cpp
@@ -633,6 +633,20 @@ status_t AudioFlinger::setVoiceVolume(float value)
return ret;
}
+status_t AudioFlinger::getRenderPosition(uint32_t *halFrames, uint32_t *dspFrames, int output)
+{
+ status_t status;
+
+ Mutex::Autolock _l(mLock);
+
+ PlaybackThread *playbackThread = checkPlaybackThread_l(output);
+ if (playbackThread != NULL) {
+ return playbackThread->getRenderPosition(halFrames, dspFrames);
+ }
+
+ return BAD_VALUE;
+}
+
void AudioFlinger::registerClient(const sp<IAudioFlingerClient>& client)
{
@@ -1166,6 +1180,19 @@ void AudioFlinger::PlaybackThread::readOutputParameters()
memset(mMixBuffer, 0, mFrameCount * 2 * sizeof(int16_t));
}
+status_t AudioFlinger::PlaybackThread::getRenderPosition(uint32_t *halFrames, uint32_t *dspFrames)
+{
+ if (halFrames == 0 || dspFrames == 0) {
+ return BAD_VALUE;
+ }
+ if (mOutput == 0) {
+ return INVALID_OPERATION;
+ }
+ *halFrames = mBytesWritten/mOutput->frameSize();
+
+ return mOutput->getRenderPosition(dspFrames);
+}
+
// ----------------------------------------------------------------------------
AudioFlinger::MixerThread::MixerThread(const sp<AudioFlinger>& audioFlinger, AudioStreamOut* output, int id)
@@ -1290,8 +1317,9 @@ bool AudioFlinger::MixerThread::threadLoop()
if (sleepTime == 0) {
mLastWriteTime = systemTime();
mInWrite = true;
+ mBytesWritten += mixBufferSize;
int bytesWritten = (int)mOutput->write(curBuf, mixBufferSize);
- if (bytesWritten > 0) mBytesWritten += bytesWritten;
+ if (bytesWritten < 0) mBytesWritten -= mixBufferSize;
mNumWrites++;
mInWrite = false;
nsecs_t now = systemTime();
@@ -1812,8 +1840,9 @@ bool AudioFlinger::DirectOutputThread::threadLoop()
if (sleepTime == 0) {
mLastWriteTime = systemTime();
mInWrite = true;
+ mBytesWritten += mixBufferSize;
int bytesWritten = (int)mOutput->write(mMixBuffer, mixBufferSize);
- if (bytesWritten) mBytesWritten += bytesWritten;
+ if (bytesWritten < 0) mBytesWritten -= mixBufferSize;
mNumWrites++;
mInWrite = false;
mStandby = false;
diff --git a/libs/audioflinger/AudioFlinger.h b/libs/audioflinger/AudioFlinger.h
index 52999b1..44da9ed 100644
--- a/libs/audioflinger/AudioFlinger.h
+++ b/libs/audioflinger/AudioFlinger.h
@@ -136,6 +136,8 @@ public:
virtual status_t setVoiceVolume(float volume);
+ virtual status_t getRenderPosition(uint32_t *halFrames, uint32_t *dspFrames, int output);
+
// IBinder::DeathRecipient
virtual void binderDied(const wp<IBinder>& who);
@@ -526,6 +528,7 @@ private:
bool isSuspended() { return (mSuspended != 0); }
virtual String8 getParameters(const String8& keys);
virtual void audioConfigChanged(int event, int param = 0);
+ virtual status_t getRenderPosition(uint32_t *halFrames, uint32_t *dspFrames);
struct stream_type_t {
stream_type_t()
diff --git a/libs/audioflinger/AudioHardwareGeneric.cpp b/libs/audioflinger/AudioHardwareGeneric.cpp
index 57874f3..d63c031 100644
--- a/libs/audioflinger/AudioHardwareGeneric.cpp
+++ b/libs/audioflinger/AudioHardwareGeneric.cpp
@@ -298,6 +298,11 @@ String8 AudioStreamOutGeneric::getParameters(const String8& keys)
return param.toString();
}
+status_t AudioStreamOutGeneric::getRenderPosition(uint32_t *dspFrames)
+{
+ return INVALID_OPERATION;
+}
+
// ----------------------------------------------------------------------------
// record functions
@@ -310,9 +315,8 @@ status_t AudioStreamInGeneric::set(
uint32_t *pRate,
AudioSystem::audio_in_acoustics acoustics)
{
- // FIXME: remove logging
if (pFormat == 0 || pChannels == 0 || pRate == 0) return BAD_VALUE;
- LOGD("AudioStreamInGeneric::set(%p, %d, %d, %d, %u)", hw, fd, *pFormat, *pChannels, *pRate);
+ LOGV("AudioStreamInGeneric::set(%p, %d, %d, %d, %u)", hw, fd, *pFormat, *pChannels, *pRate);
// check values
if ((*pFormat != format()) ||
(*pChannels != channels()) ||
@@ -332,14 +336,10 @@ status_t AudioStreamInGeneric::set(
AudioStreamInGeneric::~AudioStreamInGeneric()
{
- // FIXME: remove logging
- LOGD("AudioStreamInGeneric destructor");
}
ssize_t AudioStreamInGeneric::read(void* buffer, ssize_t bytes)
{
- // FIXME: remove logging
- LOGD("AudioStreamInGeneric::read(%p, %d) from fd %d", buffer, (int)bytes, mFd);
AutoMutex lock(mLock);
if (mFd < 0) {
LOGE("Attempt to read from unopened device");
diff --git a/libs/audioflinger/AudioHardwareGeneric.h b/libs/audioflinger/AudioHardwareGeneric.h
index 42da413..95c7ea3 100644
--- a/libs/audioflinger/AudioHardwareGeneric.h
+++ b/libs/audioflinger/AudioHardwareGeneric.h
@@ -55,6 +55,7 @@ public:
virtual status_t dump(int fd, const Vector<String16>& args);
virtual status_t setParameters(const String8& keyValuePairs);
virtual String8 getParameters(const String8& keys);
+ virtual status_t getRenderPosition(uint32_t *dspFrames);
private:
AudioHardwareGeneric *mAudioHardware;
diff --git a/libs/audioflinger/AudioHardwareStub.cpp b/libs/audioflinger/AudioHardwareStub.cpp
index ae391ee..ae215d1 100644
--- a/libs/audioflinger/AudioHardwareStub.cpp
+++ b/libs/audioflinger/AudioHardwareStub.cpp
@@ -158,6 +158,11 @@ String8 AudioStreamOutStub::getParameters(const String8& keys)
return param.toString();
}
+status_t AudioStreamOutStub::getRenderPosition(uint32_t *dspFrames)
+{
+ return INVALID_OPERATION;
+}
+
// ----------------------------------------------------------------------------
status_t AudioStreamInStub::set(int *pFormat, uint32_t *pChannels, uint32_t *pRate,
diff --git a/libs/audioflinger/AudioHardwareStub.h b/libs/audioflinger/AudioHardwareStub.h
index 583f852..769ae3f 100644
--- a/libs/audioflinger/AudioHardwareStub.h
+++ b/libs/audioflinger/AudioHardwareStub.h
@@ -41,6 +41,7 @@ public:
virtual status_t dump(int fd, const Vector<String16>& args);
virtual status_t setParameters(const String8& keyValuePairs) { return NO_ERROR;}
virtual String8 getParameters(const String8& keys);
+ virtual status_t getRenderPosition(uint32_t *dspFrames);
};
class AudioStreamInStub : public AudioStreamIn {