Merge "Precautionary logging to identify a potential infinite loop." into jb-dev
diff --git a/media/libeffects/downmix/EffectDownmix.c b/media/libeffects/downmix/EffectDownmix.c
index 8735503..5bf052a 100644
--- a/media/libeffects/downmix/EffectDownmix.c
+++ b/media/libeffects/downmix/EffectDownmix.c
@@ -822,9 +822,9 @@
if (accumulate) {
while (numFrames) {
// FL + RL
- pDst[0] = clamp16(pDst[0] + pSrc[0] + pSrc[2]);
+ pDst[0] = clamp16(pDst[0] + ((pSrc[0] + pSrc[2]) >> 1));
// FR + RR
- pDst[1] = clamp16(pDst[1] + pSrc[1] + pSrc[3]);
+ pDst[1] = clamp16(pDst[1] + ((pSrc[1] + pSrc[3]) >> 1));
pSrc += 4;
pDst += 2;
numFrames--;
@@ -832,9 +832,9 @@
} else { // same code as above but without adding and clamping pDst[i] to itself
while (numFrames) {
// FL + RL
- pDst[0] = clamp16(pSrc[0] + pSrc[2]);
+ pDst[0] = clamp16((pSrc[0] + pSrc[2]) >> 1);
// FR + RR
- pDst[1] = clamp16(pSrc[1] + pSrc[3]);
+ pDst[1] = clamp16((pSrc[1] + pSrc[3]) >> 1);
pSrc += 4;
pDst += 2;
numFrames--;
@@ -877,8 +877,8 @@
// FR + centerPlusRearContrib
rt = (pSrc[1] << 12) + centerPlusRearContrib;
// accumulate in destination
- pDst[0] = clamp16(pDst[0] + (lt >> 12));
- pDst[1] = clamp16(pDst[1] + (rt >> 12));
+ pDst[0] = clamp16(pDst[0] + (lt >> 13));
+ pDst[1] = clamp16(pDst[1] + (rt >> 13));
pSrc += 4;
pDst += 2;
numFrames--;
@@ -892,8 +892,8 @@
// FR + centerPlusRearContrib
rt = (pSrc[1] << 12) + centerPlusRearContrib;
// store in destination
- pDst[0] = clamp16(lt >> 12); // differs from when accumulate is true above
- pDst[1] = clamp16(rt >> 12); // differs from when accumulate is true above
+ pDst[0] = clamp16(lt >> 13); // differs from when accumulate is true above
+ pDst[1] = clamp16(rt >> 13); // differs from when accumulate is true above
pSrc += 4;
pDst += 2;
numFrames--;
@@ -939,8 +939,8 @@
// FR + centerPlusLfeContrib + RR
rt = (pSrc[1] << 12) + centerPlusLfeContrib + (pSrc[5] << 12);
// accumulate in destination
- pDst[0] = clamp16(pDst[0] + (lt >> 12));
- pDst[1] = clamp16(pDst[1] + (rt >> 12));
+ pDst[0] = clamp16(pDst[0] + (lt >> 13));
+ pDst[1] = clamp16(pDst[1] + (rt >> 13));
pSrc += 6;
pDst += 2;
numFrames--;
@@ -955,8 +955,8 @@
// FR + centerPlusLfeContrib + RR
rt = (pSrc[1] << 12) + centerPlusLfeContrib + (pSrc[5] << 12);
// store in destination
- pDst[0] = clamp16(lt >> 12); // differs from when accumulate is true above
- pDst[1] = clamp16(rt >> 12); // differs from when accumulate is true above
+ pDst[0] = clamp16(lt >> 13); // differs from when accumulate is true above
+ pDst[1] = clamp16(rt >> 13); // differs from when accumulate is true above
pSrc += 6;
pDst += 2;
numFrames--;
@@ -1004,8 +1004,8 @@
// FR + centerPlusLfeContrib + SR + RR
rt = (pSrc[1] << 12) + centerPlusLfeContrib + (pSrc[7] << 12) + (pSrc[5] << 12);
//accumulate in destination
- pDst[0] = clamp16(pDst[0] + (lt >> 12));
- pDst[1] = clamp16(pDst[1] + (rt >> 12));
+ pDst[0] = clamp16(pDst[0] + (lt >> 13));
+ pDst[1] = clamp16(pDst[1] + (rt >> 13));
pSrc += 8;
pDst += 2;
numFrames--;
@@ -1020,8 +1020,8 @@
// FR + centerPlusLfeContrib + SR + RR
rt = (pSrc[1] << 12) + centerPlusLfeContrib + (pSrc[7] << 12) + (pSrc[5] << 12);
// store in destination
- pDst[0] = clamp16(lt >> 12); // differs from when accumulate is true above
- pDst[1] = clamp16(rt >> 12); // differs from when accumulate is true above
+ pDst[0] = clamp16(lt >> 13); // differs from when accumulate is true above
+ pDst[1] = clamp16(rt >> 13); // differs from when accumulate is true above
pSrc += 8;
pDst += 2;
numFrames--;
@@ -1130,8 +1130,8 @@
lt += centersLfeContrib;
rt += centersLfeContrib;
// accumulate in destination
- pDst[0] = clamp16(pDst[0] + (lt >> 12));
- pDst[1] = clamp16(pDst[1] + (rt >> 12));
+ pDst[0] = clamp16(pDst[0] + (lt >> 13));
+ pDst[1] = clamp16(pDst[1] + (rt >> 13));
pSrc += numChan;
pDst += 2;
numFrames--;
@@ -1159,8 +1159,8 @@
lt += centersLfeContrib;
rt += centersLfeContrib;
// store in destination
- pDst[0] = clamp16(lt >> 12); // differs from when accumulate is true above
- pDst[1] = clamp16(rt >> 12); // differs from when accumulate is true above
+ pDst[0] = clamp16(lt >> 13); // differs from when accumulate is true above
+ pDst[1] = clamp16(rt >> 13); // differs from when accumulate is true above
pSrc += numChan;
pDst += 2;
numFrames--;
diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp
index b2f1746..c4743a1 100644
--- a/media/libstagefright/ACodec.cpp
+++ b/media/libstagefright/ACodec.cpp
@@ -3472,11 +3472,14 @@
mCodec->signalError(OMX_ErrorUndefined, err);
- // This is technically not correct, since we were unable
- // to allocate output buffers and therefore the output port
- // remains disabled. It is necessary however to allow us
- // to shutdown the codec properly.
- mCodec->changeState(mCodec->mExecutingState);
+ // This is technically not correct, but appears to be
+ // the only way to free the component instance.
+ // Controlled transitioning from excecuting->idle
+ // and idle->loaded seem impossible probably because
+ // the output port never finishes re-enabling.
+ mCodec->mShutdownInProgress = true;
+ mCodec->mKeepComponentAllocated = false;
+ mCodec->changeState(mCodec->mLoadedState);
}
return true;
diff --git a/media/libstagefright/MPEG4Writer.cpp b/media/libstagefright/MPEG4Writer.cpp
index 85fbcdf..755b502 100755
--- a/media/libstagefright/MPEG4Writer.cpp
+++ b/media/libstagefright/MPEG4Writer.cpp
@@ -2811,8 +2811,8 @@
mOwner->beginBox("stsz");
mOwner->writeInt32(0); // version=0, flags=0
if (mSamplesHaveSameSize) {
- List<uint32_t *>::iterator it = mSampleSizes.begin();
- mOwner->writeInt32((*it)[0]); // default sample size
+ CHECK(mCurrentSampleSizeArr != 0);
+ mOwner->write(mCurrentSampleSizeArr, 4, 1); // default sample size
} else {
mOwner->writeInt32(0);
}
diff --git a/media/libstagefright/OMXCodec.cpp b/media/libstagefright/OMXCodec.cpp
index 66111dc..baabd37 100755
--- a/media/libstagefright/OMXCodec.cpp
+++ b/media/libstagefright/OMXCodec.cpp
@@ -2475,7 +2475,12 @@
} else {
err = allocateBuffersOnPort(portIndex);
if (err != OK) {
- CODEC_LOGE("allocateBuffersOnPort failed (err = %d)", err);
+ CODEC_LOGE("allocateBuffersOnPort (%s) failed "
+ "(err = %d)",
+ portIndex == kPortIndexInput
+ ? "input" : "output",
+ err);
+
setState(ERROR);
}
}
@@ -3643,7 +3648,7 @@
}
status_t OMXCodec::stop() {
- CODEC_LOGV("stop mState=%d", mState);
+ CODEC_LOGI("stop mState=%d", mState);
Mutex::Autolock autoLock(mLock);
@@ -3658,14 +3663,33 @@
case ERROR:
{
- OMX_STATETYPE state = OMX_StateInvalid;
- status_t err = mOMX->getState(mNode, &state);
- CHECK_EQ(err, (status_t)OK);
-
- if (state != OMX_StateExecuting) {
+ if (mPortStatus[kPortIndexOutput] == ENABLING) {
+ // Codec is in a wedged state (technical term)
+ // We've seen an output port settings change from the codec,
+ // We've disabled the output port, then freed the output
+ // buffers, initiated re-enabling the output port but
+ // failed to reallocate the output buffers.
+ // There doesn't seem to be a way to orderly transition
+ // from executing->idle and idle->loaded now that the
+ // output port hasn't been reenabled yet...
+ // Simply free as many resources as we can and pretend
+ // that we're in LOADED state so that the destructor
+ // will free the component instance without asserting.
+ freeBuffersOnPort(kPortIndexInput, true /* onlyThoseWeOwn */);
+ freeBuffersOnPort(kPortIndexOutput, true /* onlyThoseWeOwn */);
+ setState(LOADED);
break;
+ } else {
+ OMX_STATETYPE state = OMX_StateInvalid;
+ status_t err = mOMX->getState(mNode, &state);
+ CHECK_EQ(err, (status_t)OK);
+
+ if (state != OMX_StateExecuting) {
+ break;
+ }
+ // else fall through to the idling code
}
- // else fall through to the idling code
+
isError = true;
}
@@ -3724,9 +3748,10 @@
mLeftOverBuffer = NULL;
}
+ CODEC_LOGI("stopping in state %d", mState);
mSource->stop();
- CODEC_LOGV("stopped in state %d", mState);
+ CODEC_LOGI("stopped in state %d", mState);
return OK;
}
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index 68be7a7..57d7089 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -474,19 +474,15 @@
ALOGV("createTrack() sessionId: %d", (sessionId == NULL) ? -2 : *sessionId);
if (sessionId != NULL && *sessionId != AUDIO_SESSION_OUTPUT_MIX) {
+ // check if an effect chain with the same session ID is present on another
+ // output thread and move it here.
for (size_t i = 0; i < mPlaybackThreads.size(); i++) {
sp<PlaybackThread> t = mPlaybackThreads.valueAt(i);
if (mPlaybackThreads.keyAt(i) != output) {
- // prevent same audio session on different output threads
uint32_t sessions = t->hasAudioSession(*sessionId);
- if (sessions & PlaybackThread::TRACK_SESSION) {
- ALOGE("createTrack() session ID %d already in use", *sessionId);
- lStatus = BAD_VALUE;
- goto Exit;
- }
- // check if an effect with same session ID is waiting for a track to be created
if (sessions & PlaybackThread::EFFECT_SESSION) {
effectThread = t.get();
+ break;
}
}
}
diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp
index 92d1223..bf07f8b 100644
--- a/services/camera/libcameraservice/CameraService.cpp
+++ b/services/camera/libcameraservice/CameraService.cpp
@@ -410,6 +410,7 @@
status_t CameraService::Client::lock() {
int callingPid = getCallingPid();
LOG1("lock (pid %d)", callingPid);
+ Mutex::Autolock ilock(mICameraLock);
Mutex::Autolock lock(mLock);
// lock camera to this client if the the camera is unlocked
@@ -425,6 +426,7 @@
status_t CameraService::Client::unlock() {
int callingPid = getCallingPid();
LOG1("unlock (pid %d)", callingPid);
+ Mutex::Autolock iLock(mICameraLock);
Mutex::Autolock lock(mLock);
// allow anyone to use camera (after they lock the camera)
@@ -447,6 +449,7 @@
status_t CameraService::Client::connect(const sp<ICameraClient>& client) {
int callingPid = getCallingPid();
LOG1("connect E (pid %d)", callingPid);
+ Mutex::Autolock iLock(mICameraLock);
Mutex::Autolock lock(mLock);
if (mClientPid != 0 && checkPid() != NO_ERROR) {
@@ -482,6 +485,7 @@
void CameraService::Client::disconnect() {
int callingPid = getCallingPid();
LOG1("disconnect E (pid %d)", callingPid);
+ Mutex::Autolock iLock(mICameraLock);
Mutex::Autolock lock(mLock);
if (checkPid() != NO_ERROR) {
@@ -526,6 +530,7 @@
status_t CameraService::Client::setPreviewWindow(const sp<IBinder>& binder,
const sp<ANativeWindow>& window) {
+ Mutex::Autolock iLock(mICameraLock);
Mutex::Autolock lock(mLock);
status_t result = checkPidAndHardware();
if (result != NO_ERROR) return result;
@@ -597,6 +602,7 @@
// preview are handled.
void CameraService::Client::setPreviewCallbackFlag(int callback_flag) {
LOG1("setPreviewCallbackFlag(%d) (pid %d)", callback_flag, getCallingPid());
+ Mutex::Autolock iLock(mICameraLock);
Mutex::Autolock lock(mLock);
if (checkPidAndHardware() != NO_ERROR) return;
@@ -623,6 +629,7 @@
// start preview or recording
status_t CameraService::Client::startCameraMode(camera_mode mode) {
LOG1("startCameraMode(%d)", mode);
+ Mutex::Autolock iLock(mICameraLock);
Mutex::Autolock lock(mLock);
status_t result = checkPidAndHardware();
if (result != NO_ERROR) return result;
@@ -696,6 +703,7 @@
// stop preview mode
void CameraService::Client::stopPreview() {
LOG1("stopPreview (pid %d)", getCallingPid());
+ Mutex::Autolock iLock(mICameraLock);
Mutex::Autolock lock(mLock);
if (checkPidAndHardware() != NO_ERROR) return;
@@ -709,6 +717,7 @@
// stop recording mode
void CameraService::Client::stopRecording() {
LOG1("stopRecording (pid %d)", getCallingPid());
+ Mutex::Autolock iLock(mICameraLock);
Mutex::Autolock lock(mLock);
if (checkPidAndHardware() != NO_ERROR) return;
@@ -721,6 +730,7 @@
// release a recording frame
void CameraService::Client::releaseRecordingFrame(const sp<IMemory>& mem) {
+ Mutex::Autolock iLock(mICameraLock);
Mutex::Autolock lock(mLock);
if (checkPidAndHardware() != NO_ERROR) return;
mHardware->releaseRecordingFrame(mem);
@@ -729,6 +739,7 @@
status_t CameraService::Client::storeMetaDataInBuffers(bool enabled)
{
LOG1("storeMetaDataInBuffers: %s", enabled? "true": "false");
+ Mutex::Autolock iLock(mICameraLock);
Mutex::Autolock lock(mLock);
if (checkPidAndHardware() != NO_ERROR) {
return UNKNOWN_ERROR;
@@ -739,6 +750,7 @@
bool CameraService::Client::previewEnabled() {
LOG1("previewEnabled (pid %d)", getCallingPid());
+ Mutex::Autolock iLock(mICameraLock);
Mutex::Autolock lock(mLock);
if (checkPidAndHardware() != NO_ERROR) return false;
return mHardware->previewEnabled();
@@ -747,6 +759,7 @@
bool CameraService::Client::recordingEnabled() {
LOG1("recordingEnabled (pid %d)", getCallingPid());
+ Mutex::Autolock iLock(mICameraLock);
Mutex::Autolock lock(mLock);
if (checkPidAndHardware() != NO_ERROR) return false;
return mHardware->recordingEnabled();
@@ -755,6 +768,7 @@
status_t CameraService::Client::autoFocus() {
LOG1("autoFocus (pid %d)", getCallingPid());
+ Mutex::Autolock iLock(mICameraLock);
Mutex::Autolock lock(mLock);
status_t result = checkPidAndHardware();
if (result != NO_ERROR) return result;
@@ -765,6 +779,7 @@
status_t CameraService::Client::cancelAutoFocus() {
LOG1("cancelAutoFocus (pid %d)", getCallingPid());
+ Mutex::Autolock iLock(mICameraLock);
Mutex::Autolock lock(mLock);
status_t result = checkPidAndHardware();
if (result != NO_ERROR) return result;
@@ -776,26 +791,30 @@
status_t CameraService::Client::takePicture(int msgType) {
LOG1("takePicture (pid %d): 0x%x", getCallingPid(), msgType);
- Mutex::Autolock lock(mLock);
- status_t result = checkPidAndHardware();
- if (result != NO_ERROR) return result;
+ Mutex::Autolock iLock(mICameraLock);
+ int picMsgType = 0;
+ { // scope for lock
+ Mutex::Autolock lock(mLock);
+ status_t result = checkPidAndHardware();
+ if (result != NO_ERROR) return result;
- if ((msgType & CAMERA_MSG_RAW_IMAGE) &&
- (msgType & CAMERA_MSG_RAW_IMAGE_NOTIFY)) {
- ALOGE("CAMERA_MSG_RAW_IMAGE and CAMERA_MSG_RAW_IMAGE_NOTIFY"
- " cannot be both enabled");
- return BAD_VALUE;
+ if ((msgType & CAMERA_MSG_RAW_IMAGE) &&
+ (msgType & CAMERA_MSG_RAW_IMAGE_NOTIFY)) {
+ ALOGE("CAMERA_MSG_RAW_IMAGE and CAMERA_MSG_RAW_IMAGE_NOTIFY"
+ " cannot be both enabled");
+ return BAD_VALUE;
+ }
+
+ // We only accept picture related message types
+ // and ignore other types of messages for takePicture().
+ picMsgType = msgType
+ & (CAMERA_MSG_SHUTTER |
+ CAMERA_MSG_POSTVIEW_FRAME |
+ CAMERA_MSG_RAW_IMAGE |
+ CAMERA_MSG_RAW_IMAGE_NOTIFY |
+ CAMERA_MSG_COMPRESSED_IMAGE);
+
}
-
- // We only accept picture related message types
- // and ignore other types of messages for takePicture().
- int picMsgType = msgType
- & (CAMERA_MSG_SHUTTER |
- CAMERA_MSG_POSTVIEW_FRAME |
- CAMERA_MSG_RAW_IMAGE |
- CAMERA_MSG_RAW_IMAGE_NOTIFY |
- CAMERA_MSG_COMPRESSED_IMAGE);
-
enableMsgType(picMsgType);
return mHardware->takePicture();
@@ -805,6 +824,7 @@
status_t CameraService::Client::setParameters(const String8& params) {
LOG1("setParameters (pid %d) (%s)", getCallingPid(), params.string());
+ Mutex::Autolock iLock(mICameraLock);
Mutex::Autolock lock(mLock);
status_t result = checkPidAndHardware();
if (result != NO_ERROR) return result;
@@ -815,6 +835,7 @@
// get preview/capture parameters - key/value pairs
String8 CameraService::Client::getParameters() const {
+ Mutex::Autolock iLock(mICameraLock);
Mutex::Autolock lock(mLock);
if (checkPidAndHardware() != NO_ERROR) return String8();
@@ -855,6 +876,7 @@
status_t CameraService::Client::sendCommand(int32_t cmd, int32_t arg1, int32_t arg2) {
LOG1("sendCommand (pid %d)", getCallingPid());
int orientation;
+ Mutex::Autolock iLock(mICameraLock);
Mutex::Autolock lock(mLock);
status_t result = checkPidAndHardware();
if (result != NO_ERROR) return result;
diff --git a/services/camera/libcameraservice/CameraService.h b/services/camera/libcameraservice/CameraService.h
index 5b63399..95ac197 100644
--- a/services/camera/libcameraservice/CameraService.h
+++ b/services/camera/libcameraservice/CameraService.h
@@ -190,6 +190,11 @@
// Ensures atomicity among the public methods
mutable Mutex mLock;
+ // A lock to synchronize access through the ICamera binder
+ // interface. The entire binder call should be done with mICameraLock
+ // locked, to serialize ICamera access, even when mLock is disabled for
+ // calls to the HAL.
+ mutable Mutex mICameraLock;
// This is a binder of Surface or SurfaceTexture.
sp<IBinder> mSurface;
sp<ANativeWindow> mPreviewWindow;