summaryrefslogtreecommitdiffstats
path: root/media/libmedia/AudioTrack.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'media/libmedia/AudioTrack.cpp')
-rw-r--r--media/libmedia/AudioTrack.cpp59
1 files changed, 45 insertions, 14 deletions
diff --git a/media/libmedia/AudioTrack.cpp b/media/libmedia/AudioTrack.cpp
index fe5cd9e..a9d6993 100644
--- a/media/libmedia/AudioTrack.cpp
+++ b/media/libmedia/AudioTrack.cpp
@@ -101,7 +101,8 @@ AudioTrack::AudioTrack(
int notificationFrames,
int sessionId,
transfer_type transferType,
- const audio_offload_info_t *offloadInfo)
+ const audio_offload_info_t *offloadInfo,
+ int uid)
: mStatus(NO_INIT),
mIsTimed(false),
mPreviousPriority(ANDROID_PRIORITY_NORMAL),
@@ -109,7 +110,8 @@ AudioTrack::AudioTrack(
{
mStatus = set(streamType, sampleRate, format, channelMask,
frameCount, flags, cbf, user, notificationFrames,
- 0 /*sharedBuffer*/, false /*threadCanCallJava*/, sessionId, transferType, offloadInfo);
+ 0 /*sharedBuffer*/, false /*threadCanCallJava*/, sessionId, transferType,
+ offloadInfo, uid);
}
AudioTrack::AudioTrack(
@@ -124,7 +126,8 @@ AudioTrack::AudioTrack(
int notificationFrames,
int sessionId,
transfer_type transferType,
- const audio_offload_info_t *offloadInfo)
+ const audio_offload_info_t *offloadInfo,
+ int uid)
: mStatus(NO_INIT),
mIsTimed(false),
mPreviousPriority(ANDROID_PRIORITY_NORMAL),
@@ -132,7 +135,7 @@ AudioTrack::AudioTrack(
{
mStatus = set(streamType, sampleRate, format, channelMask,
0 /*frameCount*/, flags, cbf, user, notificationFrames,
- sharedBuffer, false /*threadCanCallJava*/, sessionId, transferType, offloadInfo);
+ sharedBuffer, false /*threadCanCallJava*/, sessionId, transferType, offloadInfo, uid);
}
AudioTrack::~AudioTrack()
@@ -169,7 +172,8 @@ status_t AudioTrack::set(
bool threadCanCallJava,
int sessionId,
transfer_type transferType,
- const audio_offload_info_t *offloadInfo)
+ const audio_offload_info_t *offloadInfo,
+ int uid)
{
switch (transferType) {
case TRANSFER_DEFAULT:
@@ -313,6 +317,11 @@ status_t AudioTrack::set(
mNotificationFramesReq = notificationFrames;
mNotificationFramesAct = 0;
mSessionId = sessionId;
+ if (uid == -1 || (IPCThreadState::self()->getCallingPid() != getpid())) {
+ mClientUid = IPCThreadState::self()->getCallingUid();
+ } else {
+ mClientUid = uid;
+ }
mAuxEffectId = 0;
mFlags = flags;
mCbf = cbf;
@@ -594,6 +603,19 @@ uint32_t AudioTrack::getSampleRate() const
}
AutoMutex lock(mLock);
+
+ // sample rate can be updated during playback by the offloaded decoder so we need to
+ // query the HAL and update if needed.
+// FIXME use Proxy return channel to update the rate from server and avoid polling here
+ if (isOffloaded()) {
+ if (mOutput != 0) {
+ uint32_t sampleRate = 0;
+ status_t status = AudioSystem::getSamplingRate(mOutput, mStreamType, &sampleRate);
+ if (status == NO_ERROR) {
+ mSampleRate = sampleRate;
+ }
+ }
+ }
return mSampleRate;
}
@@ -738,7 +760,7 @@ status_t AudioTrack::getPosition(uint32_t *position) const
return NO_ERROR;
}
-status_t AudioTrack::getBufferPosition(size_t *position)
+status_t AudioTrack::getBufferPosition(uint32_t *position)
{
if (mSharedBuffer == 0 || mIsTimed) {
return INVALID_OPERATION;
@@ -856,8 +878,15 @@ status_t AudioTrack::createTrack_l(
}
ALOGV("createTrack_l() output %d afLatency %d", output, afLatency);
+ if ((flags & AUDIO_OUTPUT_FLAG_FAST) && sampleRate != afSampleRate) {
+ ALOGW("AUDIO_OUTPUT_FLAG_FAST denied by client due to mismatching sample rate (%d vs %d)",
+ sampleRate, afSampleRate);
+ flags = (audio_output_flags_t) (flags & ~AUDIO_OUTPUT_FLAG_FAST);
+ }
+
// The client's AudioTrack buffer is divided into n parts for purpose of wakeup by server, where
- // n = 1 fast track; nBuffering is ignored
+ // n = 1 fast track with single buffering; nBuffering is ignored
+ // n = 2 fast track with double buffering
// n = 2 normal track, no sample rate conversion
// n = 3 normal track, with sample rate conversion
// (pessimistic; some non-1:1 conversion ratios don't actually need triple-buffering)
@@ -886,7 +915,7 @@ status_t AudioTrack::createTrack_l(
// More than 2 channels does not require stronger alignment than stereo
alignment <<= 1;
}
- if (((size_t)sharedBuffer->pointer() & (alignment - 1)) != 0) {
+ if (((uintptr_t)sharedBuffer->pointer() & (alignment - 1)) != 0) {
ALOGE("Invalid buffer alignment: address %p, channel count %u",
sharedBuffer->pointer(), mChannelCount);
return BAD_VALUE;
@@ -962,6 +991,7 @@ status_t AudioTrack::createTrack_l(
tid,
&mSessionId,
mName,
+ mClientUid,
&status);
if (track == 0) {
@@ -996,9 +1026,11 @@ status_t AudioTrack::createTrack_l(
ALOGV("AUDIO_OUTPUT_FLAG_FAST successful; frameCount %u", frameCount);
mAwaitBoost = true;
if (sharedBuffer == 0) {
- // double-buffering is not required for fast tracks, due to tighter scheduling
- if (mNotificationFramesAct == 0 || mNotificationFramesAct > frameCount) {
- mNotificationFramesAct = frameCount;
+ // Theoretically double-buffering is not required for fast tracks,
+ // due to tighter scheduling. But in practice, to accommodate kernels with
+ // scheduling jitter, and apps with computation jitter, we use double-buffering.
+ if (mNotificationFramesAct == 0 || mNotificationFramesAct > frameCount/nBuffering) {
+ mNotificationFramesAct = frameCount/nBuffering;
}
}
} else {
@@ -1212,7 +1244,7 @@ ssize_t AudioTrack::write(const void* buffer, size_t userSize)
if (ssize_t(userSize) < 0 || (buffer == NULL && userSize != 0)) {
// Sanity-check: user is most-likely passing an error code, and it would
// make the return value ambiguous (actualSize vs error).
- ALOGE("AudioTrack::write(buffer=%p, size=%u (%d)", buffer, userSize, userSize);
+ ALOGE("AudioTrack::write(buffer=%p, size=%zu (%zd)", buffer, userSize, userSize);
return BAD_VALUE;
}
@@ -1665,7 +1697,6 @@ status_t AudioTrack::restoreTrack_l(const char *from)
// take the frames that will be lost by track recreation into account in saved position
size_t position = mProxy->getPosition() + mProxy->getFramesFilled();
- mNewPosition = position + mUpdatePeriod;
size_t bufferPosition = mStaticProxy != NULL ? mStaticProxy->getBufferPosition() : 0;
result = createTrack_l(mStreamType,
mSampleRate,
@@ -1756,7 +1787,7 @@ status_t AudioTrack::dump(int fd, const Vector<String16>& args) const
snprintf(buffer, 255, " stream type(%d), left - right volume(%f, %f)\n", mStreamType,
mVolume[0], mVolume[1]);
result.append(buffer);
- snprintf(buffer, 255, " format(%d), channel count(%d), frame count(%d)\n", mFormat,
+ snprintf(buffer, 255, " format(%d), channel count(%d), frame count(%zu)\n", mFormat,
mChannelCount, mFrameCount);
result.append(buffer);
snprintf(buffer, 255, " sample rate(%u), status(%d)\n", mSampleRate, mStatus);