summaryrefslogtreecommitdiffstats
path: root/media/libmedia
diff options
context:
space:
mode:
Diffstat (limited to 'media/libmedia')
-rw-r--r--media/libmedia/AudioRecord.cpp2
-rw-r--r--media/libmedia/AudioTrack.cpp59
-rw-r--r--media/libmedia/IDrm.cpp60
3 files changed, 95 insertions, 26 deletions
diff --git a/media/libmedia/AudioRecord.cpp b/media/libmedia/AudioRecord.cpp
index 666fafa..ccbc5a3 100644
--- a/media/libmedia/AudioRecord.cpp
+++ b/media/libmedia/AudioRecord.cpp
@@ -545,13 +545,13 @@ status_t AudioRecord::obtainBuffer(Buffer* audioBuffer, int32_t waitCount)
}
const struct timespec *requested;
+ struct timespec timeout;
if (waitCount == -1) {
requested = &ClientProxy::kForever;
} else if (waitCount == 0) {
requested = &ClientProxy::kNonBlocking;
} else if (waitCount > 0) {
long long ms = WAIT_PERIOD_MS * (long long) waitCount;
- struct timespec timeout;
timeout.tv_sec = ms / 1000;
timeout.tv_nsec = (int) (ms % 1000) * 1000000;
requested = &timeout;
diff --git a/media/libmedia/AudioTrack.cpp b/media/libmedia/AudioTrack.cpp
index a9d6993..3f3a88c 100644
--- a/media/libmedia/AudioTrack.cpp
+++ b/media/libmedia/AudioTrack.cpp
@@ -85,7 +85,8 @@ AudioTrack::AudioTrack()
: mStatus(NO_INIT),
mIsTimed(false),
mPreviousPriority(ANDROID_PRIORITY_NORMAL),
- mPreviousSchedulingGroup(SP_DEFAULT)
+ mPreviousSchedulingGroup(SP_DEFAULT),
+ mPausedPosition(0)
{
}
@@ -106,7 +107,8 @@ AudioTrack::AudioTrack(
: mStatus(NO_INIT),
mIsTimed(false),
mPreviousPriority(ANDROID_PRIORITY_NORMAL),
- mPreviousSchedulingGroup(SP_DEFAULT)
+ mPreviousSchedulingGroup(SP_DEFAULT),
+ mPausedPosition(0)
{
mStatus = set(streamType, sampleRate, format, channelMask,
frameCount, flags, cbf, user, notificationFrames,
@@ -131,7 +133,8 @@ AudioTrack::AudioTrack(
: mStatus(NO_INIT),
mIsTimed(false),
mPreviousPriority(ANDROID_PRIORITY_NORMAL),
- mPreviousSchedulingGroup(SP_DEFAULT)
+ mPreviousSchedulingGroup(SP_DEFAULT),
+ mPausedPosition(0)
{
mStatus = set(streamType, sampleRate, format, channelMask,
0 /*frameCount*/, flags, cbf, user, notificationFrames,
@@ -529,6 +532,16 @@ void AudioTrack::pause()
}
mProxy->interrupt();
mAudioTrack->pause();
+
+ if (isOffloaded()) {
+ if (mOutput != 0) {
+ uint32_t halFrames;
+ // OffloadThread sends HAL pause in its threadLoop.. time saved
+ // here can be slightly off
+ AudioSystem::getRenderPosition(mOutput, &halFrames, &mPausedPosition);
+ ALOGV("AudioTrack::pause for offload, cache current position %u", mPausedPosition);
+ }
+ }
}
status_t AudioTrack::setVolume(float left, float right)
@@ -747,6 +760,12 @@ status_t AudioTrack::getPosition(uint32_t *position) const
if (isOffloaded()) {
uint32_t dspFrames = 0;
+ if ((mState == STATE_PAUSED) || (mState == STATE_PAUSED_STOPPING)) {
+ ALOGV("getPosition called in paused state, return cached position %u", mPausedPosition);
+ *position = mPausedPosition;
+ return NO_ERROR;
+ }
+
if (mOutput != 0) {
uint32_t halFrames;
AudioSystem::getRenderPosition(mOutput, &halFrames, &dspFrames);
@@ -1113,13 +1132,13 @@ status_t AudioTrack::obtainBuffer(Buffer* audioBuffer, int32_t waitCount)
}
const struct timespec *requested;
+ struct timespec timeout;
if (waitCount == -1) {
requested = &ClientProxy::kForever;
} else if (waitCount == 0) {
requested = &ClientProxy::kNonBlocking;
} else if (waitCount > 0) {
long long ms = WAIT_PERIOD_MS * (long long) waitCount;
- struct timespec timeout;
timeout.tv_sec = ms / 1000;
timeout.tv_nsec = (int) (ms % 1000) * 1000000;
requested = &timeout;
@@ -1451,6 +1470,7 @@ nsecs_t AudioTrack::processAudioBuffer(const sp<AudioTrackThread>& thread)
}
size_t misalignment = mProxy->getMisalignment();
uint32_t sequence = mSequence;
+ sp<AudioTrackClientProxy> proxy = mProxy;
// These fields don't need to be cached, because they are assigned only by set():
// mTransfer, mCbf, mUserData, mFormat, mFrameSize, mFrameSizeAF, mFlags
@@ -1459,35 +1479,32 @@ nsecs_t AudioTrack::processAudioBuffer(const sp<AudioTrackThread>& thread)
mLock.unlock();
if (waitStreamEnd) {
- AutoMutex lock(mLock);
-
- sp<AudioTrackClientProxy> proxy = mProxy;
- sp<IMemory> iMem = mCblkMemory;
-
struct timespec timeout;
timeout.tv_sec = WAIT_STREAM_END_TIMEOUT_SEC;
timeout.tv_nsec = 0;
- mLock.unlock();
- status_t status = mProxy->waitStreamEndDone(&timeout);
- mLock.lock();
+ status_t status = proxy->waitStreamEndDone(&timeout);
switch (status) {
case NO_ERROR:
case DEAD_OBJECT:
case TIMED_OUT:
- mLock.unlock();
mCbf(EVENT_STREAM_END, mUserData, NULL);
- mLock.lock();
- if (mState == STATE_STOPPING) {
- mState = STATE_STOPPED;
- if (status != DEAD_OBJECT) {
- return NS_INACTIVE;
+ {
+ AutoMutex lock(mLock);
+ // The previously assigned value of waitStreamEnd is no longer valid,
+ // since the mutex has been unlocked and either the callback handler
+ // or another thread could have re-started the AudioTrack during that time.
+ waitStreamEnd = mState == STATE_STOPPING;
+ if (waitStreamEnd) {
+ mState = STATE_STOPPED;
}
}
- return 0;
- default:
- return 0;
+ if (waitStreamEnd && status != DEAD_OBJECT) {
+ return NS_INACTIVE;
+ }
+ break;
}
+ return 0;
}
// perform callbacks while unlocked
diff --git a/media/libmedia/IDrm.cpp b/media/libmedia/IDrm.cpp
index f7a9a75..f1a6a9f 100644
--- a/media/libmedia/IDrm.cpp
+++ b/media/libmedia/IDrm.cpp
@@ -51,6 +51,7 @@ enum {
ENCRYPT,
DECRYPT,
SIGN,
+ SIGN_RSA,
VERIFY,
SET_LISTENER
};
@@ -196,11 +197,15 @@ struct BpDrm : public BpInterface<IDrm> {
return reply.readInt32();
}
- virtual status_t getProvisionRequest(Vector<uint8_t> &request,
+ virtual status_t getProvisionRequest(String8 const &certType,
+ String8 const &certAuthority,
+ Vector<uint8_t> &request,
String8 &defaultUrl) {
Parcel data, reply;
data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
+ data.writeString8(certType);
+ data.writeString8(certAuthority);
remote()->transact(GET_PROVISION_REQUEST, data, &reply);
readVector(reply, request);
@@ -209,13 +214,18 @@ struct BpDrm : public BpInterface<IDrm> {
return reply.readInt32();
}
- virtual status_t provideProvisionResponse(Vector<uint8_t> const &response) {
+ virtual status_t provideProvisionResponse(Vector<uint8_t> const &response,
+ Vector<uint8_t> &certificate,
+ Vector<uint8_t> &wrappedKey) {
Parcel data, reply;
data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
writeVector(data, response);
remote()->transact(PROVIDE_PROVISION_RESPONSE, data, &reply);
+ readVector(reply, certificate);
+ readVector(reply, wrappedKey);
+
return reply.readInt32();
}
@@ -386,6 +396,25 @@ struct BpDrm : public BpInterface<IDrm> {
return reply.readInt32();
}
+ virtual status_t signRSA(Vector<uint8_t> const &sessionId,
+ String8 const &algorithm,
+ Vector<uint8_t> const &message,
+ Vector<uint8_t> const &wrappedKey,
+ Vector<uint8_t> &signature) {
+ Parcel data, reply;
+ data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
+
+ writeVector(data, sessionId);
+ data.writeString8(algorithm);
+ writeVector(data, message);
+ writeVector(data, wrappedKey);
+
+ remote()->transact(SIGN_RSA, data, &reply);
+ readVector(reply, signature);
+
+ return reply.readInt32();
+ }
+
virtual status_t setListener(const sp<IDrmClient>& listener) {
Parcel data, reply;
data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
@@ -563,9 +592,13 @@ status_t BnDrm::onTransact(
case GET_PROVISION_REQUEST:
{
CHECK_INTERFACE(IDrm, data, reply);
+ String8 certType = data.readString8();
+ String8 certAuthority = data.readString8();
+
Vector<uint8_t> request;
String8 defaultUrl;
- status_t result = getProvisionRequest(request, defaultUrl);
+ status_t result = getProvisionRequest(certType, certAuthority,
+ request, defaultUrl);
writeVector(reply, request);
reply->writeString8(defaultUrl);
reply->writeInt32(result);
@@ -576,8 +609,13 @@ status_t BnDrm::onTransact(
{
CHECK_INTERFACE(IDrm, data, reply);
Vector<uint8_t> response;
+ Vector<uint8_t> certificate;
+ Vector<uint8_t> wrappedKey;
readVector(data, response);
- reply->writeInt32(provideProvisionResponse(response));
+ status_t result = provideProvisionResponse(response, certificate, wrappedKey);
+ writeVector(reply, certificate);
+ writeVector(reply, wrappedKey);
+ reply->writeInt32(result);
return OK;
}
@@ -725,6 +763,20 @@ status_t BnDrm::onTransact(
return OK;
}
+ case SIGN_RSA:
+ {
+ CHECK_INTERFACE(IDrm, data, reply);
+ Vector<uint8_t> sessionId, message, wrappedKey, signature;
+ readVector(data, sessionId);
+ String8 algorithm = data.readString8();
+ readVector(data, message);
+ readVector(data, wrappedKey);
+ uint32_t result = signRSA(sessionId, algorithm, message, wrappedKey, signature);
+ writeVector(reply, signature);
+ reply->writeInt32(result);
+ return OK;
+ }
+
case SET_LISTENER: {
CHECK_INTERFACE(IDrm, data, reply);
sp<IDrmClient> listener =