summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGlenn Kasten <gkasten@google.com>2013-08-29 09:01:02 -0700
committerGlenn Kasten <gkasten@google.com>2013-08-29 09:19:07 -0700
commit53cec22821072719ee02c856e9ac2dda2496c570 (patch)
tree1ac72eaf3ba6059680f8c3d7e39ae58a9e03adc8
parentce70374bf105f8a6160bf5dd70affea012b2a464 (diff)
downloadframeworks_av-53cec22821072719ee02c856e9ac2dda2496c570.zip
frameworks_av-53cec22821072719ee02c856e9ac2dda2496c570.tar.gz
frameworks_av-53cec22821072719ee02c856e9ac2dda2496c570.tar.bz2
Add IAudioTrack::getTimestamp()
with dummy implementation in AudioFlinger::TrackHandle, and implement AudioTrack::getTimestamp() using IAudioTrack. Also document invariant that mAudioTrack and control block are always non-0 after successful initialization. Change-Id: I9861d1454cff7decf795d5d5898ac7999a9f3b7e
-rw-r--r--include/media/AudioTrack.h5
-rw-r--r--include/media/IAudioTrack.h4
-rw-r--r--media/libmedia/AudioTrack.cpp17
-rw-r--r--media/libmedia/IAudioTrack.cpp30
-rw-r--r--services/audioflinger/AudioFlinger.h1
-rw-r--r--services/audioflinger/Tracks.cpp5
6 files changed, 49 insertions, 13 deletions
diff --git a/include/media/AudioTrack.h b/include/media/AudioTrack.h
index ebb7ef3..453c106 100644
--- a/include/media/AudioTrack.h
+++ b/include/media/AudioTrack.h
@@ -227,6 +227,7 @@ public:
* - INVALID_OPERATION: AudioTrack is already initialized
* - BAD_VALUE: invalid parameter (channelMask, format, sampleRate...)
* - NO_INIT: audio server or audio hardware not initialized
+ * If status is not equal to NO_ERROR, don't call any other APIs on this AudioTrack.
* If sharedBuffer is non-0, the frameCount parameter is ignored and
* replaced by the shared buffer's total allocated size in frame units.
*
@@ -249,7 +250,7 @@ public:
transfer_type transferType = TRANSFER_DEFAULT,
const audio_offload_info_t *offloadInfo = NULL);
- /* Result of constructing the AudioTrack. This must be checked
+ /* Result of constructing the AudioTrack. This must be checked for successful initialization
* before using any AudioTrack API (except for set()), because using
* an uninitialized AudioTrack produces undefined results.
* See set() method above for possible return codes.
@@ -646,7 +647,7 @@ protected:
bool isOffloaded() const
{ return (mFlags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) != 0; }
- // may be changed if IAudioTrack is re-created
+ // Next 3 fields may be changed if IAudioTrack is re-created, but always != 0
sp<IAudioTrack> mAudioTrack;
sp<IMemory> mCblkMemory;
audio_track_cblk_t* mCblk; // re-load after mLock.unlock()
diff --git a/include/media/IAudioTrack.h b/include/media/IAudioTrack.h
index 1014403..afac4ae 100644
--- a/include/media/IAudioTrack.h
+++ b/include/media/IAudioTrack.h
@@ -26,6 +26,7 @@
#include <binder/IMemory.h>
#include <utils/LinearTransform.h>
#include <utils/String8.h>
+#include <media/AudioTimestamp.h>
namespace android {
@@ -86,6 +87,9 @@ public:
/* Send parameters to the audio hardware */
virtual status_t setParameters(const String8& keyValuePairs) = 0;
+
+ /* Return NO_ERROR if timestamp is valid */
+ virtual status_t getTimestamp(AudioTimestamp& timestamp) = 0;
};
// ----------------------------------------------------------------------------
diff --git a/media/libmedia/AudioTrack.cpp b/media/libmedia/AudioTrack.cpp
index d90e733..78ae37e 100644
--- a/media/libmedia/AudioTrack.cpp
+++ b/media/libmedia/AudioTrack.cpp
@@ -148,10 +148,8 @@ AudioTrack::~AudioTrack()
mAudioTrackThread->requestExitAndWait();
mAudioTrackThread.clear();
}
- if (mAudioTrack != 0) {
- mAudioTrack->asBinder()->unlinkToDeath(mDeathNotifier, this);
- mAudioTrack.clear();
- }
+ mAudioTrack->asBinder()->unlinkToDeath(mDeathNotifier, this);
+ mAudioTrack.clear();
IPCThreadState::self()->flushCommands();
AudioSystem::releaseAudioSessionId(mSessionId);
}
@@ -222,6 +220,7 @@ status_t AudioTrack::set(
AutoMutex lock(mLock);
+ // invariant that mAudioTrack != 0 is true only after set() returns successfully
if (mAudioTrack != 0) {
ALOGE("Track already in use");
return INVALID_OPERATION;
@@ -965,6 +964,7 @@ status_t AudioTrack::createTrack_l(
ALOGE("Could not get control block");
return NO_INIT;
}
+ // invariant that mAudioTrack != 0 is true only after set() returns successfully
if (mAudioTrack != 0) {
mAudioTrack->asBinder()->unlinkToDeath(mDeathNotifier, this);
mDeathNotifier.clear();
@@ -1705,16 +1705,13 @@ status_t AudioTrack::restoreTrack_l(const char *from)
status_t AudioTrack::setParameters(const String8& keyValuePairs)
{
AutoMutex lock(mLock);
- if (mAudioTrack != 0) {
- return mAudioTrack->setParameters(keyValuePairs);
- } else {
- return NO_INIT;
- }
+ return mAudioTrack->setParameters(keyValuePairs);
}
status_t AudioTrack::getTimestamp(AudioTimestamp& timestamp)
{
- return INVALID_OPERATION;
+ AutoMutex lock(mLock);
+ return mAudioTrack->getTimestamp(timestamp);
}
String8 AudioTrack::getParameters(const String8& keys)
diff --git a/media/libmedia/IAudioTrack.cpp b/media/libmedia/IAudioTrack.cpp
index a2b49a3..f0d75ba 100644
--- a/media/libmedia/IAudioTrack.cpp
+++ b/media/libmedia/IAudioTrack.cpp
@@ -39,7 +39,8 @@ enum {
ALLOCATE_TIMED_BUFFER,
QUEUE_TIMED_BUFFER,
SET_MEDIA_TIME_TRANSFORM,
- SET_PARAMETERS
+ SET_PARAMETERS,
+ GET_TIMESTAMP,
};
class BpAudioTrack : public BpInterface<IAudioTrack>
@@ -166,6 +167,21 @@ public:
}
return status;
}
+
+ virtual status_t getTimestamp(AudioTimestamp& timestamp) {
+ Parcel data, reply;
+ data.writeInterfaceToken(IAudioTrack::getInterfaceDescriptor());
+ status_t status = remote()->transact(GET_TIMESTAMP, data, &reply);
+ if (status == NO_ERROR) {
+ status = reply.readInt32();
+ if (status == NO_ERROR) {
+ timestamp.mPosition = reply.readInt32();
+ timestamp.mTime.tv_sec = reply.readInt32();
+ timestamp.mTime.tv_nsec = reply.readInt32();
+ }
+ }
+ return status;
+ }
};
IMPLEMENT_META_INTERFACE(AudioTrack, "android.media.IAudioTrack");
@@ -241,6 +257,18 @@ status_t BnAudioTrack::onTransact(
reply->writeInt32(setParameters(keyValuePairs));
return NO_ERROR;
} break;
+ case GET_TIMESTAMP: {
+ CHECK_INTERFACE(IAudioTrack, data, reply);
+ AudioTimestamp timestamp;
+ status_t status = getTimestamp(timestamp);
+ reply->writeInt32(status);
+ if (status == NO_ERROR) {
+ reply->writeInt32(timestamp.mPosition);
+ reply->writeInt32(timestamp.mTime.tv_sec);
+ reply->writeInt32(timestamp.mTime.tv_nsec);
+ }
+ return NO_ERROR;
+ } break;
default:
return BBinder::onTransact(code, data, reply, flags);
}
diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h
index e5e4113..5df04f4 100644
--- a/services/audioflinger/AudioFlinger.h
+++ b/services/audioflinger/AudioFlinger.h
@@ -411,6 +411,7 @@ private:
virtual status_t setMediaTimeTransform(const LinearTransform& xform,
int target);
virtual status_t setParameters(const String8& keyValuePairs);
+ virtual status_t getTimestamp(AudioTimestamp& timestamp);
virtual status_t onTransact(
uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags);
diff --git a/services/audioflinger/Tracks.cpp b/services/audioflinger/Tracks.cpp
index e676365..d1ab3c8 100644
--- a/services/audioflinger/Tracks.cpp
+++ b/services/audioflinger/Tracks.cpp
@@ -283,6 +283,11 @@ status_t AudioFlinger::TrackHandle::setParameters(const String8& keyValuePairs)
return mTrack->setParameters(keyValuePairs);
}
+status_t AudioFlinger::TrackHandle::getTimestamp(AudioTimestamp& timestamp)
+{
+ return INVALID_OPERATION;
+}
+
status_t AudioFlinger::TrackHandle::onTransact(
uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{