summaryrefslogtreecommitdiffstats
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
commit342e9cf388cceb807def720e40e8b0a217f4bcaa (patch)
tree2d443e1de1a10b628016a5ceffb4b5a1cb031dd7
parent2dce41ad26cb3e9e15c9e456a84bcf5309548ca0 (diff)
downloadframeworks_av-342e9cf388cceb807def720e40e8b0a217f4bcaa.zip
frameworks_av-342e9cf388cceb807def720e40e8b0a217f4bcaa.tar.gz
frameworks_av-342e9cf388cceb807def720e40e8b0a217f4bcaa.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.
-rw-r--r--include/media/AudioSystem.h11
-rw-r--r--include/media/IAudioFlinger.h1
-rw-r--r--include/media/MediaPlayerInterface.h1
-rw-r--r--media/libmedia/AudioSystem.cpp12
-rw-r--r--media/libmedia/IAudioFlinger.cpp36
-rw-r--r--media/libmediaplayerservice/MediaPlayerService.cpp13
-rw-r--r--media/libmediaplayerservice/MediaPlayerService.h2
7 files changed, 75 insertions, 1 deletions
diff --git a/include/media/AudioSystem.h b/include/media/AudioSystem.h
index b42bf54..42bb4df 100644
--- a/include/media/AudioSystem.h
+++ b/include/media/AudioSystem.h
@@ -222,6 +222,17 @@ public:
static status_t setVoiceVolume(float volume);
+ // return the number of audio frames written by AudioFlinger to audio HAL and
+ // audio dsp to DAC since the output on which the specificed stream is playing
+ // has exited standby.
+ // returned status (from utils/Errors.h) can be:
+ // - NO_ERROR: successful operation, halFrames and dspFrames point to valid data
+ // - INVALID_OPERATION: Not supported on current hardware platform
+ // - BAD_VALUE: invalid parameter
+ // NOTE: this feature is not supported on all hardware platforms and it is
+ // necessary to check returned status before using the returned values.
+ static status_t getRenderPosition(uint32_t *halFrames, uint32_t *dspFrames, int stream = DEFAULT);
+
//
// AudioPolicyService interface
//
diff --git a/include/media/IAudioFlinger.h b/include/media/IAudioFlinger.h
index b689dcb..bddd23e 100644
--- a/include/media/IAudioFlinger.h
+++ b/include/media/IAudioFlinger.h
@@ -130,6 +130,7 @@ public:
virtual status_t setStreamOutput(uint32_t stream, int output) = 0;
virtual status_t setVoiceVolume(float volume) = 0;
+ virtual status_t getRenderPosition(uint32_t *halFrames, uint32_t *dspFrames, int output) = 0;
};
diff --git a/include/media/MediaPlayerInterface.h b/include/media/MediaPlayerInterface.h
index 6575da6..588c51a 100644
--- a/include/media/MediaPlayerInterface.h
+++ b/include/media/MediaPlayerInterface.h
@@ -72,6 +72,7 @@ public:
virtual ssize_t frameSize() const = 0;
virtual uint32_t latency() const = 0;
virtual float msecsPerFrame() const = 0;
+ virtual status_t getPosition(uint32_t *position) = 0;
// If no callback is specified, use the "write" API below to submit
// audio data. Otherwise return a full buffer of audio data on each
diff --git a/media/libmedia/AudioSystem.cpp b/media/libmedia/AudioSystem.cpp
index e3b829b..c5dfbb5 100644
--- a/media/libmedia/AudioSystem.cpp
+++ b/media/libmedia/AudioSystem.cpp
@@ -342,6 +342,18 @@ status_t AudioSystem::setVoiceVolume(float value)
return af->setVoiceVolume(value);
}
+status_t AudioSystem::getRenderPosition(uint32_t *halFrames, uint32_t *dspFrames, int stream)
+{
+ const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
+ if (af == 0) return PERMISSION_DENIED;
+
+ if (stream == DEFAULT) {
+ stream = MUSIC;
+ }
+
+ return af->getRenderPosition(halFrames, dspFrames, getOutput((stream_type)stream));
+}
+
// ---------------------------------------------------------------------------
void AudioSystem::AudioFlingerClient::binderDied(const wp<IBinder>& who) {
diff --git a/media/libmedia/IAudioFlinger.cpp b/media/libmedia/IAudioFlinger.cpp
index fc42979..ca3a2a6 100644
--- a/media/libmedia/IAudioFlinger.cpp
+++ b/media/libmedia/IAudioFlinger.cpp
@@ -60,7 +60,8 @@ enum {
OPEN_INPUT,
CLOSE_INPUT,
SET_STREAM_OUTPUT,
- SET_VOICE_VOLUME
+ SET_VOICE_VOLUME,
+ GET_RENDER_POSITION
};
class BpAudioFlinger : public BpInterface<IAudioFlinger>
@@ -466,6 +467,26 @@ public:
remote()->transact(SET_VOICE_VOLUME, data, &reply);
return reply.readInt32();
}
+
+ virtual status_t getRenderPosition(uint32_t *halFrames, uint32_t *dspFrames, int output)
+ {
+ Parcel data, reply;
+ data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
+ data.writeInt32(output);
+ remote()->transact(GET_RENDER_POSITION, data, &reply);
+ status_t status = reply.readInt32();
+ if (status == NO_ERROR) {
+ uint32_t tmp = reply.readInt32();
+ if (halFrames) {
+ *halFrames = tmp;
+ }
+ tmp = reply.readInt32();
+ if (dspFrames) {
+ *dspFrames = tmp;
+ }
+ }
+ return status;
+ }
};
IMPLEMENT_META_INTERFACE(AudioFlinger, "android.media.IAudioFlinger");
@@ -718,6 +739,19 @@ status_t BnAudioFlinger::onTransact(
reply->writeInt32( setVoiceVolume(volume) );
return NO_ERROR;
} break;
+ case GET_RENDER_POSITION: {
+ CHECK_INTERFACE(IAudioFlinger, data, reply);
+ int output = data.readInt32();
+ uint32_t halFrames;
+ uint32_t dspFrames;
+ status_t status = getRenderPosition(&halFrames, &dspFrames, output);
+ reply->writeInt32(status);
+ if (status == NO_ERROR) {
+ reply->writeInt32(halFrames);
+ reply->writeInt32(dspFrames);
+ }
+ return NO_ERROR;
+ }
default:
return BBinder::onTransact(code, data, reply, flags);
}
diff --git a/media/libmediaplayerservice/MediaPlayerService.cpp b/media/libmediaplayerservice/MediaPlayerService.cpp
index af8d1b5..5b061b1 100644
--- a/media/libmediaplayerservice/MediaPlayerService.cpp
+++ b/media/libmediaplayerservice/MediaPlayerService.cpp
@@ -1432,6 +1432,12 @@ float MediaPlayerService::AudioOutput::msecsPerFrame() const
return mMsecsPerFrame;
}
+status_t MediaPlayerService::AudioOutput::getPosition(uint32_t *position)
+{
+ if (mTrack == 0) return NO_INIT;
+ return mTrack->getPosition(position);
+}
+
status_t MediaPlayerService::AudioOutput::open(
uint32_t sampleRate, int channelCount, int format, int bufferCount,
AudioCallback cb, void *cookie)
@@ -1613,6 +1619,13 @@ float MediaPlayerService::AudioCache::msecsPerFrame() const
return mMsecsPerFrame;
}
+status_t MediaPlayerService::AudioCache::getPosition(uint32_t *position)
+{
+ if (position == 0) return BAD_VALUE;
+ *position = mSize;
+ return NO_ERROR;
+}
+
status_t MediaPlayerService::AudioCache::open(
uint32_t sampleRate, int channelCount, int format, int bufferCount,
AudioCallback cb, void *cookie)
diff --git a/media/libmediaplayerservice/MediaPlayerService.h b/media/libmediaplayerservice/MediaPlayerService.h
index d1206b4..d243b96 100644
--- a/media/libmediaplayerservice/MediaPlayerService.h
+++ b/media/libmediaplayerservice/MediaPlayerService.h
@@ -76,6 +76,7 @@ class MediaPlayerService : public BnMediaPlayerService
virtual ssize_t frameSize() const;
virtual uint32_t latency() const;
virtual float msecsPerFrame() const;
+ virtual status_t getPosition(uint32_t *position);
virtual status_t open(
uint32_t sampleRate, int channelCount,
@@ -130,6 +131,7 @@ class MediaPlayerService : public BnMediaPlayerService
virtual ssize_t frameSize() const { return ssize_t(mChannelCount * ((mFormat == AudioSystem::PCM_16_BIT)?sizeof(int16_t):sizeof(u_int8_t))); }
virtual uint32_t latency() const;
virtual float msecsPerFrame() const;
+ virtual status_t getPosition(uint32_t *position);
virtual status_t open(
uint32_t sampleRate, int channelCount, int format,