Merge "AudioTrack: Prevent stop() from reissuing last marker event" into mnc-dr-dev
diff --git a/include/media/AudioSystem.h b/include/media/AudioSystem.h
index 06116a5..26a0bb2 100644
--- a/include/media/AudioSystem.h
+++ b/include/media/AudioSystem.h
@@ -399,6 +399,7 @@
uint32_t mInSamplingRate;
audio_format_t mInFormat;
audio_channel_mask_t mInChannelMask;
+ sp<AudioIoDescriptor> getIoDescriptor_l(audio_io_handle_t ioHandle);
};
class AudioPolicyServiceClient: public IBinder::DeathRecipient,
diff --git a/include/media/IOMX.h b/include/media/IOMX.h
index 3d29e4a..27ad694 100644
--- a/include/media/IOMX.h
+++ b/include/media/IOMX.h
@@ -249,6 +249,12 @@
virtual status_t onTransact(
uint32_t code, const Parcel &data, Parcel *reply,
uint32_t flags = 0);
+
+protected:
+ // check if the codec is secure.
+ virtual bool isSecure(IOMX::node_id node) {
+ return false;
+ }
};
class BnOMXObserver : public BnInterface<IOMXObserver> {
diff --git a/media/libmedia/AudioSystem.cpp b/media/libmedia/AudioSystem.cpp
index 3bfb09a..9d645f0 100644
--- a/media/libmedia/AudioSystem.cpp
+++ b/media/libmedia/AudioSystem.cpp
@@ -476,7 +476,7 @@
switch (event) {
case AUDIO_OUTPUT_OPENED:
case AUDIO_INPUT_OPENED: {
- sp<AudioIoDescriptor> oldDesc = getIoDescriptor(ioDesc->mIoHandle);
+ sp<AudioIoDescriptor> oldDesc = getIoDescriptor_l(ioDesc->mIoHandle);
if (oldDesc == 0) {
mIoDescriptors.add(ioDesc->mIoHandle, ioDesc);
} else {
@@ -498,7 +498,7 @@
} break;
case AUDIO_OUTPUT_CLOSED:
case AUDIO_INPUT_CLOSED: {
- if (getIoDescriptor(ioDesc->mIoHandle) == 0) {
+ if (getIoDescriptor_l(ioDesc->mIoHandle) == 0) {
ALOGW("ioConfigChanged() closing unknown %s %d",
event == AUDIO_OUTPUT_CLOSED ? "output" : "input", ioDesc->mIoHandle);
break;
@@ -512,7 +512,7 @@
case AUDIO_OUTPUT_CONFIG_CHANGED:
case AUDIO_INPUT_CONFIG_CHANGED: {
- sp<AudioIoDescriptor> oldDesc = getIoDescriptor(ioDesc->mIoHandle);
+ sp<AudioIoDescriptor> oldDesc = getIoDescriptor_l(ioDesc->mIoHandle);
if (oldDesc == 0) {
ALOGW("ioConfigChanged() modifying unknown output! %d", ioDesc->mIoHandle);
break;
@@ -575,7 +575,7 @@
return NO_ERROR;
}
-sp<AudioIoDescriptor> AudioSystem::AudioFlingerClient::getIoDescriptor(audio_io_handle_t ioHandle)
+sp<AudioIoDescriptor> AudioSystem::AudioFlingerClient::getIoDescriptor_l(audio_io_handle_t ioHandle)
{
sp<AudioIoDescriptor> desc;
ssize_t index = mIoDescriptors.indexOfKey(ioHandle);
@@ -585,6 +585,12 @@
return desc;
}
+sp<AudioIoDescriptor> AudioSystem::AudioFlingerClient::getIoDescriptor(audio_io_handle_t ioHandle)
+{
+ Mutex::Autolock _l(mLock);
+ return getIoDescriptor_l(ioHandle);
+}
+
status_t AudioSystem::AudioFlingerClient::addAudioDeviceCallback(
const sp<AudioDeviceCallback>& callback, audio_io_handle_t audioIo)
{
diff --git a/media/libmedia/IOMX.cpp b/media/libmedia/IOMX.cpp
index 16da65e..5423c2a 100644
--- a/media/libmedia/IOMX.cpp
+++ b/media/libmedia/IOMX.cpp
@@ -963,6 +963,12 @@
node_id node = (node_id)data.readInt32();
OMX_U32 port_index = data.readInt32();
+ if (!isSecure(node) || port_index != 0 /* kPortIndexInput */) {
+ ALOGE("b/24310423");
+ reply->writeInt32(INVALID_OPERATION);
+ return NO_ERROR;
+ }
+
size_t size = data.readInt64();
buffer_id buffer;
diff --git a/media/libstagefright/MPEG4Extractor.cpp b/media/libstagefright/MPEG4Extractor.cpp
index 38ae6f3..a1af3aa 100755
--- a/media/libstagefright/MPEG4Extractor.cpp
+++ b/media/libstagefright/MPEG4Extractor.cpp
@@ -2564,6 +2564,12 @@
mLastCommentName.setTo((const char *)buffer + 4);
break;
case FOURCC('d', 'a', 't', 'a'):
+ if (size < 8) {
+ delete[] buffer;
+ buffer = NULL;
+ ALOGE("b/24346430");
+ return ERROR_MALFORMED;
+ }
mLastCommentData.setTo((const char *)buffer + 8);
break;
}
@@ -4144,7 +4150,10 @@
(const uint8_t *)mBuffer->data() + mBuffer->range_offset();
size_t nal_size = parseNALSize(src);
- if (mBuffer->range_length() < mNALLengthSize + nal_size) {
+ if (mNALLengthSize > SIZE_MAX - nal_size) {
+ ALOGE("b/24441553, b/24445122");
+ }
+ if (mBuffer->range_length() - mNALLengthSize < nal_size) {
ALOGE("incomplete NAL unit.");
mBuffer->release();
@@ -4431,7 +4440,11 @@
(const uint8_t *)mBuffer->data() + mBuffer->range_offset();
size_t nal_size = parseNALSize(src);
- if (mBuffer->range_length() < mNALLengthSize + nal_size) {
+ if (mNALLengthSize > SIZE_MAX - nal_size) {
+ ALOGE("b/24441553, b/24445122");
+ }
+
+ if (mBuffer->range_length() - mNALLengthSize < nal_size) {
ALOGE("incomplete NAL unit.");
mBuffer->release();
diff --git a/media/libstagefright/codecs/m4v_h263/dec/src/conceal.cpp b/media/libstagefright/codecs/m4v_h263/dec/src/conceal.cpp
index e9ead01..03e4119 100644
--- a/media/libstagefright/codecs/m4v_h263/dec/src/conceal.cpp
+++ b/media/libstagefright/codecs/m4v_h263/dec/src/conceal.cpp
@@ -19,6 +19,7 @@
#include "vlc_decode.h"
#include "bitstream.h"
#include "scaling.h"
+#include "log/log.h"
/* ====================================================================== /
Function : ConcealTexture_I()
@@ -137,6 +138,10 @@
****************************************************************************/
void CopyVopMB(Vop *curr, uint8 *prevFrame, int mbnum, int width_Y, int height)
{
+ if (curr == NULL || prevFrame == NULL) {
+ ALOGE("b/24630158");
+ return;
+ }
int width_C = width_Y >> 1;
int row = MB_SIZE;
uint8 *y1, *y2, *u1, *u2, *v1, *v2;
diff --git a/media/libstagefright/foundation/AMessage.cpp b/media/libstagefright/foundation/AMessage.cpp
index e549ff6..725a574 100644
--- a/media/libstagefright/foundation/AMessage.cpp
+++ b/media/libstagefright/foundation/AMessage.cpp
@@ -601,13 +601,24 @@
msg->setWhat(what);
msg->mNumItems = static_cast<size_t>(parcel.readInt32());
+ if (msg->mNumItems > kMaxNumItems) {
+ ALOGE("Too large number of items clipped.");
+ msg->mNumItems = kMaxNumItems;
+ }
+
for (size_t i = 0; i < msg->mNumItems; ++i) {
Item *item = &msg->mItems[i];
const char *name = parcel.readCString();
- item->setName(name, strlen(name));
- item->mType = static_cast<Type>(parcel.readInt32());
+ if (name == NULL) {
+ ALOGE("Failed reading name for an item. Parsing aborted.");
+ msg->mNumItems = i;
+ break;
+ }
+ item->mType = static_cast<Type>(parcel.readInt32());
+ // setName() happens below so that we don't leak memory when parsing
+ // is aborted in the middle.
switch (item->mType) {
case kTypeInt32:
{
@@ -641,7 +652,16 @@
case kTypeString:
{
- item->u.stringValue = new AString(parcel.readCString());
+ const char *stringValue = parcel.readCString();
+ if (stringValue == NULL) {
+ ALOGE("Failed reading string value from a parcel. "
+ "Parsing aborted.");
+ msg->mNumItems = i;
+ continue;
+ // The loop will terminate subsequently.
+ } else {
+ item->u.stringValue = new AString(stringValue);
+ }
break;
}
@@ -660,6 +680,8 @@
TRESPASS();
}
}
+
+ item->setName(name, strlen(name));
}
return msg;
diff --git a/media/libstagefright/id3/ID3.cpp b/media/libstagefright/id3/ID3.cpp
index 00f87aa..4410579 100644
--- a/media/libstagefright/id3/ID3.cpp
+++ b/media/libstagefright/id3/ID3.cpp
@@ -194,6 +194,13 @@
if (header.version_major == 4) {
void *copy = malloc(size);
+ if (copy == NULL) {
+ free(mData);
+ mData = NULL;
+ ALOGE("b/24623447, no more memory");
+ return false;
+ }
+
memcpy(copy, mData, size);
bool success = removeUnsynchronizationV2_4(false /* iTunesHack */);
@@ -234,7 +241,14 @@
return false;
}
- size_t extendedHeaderSize = U32_AT(&mData[0]) + 4;
+ size_t extendedHeaderSize = U32_AT(&mData[0]);
+ if (extendedHeaderSize > SIZE_MAX - 4) {
+ free(mData);
+ mData = NULL;
+ ALOGE("b/24623447, extendedHeaderSize is too large");
+ return false;
+ }
+ extendedHeaderSize += 4;
if (extendedHeaderSize > mSize) {
free(mData);
@@ -252,7 +266,10 @@
if (extendedHeaderSize >= 10) {
size_t paddingSize = U32_AT(&mData[6]);
- if (mFirstFrameOffset + paddingSize > mSize) {
+ if (paddingSize > SIZE_MAX - mFirstFrameOffset) {
+ ALOGE("b/24623447, paddingSize is too large");
+ }
+ if (paddingSize > mSize - mFirstFrameOffset) {
free(mData);
mData = NULL;
diff --git a/media/libstagefright/include/OMX.h b/media/libstagefright/include/OMX.h
index d468dfc..e7c4f6d 100644
--- a/media/libstagefright/include/OMX.h
+++ b/media/libstagefright/include/OMX.h
@@ -140,6 +140,8 @@
virtual void binderDied(const wp<IBinder> &the_late_who);
+ virtual bool isSecure(IOMX::node_id node);
+
OMX_ERRORTYPE OnEvent(
node_id node,
OMX_IN OMX_EVENTTYPE eEvent,
diff --git a/media/libstagefright/include/OMXNodeInstance.h b/media/libstagefright/include/OMXNodeInstance.h
index f68e0a9..e5fb45b 100644
--- a/media/libstagefright/include/OMXNodeInstance.h
+++ b/media/libstagefright/include/OMXNodeInstance.h
@@ -125,6 +125,10 @@
const void *data,
size_t size);
+ bool isSecure() const {
+ return mIsSecure;
+ }
+
// handles messages and removes them from the list
void onMessages(std::list<omx_message> &messages);
void onMessage(const omx_message &msg);
@@ -142,6 +146,7 @@
OMX_HANDLETYPE mHandle;
sp<IOMXObserver> mObserver;
bool mDying;
+ bool mIsSecure;
// Lock only covers mGraphicBufferSource. We can't always use mLock
// because of rare instances where we'd end up locking it recursively.
diff --git a/media/libstagefright/omx/OMX.cpp b/media/libstagefright/omx/OMX.cpp
index cb7ab5e..7f357c9 100644
--- a/media/libstagefright/omx/OMX.cpp
+++ b/media/libstagefright/omx/OMX.cpp
@@ -194,6 +194,11 @@
instance->onObserverDied(mMaster);
}
+bool OMX::isSecure(node_id node) {
+ OMXNodeInstance *instance = findInstance(node);
+ return (instance == NULL ? false : instance->isSecure());
+}
+
bool OMX::livesLocally(node_id /* node */, pid_t pid) {
return pid == getpid();
}
diff --git a/media/libstagefright/omx/OMXNodeInstance.cpp b/media/libstagefright/omx/OMXNodeInstance.cpp
index 9f1c5d8..94a213a 100644
--- a/media/libstagefright/omx/OMXNodeInstance.cpp
+++ b/media/libstagefright/omx/OMXNodeInstance.cpp
@@ -203,6 +203,7 @@
mDebugLevelBumpPendingBuffers[1] = 0;
mMetadataType[0] = kMetadataBufferTypeInvalid;
mMetadataType[1] = kMetadataBufferTypeInvalid;
+ mIsSecure = AString(name).endsWith(".secure");
}
OMXNodeInstance::~OMXNodeInstance() {
diff --git a/services/camera/libcameraservice/device3/Camera3Device.cpp b/services/camera/libcameraservice/device3/Camera3Device.cpp
index 1a3a770..50d9d75 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.cpp
+++ b/services/camera/libcameraservice/device3/Camera3Device.cpp
@@ -67,6 +67,7 @@
mNextResultFrameNumber(0),
mNextReprocessResultFrameNumber(0),
mNextShutterFrameNumber(0),
+ mNextReprocessShutterFrameNumber(0),
mListener(NULL)
{
ATRACE_CALL();
@@ -2534,18 +2535,6 @@
void Camera3Device::notifyShutter(const camera3_shutter_msg_t &msg,
NotificationListener *listener) {
ssize_t idx;
- // Verify ordering of shutter notifications
- {
- Mutex::Autolock l(mOutputLock);
- // TODO: need to track errors for tighter bounds on expected frame number.
- if (msg.frame_number < mNextShutterFrameNumber) {
- SET_ERR("Shutter notification out-of-order. Expected "
- "notification for frame %d, got frame %d",
- mNextShutterFrameNumber, msg.frame_number);
- return;
- }
- mNextShutterFrameNumber = msg.frame_number + 1;
- }
// Set timestamp for the request in the in-flight tracking
// and get the request ID to send upstream
@@ -2555,6 +2544,29 @@
if (idx >= 0) {
InFlightRequest &r = mInFlightMap.editValueAt(idx);
+ // Verify ordering of shutter notifications
+ {
+ Mutex::Autolock l(mOutputLock);
+ // TODO: need to track errors for tighter bounds on expected frame number.
+ if (r.hasInputBuffer) {
+ if (msg.frame_number < mNextReprocessShutterFrameNumber) {
+ SET_ERR("Shutter notification out-of-order. Expected "
+ "notification for frame %d, got frame %d",
+ mNextReprocessShutterFrameNumber, msg.frame_number);
+ return;
+ }
+ mNextReprocessShutterFrameNumber = msg.frame_number + 1;
+ } else {
+ if (msg.frame_number < mNextShutterFrameNumber) {
+ SET_ERR("Shutter notification out-of-order. Expected "
+ "notification for frame %d, got frame %d",
+ mNextShutterFrameNumber, msg.frame_number);
+ return;
+ }
+ mNextShutterFrameNumber = msg.frame_number + 1;
+ }
+ }
+
ALOGVV("Camera %d: %s: Shutter fired for frame %d (id %d) at %" PRId64,
mId, __FUNCTION__,
msg.frame_number, r.resultExtras.requestId, msg.timestamp);
diff --git a/services/camera/libcameraservice/device3/Camera3Device.h b/services/camera/libcameraservice/device3/Camera3Device.h
index 402cb1d..2cd5af3 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.h
+++ b/services/camera/libcameraservice/device3/Camera3Device.h
@@ -162,7 +162,7 @@
static const size_t kInFlightWarnLimit = 20;
static const size_t kInFlightWarnLimitHighSpeed = 256; // batch size 32 * pipe depth 8
// SCHED_FIFO priority for request submission thread in HFR mode
- static const int kConstrainedHighSpeedThreadPriority = 3;
+ static const int kConstrainedHighSpeedThreadPriority = 1;
struct RequestTrigger;
// minimal jpeg buffer size: 256KB + blob header
@@ -771,7 +771,10 @@
uint32_t mNextResultFrameNumber;
// the minimal frame number of the next reprocess result
uint32_t mNextReprocessResultFrameNumber;
+ // the minimal frame number of the next non-reprocess shutter
uint32_t mNextShutterFrameNumber;
+ // the minimal frame number of the next reprocess shutter
+ uint32_t mNextReprocessShutterFrameNumber;
List<CaptureResult> mResultQueue;
Condition mResultSignal;
NotificationListener *mListener;