Merge "mediaex: arm: add syscalls for debuggerd attach"
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
index cede584..5c13633 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
@@ -2142,7 +2142,11 @@
mPausedForBuffering = true;
onPause();
}
+ // fall-thru
+ }
+ case Source::kWhatBufferingStart:
+ {
notifyListener(MEDIA_INFO, MEDIA_INFO_BUFFERING_START, 0);
break;
}
@@ -2160,7 +2164,11 @@
onResume();
}
}
+ // fall-thru
+ }
+ case Source::kWhatBufferingEnd:
+ {
notifyListener(MEDIA_INFO, MEDIA_INFO_BUFFERING_END, 0);
break;
}
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerSource.h b/media/libmediaplayerservice/nuplayer/NuPlayerSource.h
index 0176eafa..fba4540 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerSource.h
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerSource.h
@@ -46,6 +46,8 @@
kWhatFlagsChanged,
kWhatVideoSizeChanged,
kWhatBufferingUpdate,
+ kWhatBufferingStart,
+ kWhatBufferingEnd,
kWhatPauseOnBufferingStart,
kWhatResumeOnBufferingEnd,
kWhatCacheStats,
diff --git a/media/libmediaplayerservice/nuplayer/RTSPSource.cpp b/media/libmediaplayerservice/nuplayer/RTSPSource.cpp
index 2ecab6d..c861fd1 100644
--- a/media/libmediaplayerservice/nuplayer/RTSPSource.cpp
+++ b/media/libmediaplayerservice/nuplayer/RTSPSource.cpp
@@ -725,7 +725,7 @@
mBuffering = true;
sp<AMessage> notify = dupNotify();
- notify->setInt32("what", kWhatPauseOnBufferingStart);
+ notify->setInt32("what", kWhatBufferingStart);
notify->post();
}
}
@@ -741,7 +741,7 @@
mBuffering = false;
sp<AMessage> notify = dupNotify();
- notify->setInt32("what", kWhatResumeOnBufferingEnd);
+ notify->setInt32("what", kWhatBufferingEnd);
notify->post();
}
diff --git a/media/libstagefright/OMXCodec.cpp b/media/libstagefright/OMXCodec.cpp
index ee1f927..d1529b4 100644
--- a/media/libstagefright/OMXCodec.cpp
+++ b/media/libstagefright/OMXCodec.cpp
@@ -4330,7 +4330,6 @@
caps->mFlags = 0;
caps->mComponentName = componentName;
- // NOTE: OMX does not provide a way to query AAC profile support
if (isVideo) {
OMX_VIDEO_PARAM_PROFILELEVELTYPE param;
InitOMXParams(¶m);
@@ -4384,6 +4383,33 @@
}
caps->mColorFormats.push(portFormat.eColorFormat);
}
+ } else if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AAC, mime)) {
+ // More audio codecs if they have profiles.
+ OMX_AUDIO_PARAM_ANDROID_PROFILETYPE param;
+ InitOMXParams(¶m);
+ param.nPortIndex = isEncoder ? 1 : 0;
+ for (param.nProfileIndex = 0;; ++param.nProfileIndex) {
+ err = omx->getParameter(
+ node, (OMX_INDEXTYPE)OMX_IndexParamAudioProfileQuerySupported,
+ ¶m, sizeof(param));
+
+ if (err != OK) {
+ break;
+ }
+
+ CodecProfileLevel profileLevel;
+ profileLevel.mProfile = param.eProfile;
+ // For audio, level is ignored.
+ profileLevel.mLevel = 0;
+
+ caps->mProfileLevels.push(profileLevel);
+ }
+
+ // NOTE: Without Android extensions, OMX does not provide a way to query
+ // AAC profile support
+ if (param.nProfileIndex == 0) {
+ ALOGW("component %s doesn't support profile query.", componentName);
+ }
}
if (isVideo && !isEncoder) {
diff --git a/media/libstagefright/codecs/aacenc/SoftAACEncoder2.cpp b/media/libstagefright/codecs/aacenc/SoftAACEncoder2.cpp
index 35aa883..96e2f87 100644
--- a/media/libstagefright/codecs/aacenc/SoftAACEncoder2.cpp
+++ b/media/libstagefright/codecs/aacenc/SoftAACEncoder2.cpp
@@ -20,9 +20,11 @@
#include "SoftAACEncoder2.h"
#include <OMX_AudioExt.h>
+#include <OMX_IndexExt.h>
#include <media/stagefright/foundation/ADebug.h>
#include <media/stagefright/foundation/hexdump.h>
+#include <utils/misc.h>
namespace android {
@@ -35,6 +37,14 @@
params->nVersion.s.nStep = 0;
}
+static const OMX_U32 kSupportedProfiles[] = {
+ OMX_AUDIO_AACObjectLC,
+ OMX_AUDIO_AACObjectHE,
+ OMX_AUDIO_AACObjectHE_PS,
+ OMX_AUDIO_AACObjectLD,
+ OMX_AUDIO_AACObjectELD,
+};
+
SoftAACEncoder2::SoftAACEncoder2(
const char *name,
const OMX_CALLBACKTYPE *callbacks,
@@ -117,7 +127,7 @@
OMX_ERRORTYPE SoftAACEncoder2::internalGetParameter(
OMX_INDEXTYPE index, OMX_PTR params) {
- switch (index) {
+ switch ((OMX_U32) index) {
case OMX_IndexParamAudioPortFormat:
{
OMX_AUDIO_PARAM_PORTFORMATTYPE *formatParams =
@@ -220,6 +230,25 @@
return OMX_ErrorNone;
}
+ case OMX_IndexParamAudioProfileQuerySupported:
+ {
+ OMX_AUDIO_PARAM_ANDROID_PROFILETYPE *profileParams =
+ (OMX_AUDIO_PARAM_ANDROID_PROFILETYPE *)params;
+
+ if (profileParams->nPortIndex != 1) {
+ return OMX_ErrorUndefined;
+ }
+
+ if (profileParams->nProfileIndex >= NELEM(kSupportedProfiles)) {
+ return OMX_ErrorNoMore;
+ }
+
+ profileParams->eProfile =
+ kSupportedProfiles[profileParams->nProfileIndex];
+
+ return OMX_ErrorNone;
+ }
+
default:
return SimpleSoftOMXComponent::internalGetParameter(index, params);
}
diff --git a/media/libstagefright/codecs/amrwbenc/inc/basic_op.h b/media/libstagefright/codecs/amrwbenc/inc/basic_op.h
index 5808437..db3e058 100644
--- a/media/libstagefright/codecs/amrwbenc/inc/basic_op.h
+++ b/media/libstagefright/codecs/amrwbenc/inc/basic_op.h
@@ -222,14 +222,18 @@
}
else
{
- result = (Word32) var1 *((Word32) 1 << var2);
- if ((var2 > 15 && var1 != 0) || (result != (Word32) ((Word16) result)))
+ if (var2 > 15 && var1 != 0)
{
var_out = (Word16)((var1 > 0) ? MAX_16 : MIN_16);
}
else
{
- var_out = extract_l (result);
+ result = (Word32) var1 *((Word32) 1 << var2);
+ if ((result != (Word32) ((Word16) result))) {
+ var_out = (Word16)((var1 > 0) ? MAX_16 : MIN_16);
+ } else {
+ var_out = extract_l (result);
+ }
}
}
return (var_out);
diff --git a/media/libstagefright/codecs/amrwbenc/src/c2t64fx.c b/media/libstagefright/codecs/amrwbenc/src/c2t64fx.c
index c7c9279..dbb94c6 100644
--- a/media/libstagefright/codecs/amrwbenc/src/c2t64fx.c
+++ b/media/libstagefright/codecs/amrwbenc/src/c2t64fx.c
@@ -93,7 +93,7 @@
#endif
Isqrt_n(&s, &exp);
- k_dn = vo_round(L_shl(s, (exp + 8))); /* k_dn = 256..4096 */
+ k_dn = voround(L_shl(s, (exp + 8))); /* k_dn = 256..4096 */
k_dn = vo_mult_r(alp, k_dn); /* alp in Q12 */
/* mix normalized cn[] and dn[] */
diff --git a/media/libstagefright/codecs/amrwbenc/src/c4t64fx.c b/media/libstagefright/codecs/amrwbenc/src/c4t64fx.c
index e3b2f6c..8bf15ea 100644
--- a/media/libstagefright/codecs/amrwbenc/src/c4t64fx.c
+++ b/media/libstagefright/codecs/amrwbenc/src/c4t64fx.c
@@ -257,7 +257,7 @@
#endif
Isqrt_n(&s, &exp);
- k_dn = (L_shl(s, (exp + 5 + 3)) + 0x8000) >> 16; /* k_dn = 256..4096 */
+ k_dn = voround(L_shl(s, (exp + 5 + 3))); /* k_dn = 256..4096 */
k_dn = vo_mult_r(alp, k_dn); /* alp in Q12 */
/* mix normalized cn[] and dn[] */
@@ -1005,7 +1005,7 @@
for (x = track_x; x < L_SUBFR; x += STEP)
{
ps1 = *ps + dn[x];
- alp1 = alp0 + ((*p0++)<<13);
+ alp1 = L_add(alp0, ((*p0++)<<13));
if (dn2[x] < thres_ix)
{
@@ -1018,7 +1018,7 @@
alp2 = L_add(alp2, ((*p2++)<<14));
alp_16 = extract_h(alp2);
sq = vo_mult(ps2, ps2);
- s = vo_L_mult(alpk, sq) - ((sqk * alp_16)<<1);
+ s = L_sub(vo_L_mult(alpk, sq), L_mult(sqk, alp_16));
if (s > 0)
{
diff --git a/media/libstagefright/codecs/amrwbenc/src/cor_h_x.c b/media/libstagefright/codecs/amrwbenc/src/cor_h_x.c
index b2aa759..e834396 100644
--- a/media/libstagefright/codecs/amrwbenc/src/cor_h_x.c
+++ b/media/libstagefright/codecs/amrwbenc/src/cor_h_x.c
@@ -55,10 +55,10 @@
p1 = &x[i];
p2 = &h[0];
for (j = i; j < L_SUBFR; j++)
- L_tmp += vo_L_mult(*p1++, *p2++);
+ L_tmp = L_add(L_tmp, vo_L_mult(*p1++, *p2++));
y32[i] = L_tmp;
- L_tmp = (L_tmp > 0)? L_tmp:-L_tmp;
+ L_tmp = (L_tmp > 0)? L_tmp: (L_tmp == INT_MIN ? INT_MAX : -L_tmp);
if(L_tmp > L_max)
{
L_max = L_tmp;
@@ -68,10 +68,10 @@
p1 = &x[i+1];
p2 = &h[0];
for (j = i+1; j < L_SUBFR; j++)
- L_tmp += vo_L_mult(*p1++, *p2++);
+ L_tmp = L_add(L_tmp, vo_L_mult(*p1++, *p2++));
y32[i+1] = L_tmp;
- L_tmp = (L_tmp > 0)? L_tmp:-L_tmp;
+ L_tmp = (L_tmp > 0)? L_tmp: (L_tmp == INT_MIN ? INT_MAX : -L_tmp);
if(L_tmp > L_max1)
{
L_max1 = L_tmp;
@@ -81,10 +81,10 @@
p1 = &x[i+2];
p2 = &h[0];
for (j = i+2; j < L_SUBFR; j++)
- L_tmp += vo_L_mult(*p1++, *p2++);
+ L_tmp = L_add(L_tmp, vo_L_mult(*p1++, *p2++));
y32[i+2] = L_tmp;
- L_tmp = (L_tmp > 0)? L_tmp:-L_tmp;
+ L_tmp = (L_tmp > 0)? L_tmp: (L_tmp == INT_MIN ? INT_MAX : -L_tmp);
if(L_tmp > L_max2)
{
L_max2 = L_tmp;
@@ -94,17 +94,23 @@
p1 = &x[i+3];
p2 = &h[0];
for (j = i+3; j < L_SUBFR; j++)
- L_tmp += vo_L_mult(*p1++, *p2++);
+ L_tmp = L_add(L_tmp, vo_L_mult(*p1++, *p2++));
y32[i+3] = L_tmp;
- L_tmp = (L_tmp > 0)? L_tmp:-L_tmp;
+ L_tmp = (L_tmp > 0)? L_tmp: (L_tmp == INT_MIN ? INT_MAX : -L_tmp);
if(L_tmp > L_max3)
{
L_max3 = L_tmp;
}
}
/* tot += 3*max / 8 */
- L_max = ((L_max + L_max1 + L_max2 + L_max3) >> 2);
+ if (L_max > INT_MAX - L_max1 ||
+ L_max + L_max1 > INT_MAX - L_max2 ||
+ L_max + L_max1 + L_max2 > INT_MAX - L_max3) {
+ L_max = INT_MAX >> 2;
+ } else {
+ L_max = ((L_max + L_max1 + L_max2 + L_max3) >> 2);
+ }
L_tot = vo_L_add(L_tot, L_max); /* +max/4 */
L_tot = vo_L_add(L_tot, (L_max >> 1)); /* +max/8 */
diff --git a/media/mtp/MtpDevice.cpp b/media/mtp/MtpDevice.cpp
index 4dad59b..7d7ea13 100644
--- a/media/mtp/MtpDevice.cpp
+++ b/media/mtp/MtpDevice.cpp
@@ -181,7 +181,13 @@
return NULL;
}
- if (usb_device_claim_interface(device, interface->bInterfaceNumber)) {
+ int ret = usb_device_claim_interface(device, interface->bInterfaceNumber);
+ if (ret && errno == EBUSY) {
+ // disconnect kernel driver and try again
+ usb_device_connect_kernel_driver(device, interface->bInterfaceNumber, false);
+ ret = usb_device_claim_interface(device, interface->bInterfaceNumber);
+ }
+ if (ret) {
ALOGE("usb_device_claim_interface failed errno: %d\n", errno);
usb_device_close(device);
return NULL;
diff --git a/services/audioflinger/FastMixer.cpp b/services/audioflinger/FastMixer.cpp
index cc9acff..1446d19 100644
--- a/services/audioflinger/FastMixer.cpp
+++ b/services/audioflinger/FastMixer.cpp
@@ -416,7 +416,7 @@
}
if (mMasterMono.load()) { // memory_order_seq_cst
- mono_blend(mMixerBuffer, mMixerBufferFormat, Format_channelCount(mFormat), frameCount);
+ mono_blend(mMixerBuffer, mMixerBufferFormat, Format_channelCount(mFormat), frameCount, true /*limit*/);
}
// prepare the buffer used to write to sink
void *buffer = mSinkBuffer != NULL ? mSinkBuffer : mMixerBuffer;
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index 8ae798c..7a29cce 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -2917,8 +2917,8 @@
// mono blend occurs for mixer threads only (not direct or offloaded)
// and is handled here if we're going directly to the sink.
if (requireMonoBlend() && !mEffectBufferValid) {
- mono_blend(
- mMixerBuffer, mMixerBufferFormat, mChannelCount, mNormalFrameCount);
+ mono_blend(mMixerBuffer, mMixerBufferFormat, mChannelCount, mNormalFrameCount,
+ true /*limit*/);
}
memcpy_by_audio_format(buffer, format, mMixerBuffer, mMixerBufferFormat,
@@ -2958,7 +2958,8 @@
//ALOGV("writing effect buffer to sink buffer format %#x", mFormat);
if (requireMonoBlend()) {
- mono_blend(mEffectBuffer, mEffectBufferFormat, mChannelCount, mNormalFrameCount);
+ mono_blend(mEffectBuffer, mEffectBufferFormat, mChannelCount, mNormalFrameCount,
+ true /*limit*/);
}
memcpy_by_audio_format(mSinkBuffer, mFormat, mEffectBuffer, mEffectBufferFormat,
diff --git a/services/audioflinger/Threads.h b/services/audioflinger/Threads.h
index fa047fa..ae8bbb9 100644
--- a/services/audioflinger/Threads.h
+++ b/services/audioflinger/Threads.h
@@ -927,6 +927,8 @@
}
}
// the FastMixer performs mono blend if it exists.
+ // Blending with limiter is not idempotent,
+ // and blending without limiter is idempotent but inefficient to do twice.
virtual bool requireMonoBlend() { return mMasterMono.load() && !hasFastMixer(); }
};
diff --git a/services/audiopolicy/common/managerdefinitions/include/AudioInputDescriptor.h b/services/audiopolicy/common/managerdefinitions/include/AudioInputDescriptor.h
index 049079e..282bece 100644
--- a/services/audiopolicy/common/managerdefinitions/include/AudioInputDescriptor.h
+++ b/services/audiopolicy/common/managerdefinitions/include/AudioInputDescriptor.h
@@ -64,6 +64,7 @@
status_t removeAudioSession(audio_session_t session);
sp<AudioSession> getAudioSession(audio_session_t session) const;
AudioSessionCollection getAudioSessions(bool activeOnly) const;
+ size_t getAudioSessionCount(bool activeOnly) const;
audio_source_t getHighestPrioritySource(bool activeOnly) const;
private:
diff --git a/services/audiopolicy/common/managerdefinitions/include/AudioSession.h b/services/audiopolicy/common/managerdefinitions/include/AudioSession.h
index 87c4c9a..648cc00 100644
--- a/services/audiopolicy/common/managerdefinitions/include/AudioSession.h
+++ b/services/audiopolicy/common/managerdefinitions/include/AudioSession.h
@@ -85,6 +85,7 @@
uint32_t getOpenCount() const;
AudioSessionCollection getActiveSessions() const;
+ size_t getActiveSessionCount() const;
bool hasActiveSession() const;
bool isSourceActive(audio_source_t source) const;
audio_source_t getHighestPrioritySource(bool activeOnly) const;
diff --git a/services/audiopolicy/common/managerdefinitions/src/AudioInputDescriptor.cpp b/services/audiopolicy/common/managerdefinitions/src/AudioInputDescriptor.cpp
index 6281715..38d7ad5 100644
--- a/services/audiopolicy/common/managerdefinitions/src/AudioInputDescriptor.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/AudioInputDescriptor.cpp
@@ -158,6 +158,15 @@
}
}
+size_t AudioInputDescriptor::getAudioSessionCount(bool activeOnly) const
+{
+ if (activeOnly) {
+ return mSessions.getActiveSessionCount();
+ } else {
+ return mSessions.size();
+ }
+}
+
status_t AudioInputDescriptor::addAudioSession(audio_session_t session,
const sp<AudioSession>& audioSession) {
return mSessions.addSession(session, audioSession);
diff --git a/services/audiopolicy/common/managerdefinitions/src/AudioSession.cpp b/services/audiopolicy/common/managerdefinitions/src/AudioSession.cpp
index a08ce02..306ed28 100644
--- a/services/audiopolicy/common/managerdefinitions/src/AudioSession.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/AudioSession.cpp
@@ -186,9 +186,20 @@
return activeSessions;
}
+size_t AudioSessionCollection::getActiveSessionCount() const
+{
+ size_t activeCount = 0;
+ for (size_t i = 0; i < size(); i++) {
+ if (valueAt(i)->activeCount() != 0) {
+ activeCount++;
+ }
+ }
+ return activeCount;
+}
+
bool AudioSessionCollection::hasActiveSession() const
{
- return getActiveSessions().size() != 0;
+ return getActiveSessionCount() != 0;
}
bool AudioSessionCollection::isSourceActive(audio_source_t source) const
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
index 5949848..ad2ad69 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
@@ -1649,7 +1649,7 @@
setInputDevice(input, getNewInputDevice(inputDesc), true /* force */);
- if (!inputDesc->isActive()) {
+ if (inputDesc->getAudioSessionCount(true/*activeOnly*/) == 1) {
// if input maps to a dynamic policy with an activity listener, notify of state change
if ((inputDesc->mPolicyMix != NULL)
&& ((inputDesc->mPolicyMix->mCbFlags & AudioMix::kCbFlagNotifyActivity) != 0)) {
@@ -1855,8 +1855,11 @@
// update volume on all outputs whose current device is also selected by the same
// strategy as the device specified by the caller
- audio_devices_t strategyDevice = getDeviceForStrategy(getStrategy(stream), true /*fromCache*/);
-
+ audio_devices_t selectedDevices = getDeviceForStrategy(getStrategy(stream), true /*fromCache*/);
+ // it is possible that the requested device is not selected by the strategy (e.g an explicit
+ // audio patch is active causing getDevicesForStream() to return this device. We must make
+ // sure that the device passed is part of the devices considered when applying volume below.
+ selectedDevices |= device;
//FIXME: AUDIO_STREAM_ACCESSIBILITY volume follows AUDIO_STREAM_MUSIC for now
audio_devices_t accessibilityDevice = AUDIO_DEVICE_NONE;
@@ -1864,15 +1867,12 @@
mVolumeCurves->addCurrentVolumeIndex(AUDIO_STREAM_ACCESSIBILITY, device, index);
accessibilityDevice = getDeviceForStrategy(STRATEGY_ACCESSIBILITY, true /*fromCache*/);
}
- if ((device != AUDIO_DEVICE_OUT_DEFAULT) &&
- (device & (strategyDevice | accessibilityDevice)) == 0) {
- return NO_ERROR;
- }
+
status_t status = NO_ERROR;
for (size_t i = 0; i < mOutputs.size(); i++) {
sp<SwAudioOutputDescriptor> desc = mOutputs.valueAt(i);
audio_devices_t curDevice = Volume::getDeviceForVolume(desc->device());
- if ((device == AUDIO_DEVICE_OUT_DEFAULT) || ((curDevice & strategyDevice) != 0)) {
+ if ((device == AUDIO_DEVICE_OUT_DEFAULT) || ((curDevice & selectedDevices) != 0)) {
status_t volStatus = checkAndSetVolume(stream, index, desc, curDevice);
if (volStatus != NO_ERROR) {
status = volStatus;
@@ -4287,7 +4287,6 @@
devices |= AUDIO_DEVICE_OUT_SPEAKER;
devices &= ~AUDIO_DEVICE_OUT_SPEAKER_SAFE;
}
-
return devices;
}
@@ -4593,7 +4592,6 @@
patchDesc->mPatch = patch;
}
patchDesc->mAfPatchHandle = afPatchHandle;
- patchDesc->mUid = mUidCached;
if (patchHandle) {
*patchHandle = patchDesc->mHandle;
}
@@ -4698,7 +4696,6 @@
patchDesc->mPatch = patch;
}
patchDesc->mAfPatchHandle = afPatchHandle;
- patchDesc->mUid = mUidCached;
if (patchHandle) {
*patchHandle = patchDesc->mHandle;
}
diff --git a/services/audiopolicy/service/AudioPolicyService.cpp b/services/audiopolicy/service/AudioPolicyService.cpp
index 0c5d275..363968c 100644
--- a/services/audiopolicy/service/AudioPolicyService.cpp
+++ b/services/audiopolicy/service/AudioPolicyService.cpp
@@ -449,7 +449,7 @@
bool AudioPolicyService::AudioCommandThread::threadLoop()
{
- nsecs_t waitTime = INT64_MAX;
+ nsecs_t waitTime = -1;
mLock.lock();
while (!exitPending())
@@ -614,7 +614,7 @@
command->mCond.signal();
}
}
- waitTime = INT64_MAX;
+ waitTime = -1;
// release mLock before releasing strong reference on the service as
// AudioPolicyService destructor calls AudioCommandThread::exit() which
// acquires mLock.
@@ -636,7 +636,11 @@
// has a finite delay. So unless we are exiting it is safe to wait.
if (!exitPending()) {
ALOGV("AudioCommandThread() going to sleep");
- mWaitWorkCV.waitRelative(mLock, waitTime);
+ if (waitTime == -1) {
+ mWaitWorkCV.wait(mLock);
+ } else {
+ mWaitWorkCV.waitRelative(mLock, waitTime);
+ }
}
}
// release delayed commands wake lock before quitting
diff --git a/services/camera/libcameraservice/api2/CameraDeviceClient.cpp b/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
index 6b60307..7be5696 100644
--- a/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
+++ b/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
@@ -456,7 +456,6 @@
return BAD_VALUE;
}
- // TODO: Hookup the stream set id with upper layer.
int streamId = camera3::CAMERA3_STREAM_ID_INVALID;
res = mDevice->createStream(surface, width, height, format, dataSpace,
static_cast<camera3_stream_rotation_t>
diff --git a/services/camera/libcameraservice/device3/Camera3BufferManager.cpp b/services/camera/libcameraservice/device3/Camera3BufferManager.cpp
index 6d79167..73d9d3d 100644
--- a/services/camera/libcameraservice/device3/Camera3BufferManager.cpp
+++ b/services/camera/libcameraservice/device3/Camera3BufferManager.cpp
@@ -113,9 +113,10 @@
currentStreamSet.streamInfoMap.add(streamId, streamInfo);
currentStreamSet.handoutBufferCountMap.add(streamId, 0);
- // The watermark should be the max of buffer count of each stream inside a stream set.
- if (streamInfo.totalBufferCount > currentStreamSet.allocatedBufferWaterMark) {
- currentStreamSet.allocatedBufferWaterMark = streamInfo.totalBufferCount;
+ // The max allowed buffer count should be the max of buffer count of each stream inside a stream
+ // set.
+ if (streamInfo.totalBufferCount > currentStreamSet.maxAllowedBufferCount) {
+ currentStreamSet.maxAllowedBufferCount = streamInfo.totalBufferCount;
}
return OK;
@@ -147,12 +148,15 @@
// Remove the stream info from info map and recalculate the buffer count water mark.
infoMap.removeItem(streamId);
- currentSet.allocatedBufferWaterMark = 0;
+ currentSet.maxAllowedBufferCount = 0;
for (size_t i = 0; i < infoMap.size(); i++) {
- if (infoMap[i].totalBufferCount > currentSet.allocatedBufferWaterMark) {
- currentSet.allocatedBufferWaterMark = infoMap[i].totalBufferCount;
+ if (infoMap[i].totalBufferCount > currentSet.maxAllowedBufferCount) {
+ currentSet.maxAllowedBufferCount = infoMap[i].totalBufferCount;
}
}
+ // Lazy solution: when a stream is unregistered, the streams will be reconfigured, reset
+ // the water mark and let it grow again.
+ currentSet.allocatedBufferWaterMark = 0;
// Remove this stream set if all its streams have been removed.
if (freeBufs.size() == 0 && handOutBufferCounts.size() == 0 && infoMap.size() == 0) {
@@ -181,6 +185,14 @@
}
StreamSet &streamSet = mStreamSetMap.editValueFor(streamSetId);
+ BufferCountMap& handOutBufferCounts = streamSet.handoutBufferCountMap;
+ size_t& bufferCount = handOutBufferCounts.editValueFor(streamId);
+ if (bufferCount >= streamSet.maxAllowedBufferCount) {
+ ALOGE("%s: bufferCount (%zu) exceeds the max allowed buffer count (%zu) of this stream set",
+ __FUNCTION__, bufferCount, streamSet.maxAllowedBufferCount);
+ return INVALID_OPERATION;
+ }
+
GraphicBufferEntry buffer =
getFirstBufferFromBufferListLocked(streamSet.freeBuffers, streamId);
@@ -202,10 +214,10 @@
}
// Increase the hand-out buffer count for tracking purpose.
- BufferCountMap& handOutBufferCounts = streamSet.handoutBufferCountMap;
- size_t& bufferCount = handOutBufferCounts.editValueFor(streamId);
bufferCount++;
-
+ if (bufferCount > streamSet.allocatedBufferWaterMark) {
+ streamSet.allocatedBufferWaterMark = bufferCount;
+ }
*gb = buffer.graphicBuffer;
*fenceFd = buffer.fenceFd;
ALOGV("%s: get buffer (%p) with handle (%p).",
@@ -220,7 +232,8 @@
if (streamSet.streamInfoMap.size() > 1) {
for (size_t i = 0; i < streamSet.streamInfoMap.size(); i++) {
firstOtherStreamId = streamSet.streamInfoMap[i].streamId;
- if (firstOtherStreamId != streamId) {
+ if (firstOtherStreamId != streamId &&
+ hasBufferForStreamLocked(streamSet.freeBuffers, firstOtherStreamId)) {
break;
}
}
@@ -299,6 +312,8 @@
for (size_t j = 0; j < mStreamSetMap[i].streamInfoMap.size(); j++) {
lines.appendFormat(" Stream %d\n", mStreamSetMap[i].streamInfoMap[j].streamId);
}
+ lines.appendFormat(" Stream set max allowed buffer count: %zu\n",
+ mStreamSetMap[i].maxAllowedBufferCount);
lines.appendFormat(" Stream set buffer count water mark: %zu\n",
mStreamSetMap[i].allocatedBufferWaterMark);
lines.appendFormat(" Handout buffer counts:\n");
@@ -337,7 +352,7 @@
return false;
}
- size_t bufferWaterMark = mStreamSetMap[setIdx].allocatedBufferWaterMark;
+ size_t bufferWaterMark = mStreamSetMap[setIdx].maxAllowedBufferCount;
if (bufferWaterMark == 0 || bufferWaterMark > kMaxBufferCount) {
ALOGW("%s: stream %d with stream set %d is not registered correctly to stream set map,"
" as the water mark (%zu) is wrong!",
@@ -379,6 +394,19 @@
return OK;
}
+bool Camera3BufferManager::hasBufferForStreamLocked(BufferList& buffers, int streamId) {
+ BufferList::iterator i = buffers.begin();
+ while (i != buffers.end()) {
+ ssize_t idx = i->indexOfKey(streamId);
+ if (idx != NAME_NOT_FOUND) {
+ return true;
+ }
+ i++;
+ }
+
+ return false;
+}
+
Camera3BufferManager::GraphicBufferEntry Camera3BufferManager::getFirstBufferFromBufferListLocked(
BufferList& buffers, int streamId) {
// Try to get the first buffer from the free buffer list if there is one.
diff --git a/services/camera/libcameraservice/device3/Camera3BufferManager.h b/services/camera/libcameraservice/device3/Camera3BufferManager.h
index 0b4f55c..7942ae6 100644
--- a/services/camera/libcameraservice/device3/Camera3BufferManager.h
+++ b/services/camera/libcameraservice/device3/Camera3BufferManager.h
@@ -220,8 +220,18 @@
* simultaneously, the max allocated buffer count water mark for a stream set will the max
* of all streams' total buffer counts. This will avoid new buffer allocation in steady
* streaming state.
+ *
+ * This water mark can be dynamically changed, and will grow when the hand-out buffer count
+ * of each stream increases, until it reaches the maxAllowedBufferCount.
*/
size_t allocatedBufferWaterMark;
+
+ /**
+ * The max allowed buffer count for this stream set. It is the max of total number of
+ * buffers for each stream. This is the upper bound of the allocatedBufferWaterMark.
+ */
+ size_t maxAllowedBufferCount;
+
/**
* The stream info for all streams in this set
*/
@@ -237,6 +247,7 @@
BufferCountMap handoutBufferCountMap;
StreamSet() {
allocatedBufferWaterMark = 0;
+ maxAllowedBufferCount = 0;
}
};
@@ -280,6 +291,14 @@
*
*/
GraphicBufferEntry getFirstBufferFromBufferListLocked(BufferList& buffers, int streamId);
+
+ /**
+ * Check if there is any buffer associated with this stream in the given buffer list.
+ *
+ * This method needs to be called with mLock held.
+ *
+ */
+ bool inline hasBufferForStreamLocked(BufferList& buffers, int streamId);
};
} // namespace camera3
diff --git a/services/soundtrigger/SoundTriggerHwService.cpp b/services/soundtrigger/SoundTriggerHwService.cpp
index b3500f6..c891fd6 100644
--- a/services/soundtrigger/SoundTriggerHwService.cpp
+++ b/services/soundtrigger/SoundTriggerHwService.cpp
@@ -61,13 +61,13 @@
rc = hw_get_module_by_class(SOUND_TRIGGER_HARDWARE_MODULE_ID, HW_MODULE_PREFIX, &mod);
if (rc != 0) {
ALOGE("couldn't load sound trigger module %s.%s (%s)",
- SOUND_TRIGGER_HARDWARE_MODULE_ID, "primary", strerror(-rc));
+ SOUND_TRIGGER_HARDWARE_MODULE_ID, HW_MODULE_PREFIX, strerror(-rc));
return;
}
rc = sound_trigger_hw_device_open(mod, &dev);
if (rc != 0) {
ALOGE("couldn't open sound trigger hw device in %s.%s (%s)",
- SOUND_TRIGGER_HARDWARE_MODULE_ID, "primary", strerror(-rc));
+ SOUND_TRIGGER_HARDWARE_MODULE_ID, HW_MODULE_PREFIX, strerror(-rc));
return;
}
if (dev->common.version != SOUND_TRIGGER_DEVICE_API_VERSION_CURRENT) {
@@ -819,6 +819,17 @@
if (eventMemory != 0) {
events.add(eventMemory);
}
+ } else if (model->mType == SOUND_MODEL_TYPE_UNKNOWN) {
+ struct sound_trigger_phrase_recognition_event event;
+ memset(&event, 0, sizeof(struct sound_trigger_phrase_recognition_event));
+ event.common.status = RECOGNITION_STATUS_ABORT;
+ event.common.type = model->mType;
+ event.common.model = model->mHandle;
+ event.common.data_size = 0;
+ sp<IMemory> eventMemory = service->prepareRecognitionEvent_l(&event.common);
+ if (eventMemory != 0) {
+ events.add(eventMemory);
+ }
} else {
goto exit;
}