summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--camera/CameraMetadata.cpp11
-rw-r--r--include/media/stagefright/MediaSync.h8
-rw-r--r--media/libstagefright/ACodec.cpp13
-rw-r--r--media/libstagefright/MediaSync.cpp71
-rw-r--r--media/libstagefright/codecs/avcdec/SoftAVCDec.cpp2
-rw-r--r--media/libstagefright/foundation/ABuffer.cpp14
-rw-r--r--media/libstagefright/matroska/MatroskaExtractor.cpp8
7 files changed, 69 insertions, 58 deletions
diff --git a/camera/CameraMetadata.cpp b/camera/CameraMetadata.cpp
index b96a88f..46bcc1d 100644
--- a/camera/CameraMetadata.cpp
+++ b/camera/CameraMetadata.cpp
@@ -289,6 +289,17 @@ status_t CameraMetadata::updateImpl(uint32_t tag, const void *data,
ALOGE("%s: Tag %d not found", __FUNCTION__, tag);
return BAD_VALUE;
}
+ // Safety check - ensure that data isn't pointing to this metadata, since
+ // that would get invalidated if a resize is needed
+ size_t bufferSize = get_camera_metadata_size(mBuffer);
+ uintptr_t bufAddr = reinterpret_cast<uintptr_t>(mBuffer);
+ uintptr_t dataAddr = reinterpret_cast<uintptr_t>(data);
+ if (dataAddr > bufAddr && dataAddr < (bufAddr + bufferSize)) {
+ ALOGE("%s: Update attempted with data from the same metadata buffer!",
+ __FUNCTION__);
+ return INVALID_OPERATION;
+ }
+
size_t data_size = calculate_camera_metadata_entry_data_size(type,
data_count);
diff --git a/include/media/stagefright/MediaSync.h b/include/media/stagefright/MediaSync.h
index 4b5cd05..ef8cb23 100644
--- a/include/media/stagefright/MediaSync.h
+++ b/include/media/stagefright/MediaSync.h
@@ -135,8 +135,7 @@ protected:
private:
enum {
- kWhatDrainVideo = 'dVid',
- kWhatCheckFrameAvailable = 'cFrA',
+ kWhatDrainVideo = 'dVid',
};
// This is a thin wrapper class that lets us listen to
@@ -248,9 +247,8 @@ private:
// onBufferReleasedByOutput releases a buffer back to the input.
void onFrameAvailableFromInput();
- // Send |bufferItem| to the output for rendering. If this is not the only
- // buffer sent for rendering, check for any dropped frames in |checkInUs| us.
- void renderOneBufferItem_l(const BufferItem &bufferItem, int64_t checkInUs);
+ // Send |bufferItem| to the output for rendering.
+ void renderOneBufferItem_l(const BufferItem &bufferItem);
// This implements the onBufferReleased callback from IProducerListener.
// It gets called from an OutputListener.
diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp
index cebd577..4e1f094 100644
--- a/media/libstagefright/ACodec.cpp
+++ b/media/libstagefright/ACodec.cpp
@@ -1400,7 +1400,7 @@ ACodec::BufferInfo *ACodec::dequeueBufferFromNativeWindow() {
ALOGV("replaced oldest buffer #%u with age %u (%p/%p stored in %p)",
(unsigned)(oldest - &mBuffers[kPortIndexOutput][0]),
mDequeueCounter - oldest->mDequeuedAt,
- grallocMeta->pHandle,
+ (void *)(uintptr_t)grallocMeta->pHandle,
oldest->mGraphicBuffer->handle, oldest->mData->base());
} else if (mOutputMetadataType == kMetadataBufferTypeANWBuffer) {
VideoNativeMetadata *nativeMeta =
@@ -1408,7 +1408,7 @@ ACodec::BufferInfo *ACodec::dequeueBufferFromNativeWindow() {
ALOGV("replaced oldest buffer #%u with age %u (%p/%p stored in %p)",
(unsigned)(oldest - &mBuffers[kPortIndexOutput][0]),
mDequeueCounter - oldest->mDequeuedAt,
- nativeMeta->pBuffer,
+ (void *)(uintptr_t)nativeMeta->pBuffer,
oldest->mGraphicBuffer->getNativeBuffer(), oldest->mData->base());
}
@@ -4034,7 +4034,7 @@ status_t ACodec::getPortFormat(OMX_U32 portIndex, sp<AMessage> &notify) {
sizeof(describeParams.sMediaImage)));
MediaImage *img = &describeParams.sMediaImage;
- ALOGV("[%s] MediaImage { F(%zux%zu) @%zu+%zu+%zu @%zu+%zu+%zu @%zu+%zu+%zu }",
+ ALOGV("[%s] MediaImage { F(%ux%u) @%u+%u+%u @%u+%u+%u @%u+%u+%u }",
mComponentName.c_str(), img->mWidth, img->mHeight,
img->mPlane[0].mOffset, img->mPlane[0].mColInc, img->mPlane[0].mRowInc,
img->mPlane[1].mOffset, img->mPlane[1].mColInc, img->mPlane[1].mRowInc,
@@ -5144,10 +5144,15 @@ bool ACodec::BaseState::onOMXFillBufferDone(
VideoNativeMetadata &nativeMeta = *(VideoNativeMetadata *)info->mData->data();
if (info->mData->size() >= sizeof(grallocMeta)
&& grallocMeta.eType == kMetadataBufferTypeGrallocSource) {
- handle = (native_handle_t *)grallocMeta.pHandle;
+ handle = (native_handle_t *)(uintptr_t)grallocMeta.pHandle;
} else if (info->mData->size() >= sizeof(nativeMeta)
&& nativeMeta.eType == kMetadataBufferTypeANWBuffer) {
+#ifdef OMX_ANDROID_COMPILE_AS_32BIT_ON_64BIT_PLATFORMS
+ // ANativeWindowBuffer is only valid on 32-bit/mediaserver process
+ handle = NULL;
+#else
handle = (native_handle_t *)nativeMeta.pBuffer->handle;
+#endif
}
info->mData->meta()->setPointer("handle", handle);
info->mData->meta()->setInt32("rangeOffset", rangeOffset);
diff --git a/media/libstagefright/MediaSync.cpp b/media/libstagefright/MediaSync.cpp
index 0df3ec9..3a45e25 100644
--- a/media/libstagefright/MediaSync.cpp
+++ b/media/libstagefright/MediaSync.cpp
@@ -558,8 +558,7 @@ void MediaSync::onDrainVideo_l() {
// adjust video frame PTS based on vsync
itemRealUs = mFrameScheduler->schedule(itemRealUs * 1000) / 1000;
- int64_t oneVsyncUs = (mFrameScheduler->getVsyncPeriod() / 1000);
- int64_t twoVsyncsUs = oneVsyncUs * 2;
+ int64_t twoVsyncsUs = 2 * (mFrameScheduler->getVsyncPeriod() / 1000);
// post 2 display refreshes before rendering is due
if (itemRealUs <= nowUs + twoVsyncsUs) {
@@ -570,7 +569,7 @@ void MediaSync::onDrainVideo_l() {
if (mHasAudio) {
if (nowUs - itemRealUs <= kMaxAllowedVideoLateTimeUs) {
- renderOneBufferItem_l(*bufferItem, nowUs + oneVsyncUs - itemRealUs);
+ renderOneBufferItem_l(*bufferItem);
} else {
// too late.
returnBufferToInput_l(
@@ -579,7 +578,7 @@ void MediaSync::onDrainVideo_l() {
}
} else {
// always render video buffer in video-only mode.
- renderOneBufferItem_l(*bufferItem, nowUs + oneVsyncUs - itemRealUs);
+ renderOneBufferItem_l(*bufferItem);
// smooth out videos >= 10fps
mMediaClock->updateAnchor(
@@ -613,7 +612,7 @@ void MediaSync::onFrameAvailableFromInput() {
while (mNumOutstandingBuffers > mMaxAcquiredBufferCount
&& !mIsAbandoned && !mReturnPendingInputFrame) {
if (mReleaseCondition.waitRelative(mMutex, kAcquireWaitTimeout) != OK) {
- ALOGI("still waiting to release a buffer before acquire");
+ ALOGI_IF(mPlaybackRate != 0.f, "still waiting to release a buffer before acquire");
}
// If the sync is abandoned while we are waiting, the release
@@ -670,7 +669,7 @@ void MediaSync::onFrameAvailableFromInput() {
}
}
-void MediaSync::renderOneBufferItem_l(const BufferItem &bufferItem, int64_t checkInUs) {
+void MediaSync::renderOneBufferItem_l(const BufferItem &bufferItem) {
IGraphicBufferProducer::QueueBufferInput queueInput(
bufferItem.mTimestamp,
bufferItem.mIsAutoTimestamp,
@@ -710,12 +709,6 @@ void MediaSync::renderOneBufferItem_l(const BufferItem &bufferItem, int64_t chec
mBuffersSentToOutput.add(bufferItem.mGraphicBuffer->getId(), bufferItem.mGraphicBuffer);
ALOGV("queued buffer %#llx to output", (long long)bufferItem.mGraphicBuffer->getId());
-
- // If we have already queued more than one buffer, check for any free buffers in case
- // one of them were dropped - as BQ does not signal onBufferReleased in that case.
- if (mBuffersSentToOutput.size() > 1) {
- (new AMessage(kWhatCheckFrameAvailable, this))->post(checkInUs);
- }
}
void MediaSync::onBufferReleasedByOutput(sp<IGraphicBufferProducer> &output) {
@@ -727,38 +720,32 @@ void MediaSync::onBufferReleasedByOutput(sp<IGraphicBufferProducer> &output) {
sp<GraphicBuffer> buffer;
sp<Fence> fence;
- status_t status;
- // NOTE: This is a workaround for a BufferQueue bug where onBufferReleased is
- // called only for released buffers, but not for buffers that were dropped during
- // acquire. Dropped buffers can still be detached as they are on the free list.
- // TODO: remove if released callback happens also for dropped buffers
- while ((status = mOutput->detachNextBuffer(&buffer, &fence)) != NO_MEMORY) {
- ALOGE_IF(status != NO_ERROR, "detaching buffer from output failed (%d)", status);
-
- if (status == NO_INIT) {
- // If the output has been abandoned, we can't do anything else,
- // since buffer is invalid.
- onAbandoned_l(false /* isInput */);
- return;
- }
+ status_t status = mOutput->detachNextBuffer(&buffer, &fence);
+ ALOGE_IF(status != NO_ERROR, "detaching buffer from output failed (%d)", status);
- ALOGV("detached buffer %#llx from output", (long long)buffer->getId());
+ if (status == NO_INIT) {
+ // If the output has been abandoned, we can't do anything else,
+ // since buffer is invalid.
+ onAbandoned_l(false /* isInput */);
+ return;
+ }
- // If we've been abandoned, we can't return the buffer to the input, so just
- // move on.
- if (mIsAbandoned) {
- return;
- }
+ ALOGV("detached buffer %#llx from output", (long long)buffer->getId());
- ssize_t ix = mBuffersSentToOutput.indexOfKey(buffer->getId());
- if (ix < 0) {
- // The buffer is unknown, maybe leftover, ignore.
- return;
- }
- mBuffersSentToOutput.removeItemsAt(ix);
+ // If we've been abandoned, we can't return the buffer to the input, so just
+ // move on.
+ if (mIsAbandoned) {
+ return;
+ }
- returnBufferToInput_l(buffer, fence);
+ ssize_t ix = mBuffersSentToOutput.indexOfKey(buffer->getId());
+ if (ix < 0) {
+ // The buffer is unknown, maybe leftover, ignore.
+ return;
}
+ mBuffersSentToOutput.removeItemsAt(ix);
+
+ returnBufferToInput_l(buffer, fence);
}
void MediaSync::returnBufferToInput_l(
@@ -829,12 +816,6 @@ void MediaSync::onMessageReceived(const sp<AMessage> &msg) {
break;
}
- case kWhatCheckFrameAvailable:
- {
- onBufferReleasedByOutput(mOutput);
- break;
- }
-
default:
TRESPASS();
break;
diff --git a/media/libstagefright/codecs/avcdec/SoftAVCDec.cpp b/media/libstagefright/codecs/avcdec/SoftAVCDec.cpp
index aab3af7..8e7a277 100644
--- a/media/libstagefright/codecs/avcdec/SoftAVCDec.cpp
+++ b/media/libstagefright/codecs/avcdec/SoftAVCDec.cpp
@@ -526,6 +526,8 @@ OMX_ERRORTYPE SoftAVC::internalSetParameter(OMX_INDEXTYPE index, const OMX_PTR p
const uint32_t oldHeight = mHeight;
OMX_ERRORTYPE ret = SoftVideoDecoderOMXComponent::internalSetParameter(index, params);
if (mWidth != oldWidth || mHeight != oldHeight) {
+ mNewWidth = mWidth;
+ mNewHeight = mHeight;
status_t err = reInitDecoder(mNewWidth, mNewHeight);
if (err != OK) {
notify(OMX_EventError, OMX_ErrorUnsupportedSetting, err, NULL);
diff --git a/media/libstagefright/foundation/ABuffer.cpp b/media/libstagefright/foundation/ABuffer.cpp
index b214870..a5b81a8 100644
--- a/media/libstagefright/foundation/ABuffer.cpp
+++ b/media/libstagefright/foundation/ABuffer.cpp
@@ -25,12 +25,17 @@ namespace android {
ABuffer::ABuffer(size_t capacity)
: mMediaBufferBase(NULL),
- mData(malloc(capacity)),
- mCapacity(capacity),
mRangeOffset(0),
- mRangeLength(capacity),
mInt32Data(0),
mOwnsData(true) {
+ mData = malloc(capacity);
+ if (mData == NULL) {
+ mCapacity = 0;
+ mRangeLength = 0;
+ } else {
+ mCapacity = capacity;
+ mRangeLength = capacity;
+ }
}
ABuffer::ABuffer(void *data, size_t capacity)
@@ -47,6 +52,9 @@ ABuffer::ABuffer(void *data, size_t capacity)
sp<ABuffer> ABuffer::CreateAsCopy(const void *data, size_t capacity)
{
sp<ABuffer> res = new ABuffer(capacity);
+ if (res->base() == NULL) {
+ return NULL;
+ }
memcpy(res->data(), data, capacity);
return res;
}
diff --git a/media/libstagefright/matroska/MatroskaExtractor.cpp b/media/libstagefright/matroska/MatroskaExtractor.cpp
index 70d2c69..e8bd432 100644
--- a/media/libstagefright/matroska/MatroskaExtractor.cpp
+++ b/media/libstagefright/matroska/MatroskaExtractor.cpp
@@ -21,6 +21,7 @@
#include "MatroskaExtractor.h"
#include <media/stagefright/foundation/ADebug.h>
+#include <media/stagefright/foundation/AUtils.h>
#include <media/stagefright/foundation/hexdump.h>
#include <media/stagefright/DataSource.h>
#include <media/stagefright/MediaBuffer.h>
@@ -620,7 +621,12 @@ status_t MatroskaSource::read(
TRESPASS();
}
- if (srcOffset + mNALSizeLen + NALsize > srcSize) {
+ if (srcOffset + mNALSizeLen + NALsize <= srcOffset + mNALSizeLen) {
+ frame->release();
+ frame = NULL;
+
+ return ERROR_MALFORMED;
+ } else if (srcOffset + mNALSizeLen + NALsize > srcSize) {
break;
}