diff options
| -rw-r--r-- | camera/CameraMetadata.cpp | 11 | ||||
| -rw-r--r-- | include/media/stagefright/MediaSync.h | 8 | ||||
| -rw-r--r-- | media/libstagefright/ACodec.cpp | 13 | ||||
| -rw-r--r-- | media/libstagefright/MediaSync.cpp | 71 | ||||
| -rw-r--r-- | media/libstagefright/codecs/avcdec/SoftAVCDec.cpp | 2 | ||||
| -rw-r--r-- | media/libstagefright/foundation/ABuffer.cpp | 14 | ||||
| -rw-r--r-- | media/libstagefright/matroska/MatroskaExtractor.cpp | 8 |
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> ¬ify) { 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; } |
