Revert "media: Mediarecorder drops the mediabuffer with negative adjusted timestamp."
am: e35600eb62
Change-Id: Iade2645300504e8e6303ad658a56a16fb1731d9d
diff --git a/include/media/ToneGenerator.h b/include/media/ToneGenerator.h
index 75515ac..a419e17 100644
--- a/include/media/ToneGenerator.h
+++ b/include/media/ToneGenerator.h
@@ -313,7 +313,7 @@
short mA1_Q14; // Q14 coefficient
// delay line of full amplitude generator
- short mS1, mS2; // delay line S2 oldest
+ long mS1, mS2; // delay line S2 oldest
short mS2_0; // saved value for reinitialisation
short mAmplitude_Q15; // Q15 amplitude
};
diff --git a/include/media/stagefright/MediaBuffer.h b/include/media/stagefright/MediaBuffer.h
index 55b1f58..abfe068 100644
--- a/include/media/stagefright/MediaBuffer.h
+++ b/include/media/stagefright/MediaBuffer.h
@@ -108,6 +108,14 @@
return reinterpret_cast<SharedControl *>(memory->pointer())->isDeadObject();
}
+ // Sticky on enabling of shared memory MediaBuffers. By default we don't use
+ // shared memory for MediaBuffers, but we enable this for those processes
+ // that export MediaBuffers.
+ static void useSharedMemory() {
+ std::atomic_store_explicit(
+ &mUseSharedMemory, (int_least32_t)1, std::memory_order_seq_cst);
+ }
+
protected:
// MediaBuffer remote releases are handled through a
// pending release count variable stored in a SharedControl block
@@ -161,6 +169,8 @@
MediaBuffer *mOriginal;
+ static std::atomic_int_least32_t mUseSharedMemory;
+
MediaBuffer(const MediaBuffer &);
MediaBuffer &operator=(const MediaBuffer &);
diff --git a/media/libmedia/IMediaExtractorService.cpp b/media/libmedia/IMediaExtractorService.cpp
index dcbbde2..d170c22 100644
--- a/media/libmedia/IMediaExtractorService.cpp
+++ b/media/libmedia/IMediaExtractorService.cpp
@@ -71,6 +71,9 @@
ALOGE("Error reading source from parcel");
return ret;
}
+ // If we make an extractor through Binder, enabled shared memory
+ // for MediaBuffers for this process.
+ MediaBuffer::useSharedMemory();
sp<IDataSource> source = interface_cast<IDataSource>(b);
const char *mime = data.readCString();
sp<IMediaExtractor> ex = makeExtractor(source, mime);
diff --git a/media/libmedia/ToneGenerator.cpp b/media/libmedia/ToneGenerator.cpp
index 2f53637..9a087ff 100644
--- a/media/libmedia/ToneGenerator.cpp
+++ b/media/libmedia/ToneGenerator.cpp
@@ -1612,8 +1612,8 @@
lS1 = (long)0;
lS2 = (long)mS2_0;
} else {
- lS1 = (long)mS1;
- lS2 = (long)mS2;
+ lS1 = mS1;
+ lS2 = mS2;
}
lA1 = (long)mA1_Q14;
lAmplitude = (long)mAmplitude_Q15;
@@ -1649,8 +1649,8 @@
}
// save status
- mS1 = (short)lS1;
- mS2 = (short)lS2;
+ mS1 = lS1;
+ mS2 = lS2;
}
} // end namespace android
diff --git a/media/libstagefright/codecs/m4v_h263/dec/SoftMPEG4.cpp b/media/libstagefright/codecs/m4v_h263/dec/SoftMPEG4.cpp
index bb59ae4..e1cfc06 100644
--- a/media/libstagefright/codecs/m4v_h263/dec/SoftMPEG4.cpp
+++ b/media/libstagefright/codecs/m4v_h263/dec/SoftMPEG4.cpp
@@ -210,8 +210,17 @@
PortInfo *port = editPortInfo(1);
OMX_BUFFERHEADERTYPE *outHeader = port->mBuffers.editItemAt(1).mHeader;
+ OMX_U32 yFrameSize = sizeof(uint8) * mHandle->size;
+ if ((outHeader->nAllocLen < yFrameSize) ||
+ (outHeader->nAllocLen - yFrameSize < yFrameSize / 2)) {
+ ALOGE("Too small output buffer for reference frame: %zu bytes",
+ outHeader->nAllocLen);
+ android_errorWriteLog(0x534e4554, "30033990");
+ notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL);
+ mSignalledError = true;
+ return;
+ }
PVSetReferenceYUV(mHandle, outHeader->pBuffer);
-
mFramesConfigured = true;
}
@@ -229,7 +238,16 @@
int32_t bufferSize = inHeader->nFilledLen;
int32_t tmp = bufferSize;
- OMX_U32 frameSize = (mWidth * mHeight * 3) / 2;
+ OMX_U32 frameSize;
+ OMX_U64 yFrameSize = (OMX_U64)mWidth * (OMX_U64)mHeight;
+ if (yFrameSize > ((OMX_U64)UINT32_MAX / 3) * 2) {
+ ALOGE("Frame size too large");
+ notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL);
+ mSignalledError = true;
+ return;
+ }
+ frameSize = (OMX_U32)(yFrameSize + (yFrameSize / 2));
+
if (outHeader->nAllocLen < frameSize) {
android_errorWriteLog(0x534e4554, "27833616");
ALOGE("Insufficient output buffer size");
diff --git a/media/libstagefright/codecs/m4v_h263/enc/SoftMPEG4Encoder.cpp b/media/libstagefright/codecs/m4v_h263/enc/SoftMPEG4Encoder.cpp
index 8802fad..f496b0c 100644
--- a/media/libstagefright/codecs/m4v_h263/enc/SoftMPEG4Encoder.cpp
+++ b/media/libstagefright/codecs/m4v_h263/enc/SoftMPEG4Encoder.cpp
@@ -116,6 +116,10 @@
ALOGE("Failed to get default encoding parameters");
return OMX_ErrorUndefined;
}
+ if (mFramerate == 0) {
+ ALOGE("Framerate should not be 0");
+ return OMX_ErrorUndefined;
+ }
mEncParams->encMode = mEncodeMode;
mEncParams->encWidth[0] = mWidth;
mEncParams->encHeight[0] = mHeight;
diff --git a/media/libstagefright/foundation/MediaBuffer.cpp b/media/libstagefright/foundation/MediaBuffer.cpp
index 15d557d..718b7e5 100644
--- a/media/libstagefright/foundation/MediaBuffer.cpp
+++ b/media/libstagefright/foundation/MediaBuffer.cpp
@@ -30,6 +30,9 @@
namespace android {
+/* static */
+std::atomic_int_least32_t MediaBuffer::mUseSharedMemory(0);
+
MediaBuffer::MediaBuffer(void *data, size_t size)
: mObserver(NULL),
mRefCount(0),
@@ -52,7 +55,8 @@
mOwnsData(true),
mMetaData(new MetaData),
mOriginal(NULL) {
- if (size < kSharedMemThreshold) {
+ if (size < kSharedMemThreshold
+ || std::atomic_load_explicit(&mUseSharedMemory, std::memory_order_seq_cst) == 0) {
mData = malloc(size);
} else {
ALOGV("creating memoryDealer");
diff --git a/services/audioflinger/Android.mk b/services/audioflinger/Android.mk
index 8b831f0..05dacac 100644
--- a/services/audioflinger/Android.mk
+++ b/services/audioflinger/Android.mk
@@ -3,7 +3,8 @@
include $(CLEAR_VARS)
LOCAL_SRC_FILES := \
- ServiceUtilities.cpp
+ ServiceUtilities.cpp \
+ LockWatch.cpp
# FIXME Move this library to frameworks/native
LOCAL_MODULE := libserviceutility
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index 79f4a66..c32eadd 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -246,7 +246,9 @@
}
mPatchPanel = new PatchPanel(this);
-
+ // FIXME: bug 30737845: trigger audioserver restart if main audioflinger lock
+ // is held continuously for more than 3 seconds
+ mLockWatch = new LockWatch(mLock, String8("AudioFlinger"));
mMode = AUDIO_MODE_NORMAL;
}
@@ -279,6 +281,7 @@
}
}
}
+ mLockWatch->requestExitAndWait();
}
static const char * const audio_interfaces[] = {
diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h
index c56dcc1..e334d80 100644
--- a/services/audioflinger/AudioFlinger.h
+++ b/services/audioflinger/AudioFlinger.h
@@ -58,6 +58,7 @@
#include "SpdifStreamOut.h"
#include "AudioHwDevice.h"
#include "LinearMap.h"
+#include "LockWatch.h"
#include <powermanager/IPowerManager.h>
@@ -630,6 +631,7 @@
};
mutable Mutex mLock;
+ sp<LockWatch> mLockWatch;
// protects mClients and mNotificationClients.
// must be locked after mLock and ThreadBase::mLock if both must be locked
// avoids acquiring AudioFlinger::mLock from inside thread loop.
diff --git a/services/audioflinger/BufferProviders.cpp b/services/audioflinger/BufferProviders.cpp
index 2ca2cac..7b6dfcb 100644
--- a/services/audioflinger/BufferProviders.cpp
+++ b/services/audioflinger/BufferProviders.cpp
@@ -474,18 +474,18 @@
ALOGV("processFrames(%zu %zu) remaining(%zu)", *dstFrames, *srcFrames, mRemaining);
// Note dstFrames is the required number of frames.
- // Ensure consumption from src is as expected.
- //TODO: add logic to track "very accurate" consumption related to speed, original sampling
- //rate, actual frames processed.
- const size_t targetSrc = *dstFrames * mPlaybackRate.mSpeed;
- if (*srcFrames < targetSrc) { // limit dst frames to that possible
- *dstFrames = *srcFrames / mPlaybackRate.mSpeed;
- } else if (*srcFrames > targetSrc + 1) {
- *srcFrames = targetSrc + 1;
- }
-
if (!mAudioPlaybackRateValid) {
//fallback mode
+ // Ensure consumption from src is as expected.
+ // TODO: add logic to track "very accurate" consumption related to speed, original sampling
+ // rate, actual frames processed.
+
+ const size_t targetSrc = *dstFrames * mPlaybackRate.mSpeed;
+ if (*srcFrames < targetSrc) { // limit dst frames to that possible
+ *dstFrames = *srcFrames / mPlaybackRate.mSpeed;
+ } else if (*srcFrames > targetSrc + 1) {
+ *srcFrames = targetSrc + 1;
+ }
if (*dstFrames > 0) {
switch(mPlaybackRate.mFallbackMode) {
case AUDIO_TIMESTRETCH_FALLBACK_CUT_REPEAT:
diff --git a/services/audioflinger/LockWatch.cpp b/services/audioflinger/LockWatch.cpp
new file mode 100644
index 0000000..21eed6e
--- /dev/null
+++ b/services/audioflinger/LockWatch.cpp
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "LockWatch"
+//#define LOG_NDEBUG 0
+
+#include <utils/Log.h>
+#include "LockWatch.h"
+
+namespace android {
+
+void LockWatch::onFirstRef()
+{
+ run("lock watch", ANDROID_PRIORITY_URGENT_AUDIO);
+}
+
+bool LockWatch::threadLoop()
+{
+ while (!exitPending()) {
+ // we neglect previous lock time effect on period
+ usleep(mPeriodMs * 1000);
+ if (mLock.timedLock(milliseconds(mTimeOutMs)) != NO_ERROR) {
+ LOG_ALWAYS_FATAL("LockWatch timeout for: %s", mTag.string());
+ }
+ mLock.unlock();
+ }
+ return false;
+}
+
+} // namespace android
+
diff --git a/services/audioflinger/LockWatch.h b/services/audioflinger/LockWatch.h
new file mode 100644
index 0000000..2d30217
--- /dev/null
+++ b/services/audioflinger/LockWatch.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#ifndef LOCK_WATCH_H
+#define LOCK_WATCH_H
+
+#include <utils/String8.h>
+#include <utils/Thread.h>
+
+namespace android {
+
+// periodically checks if a mutex can be acquired and kill process otherwise
+class LockWatch : public Thread {
+
+public:
+ static const uint32_t DEFAULT_PERIOD_MS = 10000; // 10 seconds default check period
+ static const uint32_t DEFAULT_TIMEOUT_MS = 3000; // 3 seconds default lock timeout
+
+ LockWatch(Mutex& lock, const String8& tag = String8(""),
+ uint32_t periodMs = DEFAULT_PERIOD_MS, uint32_t timeoutMs = DEFAULT_TIMEOUT_MS)
+ : Thread(false /*canCallJava*/),
+ mLock(lock), mTag(tag), mPeriodMs(periodMs), mTimeOutMs(timeoutMs) {}
+
+ virtual ~LockWatch() { }
+
+ // RefBase
+ virtual void onFirstRef();
+
+private:
+ // Thread
+ virtual bool threadLoop();
+
+ Mutex& mLock; // monitored mutex
+ String8 mTag; // tag
+ uint32_t mPeriodMs; // check period in milliseconds
+ uint32_t mTimeOutMs; // mutex lock timeout in milliseconds
+};
+
+} // namespace android
+
+#endif // LOCK_WATCH_H
diff --git a/services/camera/libcameraservice/device3/Camera3Device.cpp b/services/camera/libcameraservice/device3/Camera3Device.cpp
index 5703934..48a2a99 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.cpp
+++ b/services/camera/libcameraservice/device3/Camera3Device.cpp
@@ -42,6 +42,7 @@
#include <utils/Log.h>
#include <utils/Trace.h>
#include <utils/Timers.h>
+#include <cutils/properties.h>
#include <android/hardware/camera2/ICameraDeviceUser.h>
@@ -169,6 +170,9 @@
return res;
}
+ /** Register in-flight map to the status tracker */
+ mInFlightStatusId = mStatusTracker->addComponent();
+
/** Create buffer manager */
mBufferManager = new Camera3BufferManager();
@@ -2037,15 +2041,20 @@
// across configure_streams() calls
mRequestThread->configurationComplete(mIsConstrainedHighSpeedConfiguration);
- // Boost priority of request thread to SCHED_FIFO.
- pid_t requestThreadTid = mRequestThread->getTid();
- res = requestPriority(getpid(), requestThreadTid,
- kRequestThreadPriority, /*asynchronous*/ false);
- if (res != OK) {
- ALOGW("Can't set realtime priority for request processing thread: %s (%d)",
- strerror(-res), res);
- } else {
- ALOGD("Set real time priority for request queue thread (tid %d)", requestThreadTid);
+ char value[PROPERTY_VALUE_MAX];
+ property_get("camera.fifo.disable", value, "0");
+ int32_t disableFifo = atoi(value);
+ if (disableFifo != 1) {
+ // Boost priority of request thread to SCHED_FIFO.
+ pid_t requestThreadTid = mRequestThread->getTid();
+ res = requestPriority(getpid(), requestThreadTid,
+ kRequestThreadPriority, /*asynchronous*/ false);
+ if (res != OK) {
+ ALOGW("Can't set realtime priority for request processing thread: %s (%d)",
+ strerror(-res), res);
+ } else {
+ ALOGD("Set real time priority for request queue thread (tid %d)", requestThreadTid);
+ }
}
// Update device state
@@ -2190,6 +2199,10 @@
aeTriggerCancelOverride));
if (res < 0) return res;
+ if (mInFlightMap.size() == 1) {
+ mStatusTracker->markComponentActive(mInFlightStatusId);
+ }
+
return OK;
}
@@ -2246,6 +2259,11 @@
mInFlightMap.removeItemsAt(idx, 1);
+ // Indicate idle inFlightMap to the status tracker
+ if (mInFlightMap.size() == 0) {
+ mStatusTracker->markComponentIdle(mInFlightStatusId, Fence::NO_FENCE);
+ }
+
ALOGVV("%s: removed frame %d from InFlightMap", __FUNCTION__, frameNumber);
}
diff --git a/services/camera/libcameraservice/device3/Camera3Device.h b/services/camera/libcameraservice/device3/Camera3Device.h
index 3244258..17893a9 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.h
+++ b/services/camera/libcameraservice/device3/Camera3Device.h
@@ -725,6 +725,7 @@
Mutex mInFlightLock; // Protects mInFlightMap
InFlightMap mInFlightMap;
+ int mInFlightStatusId;
status_t registerInFlight(uint32_t frameNumber,
int32_t numBuffers, CaptureResultExtras resultExtras, bool hasInput,