Merge "Fix the last warnings in frameworks/av/ drm code." into nyc-dev
diff --git a/include/media/AudioTimestamp.h b/include/media/AudioTimestamp.h
index e6ca225..531b548 100644
--- a/include/media/AudioTimestamp.h
+++ b/include/media/AudioTimestamp.h
@@ -79,7 +79,7 @@
// Returns the best timestamp as judged from the closest-to-hw stage in the
// pipeline with a valid timestamp.
- int getBestTimestamp(int64_t *position, int64_t *time, int timebase) {
+ status_t getBestTimestamp(int64_t *position, int64_t *time, int timebase) const {
if (position == nullptr || time == nullptr
|| timebase < 0 || timebase >= TIMEBASE_MAX) {
return BAD_VALUE;
@@ -97,6 +97,20 @@
return INVALID_OPERATION;
}
+ status_t getBestTimestamp(AudioTimestamp *timestamp) const {
+ if (timestamp == nullptr) {
+ return BAD_VALUE;
+ }
+ int64_t position, time;
+ if (getBestTimestamp(&position, &time, TIMEBASE_MONOTONIC) == OK) {
+ timestamp->mPosition = position;
+ timestamp->mTime.tv_sec = time / 1000000000;
+ timestamp->mTime.tv_nsec = time - timestamp->mTime.tv_sec * 1000000000LL;
+ return OK;
+ }
+ return INVALID_OPERATION;
+ }
+
// convert fields to a printable string
std::string toString() {
std::stringstream ss;
diff --git a/include/private/media/AudioTrackShared.h b/include/private/media/AudioTrackShared.h
index 2270c85..aa9e98c 100644
--- a/include/private/media/AudioTrackShared.h
+++ b/include/private/media/AudioTrackShared.h
@@ -315,6 +315,19 @@
// See documentation for AudioTrack.setBufferSizeInFrames()
size_t setBufferSizeInFrames(size_t requestedSize);
+ status_t getTimestamp(ExtendedTimestamp *timestamp) {
+ if (timestamp == nullptr) {
+ return BAD_VALUE;
+ }
+ (void) mTimestampObserver.poll(mTimestamp);
+ *timestamp = mTimestamp;
+ return OK;
+ }
+
+ void clearTimestamp() {
+ mTimestamp.clear();
+ }
+
protected:
// This is set by AudioTrack.setBufferSizeInFrames().
// A write will not fill the buffer above this limit.
@@ -322,6 +335,12 @@
private:
Modulo<uint32_t> mEpoch;
+
+ // The shared buffer contents referred to by the timestamp observer
+ // is initialized when the server proxy created. A local zero timestamp
+ // is initialized by the client constructor.
+ ExtendedTimestampQueue::Observer mTimestampObserver;
+ ExtendedTimestamp mTimestamp; // initialized by constructor
};
// ----------------------------------------------------------------------------
@@ -333,7 +352,9 @@
size_t frameSize, bool clientInServer = false)
: ClientProxy(cblk, buffers, frameCount, frameSize, true /*isOut*/,
clientInServer),
- mPlaybackRateMutator(&cblk->mPlaybackRateQueue) { }
+ mPlaybackRateMutator(&cblk->mPlaybackRateQueue) {
+ }
+
virtual ~AudioTrackClientProxy() { }
// No barriers on the following operations, so the ordering of loads/stores
@@ -431,23 +452,9 @@
AudioRecordClientProxy(audio_track_cblk_t* cblk, void *buffers, size_t frameCount,
size_t frameSize)
: ClientProxy(cblk, buffers, frameCount, frameSize,
- false /*isOut*/, false /*clientInServer*/)
- , mTimestampObserver(&cblk->mExtendedTimestampQueue) { }
+ false /*isOut*/, false /*clientInServer*/) { }
~AudioRecordClientProxy() { }
- status_t getTimestamp(ExtendedTimestamp *timestamp) {
- if (timestamp == nullptr) {
- return BAD_VALUE;
- }
- (void) mTimestampObserver.poll(mTimestamp);
- *timestamp = mTimestamp;
- return OK;
- }
-
- void clearTimestamp() {
- mTimestamp.clear();
- }
-
// Advances the client read pointer to the server write head pointer
// effectively flushing the client read buffer. The effect is
// instantaneous. Returns the number of frames flushed.
@@ -457,13 +464,6 @@
android_atomic_release_store(rear, &mCblk->u.mStreaming.mFront);
return (Modulo<int32_t>(rear) - front).unsignedValue();
}
-
-private:
- // The shared buffer contents referred to by the timestamp observer
- // is initialized when the server proxy created. A local zero timestamp
- // is initialized by the client constructor.
- ExtendedTimestampQueue::Observer mTimestampObserver;
- ExtendedTimestamp mTimestamp; // initialized by constructor
};
// ----------------------------------------------------------------------------
@@ -509,10 +509,20 @@
// buffer->mRaw is NULL.
virtual void releaseBuffer(Buffer* buffer);
+ // Return the total number of frames that AudioFlinger has obtained and released
+ virtual int64_t framesReleased() const { return mReleased; }
+
+ // Expose timestamp to client proxy. Should only be called by a single thread.
+ virtual void setTimestamp(const ExtendedTimestamp ×tamp) {
+ mTimestampMutator.push(timestamp);
+ }
+
protected:
size_t mAvailToClient; // estimated frames available to client prior to releaseBuffer()
int32_t mFlush; // our copy of cblk->u.mStreaming.mFlush, for streaming output only
int64_t mReleased; // our copy of cblk->mServer, at 64 bit resolution
+
+ ExtendedTimestampQueue::Mutator mTimestampMutator;
};
// Proxy used by AudioFlinger for servicing AudioTrack
@@ -556,9 +566,6 @@
// and thus which resulted in an underrun.
virtual uint32_t getUnderrunFrames() const { return mCblk->u.mStreaming.mUnderrunFrames; }
- // Return the total number of frames that AudioFlinger has obtained and released
- virtual size_t framesReleased() const { return mReleased; }
-
// Return the playback speed and pitch read atomically. Not multi-thread safe on server side.
AudioPlaybackRate getPlaybackRate();
@@ -611,20 +618,10 @@
public:
AudioRecordServerProxy(audio_track_cblk_t* cblk, void *buffers, size_t frameCount,
size_t frameSize, bool clientInServer)
- : ServerProxy(cblk, buffers, frameCount, frameSize, false /*isOut*/, clientInServer)
- , mTimestampMutator(&cblk->mExtendedTimestampQueue) { }
+ : ServerProxy(cblk, buffers, frameCount, frameSize, false /*isOut*/, clientInServer) { }
- // Return the total number of frames that AudioFlinger has obtained and released
- virtual int64_t framesReleased() const { return mReleased; }
-
- // Expose timestamp to client proxy. Should only be called by a single thread.
- virtual void setExtendedTimestamp(const ExtendedTimestamp ×tamp) {
- mTimestampMutator.push(timestamp);
- }
protected:
virtual ~AudioRecordServerProxy() { }
-
- ExtendedTimestampQueue::Mutator mTimestampMutator;
};
// ----------------------------------------------------------------------------
diff --git a/media/libmedia/AudioTrack.cpp b/media/libmedia/AudioTrack.cpp
index b2a5f14..33dcc57 100644
--- a/media/libmedia/AudioTrack.cpp
+++ b/media/libmedia/AudioTrack.cpp
@@ -528,12 +528,14 @@
mTimestampStartupGlitchReported = false;
mRetrogradeMotionReported = false;
- // If previousState == STATE_STOPPED, we reactivate markers (mMarkerPosition != 0)
+ // If previousState == STATE_STOPPED, we clear the timestamp so that it
+ // needs a new server push. We also reactivate markers (mMarkerPosition != 0)
// as the position is reset to 0. This is legacy behavior. This is not done
// in stop() to avoid a race condition where the last marker event is issued twice.
// Note: the if is technically unnecessary because previousState == STATE_FLUSHED
// is only for streaming tracks, and mMarkerReached is already set to false.
if (previousState == STATE_STOPPED) {
+ mProxy->clearTimestamp(); // need new server push for valid timestamp
mMarkerReached = false;
}
@@ -2169,11 +2171,6 @@
// Set false here to cover all the error return cases.
mPreviousTimestampValid = false;
- // FIXME not implemented for fast tracks; should use proxy and SSQ
- if (mFlags & AUDIO_OUTPUT_FLAG_FAST) {
- return INVALID_OPERATION;
- }
-
switch (mState) {
case STATE_ACTIVE:
case STATE_PAUSED:
@@ -2203,7 +2200,22 @@
// The presented frame count must always lag behind the consumed frame count.
// To avoid a race, read the presented frames first. This ensures that presented <= consumed.
- status_t status = mAudioTrack->getTimestamp(timestamp);
+
+ status_t status;
+ if (!(mFlags & AUDIO_OUTPUT_FLAG_FAST)) {
+ // use Binder to get timestamp
+ status = mAudioTrack->getTimestamp(timestamp);
+ } else {
+ // read timestamp from shared memory
+ ExtendedTimestamp ets;
+ status = mProxy->getTimestamp(&ets);
+ if (status == OK) {
+ status = ets.getBestTimestamp(×tamp);
+ }
+ if (status == INVALID_OPERATION) {
+ status = WOULD_BLOCK;
+ }
+ }
if (status != NO_ERROR) {
ALOGV_IF(status != WOULD_BLOCK, "getTimestamp error:%#x", status);
return status;
diff --git a/media/libmedia/AudioTrackShared.cpp b/media/libmedia/AudioTrackShared.cpp
index 988386e..1d15495 100644
--- a/media/libmedia/AudioTrackShared.cpp
+++ b/media/libmedia/AudioTrackShared.cpp
@@ -69,6 +69,7 @@
: Proxy(cblk, buffers, frameCount, frameSize, isOut, clientInServer)
, mBufferSizeInFrames(frameCount)
, mEpoch(0)
+ , mTimestampObserver(&cblk->mExtendedTimestampQueue)
{
}
@@ -598,6 +599,7 @@
size_t frameSize, bool isOut, bool clientInServer)
: Proxy(cblk, buffers, frameCount, frameSize, isOut, clientInServer),
mAvailToClient(0), mFlush(0), mReleased(0)
+ , mTimestampMutator(&cblk->mExtendedTimestampQueue)
{
}
diff --git a/media/libmedia/IOMX.cpp b/media/libmedia/IOMX.cpp
index d1832b6..bd398aa 100644
--- a/media/libmedia/IOMX.cpp
+++ b/media/libmedia/IOMX.cpp
@@ -447,7 +447,7 @@
remote()->transact(CONFIGURE_VIDEO_TUNNEL_MODE, data, &reply);
status_t err = reply.readInt32();
- if (sidebandHandle) {
+ if (err == OK && sidebandHandle) {
*sidebandHandle = (native_handle_t *)reply.readNativeHandle();
}
return err;
@@ -990,7 +990,9 @@
status_t err = configureVideoTunnelMode(
node, port_index, tunneled, audio_hw_sync, &sideband_handle);
reply->writeInt32(err);
- reply->writeNativeHandle(sideband_handle);
+ if(err == OK){
+ reply->writeNativeHandle(sideband_handle);
+ }
return NO_ERROR;
}
diff --git a/services/audioflinger/Android.mk b/services/audioflinger/Android.mk
index 6e3eb83..302e4dc 100644
--- a/services/audioflinger/Android.mk
+++ b/services/audioflinger/Android.mk
@@ -127,6 +127,9 @@
LOCAL_MODULE := libaudioresampler
+# uncomment to disable NEON on architectures that actually do support NEON, for benchmarking
+#LOCAL_CFLAGS += -DUSE_NEON=false
+
include $(BUILD_SHARED_LIBRARY)
include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/services/audioflinger/AudioResamplerFirOps.h b/services/audioflinger/AudioResamplerFirOps.h
index 658285d..2a26496 100644
--- a/services/audioflinger/AudioResamplerFirOps.h
+++ b/services/audioflinger/AudioResamplerFirOps.h
@@ -26,11 +26,15 @@
#endif
#if defined(__aarch64__) || defined(__ARM_NEON__)
+#ifndef USE_NEON
#define USE_NEON (true)
-#include <arm_neon.h>
+#endif
#else
#define USE_NEON (false)
#endif
+#if USE_NEON
+#include <arm_neon.h>
+#endif
template<typename T, typename U>
struct is_same
diff --git a/services/audioflinger/AudioResamplerSinc.cpp b/services/audioflinger/AudioResamplerSinc.cpp
index e93c064..f600d6c 100644
--- a/services/audioflinger/AudioResamplerSinc.cpp
+++ b/services/audioflinger/AudioResamplerSinc.cpp
@@ -43,10 +43,14 @@
#endif
#if defined(__aarch64__) || defined(__ARM_NEON__)
-#include <arm_neon.h>
-#define USE_NEON
+#ifndef USE_NEON
+#define USE_NEON (true)
+#endif
#else
-#undef USE_NEON
+#define USE_NEON (false)
+#endif
+#if USE_NEON
+#include <arm_neon.h>
#endif
#define UNUSED(x) ((void)(x))
@@ -417,7 +421,7 @@
size_t count = offset;
-#ifndef USE_NEON
+#if !USE_NEON
int32_t l = 0;
int32_t r = 0;
for (size_t i=0 ; i<count ; i++) {
diff --git a/services/audioflinger/PlaybackTracks.h b/services/audioflinger/PlaybackTracks.h
index c81bbf9..fe3cc53 100644
--- a/services/audioflinger/PlaybackTracks.h
+++ b/services/audioflinger/PlaybackTracks.h
@@ -89,6 +89,7 @@
// ExtendedAudioBufferProvider interface
virtual size_t framesReady() const;
virtual size_t framesReleased() const;
+ virtual void onTimestamp(const AudioTimestamp ×tamp);
bool isPausing() const { return mState == PAUSING; }
bool isPaused() const { return mState == PAUSED; }
diff --git a/services/audioflinger/RecordTracks.h b/services/audioflinger/RecordTracks.h
index 5f70479..6f84af1 100644
--- a/services/audioflinger/RecordTracks.h
+++ b/services/audioflinger/RecordTracks.h
@@ -76,8 +76,6 @@
// be dropped and therefore not read by the application.
sp<SyncEvent> mSyncStartEvent;
- AudioRecordServerProxy *mAudioRecordServerProxy;
-
// number of captured frames to drop after the start sync event has been received.
// when < 0, maximum frames to drop before starting capture even if sync event is
// not received
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index 5aff394..4807400 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -6157,7 +6157,7 @@
// update frame information and push timestamp out
activeTrack->updateTrackFrameInfo(
- activeTrack->mAudioRecordServerProxy->framesReleased(),
+ activeTrack->mServerProxy->framesReleased(),
mTimestamp.mPosition[ExtendedTimestamp::LOCATION_SERVER],
mSampleRate, mTimestamp);
}
diff --git a/services/audioflinger/Tracks.cpp b/services/audioflinger/Tracks.cpp
index b719046..536581c 100644
--- a/services/audioflinger/Tracks.cpp
+++ b/services/audioflinger/Tracks.cpp
@@ -596,6 +596,20 @@
return mAudioTrackServerProxy->framesReleased();
}
+void AudioFlinger::PlaybackThread::Track::onTimestamp(const AudioTimestamp ×tamp)
+{
+ // This call comes from a FastTrack and should be kept lockless.
+ // The server side frames are already translated to client frames.
+
+ ExtendedTimestamp ets;
+ ets.mTimeNs[ExtendedTimestamp::LOCATION_KERNEL] =
+ timestamp.mTime.tv_sec * 1000000000LL + timestamp.mTime.tv_nsec;
+ ets.mPosition[ExtendedTimestamp::LOCATION_KERNEL] = timestamp.mPosition;
+
+ // Caution, this doesn't set the timebase for BOOTTIME properly, but is ignored right now.
+ mAudioTrackServerProxy->setTimestamp(ets);
+}
+
// Don't call for fast tracks; the framesReady() could result in priority inversion
bool AudioFlinger::PlaybackThread::Track::isReady() const {
if (mFillingUpStatus != FS_FILLING || isStopped() || isPausing()) {
@@ -1438,9 +1452,8 @@
return;
}
- mAudioRecordServerProxy = new AudioRecordServerProxy(mCblk, mBuffer, frameCount,
+ mServerProxy = new AudioRecordServerProxy(mCblk, mBuffer, frameCount,
mFrameSize, !isExternalTrack());
- mServerProxy = mAudioRecordServerProxy;
mResamplerBufferProvider = new ResamplerBufferProvider(this);
@@ -1594,7 +1607,7 @@
local.mPosition[i] = relativeTrackFrames + trackFramesReleased;
}
}
- mAudioRecordServerProxy->setExtendedTimestamp(local);
+ mServerProxy->setTimestamp(local);
}
AudioFlinger::RecordThread::PatchRecord::PatchRecord(RecordThread *recordThread,
diff --git a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
index c7486a5..fdd6dd2 100644
--- a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
+++ b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
@@ -482,6 +482,7 @@
if (mAudioPolicyManager == NULL) {
return NO_INIT;
}
+ Mutex::Autolock _l(mEffectsLock);
return mAudioPolicyManager->registerEffect(desc, io, strategy, session, id);
}
@@ -490,6 +491,7 @@
if (mAudioPolicyManager == NULL) {
return NO_INIT;
}
+ Mutex::Autolock _l(mEffectsLock);
return mAudioPolicyManager->unregisterEffect(id);
}
@@ -498,6 +500,7 @@
if (mAudioPolicyManager == NULL) {
return NO_INIT;
}
+ Mutex::Autolock _l(mEffectsLock);
return mAudioPolicyManager->setEffectEnabled(id, enabled);
}
@@ -561,6 +564,8 @@
return false;
}
Mutex::Autolock _l(mLock);
+ Mutex::Autolock _le(mEffectsLock); // isOffloadSupported queries for
+ // non-offloadable effects
return mAudioPolicyManager->isOffloadSupported(info);
}
diff --git a/services/audiopolicy/service/AudioPolicyService.h b/services/audiopolicy/service/AudioPolicyService.h
index 160f4f0..a91c560 100644
--- a/services/audiopolicy/service/AudioPolicyService.h
+++ b/services/audiopolicy/service/AudioPolicyService.h
@@ -553,6 +553,10 @@
mutable Mutex mLock; // prevents concurrent access to AudioPolicy manager functions changing
// device connection state or routing
+ mutable Mutex mEffectsLock; // serialize access to Effect state within APM.
+ // Note: lock acquisition order is always mLock > mEffectsLock:
+ // mLock protects AudioPolicyManager methods that can call into audio flinger
+ // and possibly back in to audio policy service and acquire mEffectsLock.
sp<AudioCommandThread> mAudioCommandThread; // audio commands thread
sp<AudioCommandThread> mTonePlaybackThread; // tone playback thread
sp<AudioCommandThread> mOutputCommandThread; // process stop and release output
diff --git a/services/soundtrigger/SoundTriggerHwService.cpp b/services/soundtrigger/SoundTriggerHwService.cpp
index c891fd6..66310b5 100644
--- a/services/soundtrigger/SoundTriggerHwService.cpp
+++ b/services/soundtrigger/SoundTriggerHwService.cpp
@@ -544,19 +544,39 @@
AutoMutex lock(mLock);
if (mModels.size() >= mDescriptor.properties.max_sound_models) {
+ /* Make space for a keyphrase sound model by first trying to swap out a previously loaded
+ * keyphrase sound model, or if needed, another sound model. This decision would optimally
+ * happen in SoundTriggerHelper, but is happening here because state tracking isn't good
+ * enough in SoundTriggerHelper to ensure that state is consistent between it and the HAL,
+ * nor does sufficient error handling exist to recover from inconsistencies.
+ * Once that exists:
+ * TODO: we should return an error instead of unloading a previous sound model here.
+ */
if (mModels.size() == 0) {
return INVALID_OPERATION;
}
- ALOGW("loadSoundModel() max number of models exceeded %d making room for a new one",
- mDescriptor.properties.max_sound_models);
- unloadSoundModel_l(mModels.valueAt(0)->mHandle);
+ if (sound_model->type == SOUND_MODEL_TYPE_KEYPHRASE) {
+ ALOGW("loadSoundModel() max number of models exceeded %d making room for a new one",
+ mDescriptor.properties.max_sound_models);
+ sound_model_handle_t unload_handle = mModels.valueAt(0)->mHandle;
+ for (size_t i = 0; i < mModels.size(); i++) {
+ if (mModels.valueAt(i)->mType == SOUND_MODEL_TYPE_KEYPHRASE) {
+ unload_handle = mModels.keyAt(i);
+ break;
+ }
+ }
+ unloadSoundModel_l(unload_handle);
+ } else {
+ ALOGW("loadSoundModel(): Not loading, max number of models (%d) would be exceeded",
+ mDescriptor.properties.max_sound_models);
+ return INVALID_OPERATION;
+ }
}
- status_t status = mHwDevice->load_sound_model(mHwDevice,
- sound_model,
+ status_t status = mHwDevice->load_sound_model(mHwDevice, sound_model,
SoundTriggerHwService::soundModelCallback,
- this,
- handle);
+ this, handle);
+
if (status != NO_ERROR) {
return status;
}