From f5ab57c2d5e02af7483c94eddb177e4f5c9e9892 Mon Sep 17 00:00:00 2001 From: Andreas Huber Date: Mon, 22 Nov 2010 13:06:35 -0800 Subject: Squashed commit of the following: commit 0870f7bdd10a7cd36087d723d1957d8e1b967ca7 Author: Andreas Huber Date: Mon Nov 22 12:57:04 2010 -0800 set_surface_crop doesn't seem to work right yet, stop using it in the SoftwareRenderer. Change-Id: If0a24f78b7810a6cecaa82eb4f23d0f90c22cc42 commit 4767b52bee3a54ae117a8708d6832276a44e6a6a Author: Andreas Huber Date: Mon Nov 22 11:14:57 2010 -0800 info->mMediaBuffer may still be NULL at this point... Change-Id: I25a71569015b1bb87f1ea7efff7588958774426f commit 0cef79874e1f1ddb10b7402177a87d3cffc7de92 Author: Andreas Huber Date: Mon Nov 22 10:55:12 2010 -0800 QCOM's YVU420 color format conversion has now been tested. Change-Id: I7fef4b642a928af15d42f006f7cdc107d5ff1d67 commit 84fe05a6c969ede0ce8a85a530e110afca07c7a7 Author: Andreas Huber Date: Mon Nov 22 09:59:50 2010 -0800 Removed remaining traces of suspend/resume. Proper reporting of video dimensions based on cropping rectangle. Change-Id: Ib238b80cbc1f19e7d312f2422eb5e9ab6b06b1bc commit 50970cdc837c5c498bcf0cb61b436196ca9e2ef7 Author: Andreas Huber Date: Fri Nov 19 16:11:06 2010 -0800 Revamped Software Renderer respects the crop rectangle. Removed obsolete ADRENO support code. Change-Id: I984cbc8a99c4d97e09e7d1b1292099c88b9ae535 commit 8abbc6a5608bff650f968540f24a2eab75f254ed Author: Andreas Huber Date: Fri Nov 19 16:10:41 2010 -0800 The metadata retriever now respects the crop rectangle while capturing a video frame. Change-Id: Id3377176060086d16717f62c77ce26fabe899050 commit 2d42e4466609d304e88bd2cdd6eb7b297340cc21 Author: Andreas Huber Date: Fri Nov 19 16:09:50 2010 -0800 Changed ColorConverter APIs to be more general. Clients can now refer to crop rectangles in both source and destination. Change-Id: Ief151d736818396d0389ec04e7df5650e3ad7c04 commit 273184303d54a54febd3e9c3dd4df30507ea78b5 Author: Andreas Huber Date: Fri Nov 19 15:04:06 2010 -0800 The stagefright commandline tool now writes the extracted video frame to /sdcard/out.jpg Change-Id: Ieb2ab3fda7a7cd9294beccb8db0eed75096eeef4 commit 2d43390328cadf4ba94c1c3c02e4fb30baa29690 Author: Andreas Huber Date: Fri Nov 19 14:36:55 2010 -0800 The AVC software decoder now properly advertises the cropping rectangle. Change-Id: Idb7a8a7e2fde5740f0fc34b7e8c92eca2577104b commit 9a7ed23c2fac8ce19dce7a34a603acee945a89f6 Author: Andreas Huber Date: Fri Nov 19 13:40:39 2010 -0800 OMXCodec now signals a format change if the cropping rectangle changes. ...and puts the cropping info into its output format. Change-Id: I3ffbd8e877ba286fe06a82c536ef20d92548d2e2 commit efe0323947029df1c502599ccc288c8d676dfd31 Author: Andreas Huber Date: Fri Nov 19 11:29:39 2010 -0800 Stagefright's MetaData object now supports rectangle items. Change-Id: I5667bb5ee6622c76104b99fb57f60abb802a8504 Change-Id: I27cb78f2c5e0353f95fdfc5cb53991949ed75b70 --- cmds/stagefright/Android.mk | 7 +- cmds/stagefright/stagefright.cpp | 17 + include/media/stagefright/ColorConverter.h | 42 +- include/media/stagefright/MetaData.h | 19 + media/libmediaplayerservice/Android.mk | 1 - media/libstagefright/Android.mk | 2 +- media/libstagefright/AwesomePlayer.cpp | 243 ++--------- media/libstagefright/MetaData.cpp | 35 ++ media/libstagefright/OMXCodec.cpp | 453 +++++++++++---------- .../StagefrightMetadataRetriever.cpp | 29 +- media/libstagefright/codecs/avc/dec/AVCDecoder.cpp | 27 +- media/libstagefright/colorconversion/Android.mk | 16 +- .../colorconversion/ColorConverter.cpp | 192 +++++---- .../colorconversion/SoftwareRenderer.cpp | 147 ++----- media/libstagefright/include/AwesomePlayer.h | 33 -- media/libstagefright/include/SoftwareRenderer.h | 13 +- media/libstagefright/omx/Android.mk | 1 - 17 files changed, 581 insertions(+), 696 deletions(-) diff --git a/cmds/stagefright/Android.mk b/cmds/stagefright/Android.mk index 654d9dc..93baefd 100644 --- a/cmds/stagefright/Android.mk +++ b/cmds/stagefright/Android.mk @@ -7,13 +7,16 @@ LOCAL_SRC_FILES:= \ SineSource.cpp LOCAL_SHARED_LIBRARIES := \ - libstagefright libmedia libutils libbinder libstagefright_foundation + libstagefright libmedia libutils libbinder libstagefright_foundation \ + libskia LOCAL_C_INCLUDES:= \ $(JNI_H_INCLUDE) \ frameworks/base/media/libstagefright \ frameworks/base/media/libstagefright/include \ - $(TOP)/frameworks/base/include/media/stagefright/openmax + $(TOP)/frameworks/base/include/media/stagefright/openmax \ + external/skia/include/core \ + external/skia/include/images \ LOCAL_CFLAGS += -Wno-multichar diff --git a/cmds/stagefright/stagefright.cpp b/cmds/stagefright/stagefright.cpp index 579d8c3..7e7f6d1 100644 --- a/cmds/stagefright/stagefright.cpp +++ b/cmds/stagefright/stagefright.cpp @@ -49,6 +49,10 @@ #include #include +#include +#include +#include + #include using namespace android; @@ -681,6 +685,19 @@ int main(int argc, char **argv) { if (mem != NULL) { printf("captureFrame(%s) => OK\n", filename); + + VideoFrame *frame = (VideoFrame *)mem->pointer(); + + SkBitmap bitmap; + bitmap.setConfig( + SkBitmap::kRGB_565_Config, frame->mWidth, frame->mHeight); + + bitmap.setPixels((uint8_t *)frame + sizeof(VideoFrame)); + + CHECK(SkImageEncoder::EncodeFile( + "/sdcard/out.jpg", bitmap, + SkImageEncoder::kJPEG_Type, + SkImageEncoder::kDefaultQuality)); } else { mem = retriever->extractAlbumArt(); diff --git a/include/media/stagefright/ColorConverter.h b/include/media/stagefright/ColorConverter.h index bc3f464..2b61f58 100644 --- a/include/media/stagefright/ColorConverter.h +++ b/include/media/stagefright/ColorConverter.h @@ -33,35 +33,47 @@ struct ColorConverter { bool isValid() const; void convert( - size_t width, size_t height, - const void *srcBits, size_t srcSkip, - void *dstBits, size_t dstSkip); + const void *srcBits, + size_t srcWidth, size_t srcHeight, + size_t srcCropLeft, size_t srcCropTop, + size_t srcCropRight, size_t srcCropBottom, + void *dstBits, + size_t dstWidth, size_t dstHeight, + size_t dstCropLeft, size_t dstCropTop, + size_t dstCropRight, size_t dstCropBottom); private: + struct BitmapParams { + BitmapParams( + void *bits, + size_t width, size_t height, + size_t cropLeft, size_t cropTop, + size_t cropRight, size_t cropBottom); + + size_t cropWidth() const; + size_t cropHeight() const; + + void *mBits; + size_t mWidth, mHeight; + size_t mCropLeft, mCropTop, mCropRight, mCropBottom; + }; + OMX_COLOR_FORMATTYPE mSrcFormat, mDstFormat; uint8_t *mClip; uint8_t *initClip(); void convertCbYCrY( - size_t width, size_t height, - const void *srcBits, size_t srcSkip, - void *dstBits, size_t dstSkip); + const BitmapParams &src, const BitmapParams &dst); void convertYUV420Planar( - size_t width, size_t height, - const void *srcBits, size_t srcSkip, - void *dstBits, size_t dstSkip); + const BitmapParams &src, const BitmapParams &dst); void convertQCOMYUV420SemiPlanar( - size_t width, size_t height, - const void *srcBits, size_t srcSkip, - void *dstBits, size_t dstSkip); + const BitmapParams &src, const BitmapParams &dst); void convertYUV420SemiPlanar( - size_t width, size_t height, - const void *srcBits, size_t srcSkip, - void *dstBits, size_t dstSkip); + const BitmapParams &src, const BitmapParams &dst); ColorConverter(const ColorConverter &); ColorConverter &operator=(const ColorConverter &); diff --git a/include/media/stagefright/MetaData.h b/include/media/stagefright/MetaData.h index 295b127..5f33739 100644 --- a/include/media/stagefright/MetaData.h +++ b/include/media/stagefright/MetaData.h @@ -32,6 +32,10 @@ enum { kKeyMIMEType = 'mime', // cstring kKeyWidth = 'widt', // int32_t kKeyHeight = 'heig', // int32_t + + // a rectangle, if absent assumed to be (0, 0, width - 1, height - 1) + kKeyCropRect = 'crop', + kKeyRotation = 'rotA', // int32_t (angle in degrees) kKeyIFramesInterval = 'ifiv', // int32_t kKeyStride = 'strd', // int32_t @@ -125,6 +129,7 @@ public: TYPE_INT64 = 'in64', TYPE_FLOAT = 'floa', TYPE_POINTER = 'ptr ', + TYPE_RECT = 'rect', }; void clear(); @@ -136,12 +141,22 @@ public: bool setFloat(uint32_t key, float value); bool setPointer(uint32_t key, void *value); + bool setRect( + uint32_t key, + int32_t left, int32_t top, + int32_t right, int32_t bottom); + bool findCString(uint32_t key, const char **value); bool findInt32(uint32_t key, int32_t *value); bool findInt64(uint32_t key, int64_t *value); bool findFloat(uint32_t key, float *value); bool findPointer(uint32_t key, void **value); + bool findRect( + uint32_t key, + int32_t *left, int32_t *top, + int32_t *right, int32_t *bottom); + bool setData(uint32_t key, uint32_t type, const void *data, size_t size); bool findData(uint32_t key, uint32_t *type, @@ -187,6 +202,10 @@ private: } }; + struct Rect { + int32_t mLeft, mTop, mRight, mBottom; + }; + KeyedVector mItems; // MetaData &operator=(const MetaData &); diff --git a/media/libmediaplayerservice/Android.mk b/media/libmediaplayerservice/Android.mk index 3341ff7..a9d537f 100644 --- a/media/libmediaplayerservice/Android.mk +++ b/media/libmediaplayerservice/Android.mk @@ -31,7 +31,6 @@ LOCAL_SHARED_LIBRARIES := \ libandroid_runtime \ libstagefright \ libstagefright_omx \ - libstagefright_color_conversion \ libstagefright_foundation \ libsurfaceflinger_client diff --git a/media/libstagefright/Android.mk b/media/libstagefright/Android.mk index 4ad1eb4..db23836 100644 --- a/media/libstagefright/Android.mk +++ b/media/libstagefright/Android.mk @@ -71,6 +71,7 @@ LOCAL_SHARED_LIBRARIES := \ libcrypto LOCAL_STATIC_LIBRARIES := \ + libstagefright_color_conversion \ libstagefright_aacdec \ libstagefright_aacenc \ libstagefright_amrnbdec \ @@ -97,7 +98,6 @@ LOCAL_SHARED_LIBRARIES += \ libstagefright_enc_common \ libstagefright_avc_common \ libstagefright_foundation \ - libstagefright_color_conversion ifeq ($(TARGET_OS)-$(TARGET_SIMULATOR),linux-true) LOCAL_LDLIBS += -lpthread -ldl diff --git a/media/libstagefright/AwesomePlayer.cpp b/media/libstagefright/AwesomePlayer.cpp index 922aaa8..fe5162e 100644 --- a/media/libstagefright/AwesomePlayer.cpp +++ b/media/libstagefright/AwesomePlayer.cpp @@ -81,16 +81,8 @@ private: struct AwesomeLocalRenderer : public AwesomeRenderer { AwesomeLocalRenderer( - OMX_COLOR_FORMATTYPE colorFormat, - const sp &surface, - size_t displayWidth, size_t displayHeight, - size_t decodedWidth, size_t decodedHeight, - int32_t rotationDegrees) - : mTarget(NULL) { - init(colorFormat, surface, - displayWidth, displayHeight, - decodedWidth, decodedHeight, - rotationDegrees); + const sp &surface, const sp &meta) + : mTarget(new SoftwareRenderer(surface, meta)) { } virtual void render(MediaBuffer *buffer) { @@ -111,28 +103,10 @@ protected: private: SoftwareRenderer *mTarget; - void init( - OMX_COLOR_FORMATTYPE colorFormat, - const sp &surface, - size_t displayWidth, size_t displayHeight, - size_t decodedWidth, size_t decodedHeight, - int32_t rotationDegrees); - AwesomeLocalRenderer(const AwesomeLocalRenderer &); AwesomeLocalRenderer &operator=(const AwesomeLocalRenderer &);; }; -void AwesomeLocalRenderer::init( - OMX_COLOR_FORMATTYPE colorFormat, - const sp &surface, - size_t displayWidth, size_t displayHeight, - size_t decodedWidth, size_t decodedHeight, - int32_t rotationDegrees) { - mTarget = new SoftwareRenderer( - colorFormat, surface, displayWidth, displayHeight, - decodedWidth, decodedHeight, rotationDegrees); -} - struct AwesomeNativeWindowRenderer : public AwesomeRenderer { AwesomeNativeWindowRenderer( const sp &nativeWindow, @@ -188,9 +162,7 @@ AwesomePlayer::AwesomePlayer() mAudioPlayer(NULL), mFlags(0), mExtractorFlags(0), - mLastVideoBuffer(NULL), mVideoBuffer(NULL), - mSuspensionState(NULL), mDecryptHandle(NULL) { CHECK_EQ(mClient.connect(), OK); @@ -433,11 +405,6 @@ void AwesomePlayer::reset_l() { mVideoRenderer.clear(); - if (mLastVideoBuffer) { - mLastVideoBuffer->release(); - mLastVideoBuffer = NULL; - } - if (mVideoBuffer) { mVideoBuffer->release(); mVideoBuffer = NULL; @@ -469,7 +436,6 @@ void AwesomePlayer::reset_l() { mDurationUs = -1; mFlags = 0; mExtractorFlags = 0; - mVideoWidth = mVideoHeight = -1; mTimeSourceDeltaUs = 0; mVideoTimeUs = 0; @@ -482,9 +448,6 @@ void AwesomePlayer::reset_l() { mFileSource.clear(); - delete mSuspensionState; - mSuspensionState = NULL; - mBitrate = -1; } @@ -637,11 +600,6 @@ void AwesomePlayer::partial_reset_l() { mVideoRenderer.clear(); - if (mLastVideoBuffer) { - mLastVideoBuffer->release(); - mLastVideoBuffer = NULL; - } - if (mVideoBuffer) { mVideoBuffer->release(); mVideoBuffer = NULL; @@ -815,9 +773,25 @@ status_t AwesomePlayer::play_l() { void AwesomePlayer::notifyVideoSize_l() { sp meta = mVideoSource->getFormat(); - int32_t decodedWidth, decodedHeight; - CHECK(meta->findInt32(kKeyWidth, &decodedWidth)); - CHECK(meta->findInt32(kKeyHeight, &decodedHeight)); + int32_t cropLeft, cropTop, cropRight, cropBottom; + if (!meta->findRect( + kKeyCropRect, &cropLeft, &cropTop, &cropRight, &cropBottom)) { + int32_t width, height; + CHECK(meta->findInt32(kKeyWidth, &width)); + CHECK(meta->findInt32(kKeyHeight, &height)); + + cropLeft = cropTop = 0; + cropRight = width - 1; + cropBottom = height - 1; + + LOGV("got dimensions only %d x %d", width, height); + } else { + LOGV("got crop rect %d, %d, %d, %d", + cropLeft, cropTop, cropRight, cropBottom); + } + + int32_t usableWidth = cropRight - cropLeft + 1; + int32_t usableHeight = cropBottom - cropTop + 1; int32_t rotationDegrees; if (!mVideoTrack->getFormat()->findInt32( @@ -827,10 +801,10 @@ void AwesomePlayer::notifyVideoSize_l() { if (rotationDegrees == 90 || rotationDegrees == 270) { notifyListener_l( - MEDIA_SET_VIDEO_SIZE, decodedHeight, decodedWidth); + MEDIA_SET_VIDEO_SIZE, usableHeight, usableWidth); } else { notifyListener_l( - MEDIA_SET_VIDEO_SIZE, decodedWidth, decodedHeight); + MEDIA_SET_VIDEO_SIZE, usableWidth, usableHeight); } } @@ -872,12 +846,7 @@ void AwesomePlayer::initRenderer_l() { // allocate their buffers in local address space. This renderer // then performs a color conversion and copy to get the data // into the ANativeBuffer. - mVideoRenderer = new AwesomeLocalRenderer( - (OMX_COLOR_FORMATTYPE)format, - mSurface, - mVideoWidth, mVideoHeight, - decodedWidth, decodedHeight, - rotationDegrees); + mVideoRenderer = new AwesomeLocalRenderer(mSurface, meta); } } @@ -1041,20 +1010,6 @@ void AwesomePlayer::seekAudioIfNecessary_l() { } } -status_t AwesomePlayer::getVideoDimensions( - int32_t *width, int32_t *height) const { - Mutex::Autolock autoLock(mLock); - - if (mVideoWidth < 0 || mVideoHeight < 0) { - return UNKNOWN_ERROR; - } - - *width = mVideoWidth; - *height = mVideoHeight; - - return OK; -} - void AwesomePlayer::setAudioSource(sp source) { CHECK(source != NULL); @@ -1123,9 +1078,6 @@ status_t AwesomePlayer::initVideoDecoder(uint32_t flags) { } } - CHECK(mVideoTrack->getFormat()->findInt32(kKeyWidth, &mVideoWidth)); - CHECK(mVideoTrack->getFormat()->findInt32(kKeyHeight, &mVideoHeight)); - status_t err = mVideoSource->start(); if (err != OK) { @@ -1180,11 +1132,6 @@ void AwesomePlayer::onVideoEvent() { mVideoEventPending = false; if (mSeeking) { - if (mLastVideoBuffer) { - mLastVideoBuffer->release(); - mLastVideoBuffer = NULL; - } - if (mVideoBuffer) { mVideoBuffer->release(); mVideoBuffer = NULL; @@ -1327,11 +1274,7 @@ void AwesomePlayer::onVideoEvent() { mVideoRenderer->render(mVideoBuffer); } - if (mLastVideoBuffer) { - mLastVideoBuffer->release(); - mLastVideoBuffer = NULL; - } - mLastVideoBuffer = mVideoBuffer; + mVideoBuffer->release(); mVideoBuffer = NULL; postVideoEvent_l(); @@ -1745,142 +1688,6 @@ void AwesomePlayer::finishAsyncPrepare_l() { mPreparedCondition.broadcast(); } -status_t AwesomePlayer::suspend() { - LOGV("suspend"); - Mutex::Autolock autoLock(mLock); - - if (mSuspensionState != NULL) { - if (mLastVideoBuffer == NULL) { - //go into here if video is suspended again - //after resuming without being played between - //them - SuspensionState *state = mSuspensionState; - mSuspensionState = NULL; - reset_l(); - mSuspensionState = state; - return OK; - } - - delete mSuspensionState; - mSuspensionState = NULL; - } - - if (mFlags & PREPARING) { - mFlags |= PREPARE_CANCELLED; - if (mConnectingDataSource != NULL) { - LOGI("interrupting the connection process"); - mConnectingDataSource->disconnect(); - } - } - - while (mFlags & PREPARING) { - mPreparedCondition.wait(mLock); - } - - SuspensionState *state = new SuspensionState; - state->mUri = mUri; - state->mUriHeaders = mUriHeaders; - state->mFileSource = mFileSource; - - state->mFlags = mFlags & (PLAYING | AUTO_LOOPING | LOOPING | AT_EOS); - getPosition(&state->mPositionUs); - - if (mLastVideoBuffer) { - size_t size = mLastVideoBuffer->range_length(); - - if (size) { - int32_t unreadable; - if (!mLastVideoBuffer->meta_data()->findInt32( - kKeyIsUnreadable, &unreadable) - || unreadable == 0) { - state->mLastVideoFrameSize = size; - state->mLastVideoFrame = malloc(size); - memcpy(state->mLastVideoFrame, - (const uint8_t *)mLastVideoBuffer->data() - + mLastVideoBuffer->range_offset(), - size); - - state->mVideoWidth = mVideoWidth; - state->mVideoHeight = mVideoHeight; - - sp meta = mVideoSource->getFormat(); - CHECK(meta->findInt32(kKeyColorFormat, &state->mColorFormat)); - CHECK(meta->findInt32(kKeyWidth, &state->mDecodedWidth)); - CHECK(meta->findInt32(kKeyHeight, &state->mDecodedHeight)); - } else { - LOGV("Unable to save last video frame, we have no access to " - "the decoded video data."); - } - } - } - - reset_l(); - - mSuspensionState = state; - - return OK; -} - -status_t AwesomePlayer::resume() { - LOGV("resume"); - Mutex::Autolock autoLock(mLock); - - if (mSuspensionState == NULL) { - return INVALID_OPERATION; - } - - SuspensionState *state = mSuspensionState; - mSuspensionState = NULL; - - status_t err; - if (state->mFileSource != NULL) { - err = setDataSource_l(state->mFileSource); - - if (err == OK) { - mFileSource = state->mFileSource; - } - } else { - err = setDataSource_l(state->mUri, &state->mUriHeaders); - } - - if (err != OK) { - delete state; - state = NULL; - - return err; - } - - seekTo_l(state->mPositionUs); - - mFlags = state->mFlags & (AUTO_LOOPING | LOOPING | AT_EOS); - - if (state->mLastVideoFrame && mSurface != NULL) { - mVideoRenderer = - new AwesomeLocalRenderer( - (OMX_COLOR_FORMATTYPE)state->mColorFormat, - mSurface, - state->mVideoWidth, - state->mVideoHeight, - state->mDecodedWidth, - state->mDecodedHeight, - 0); - - mVideoRendererIsPreview = true; - - ((AwesomeLocalRenderer *)mVideoRenderer.get())->render( - state->mLastVideoFrame, state->mLastVideoFrameSize); - } - - if (state->mFlags & PLAYING) { - play_l(); - } - - mSuspensionState = state; - state = NULL; - - return OK; -} - uint32_t AwesomePlayer::flags() const { return mExtractorFlags; } diff --git a/media/libstagefright/MetaData.cpp b/media/libstagefright/MetaData.cpp index 63b476e..884f3b4 100644 --- a/media/libstagefright/MetaData.cpp +++ b/media/libstagefright/MetaData.cpp @@ -70,6 +70,19 @@ bool MetaData::setPointer(uint32_t key, void *value) { return setData(key, TYPE_POINTER, &value, sizeof(value)); } +bool MetaData::setRect( + uint32_t key, + int32_t left, int32_t top, + int32_t right, int32_t bottom) { + Rect r; + r.mLeft = left; + r.mTop = top; + r.mRight = right; + r.mBottom = bottom; + + return setData(key, TYPE_RECT, &r, sizeof(r)); +} + bool MetaData::findCString(uint32_t key, const char **value) { uint32_t type; const void *data; @@ -143,6 +156,28 @@ bool MetaData::findPointer(uint32_t key, void **value) { return true; } +bool MetaData::findRect( + uint32_t key, + int32_t *left, int32_t *top, + int32_t *right, int32_t *bottom) { + uint32_t type; + const void *data; + size_t size; + if (!findData(key, &type, &data, &size) || type != TYPE_RECT) { + return false; + } + + CHECK_EQ(size, sizeof(Rect)); + + const Rect *r = (const Rect *)data; + *left = r->mLeft; + *top = r->mTop; + *right = r->mRight; + *bottom = r->mBottom; + + return true; +} + bool MetaData::setData( uint32_t key, uint32_t type, const void *data, size_t size) { bool overwrote_existing = true; diff --git a/media/libstagefright/OMXCodec.cpp b/media/libstagefright/OMXCodec.cpp index 6ca0f4f..3f32f2f 100644 --- a/media/libstagefright/OMXCodec.cpp +++ b/media/libstagefright/OMXCodec.cpp @@ -38,11 +38,11 @@ #include #include #include +#include #include #include #include #include -#include #include #include #include @@ -526,7 +526,7 @@ status_t OMXCodec::configureCodec(const sp &meta, uint32_t flags) { size_t size; if (meta->findData(kKeyESDS, &type, &data, &size)) { ESDS esds((const char *)data, size); - CHECK_EQ(esds.InitCheck(), OK); + CHECK_EQ(esds.InitCheck(), (status_t)OK); const void *codec_specific_data; size_t codec_specific_data_size; @@ -541,7 +541,7 @@ status_t OMXCodec::configureCodec(const sp &meta, uint32_t flags) { const uint8_t *ptr = (const uint8_t *)data; CHECK(size >= 7); - CHECK_EQ(ptr[0], 1); // configurationVersion == 1 + CHECK_EQ((unsigned)ptr[0], 1u); // configurationVersion == 1 uint8_t profile = ptr[1]; uint8_t level = ptr[3]; @@ -730,7 +730,7 @@ void OMXCodec::setMinBufferSize(OMX_U32 portIndex, OMX_U32 size) { status_t err = mOMX->getParameter( mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); - CHECK_EQ(err, OK); + CHECK_EQ(err, (status_t)OK); if ((portIndex == kPortIndexInput && (mQuirks & kInputBufferSizesAreBogus)) || (def.nBufferSize < size)) { @@ -739,11 +739,11 @@ void OMXCodec::setMinBufferSize(OMX_U32 portIndex, OMX_U32 size) { err = mOMX->setParameter( mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); - CHECK_EQ(err, OK); + CHECK_EQ(err, (status_t)OK); err = mOMX->getParameter( mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); - CHECK_EQ(err, OK); + CHECK_EQ(err, (status_t)OK); // Make sure the setting actually stuck. if (portIndex == kPortIndexInput @@ -923,7 +923,7 @@ void OMXCodec::setVideoInputFormat( } OMX_COLOR_FORMATTYPE colorFormat; - CHECK_EQ(OK, findTargetColorFormat(meta, &colorFormat)); + CHECK_EQ((status_t)OK, findTargetColorFormat(meta, &colorFormat)); status_t err; OMX_PARAM_PORTDEFINITIONTYPE def; @@ -932,19 +932,19 @@ void OMXCodec::setVideoInputFormat( //////////////////////// Input port ///////////////////////// CHECK_EQ(setVideoPortFormatType( kPortIndexInput, OMX_VIDEO_CodingUnused, - colorFormat), OK); + colorFormat), (status_t)OK); InitOMXParams(&def); def.nPortIndex = kPortIndexInput; err = mOMX->getParameter( mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); - CHECK_EQ(err, OK); + CHECK_EQ(err, (status_t)OK); def.nBufferSize = getFrameSize(colorFormat, stride > 0? stride: -stride, sliceHeight); - CHECK_EQ(def.eDomain, OMX_PortDomainVideo); + CHECK_EQ((int)def.eDomain, (int)OMX_PortDomainVideo); video_def->nFrameWidth = width; video_def->nFrameHeight = height; @@ -956,20 +956,20 @@ void OMXCodec::setVideoInputFormat( err = mOMX->setParameter( mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); - CHECK_EQ(err, OK); + CHECK_EQ(err, (status_t)OK); //////////////////////// Output port ///////////////////////// CHECK_EQ(setVideoPortFormatType( kPortIndexOutput, compressionFormat, OMX_COLOR_FormatUnused), - OK); + (status_t)OK); InitOMXParams(&def); def.nPortIndex = kPortIndexOutput; err = mOMX->getParameter( mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); - CHECK_EQ(err, OK); - CHECK_EQ(def.eDomain, OMX_PortDomainVideo); + CHECK_EQ(err, (status_t)OK); + CHECK_EQ((int)def.eDomain, (int)OMX_PortDomainVideo); video_def->nFrameWidth = width; video_def->nFrameHeight = height; @@ -984,23 +984,23 @@ void OMXCodec::setVideoInputFormat( err = mOMX->setParameter( mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); - CHECK_EQ(err, OK); + CHECK_EQ(err, (status_t)OK); /////////////////// Codec-specific //////////////////////// switch (compressionFormat) { case OMX_VIDEO_CodingMPEG4: { - CHECK_EQ(setupMPEG4EncoderParameters(meta), OK); + CHECK_EQ(setupMPEG4EncoderParameters(meta), (status_t)OK); break; } case OMX_VIDEO_CodingH263: - CHECK_EQ(setupH263EncoderParameters(meta), OK); + CHECK_EQ(setupH263EncoderParameters(meta), (status_t)OK); break; case OMX_VIDEO_CodingAVC: { - CHECK_EQ(setupAVCEncoderParameters(meta), OK); + CHECK_EQ(setupAVCEncoderParameters(meta), (status_t)OK); break; } @@ -1059,7 +1059,7 @@ status_t OMXCodec::setupBitRate(int32_t bitRate) { status_t err = mOMX->getParameter( mNode, OMX_IndexParamVideoBitrate, &bitrateType, sizeof(bitrateType)); - CHECK_EQ(err, OK); + CHECK_EQ(err, (status_t)OK); bitrateType.eControlRate = OMX_Video_ControlRateVariable; bitrateType.nTargetBitrate = bitRate; @@ -1067,7 +1067,7 @@ status_t OMXCodec::setupBitRate(int32_t bitRate) { err = mOMX->setParameter( mNode, OMX_IndexParamVideoBitrate, &bitrateType, sizeof(bitrateType)); - CHECK_EQ(err, OK); + CHECK_EQ(err, (status_t)OK); return OK; } @@ -1132,7 +1132,7 @@ status_t OMXCodec::setupH263EncoderParameters(const sp& meta) { status_t err = mOMX->getParameter( mNode, OMX_IndexParamVideoH263, &h263type, sizeof(h263type)); - CHECK_EQ(err, OK); + CHECK_EQ(err, (status_t)OK); h263type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP; @@ -1159,10 +1159,10 @@ status_t OMXCodec::setupH263EncoderParameters(const sp& meta) { err = mOMX->setParameter( mNode, OMX_IndexParamVideoH263, &h263type, sizeof(h263type)); - CHECK_EQ(err, OK); + CHECK_EQ(err, (status_t)OK); - CHECK_EQ(setupBitRate(bitRate), OK); - CHECK_EQ(setupErrorCorrectionParameters(), OK); + CHECK_EQ(setupBitRate(bitRate), (status_t)OK); + CHECK_EQ(setupErrorCorrectionParameters(), (status_t)OK); return OK; } @@ -1179,7 +1179,7 @@ status_t OMXCodec::setupMPEG4EncoderParameters(const sp& meta) { status_t err = mOMX->getParameter( mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type)); - CHECK_EQ(err, OK); + CHECK_EQ(err, (status_t)OK); mpeg4type.nSliceHeaderSpacing = 0; mpeg4type.bSVH = OMX_FALSE; @@ -1211,10 +1211,10 @@ status_t OMXCodec::setupMPEG4EncoderParameters(const sp& meta) { err = mOMX->setParameter( mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type)); - CHECK_EQ(err, OK); + CHECK_EQ(err, (status_t)OK); - CHECK_EQ(setupBitRate(bitRate), OK); - CHECK_EQ(setupErrorCorrectionParameters(), OK); + CHECK_EQ(setupBitRate(bitRate), (status_t)OK); + CHECK_EQ(setupErrorCorrectionParameters(), (status_t)OK); return OK; } @@ -1232,7 +1232,7 @@ status_t OMXCodec::setupAVCEncoderParameters(const sp& meta) { status_t err = mOMX->getParameter( mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type)); - CHECK_EQ(err, OK); + CHECK_EQ(err, (status_t)OK); h264type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP; @@ -1284,9 +1284,9 @@ status_t OMXCodec::setupAVCEncoderParameters(const sp& meta) { err = mOMX->setParameter( mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type)); - CHECK_EQ(err, OK); + CHECK_EQ(err, (status_t)OK); - CHECK_EQ(setupBitRate(bitRate), OK); + CHECK_EQ(setupBitRate(bitRate), (status_t)OK); return OK; } @@ -1324,8 +1324,8 @@ status_t OMXCodec::setVideoOutputFormat( status_t err = mOMX->getParameter( mNode, OMX_IndexParamVideoPortFormat, &format, sizeof(format)); - CHECK_EQ(err, OK); - CHECK_EQ(format.eCompressionFormat, OMX_VIDEO_CodingUnused); + CHECK_EQ(err, (status_t)OK); + CHECK_EQ((int)format.eCompressionFormat, (int)OMX_VIDEO_CodingUnused); static const int OMX_QCOM_COLOR_FormatYVU420SemiPlanar = 0x7FA30C00; @@ -1353,7 +1353,7 @@ status_t OMXCodec::setVideoOutputFormat( err = mOMX->getParameter( mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); - CHECK_EQ(err, OK); + CHECK_EQ(err, (status_t)OK); #if 1 // XXX Need a (much) better heuristic to compute input buffer sizes. @@ -1363,7 +1363,7 @@ status_t OMXCodec::setVideoOutputFormat( } #endif - CHECK_EQ(def.eDomain, OMX_PortDomainVideo); + CHECK_EQ((int)def.eDomain, (int)OMX_PortDomainVideo); video_def->nFrameWidth = width; video_def->nFrameHeight = height; @@ -1385,8 +1385,8 @@ status_t OMXCodec::setVideoOutputFormat( err = mOMX->getParameter( mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); - CHECK_EQ(err, OK); - CHECK_EQ(def.eDomain, OMX_PortDomainVideo); + CHECK_EQ(err, (status_t)OK); + CHECK_EQ((int)def.eDomain, (int)OMX_PortDomainVideo); #if 0 def.nBufferSize = @@ -1510,7 +1510,7 @@ OMXCodec::~OMXCodec() { CHECK(mState == LOADED || mState == ERROR); status_t err = mOMX->freeNode(mNode); - CHECK_EQ(err, OK); + CHECK_EQ(err, (status_t)OK); mNode = NULL; setState(DEAD); @@ -1527,21 +1527,21 @@ OMXCodec::~OMXCodec() { status_t OMXCodec::init() { // mLock is held. - CHECK_EQ(mState, LOADED); + CHECK_EQ((int)mState, (int)LOADED); status_t err; if (!(mQuirks & kRequiresLoadedToIdleAfterAllocation)) { err = mOMX->sendCommand(mNode, OMX_CommandStateSet, OMX_StateIdle); - CHECK_EQ(err, OK); + CHECK_EQ(err, (status_t)OK); setState(LOADED_TO_IDLE); } err = allocateBuffers(); - CHECK_EQ(err, OK); + CHECK_EQ(err, (status_t)OK); if (mQuirks & kRequiresLoadedToIdleAfterAllocation) { err = mOMX->sendCommand(mNode, OMX_CommandStateSet, OMX_StateIdle); - CHECK_EQ(err, OK); + CHECK_EQ(err, (status_t)OK); setState(LOADED_TO_IDLE); } @@ -1896,10 +1896,10 @@ void OMXCodec::on_message(const omx_message &msg) { CODEC_LOGV("Port is disabled, freeing buffer %p", buffer); status_t err = freeBuffer(kPortIndexInput, i); - CHECK_EQ(err, OK); + CHECK_EQ(err, (status_t)OK); } else if (mState != ERROR && mPortStatus[kPortIndexInput] != SHUTTING_DOWN) { - CHECK_EQ(mPortStatus[kPortIndexInput], ENABLED); + CHECK_EQ((int)mPortStatus[kPortIndexInput], (int)ENABLED); drainInputBuffer(&buffers->editItemAt(i)); } break; @@ -1937,7 +1937,7 @@ void OMXCodec::on_message(const omx_message &msg) { CODEC_LOGV("Port is disabled, freeing buffer %p", buffer); status_t err = freeBuffer(kPortIndexOutput, i); - CHECK_EQ(err, OK); + CHECK_EQ(err, (status_t)OK); #if 0 } else if (mPortStatus[kPortIndexOutput] == ENABLED @@ -1947,7 +1947,7 @@ void OMXCodec::on_message(const omx_message &msg) { mBufferFilled.signal(); #endif } else if (mPortStatus[kPortIndexOutput] != SHUTTING_DOWN) { - CHECK_EQ(mPortStatus[kPortIndexOutput], ENABLED); + CHECK_EQ((int)mPortStatus[kPortIndexOutput], (int)ENABLED); if (info->mMediaBuffer == NULL) { CHECK(mOMXLivesLocally); @@ -2045,84 +2045,6 @@ void OMXCodec::on_message(const omx_message &msg) { } } -void OMXCodec::onEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) { - switch (event) { - case OMX_EventCmdComplete: - { - onCmdComplete((OMX_COMMANDTYPE)data1, data2); - break; - } - - case OMX_EventError: - { - CODEC_LOGE("ERROR(0x%08lx, %ld)", data1, data2); - - setState(ERROR); - break; - } - - case OMX_EventPortSettingsChanged: - { - CODEC_LOGV("OMX_EventPortSettingsChanged(port=%ld, data2=0x%08lx)", - data1, data2); - - if (data2 == 0 || data2 == OMX_IndexParamPortDefinition) { - onPortSettingsChanged(data1); - } else if (data1 == kPortIndexOutput - && data2 == OMX_IndexConfigCommonOutputCrop) { - - OMX_CONFIG_RECTTYPE rect; - rect.nPortIndex = kPortIndexOutput; - InitOMXParams(&rect); - - status_t err = - mOMX->getConfig( - mNode, OMX_IndexConfigCommonOutputCrop, - &rect, sizeof(rect)); - - if (err == OK) { - CODEC_LOGV( - "output crop (%ld, %ld, %ld, %ld)", - rect.nLeft, rect.nTop, rect.nWidth, rect.nHeight); - - if (mNativeWindow != NULL) { - android_native_rect_t crop; - crop.left = rect.nLeft; - crop.top = rect.nTop; - crop.right = crop.left + rect.nWidth - 1; - crop.bottom = crop.top + rect.nHeight - 1; - - CHECK_EQ(0, native_window_set_crop( - mNativeWindow.get(), &crop)); - } - } else { - CODEC_LOGE("getConfig(OMX_IndexConfigCommonOutputCrop) " - "returned error 0x%08x", err); - } - } - break; - } - -#if 0 - case OMX_EventBufferFlag: - { - CODEC_LOGV("EVENT_BUFFER_FLAG(%ld)", data1); - - if (data1 == kPortIndexOutput) { - mNoMoreOutputData = true; - } - break; - } -#endif - - default: - { - CODEC_LOGV("EVENT(%d, %ld, %ld)", event, data1, data2); - break; - } - } -} - // Has the format changed in any way that the client would have to be aware of? static bool formatHasNotablyChanged( const sp &from, const sp &to) { @@ -2167,6 +2089,21 @@ static bool formatHasNotablyChanged( if (height_from != height_to) { return true; } + + int32_t left_from, top_from, right_from, bottom_from; + CHECK(from->findRect( + kKeyCropRect, + &left_from, &top_from, &right_from, &bottom_from)); + + int32_t left_to, top_to, right_to, bottom_to; + CHECK(to->findRect( + kKeyCropRect, + &left_to, &top_to, &right_to, &bottom_to)); + + if (left_to != left_from || top_to != top_from + || right_to != right_from || bottom_to != bottom_from) { + return true; + } } else if (!strcasecmp(mime_from, MEDIA_MIMETYPE_AUDIO_RAW)) { int32_t numChannels_from, numChannels_to; CHECK(from->findInt32(kKeyChannelCount, &numChannels_from)); @@ -2188,6 +2125,78 @@ static bool formatHasNotablyChanged( return false; } +void OMXCodec::onEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) { + switch (event) { + case OMX_EventCmdComplete: + { + onCmdComplete((OMX_COMMANDTYPE)data1, data2); + break; + } + + case OMX_EventError: + { + CODEC_LOGE("ERROR(0x%08lx, %ld)", data1, data2); + + setState(ERROR); + break; + } + + case OMX_EventPortSettingsChanged: + { + CODEC_LOGV("OMX_EventPortSettingsChanged(port=%ld, data2=0x%08lx)", + data1, data2); + + if (data2 == 0 || data2 == OMX_IndexParamPortDefinition) { + onPortSettingsChanged(data1); + } else if (data1 == kPortIndexOutput + && data2 == OMX_IndexConfigCommonOutputCrop) { + + sp oldOutputFormat = mOutputFormat; + initOutputFormat(mSource->getFormat()); + + if (formatHasNotablyChanged(oldOutputFormat, mOutputFormat)) { + mOutputPortSettingsHaveChanged = true; + + if (mNativeWindow != NULL) { + int32_t left, top, right, bottom; + CHECK(mOutputFormat->findRect( + kKeyCropRect, + &left, &top, &right, &bottom)); + + android_native_rect_t crop; + crop.left = left; + crop.top = top; + crop.right = right; + crop.bottom = bottom; + + CHECK_EQ(0, native_window_set_crop( + mNativeWindow.get(), &crop)); + } + } + } + break; + } + +#if 0 + case OMX_EventBufferFlag: + { + CODEC_LOGV("EVENT_BUFFER_FLAG(%ld)", data1); + + if (data1 == kPortIndexOutput) { + mNoMoreOutputData = true; + } + break; + } +#endif + + default: + { + CODEC_LOGV("EVENT(%d, %ld, %ld)", event, data1, data2); + break; + } + } +} + void OMXCodec::onCmdComplete(OMX_COMMANDTYPE cmd, OMX_U32 data) { switch (cmd) { case OMX_CommandStateSet: @@ -2202,13 +2211,13 @@ void OMXCodec::onCmdComplete(OMX_COMMANDTYPE cmd, OMX_U32 data) { CODEC_LOGV("PORT_DISABLED(%ld)", portIndex); CHECK(mState == EXECUTING || mState == RECONFIGURING); - CHECK_EQ(mPortStatus[portIndex], DISABLING); - CHECK_EQ(mPortBuffers[portIndex].size(), 0); + CHECK_EQ((int)mPortStatus[portIndex], (int)DISABLING); + CHECK_EQ(mPortBuffers[portIndex].size(), 0u); mPortStatus[portIndex] = DISABLED; if (mState == RECONFIGURING) { - CHECK_EQ(portIndex, kPortIndexOutput); + CHECK_EQ(portIndex, (OMX_U32)kPortIndexOutput); sp oldOutputFormat = mOutputFormat; initOutputFormat(mSource->getFormat()); @@ -2222,7 +2231,7 @@ void OMXCodec::onCmdComplete(OMX_COMMANDTYPE cmd, OMX_U32 data) { enablePortAsync(portIndex); status_t err = allocateBuffersOnPort(portIndex); - CHECK_EQ(err, OK); + CHECK_EQ(err, (status_t)OK); } break; } @@ -2233,12 +2242,12 @@ void OMXCodec::onCmdComplete(OMX_COMMANDTYPE cmd, OMX_U32 data) { CODEC_LOGV("PORT_ENABLED(%ld)", portIndex); CHECK(mState == EXECUTING || mState == RECONFIGURING); - CHECK_EQ(mPortStatus[portIndex], ENABLING); + CHECK_EQ((int)mPortStatus[portIndex], (int)ENABLING); mPortStatus[portIndex] = ENABLED; if (mState == RECONFIGURING) { - CHECK_EQ(portIndex, kPortIndexOutput); + CHECK_EQ(portIndex, (OMX_U32)kPortIndexOutput); setState(EXECUTING); @@ -2253,14 +2262,14 @@ void OMXCodec::onCmdComplete(OMX_COMMANDTYPE cmd, OMX_U32 data) { CODEC_LOGV("FLUSH_DONE(%ld)", portIndex); - CHECK_EQ(mPortStatus[portIndex], SHUTTING_DOWN); + CHECK_EQ((int)mPortStatus[portIndex], (int)SHUTTING_DOWN); mPortStatus[portIndex] = ENABLED; CHECK_EQ(countBuffersWeOwn(mPortBuffers[portIndex]), mPortBuffers[portIndex].size()); if (mState == RECONFIGURING) { - CHECK_EQ(portIndex, kPortIndexOutput); + CHECK_EQ(portIndex, (OMX_U32)kPortIndexOutput); disablePortAsync(portIndex); } else if (mState == EXECUTING_TO_IDLE) { @@ -2274,7 +2283,7 @@ void OMXCodec::onCmdComplete(OMX_COMMANDTYPE cmd, OMX_U32 data) { status_t err = mOMX->sendCommand(mNode, OMX_CommandStateSet, OMX_StateIdle); - CHECK_EQ(err, OK); + CHECK_EQ(err, (status_t)OK); } } else { // We're flushing both ports in preparation for seeking. @@ -2314,11 +2323,11 @@ void OMXCodec::onStateChange(OMX_STATETYPE newState) { status_t err = mOMX->sendCommand( mNode, OMX_CommandStateSet, OMX_StateExecuting); - CHECK_EQ(err, OK); + CHECK_EQ(err, (status_t)OK); setState(IDLE_TO_EXECUTING); } else { - CHECK_EQ(mState, EXECUTING_TO_IDLE); + CHECK_EQ((int)mState, (int)EXECUTING_TO_IDLE); CHECK_EQ( countBuffersWeOwn(mPortBuffers[kPortIndexInput]), @@ -2331,13 +2340,13 @@ void OMXCodec::onStateChange(OMX_STATETYPE newState) { status_t err = mOMX->sendCommand( mNode, OMX_CommandStateSet, OMX_StateLoaded); - CHECK_EQ(err, OK); + CHECK_EQ(err, (status_t)OK); err = freeBuffersOnPort(kPortIndexInput); - CHECK_EQ(err, OK); + CHECK_EQ(err, (status_t)OK); err = freeBuffersOnPort(kPortIndexOutput); - CHECK_EQ(err, OK); + CHECK_EQ(err, (status_t)OK); mPortStatus[kPortIndexInput] = ENABLED; mPortStatus[kPortIndexOutput] = ENABLED; @@ -2349,7 +2358,7 @@ void OMXCodec::onStateChange(OMX_STATETYPE newState) { case OMX_StateExecuting: { - CHECK_EQ(mState, IDLE_TO_EXECUTING); + CHECK_EQ((int)mState, (int)IDLE_TO_EXECUTING); CODEC_LOGV("Now Executing."); @@ -2365,7 +2374,7 @@ void OMXCodec::onStateChange(OMX_STATETYPE newState) { case OMX_StateLoaded: { - CHECK_EQ(mState, IDLE_TO_LOADED); + CHECK_EQ((int)mState, (int)IDLE_TO_LOADED); CODEC_LOGV("Now Loaded."); @@ -2412,7 +2421,7 @@ status_t OMXCodec::freeBuffersOnPort( continue; } - CHECK_EQ(info->mOwnedByComponent, false); + CHECK_EQ((int)info->mOwnedByComponent, (int)false); CODEC_LOGV("freeing buffer %p on port %ld", info->mBuffer, portIndex); @@ -2437,7 +2446,7 @@ status_t OMXCodec::freeBuffer(OMX_U32 portIndex, size_t bufIndex) { status_t err = mOMX->freeBuffer(mNode, portIndex, info->mBuffer); if (err == OK && info->mMediaBuffer != NULL) { - CHECK_EQ(portIndex, kPortIndexOutput); + CHECK_EQ(portIndex, (OMX_U32)kPortIndexOutput); info->mMediaBuffer->setObserver(NULL); // Make sure nobody but us owns this buffer at this point. @@ -2463,8 +2472,8 @@ status_t OMXCodec::freeBuffer(OMX_U32 portIndex, size_t bufIndex) { void OMXCodec::onPortSettingsChanged(OMX_U32 portIndex) { CODEC_LOGV("PORT_SETTINGS_CHANGED(%ld)", portIndex); - CHECK_EQ(mState, EXECUTING); - CHECK_EQ(portIndex, kPortIndexOutput); + CHECK_EQ((int)mState, (int)EXECUTING); + CHECK_EQ(portIndex, (OMX_U32)kPortIndexOutput); setState(RECONFIGURING); if (mQuirks & kNeedsFlushBeforeDisable) { @@ -2484,7 +2493,7 @@ bool OMXCodec::flushPortAsync(OMX_U32 portIndex) { portIndex, countBuffersWeOwn(mPortBuffers[portIndex]), mPortBuffers[portIndex].size()); - CHECK_EQ(mPortStatus[portIndex], ENABLED); + CHECK_EQ((int)mPortStatus[portIndex], (int)ENABLED); mPortStatus[portIndex] = SHUTTING_DOWN; if ((mQuirks & kRequiresFlushCompleteEmulation) @@ -2498,7 +2507,7 @@ bool OMXCodec::flushPortAsync(OMX_U32 portIndex) { status_t err = mOMX->sendCommand(mNode, OMX_CommandFlush, portIndex); - CHECK_EQ(err, OK); + CHECK_EQ(err, (status_t)OK); return true; } @@ -2506,13 +2515,13 @@ bool OMXCodec::flushPortAsync(OMX_U32 portIndex) { void OMXCodec::disablePortAsync(OMX_U32 portIndex) { CHECK(mState == EXECUTING || mState == RECONFIGURING); - CHECK_EQ(mPortStatus[portIndex], ENABLED); + CHECK_EQ((int)mPortStatus[portIndex], (int)ENABLED); mPortStatus[portIndex] = DISABLING; CODEC_LOGV("sending OMX_CommandPortDisable(%ld)", portIndex); status_t err = mOMX->sendCommand(mNode, OMX_CommandPortDisable, portIndex); - CHECK_EQ(err, OK); + CHECK_EQ(err, (status_t)OK); freeBuffersOnPort(portIndex, true); } @@ -2520,17 +2529,17 @@ void OMXCodec::disablePortAsync(OMX_U32 portIndex) { void OMXCodec::enablePortAsync(OMX_U32 portIndex) { CHECK(mState == EXECUTING || mState == RECONFIGURING); - CHECK_EQ(mPortStatus[portIndex], DISABLED); + CHECK_EQ((int)mPortStatus[portIndex], (int)DISABLED); mPortStatus[portIndex] = ENABLING; CODEC_LOGV("sending OMX_CommandPortEnable(%ld)", portIndex); status_t err = mOMX->sendCommand(mNode, OMX_CommandPortEnable, portIndex); - CHECK_EQ(err, OK); + CHECK_EQ(err, (status_t)OK); } void OMXCodec::fillOutputBuffers() { - CHECK_EQ(mState, EXECUTING); + CHECK_EQ((int)mState, (int)EXECUTING); // This is a workaround for some decoders not properly reporting // end-of-output-stream. If we own all input buffers and also own @@ -2566,7 +2575,7 @@ void OMXCodec::drainInputBuffers() { } void OMXCodec::drainInputBuffer(BufferInfo *info) { - CHECK_EQ(info->mOwnedByComponent, false); + CHECK_EQ((int)info->mOwnedByComponent, (int)false); if (mSignalledEOS) { return; @@ -2603,7 +2612,7 @@ void OMXCodec::drainInputBuffer(BufferInfo *info) { mNode, info->mBuffer, 0, size, OMX_BUFFERFLAG_ENDOFFRAME | OMX_BUFFERFLAG_CODECCONFIG, 0); - CHECK_EQ(err, OK); + CHECK_EQ(err, (status_t)OK); info->mOwnedByComponent = true; @@ -2771,7 +2780,7 @@ void OMXCodec::drainInputBuffer(BufferInfo *info) { } void OMXCodec::fillOutputBuffer(BufferInfo *info) { - CHECK_EQ(info->mOwnedByComponent, false); + CHECK_EQ((int)info->mOwnedByComponent, (int)false); if (mNoMoreOutputData) { CODEC_LOGV("There is no more output data available, not " @@ -2779,19 +2788,21 @@ void OMXCodec::fillOutputBuffer(BufferInfo *info) { return; } - sp graphicBuffer = info->mMediaBuffer->graphicBuffer(); - if (graphicBuffer != 0) { - // When using a native buffer we need to lock the buffer before giving - // it to OMX. - CHECK(!info->mOwnedByNativeWindow); - CODEC_LOGV("Calling lockBuffer on %p", info->mBuffer); - int err = mNativeWindow->lockBuffer(mNativeWindow.get(), - graphicBuffer.get()); - if (err != 0) { - CODEC_LOGE("lockBuffer failed w/ error 0x%08x", err); + if (info->mMediaBuffer != NULL) { + sp graphicBuffer = info->mMediaBuffer->graphicBuffer(); + if (graphicBuffer != 0) { + // When using a native buffer we need to lock the buffer before + // giving it to OMX. + CHECK(!info->mOwnedByNativeWindow); + CODEC_LOGV("Calling lockBuffer on %p", info->mBuffer); + int err = mNativeWindow->lockBuffer(mNativeWindow.get(), + graphicBuffer.get()); + if (err != 0) { + CODEC_LOGE("lockBuffer failed w/ error 0x%08x", err); - setState(ERROR); - return; + setState(ERROR); + return; + } } } @@ -2850,10 +2861,10 @@ void OMXCodec::setRawAudioFormat( def.nPortIndex = portIndex; status_t err = mOMX->getParameter( mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); - CHECK_EQ(err, OK); + CHECK_EQ(err, (status_t)OK); def.format.audio.eEncoding = OMX_AUDIO_CodingPCM; CHECK_EQ(mOMX->setParameter(mNode, OMX_IndexParamPortDefinition, - &def, sizeof(def)), OK); + &def, sizeof(def)), (status_t)OK); // pcm param OMX_AUDIO_PARAM_PCMMODETYPE pcmParams; @@ -2863,7 +2874,7 @@ void OMXCodec::setRawAudioFormat( err = mOMX->getParameter( mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams)); - CHECK_EQ(err, OK); + CHECK_EQ(err, (status_t)OK); pcmParams.nChannels = numChannels; pcmParams.eNumData = OMX_NumericalDataSigned; @@ -2884,7 +2895,7 @@ void OMXCodec::setRawAudioFormat( err = mOMX->setParameter( mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams)); - CHECK_EQ(err, OK); + CHECK_EQ(err, (status_t)OK); } static OMX_AUDIO_AMRBANDMODETYPE pickModeFromBitRate(bool isAMRWB, int32_t bps) { @@ -2941,13 +2952,13 @@ void OMXCodec::setAMRFormat(bool isWAMR, int32_t bitRate) { status_t err = mOMX->getParameter(mNode, OMX_IndexParamAudioAmr, &def, sizeof(def)); - CHECK_EQ(err, OK); + CHECK_EQ(err, (status_t)OK); def.eAMRFrameFormat = OMX_AUDIO_AMRFrameFormatFSF; def.eAMRBandMode = pickModeFromBitRate(isWAMR, bitRate); err = mOMX->setParameter(mNode, OMX_IndexParamAudioAmr, &def, sizeof(def)); - CHECK_EQ(err, OK); + CHECK_EQ(err, (status_t)OK); //////////////////////// @@ -2976,33 +2987,33 @@ void OMXCodec::setAACFormat(int32_t numChannels, int32_t sampleRate, int32_t bit status_t err = OMX_ErrorNone; while (OMX_ErrorNone == err) { CHECK_EQ(mOMX->getParameter(mNode, OMX_IndexParamAudioPortFormat, - &format, sizeof(format)), OK); + &format, sizeof(format)), (status_t)OK); if (format.eEncoding == OMX_AUDIO_CodingAAC) { break; } format.nIndex++; } - CHECK_EQ(OK, err); + CHECK_EQ((status_t)OK, err); CHECK_EQ(mOMX->setParameter(mNode, OMX_IndexParamAudioPortFormat, - &format, sizeof(format)), OK); + &format, sizeof(format)), (status_t)OK); // port definition OMX_PARAM_PORTDEFINITIONTYPE def; InitOMXParams(&def); def.nPortIndex = kPortIndexOutput; CHECK_EQ(mOMX->getParameter(mNode, OMX_IndexParamPortDefinition, - &def, sizeof(def)), OK); + &def, sizeof(def)), (status_t)OK); def.format.audio.bFlagErrorConcealment = OMX_TRUE; def.format.audio.eEncoding = OMX_AUDIO_CodingAAC; CHECK_EQ(mOMX->setParameter(mNode, OMX_IndexParamPortDefinition, - &def, sizeof(def)), OK); + &def, sizeof(def)), (status_t)OK); // profile OMX_AUDIO_PARAM_AACPROFILETYPE profile; InitOMXParams(&profile); profile.nPortIndex = kPortIndexOutput; CHECK_EQ(mOMX->getParameter(mNode, OMX_IndexParamAudioAac, - &profile, sizeof(profile)), OK); + &profile, sizeof(profile)), (status_t)OK); profile.nChannels = numChannels; profile.eChannelMode = (numChannels == 1? OMX_AUDIO_ChannelModeMono: OMX_AUDIO_ChannelModeStereo); @@ -3015,7 +3026,7 @@ void OMXCodec::setAACFormat(int32_t numChannels, int32_t sampleRate, int32_t bit profile.eAACProfile = OMX_AUDIO_AACObjectLC; profile.eAACStreamFormat = OMX_AUDIO_AACStreamFormatMP4FF; CHECK_EQ(mOMX->setParameter(mNode, OMX_IndexParamAudioAac, - &profile, sizeof(profile)), OK); + &profile, sizeof(profile)), (status_t)OK); } else { OMX_AUDIO_PARAM_AACPROFILETYPE profile; @@ -3024,7 +3035,7 @@ void OMXCodec::setAACFormat(int32_t numChannels, int32_t sampleRate, int32_t bit status_t err = mOMX->getParameter( mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile)); - CHECK_EQ(err, OK); + CHECK_EQ(err, (status_t)OK); profile.nChannels = numChannels; profile.nSampleRate = sampleRate; @@ -3032,7 +3043,7 @@ void OMXCodec::setAACFormat(int32_t numChannels, int32_t sampleRate, int32_t bit err = mOMX->setParameter( mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile)); - CHECK_EQ(err, OK); + CHECK_EQ(err, (status_t)OK); } } @@ -3044,10 +3055,10 @@ void OMXCodec::setImageOutputFormat( OMX_INDEXTYPE index; status_t err = mOMX->get_extension_index( mNode, "OMX.TI.JPEG.decode.Config.OutputColorFormat", &index); - CHECK_EQ(err, OK); + CHECK_EQ(err, (status_t)OK); err = mOMX->set_config(mNode, index, &format, sizeof(format)); - CHECK_EQ(err, OK); + CHECK_EQ(err, (status_t)OK); #endif OMX_PARAM_PORTDEFINITIONTYPE def; @@ -3056,13 +3067,13 @@ void OMXCodec::setImageOutputFormat( status_t err = mOMX->getParameter( mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); - CHECK_EQ(err, OK); + CHECK_EQ(err, (status_t)OK); - CHECK_EQ(def.eDomain, OMX_PortDomainImage); + CHECK_EQ((int)def.eDomain, (int)OMX_PortDomainImage); OMX_IMAGE_PORTDEFINITIONTYPE *imageDef = &def.format.image; - CHECK_EQ(imageDef->eCompressionFormat, OMX_IMAGE_CodingUnused); + CHECK_EQ((int)imageDef->eCompressionFormat, (int)OMX_IMAGE_CodingUnused); imageDef->eColorFormat = format; imageDef->nFrameWidth = width; imageDef->nFrameHeight = height; @@ -3105,7 +3116,7 @@ void OMXCodec::setImageOutputFormat( err = mOMX->setParameter( mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); - CHECK_EQ(err, OK); + CHECK_EQ(err, (status_t)OK); } void OMXCodec::setJPEGInputFormat( @@ -3116,12 +3127,12 @@ void OMXCodec::setJPEGInputFormat( status_t err = mOMX->getParameter( mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); - CHECK_EQ(err, OK); + CHECK_EQ(err, (status_t)OK); - CHECK_EQ(def.eDomain, OMX_PortDomainImage); + CHECK_EQ((int)def.eDomain, (int)OMX_PortDomainImage); OMX_IMAGE_PORTDEFINITIONTYPE *imageDef = &def.format.image; - CHECK_EQ(imageDef->eCompressionFormat, OMX_IMAGE_CodingJPEG); + CHECK_EQ((int)imageDef->eCompressionFormat, (int)OMX_IMAGE_CodingJPEG); imageDef->nFrameWidth = width; imageDef->nFrameHeight = height; @@ -3130,7 +3141,7 @@ void OMXCodec::setJPEGInputFormat( err = mOMX->setParameter( mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); - CHECK_EQ(err, OK); + CHECK_EQ(err, (status_t)OK); } void OMXCodec::addCodecSpecificData(const void *data, size_t size) { @@ -3231,7 +3242,7 @@ status_t OMXCodec::stop() { status_t err = mOMX->sendCommand(mNode, OMX_CommandStateSet, OMX_StateIdle); - CHECK_EQ(err, OK); + CHECK_EQ(err, (status_t)OK); } while (mState != LOADED && mState != ERROR) { @@ -3323,7 +3334,7 @@ status_t OMXCodec::read( mFilledBuffers.clear(); - CHECK_EQ(mState, EXECUTING); + CHECK_EQ((int)mState, (int)EXECUTING); bool emulateInputFlushCompletion = !flushPortAsync(kPortIndexInput); bool emulateOutputFlushCompletion = !flushPortAsync(kPortIndexOutput); @@ -3377,7 +3388,7 @@ void OMXCodec::signalBufferReturned(MediaBuffer *buffer) { BufferInfo *info = &buffers->editItemAt(i); if (info->mMediaBuffer == buffer) { - CHECK_EQ(mPortStatus[kPortIndexOutput], ENABLED); + CHECK_EQ((int)mPortStatus[kPortIndexOutput], (int)ENABLED); if (buffer->graphicBuffer() == 0) { fillOutputBuffer(info); } else { @@ -3629,7 +3640,7 @@ void OMXCodec::dumpPortStatus(OMX_U32 portIndex) { status_t err = mOMX->getParameter( mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); - CHECK_EQ(err, OK); + CHECK_EQ(err, (status_t)OK); printf("%s Port = {\n", portIndex == kPortIndexInput ? "Input" : "Output"); @@ -3695,7 +3706,7 @@ void OMXCodec::dumpPortStatus(OMX_U32 portIndex) { err = mOMX->getParameter( mNode, OMX_IndexParamAudioPcm, ¶ms, sizeof(params)); - CHECK_EQ(err, OK); + CHECK_EQ(err, (status_t)OK); printf(" nSamplingRate = %ld\n", params.nSamplingRate); printf(" nChannels = %ld\n", params.nChannels); @@ -3714,7 +3725,7 @@ void OMXCodec::dumpPortStatus(OMX_U32 portIndex) { err = mOMX->getParameter( mNode, OMX_IndexParamAudioAmr, &amr, sizeof(amr)); - CHECK_EQ(err, OK); + CHECK_EQ(err, (status_t)OK); printf(" nChannels = %ld\n", amr.nChannels); printf(" eAMRBandMode = %s\n", @@ -3764,13 +3775,14 @@ void OMXCodec::initOutputFormat(const sp &inputFormat) { status_t err = mOMX->getParameter( mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); - CHECK_EQ(err, OK); + CHECK_EQ(err, (status_t)OK); switch (def.eDomain) { case OMX_PortDomainImage: { OMX_IMAGE_PORTDEFINITIONTYPE *imageDef = &def.format.image; - CHECK_EQ(imageDef->eCompressionFormat, OMX_IMAGE_CodingUnused); + CHECK_EQ((int)imageDef->eCompressionFormat, + (int)OMX_IMAGE_CodingUnused); mOutputFormat->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_RAW); mOutputFormat->setInt32(kKeyColorFormat, imageDef->eColorFormat); @@ -3790,11 +3802,11 @@ void OMXCodec::initOutputFormat(const sp &inputFormat) { err = mOMX->getParameter( mNode, OMX_IndexParamAudioPcm, ¶ms, sizeof(params)); - CHECK_EQ(err, OK); + CHECK_EQ(err, (status_t)OK); - CHECK_EQ(params.eNumData, OMX_NumericalDataSigned); - CHECK_EQ(params.nBitPerSample, 16); - CHECK_EQ(params.ePCMMode, OMX_AUDIO_PCMModeLinear); + CHECK_EQ((int)params.eNumData, (int)OMX_NumericalDataSigned); + CHECK_EQ(params.nBitPerSample, 16u); + CHECK_EQ((int)params.ePCMMode, (int)OMX_AUDIO_PCMModeLinear); int32_t numChannels, sampleRate; inputFormat->findInt32(kKeyChannelCount, &numChannels); @@ -3828,9 +3840,9 @@ void OMXCodec::initOutputFormat(const sp &inputFormat) { err = mOMX->getParameter( mNode, OMX_IndexParamAudioAmr, &amr, sizeof(amr)); - CHECK_EQ(err, OK); + CHECK_EQ(err, (status_t)OK); - CHECK_EQ(amr.nChannels, 1); + CHECK_EQ(amr.nChannels, 1u); mOutputFormat->setInt32(kKeyChannelCount, 1); if (amr.eAMRBandMode >= OMX_AUDIO_AMRBandModeNB0 @@ -3885,6 +3897,35 @@ void OMXCodec::initOutputFormat(const sp &inputFormat) { mOutputFormat->setInt32(kKeyWidth, video_def->nFrameWidth); mOutputFormat->setInt32(kKeyHeight, video_def->nFrameHeight); mOutputFormat->setInt32(kKeyColorFormat, video_def->eColorFormat); + + OMX_CONFIG_RECTTYPE rect; + status_t err = + mOMX->getConfig( + mNode, OMX_IndexConfigCommonOutputCrop, + &rect, sizeof(rect)); + + if (err == OK) { + CHECK_GE(rect.nLeft, 0); + CHECK_GE(rect.nTop, 0); + CHECK_GE(rect.nWidth, 0u); + CHECK_GE(rect.nHeight, 0u); + CHECK_LE(rect.nLeft + rect.nWidth - 1, video_def->nFrameWidth); + CHECK_LE(rect.nTop + rect.nHeight - 1, video_def->nFrameHeight); + + mOutputFormat->setRect( + kKeyCropRect, + rect.nLeft, + rect.nTop, + rect.nLeft + rect.nWidth - 1, + rect.nTop + rect.nHeight - 1); + } else { + mOutputFormat->setRect( + kKeyCropRect, + 0, 0, + video_def->nFrameWidth - 1, + video_def->nFrameHeight - 1); + } + break; } @@ -3988,7 +4029,7 @@ status_t QueryCodecs( caps->mColorFormats.push(portFormat.eColorFormat); } - CHECK_EQ(omx->freeNode(node), OK); + CHECK_EQ(omx->freeNode(node), (status_t)OK); } } diff --git a/media/libstagefright/StagefrightMetadataRetriever.cpp b/media/libstagefright/StagefrightMetadataRetriever.cpp index 9b2dec9..763a914 100644 --- a/media/libstagefright/StagefrightMetadataRetriever.cpp +++ b/media/libstagefright/StagefrightMetadataRetriever.cpp @@ -191,17 +191,26 @@ static VideoFrame *extractVideoFrameWithCodecFlags( CHECK(meta->findInt32(kKeyWidth, &width)); CHECK(meta->findInt32(kKeyHeight, &height)); + int32_t crop_left, crop_top, crop_right, crop_bottom; + if (!meta->findRect( + kKeyCropRect, + &crop_left, &crop_top, &crop_right, &crop_bottom)) { + crop_left = crop_top = 0; + crop_right = width - 1; + crop_bottom = height - 1; + } + int32_t rotationAngle; if (!trackMeta->findInt32(kKeyRotation, &rotationAngle)) { rotationAngle = 0; // By default, no rotation } VideoFrame *frame = new VideoFrame; - frame->mWidth = width; - frame->mHeight = height; - frame->mDisplayWidth = width; - frame->mDisplayHeight = height; - frame->mSize = width * height * 2; + frame->mWidth = crop_right - crop_left + 1; + frame->mHeight = crop_bottom - crop_top + 1; + frame->mDisplayWidth = frame->mWidth; + frame->mDisplayHeight = frame->mHeight; + frame->mSize = frame->mWidth * frame->mHeight * 2; frame->mData = new uint8_t[frame->mSize]; frame->mRotationAngle = rotationAngle; @@ -213,10 +222,13 @@ static VideoFrame *extractVideoFrameWithCodecFlags( CHECK(converter.isValid()); converter.convert( - width, height, (const uint8_t *)buffer->data() + buffer->range_offset(), - 0, - frame->mData, width * 2); + width, height, + crop_left, crop_top, crop_right, crop_bottom, + frame->mData, + frame->mWidth, + frame->mHeight, + 0, 0, frame->mWidth - 1, frame->mHeight - 1); buffer->release(); buffer = NULL; @@ -418,5 +430,4 @@ void StagefrightMetadataRetriever::parseMetaData() { } } - } // namespace android diff --git a/media/libstagefright/codecs/avc/dec/AVCDecoder.cpp b/media/libstagefright/codecs/avc/dec/AVCDecoder.cpp index 868c514..5bbba35 100644 --- a/media/libstagefright/codecs/avc/dec/AVCDecoder.cpp +++ b/media/libstagefright/codecs/avc/dec/AVCDecoder.cpp @@ -73,6 +73,7 @@ AVCDecoder::AVCDecoder(const sp &source) CHECK(mSource->getFormat()->findInt32(kKeyHeight, &height)); mFormat->setInt32(kKeyWidth, width); mFormat->setInt32(kKeyHeight, height); + mFormat->setRect(kKeyCropRect, 0, 0, width - 1, height - 1); mFormat->setInt32(kKeyColorFormat, OMX_COLOR_FormatYUV420Planar); mFormat->setCString(kKeyDecoderComponent, "AVCDecoder"); @@ -418,16 +419,32 @@ status_t AVCDecoder::read( crop_top = crop_left = 0; } - int32_t aligned_width = (crop_right - crop_left + 1 + 15) & ~15; - int32_t aligned_height = (crop_bottom - crop_top + 1 + 15) & ~15; + int32_t prevCropLeft, prevCropTop; + int32_t prevCropRight, prevCropBottom; + if (!mFormat->findRect( + kKeyCropRect, + &prevCropLeft, &prevCropTop, + &prevCropRight, &prevCropBottom)) { + prevCropLeft = prevCropTop = 0; + prevCropRight = width - 1; + prevCropBottom = height - 1; + } int32_t oldWidth, oldHeight; CHECK(mFormat->findInt32(kKeyWidth, &oldWidth)); CHECK(mFormat->findInt32(kKeyHeight, &oldHeight)); - if (oldWidth != aligned_width || oldHeight != aligned_height) { - mFormat->setInt32(kKeyWidth, aligned_width); - mFormat->setInt32(kKeyHeight, aligned_height); + if (oldWidth != width || oldHeight != height + || prevCropLeft != crop_left + || prevCropTop != crop_top + || prevCropRight != crop_right + || prevCropBottom != crop_bottom) { + mFormat->setRect( + kKeyCropRect, + crop_left, crop_top, crop_right, crop_bottom); + + mFormat->setInt32(kKeyWidth, width); + mFormat->setInt32(kKeyHeight, height); err = INFO_FORMAT_CHANGED; } else { diff --git a/media/libstagefright/colorconversion/Android.mk b/media/libstagefright/colorconversion/Android.mk index ef2dba0..62ba40f 100644 --- a/media/libstagefright/colorconversion/Android.mk +++ b/media/libstagefright/colorconversion/Android.mk @@ -9,20 +9,6 @@ LOCAL_C_INCLUDES := \ $(TOP)/frameworks/base/include/media/stagefright/openmax \ $(TOP)/hardware/msm7k -LOCAL_SHARED_LIBRARIES := \ - libbinder \ - libmedia \ - libutils \ - libui \ - libcutils \ - libsurfaceflinger_client\ - libcamera_client - -# ifeq ($(TARGET_BOARD_PLATFORM),msm7k) -ifeq ($(TARGET_PRODUCT),passion) - LOCAL_CFLAGS += -DHAS_YCBCR420_SP_ADRENO -endif - LOCAL_MODULE:= libstagefright_color_conversion -include $(BUILD_SHARED_LIBRARY) +include $(BUILD_STATIC_LIBRARY) diff --git a/media/libstagefright/colorconversion/ColorConverter.cpp b/media/libstagefright/colorconversion/ColorConverter.cpp index 5b16997..600f040 100644 --- a/media/libstagefright/colorconversion/ColorConverter.cpp +++ b/media/libstagefright/colorconversion/ColorConverter.cpp @@ -50,31 +50,64 @@ bool ColorConverter::isValid() const { } } -void ColorConverter::convert( +ColorConverter::BitmapParams::BitmapParams( + void *bits, size_t width, size_t height, - const void *srcBits, size_t srcSkip, - void *dstBits, size_t dstSkip) { + size_t cropLeft, size_t cropTop, + size_t cropRight, size_t cropBottom) + : mBits(bits), + mWidth(width), + mHeight(height), + mCropLeft(cropLeft), + mCropTop(cropTop), + mCropRight(cropRight), + mCropBottom(cropBottom) { +} + +size_t ColorConverter::BitmapParams::cropWidth() const { + return mCropRight - mCropLeft + 1; +} + +size_t ColorConverter::BitmapParams::cropHeight() const { + return mCropBottom - mCropTop + 1; +} + +void ColorConverter::convert( + const void *srcBits, + size_t srcWidth, size_t srcHeight, + size_t srcCropLeft, size_t srcCropTop, + size_t srcCropRight, size_t srcCropBottom, + void *dstBits, + size_t dstWidth, size_t dstHeight, + size_t dstCropLeft, size_t dstCropTop, + size_t dstCropRight, size_t dstCropBottom) { CHECK_EQ(mDstFormat, OMX_COLOR_Format16bitRGB565); + BitmapParams src( + const_cast(srcBits), + srcWidth, srcHeight, + srcCropLeft, srcCropTop, srcCropRight, srcCropBottom); + + BitmapParams dst( + dstBits, + dstWidth, dstHeight, + dstCropLeft, dstCropTop, dstCropRight, dstCropBottom); + switch (mSrcFormat) { case OMX_COLOR_FormatYUV420Planar: - convertYUV420Planar( - width, height, srcBits, srcSkip, dstBits, dstSkip); + convertYUV420Planar(src, dst); break; case OMX_COLOR_FormatCbYCrY: - convertCbYCrY( - width, height, srcBits, srcSkip, dstBits, dstSkip); + convertCbYCrY(src, dst); break; case OMX_QCOM_COLOR_FormatYVU420SemiPlanar: - convertQCOMYUV420SemiPlanar( - width, height, srcBits, srcSkip, dstBits, dstSkip); + convertQCOMYUV420SemiPlanar(src, dst); break; case OMX_COLOR_FormatYUV420SemiPlanar: - convertYUV420SemiPlanar( - width, height, srcBits, srcSkip, dstBits, dstSkip); + convertYUV420SemiPlanar(src, dst); break; default: @@ -86,25 +119,27 @@ void ColorConverter::convert( } void ColorConverter::convertCbYCrY( - size_t width, size_t height, - const void *srcBits, size_t srcSkip, - void *dstBits, size_t dstSkip) { - CHECK_EQ(srcSkip, 0); // Doesn't really make sense for YUV formats. - CHECK(dstSkip >= width * 2); - CHECK((dstSkip & 3) == 0); + const BitmapParams &src, const BitmapParams &dst) { + // XXX Untested uint8_t *kAdjustedClip = initClip(); - uint32_t *dst_ptr = (uint32_t *)dstBits; + CHECK((src.mCropLeft & 1) == 0); + CHECK_EQ(src.cropWidth(), dst.cropWidth()); + CHECK_EQ(src.cropHeight(), dst.cropHeight()); + + uint32_t *dst_ptr = (uint32_t *)dst.mBits + + (dst.mCropTop * dst.mWidth + dst.mCropLeft) / 2; - const uint8_t *src = (const uint8_t *)srcBits; + const uint8_t *src_ptr = (const uint8_t *)src.mBits + + (src.mCropTop * dst.mWidth + src.mCropLeft) * 2; - for (size_t y = 0; y < height; ++y) { - for (size_t x = 0; x < width; x += 2) { - signed y1 = (signed)src[2 * x + 1] - 16; - signed y2 = (signed)src[2 * x + 3] - 16; - signed u = (signed)src[2 * x] - 128; - signed v = (signed)src[2 * x + 2] - 128; + for (size_t y = 0; y < src.cropHeight(); ++y) { + for (size_t x = 0; x < src.cropWidth(); x += 2) { + signed y1 = (signed)src_ptr[2 * x + 1] - 16; + signed y2 = (signed)src_ptr[2 * x + 3] - 16; + signed u = (signed)src_ptr[2 * x] - 128; + signed v = (signed)src_ptr[2 * x + 2] - 128; signed u_b = u * 517; signed u_g = -u * 100; @@ -134,32 +169,35 @@ void ColorConverter::convertCbYCrY( dst_ptr[x / 2] = (rgb2 << 16) | rgb1; } - src += width * 2; - dst_ptr += dstSkip / 4; + src_ptr += src.mWidth * 2; + dst_ptr += dst.mWidth / 2; } } void ColorConverter::convertYUV420Planar( - size_t width, size_t height, - const void *srcBits, size_t srcSkip, - void *dstBits, size_t dstSkip) { - CHECK_EQ(srcSkip, 0); // Doesn't really make sense for YUV formats. - CHECK(dstSkip >= width * 2); - CHECK((dstSkip & 3) == 0); - + const BitmapParams &src, const BitmapParams &dst) { uint8_t *kAdjustedClip = initClip(); - uint32_t *dst_ptr = (uint32_t *)dstBits; - const uint8_t *src_y = (const uint8_t *)srcBits; + CHECK((dst.mWidth & 3) == 0); + CHECK((src.mCropLeft & 1) == 0); + CHECK_EQ(src.cropWidth(), dst.cropWidth()); + CHECK_EQ(src.cropHeight(), dst.cropHeight()); + + uint32_t *dst_ptr = (uint32_t *)dst.mBits + + (dst.mCropTop * dst.mWidth + dst.mCropLeft) / 2; + + const uint8_t *src_y = + (const uint8_t *)src.mBits + src.mCropTop * src.mWidth + src.mCropLeft; const uint8_t *src_u = - (const uint8_t *)src_y + width * height; + (const uint8_t *)src_y + src.mWidth * src.mHeight + + src.mCropTop * (src.mWidth / 2) + src.mCropLeft / 2; const uint8_t *src_v = - (const uint8_t *)src_u + (width / 2) * (height / 2); + src_u + (src.mWidth / 2) * (src.mHeight / 2); - for (size_t y = 0; y < height; ++y) { - for (size_t x = 0; x < width; x += 2) { + for (size_t y = 0; y < src.cropHeight(); ++y) { + for (size_t x = 0; x < src.cropWidth(); x += 2) { // B = 1.164 * (Y - 16) + 2.018 * (U - 128) // G = 1.164 * (Y - 16) - 0.813 * (V - 128) - 0.391 * (U - 128) // R = 1.164 * (Y - 16) + 1.596 * (V - 128) @@ -212,35 +250,38 @@ void ColorConverter::convertYUV420Planar( dst_ptr[x / 2] = (rgb2 << 16) | rgb1; } - src_y += width; + src_y += src.mWidth; if (y & 1) { - src_u += width / 2; - src_v += width / 2; + src_u += src.mWidth / 2; + src_v += src.mWidth / 2; } - dst_ptr += dstSkip / 4; + dst_ptr += dst.mWidth / 2; } } void ColorConverter::convertQCOMYUV420SemiPlanar( - size_t width, size_t height, - const void *srcBits, size_t srcSkip, - void *dstBits, size_t dstSkip) { - CHECK_EQ(srcSkip, 0); // Doesn't really make sense for YUV formats. - CHECK(dstSkip >= width * 2); - CHECK((dstSkip & 3) == 0); - + const BitmapParams &src, const BitmapParams &dst) { uint8_t *kAdjustedClip = initClip(); - uint32_t *dst_ptr = (uint32_t *)dstBits; - const uint8_t *src_y = (const uint8_t *)srcBits; + CHECK((dst.mWidth & 3) == 0); + CHECK((src.mCropLeft & 1) == 0); + CHECK_EQ(src.cropWidth(), dst.cropWidth()); + CHECK_EQ(src.cropHeight(), dst.cropHeight()); + + uint32_t *dst_ptr = (uint32_t *)dst.mBits + + (dst.mCropTop * dst.mWidth + dst.mCropLeft) / 2; + + const uint8_t *src_y = + (const uint8_t *)src.mBits + src.mCropTop * src.mWidth + src.mCropLeft; const uint8_t *src_u = - (const uint8_t *)src_y + width * height; + (const uint8_t *)src_y + src.mWidth * src.mHeight + + src.mCropTop * src.mWidth + src.mCropLeft; - for (size_t y = 0; y < height; ++y) { - for (size_t x = 0; x < width; x += 2) { + for (size_t y = 0; y < src.cropHeight(); ++y) { + for (size_t x = 0; x < src.cropWidth(); x += 2) { signed y1 = (signed)src_y[x] - 16; signed y2 = (signed)src_y[x + 1] - 16; @@ -275,34 +316,39 @@ void ColorConverter::convertQCOMYUV420SemiPlanar( dst_ptr[x / 2] = (rgb2 << 16) | rgb1; } - src_y += width; + src_y += src.mWidth; if (y & 1) { - src_u += width; + src_u += src.mWidth; } - dst_ptr += dstSkip / 4; + dst_ptr += dst.mWidth / 2; } } void ColorConverter::convertYUV420SemiPlanar( - size_t width, size_t height, - const void *srcBits, size_t srcSkip, - void *dstBits, size_t dstSkip) { - CHECK_EQ(srcSkip, 0); // Doesn't really make sense for YUV formats. - CHECK(dstSkip >= width * 2); - CHECK((dstSkip & 3) == 0); + const BitmapParams &src, const BitmapParams &dst) { + // XXX Untested uint8_t *kAdjustedClip = initClip(); - uint32_t *dst_ptr = (uint32_t *)dstBits; - const uint8_t *src_y = (const uint8_t *)srcBits; + CHECK((dst.mWidth & 3) == 0); + CHECK((src.mCropLeft & 1) == 0); + CHECK_EQ(src.cropWidth(), dst.cropWidth()); + CHECK_EQ(src.cropHeight(), dst.cropHeight()); + + uint32_t *dst_ptr = (uint32_t *)dst.mBits + + (dst.mCropTop * dst.mWidth + dst.mCropLeft) / 2; + + const uint8_t *src_y = + (const uint8_t *)src.mBits + src.mCropTop * src.mWidth + src.mCropLeft; const uint8_t *src_u = - (const uint8_t *)src_y + width * height; + (const uint8_t *)src_y + src.mWidth * src.mHeight + + src.mCropTop * src.mWidth + src.mCropLeft; - for (size_t y = 0; y < height; ++y) { - for (size_t x = 0; x < width; x += 2) { + for (size_t y = 0; y < src.cropHeight(); ++y) { + for (size_t x = 0; x < src.cropWidth(); x += 2) { signed y1 = (signed)src_y[x] - 16; signed y2 = (signed)src_y[x + 1] - 16; @@ -337,13 +383,13 @@ void ColorConverter::convertYUV420SemiPlanar( dst_ptr[x / 2] = (rgb2 << 16) | rgb1; } - src_y += width; + src_y += src.mWidth; if (y & 1) { - src_u += width; + src_u += src.mWidth; } - dst_ptr += dstSkip / 4; + dst_ptr += dst.mWidth / 2; } } diff --git a/media/libstagefright/colorconversion/SoftwareRenderer.cpp b/media/libstagefright/colorconversion/SoftwareRenderer.cpp index acbea05..70408d7 100644 --- a/media/libstagefright/colorconversion/SoftwareRenderer.cpp +++ b/media/libstagefright/colorconversion/SoftwareRenderer.cpp @@ -21,55 +21,41 @@ #include #include -#include +#include +#include #include #include #include -// XXX: Temporary hack to allow referencing the _ADRENO pixel format here. -#include - namespace android { SoftwareRenderer::SoftwareRenderer( - OMX_COLOR_FORMATTYPE colorFormat, - const sp &surface, - size_t displayWidth, size_t displayHeight, - size_t decodedWidth, size_t decodedHeight, - int32_t rotationDegrees) - : mColorFormat(colorFormat), - mConverter(NULL), + const sp &surface, const sp &meta) + : mConverter(NULL), mYUVMode(None), - mSurface(surface), - mDisplayWidth(displayWidth), - mDisplayHeight(displayHeight), - mDecodedWidth(decodedWidth), - mDecodedHeight(decodedHeight) { - LOGI("input format = %d", mColorFormat); - LOGI("display = %d x %d, decoded = %d x %d", - mDisplayWidth, mDisplayHeight, mDecodedWidth, mDecodedHeight); - - mDecodedWidth = mDisplayWidth; - mDecodedHeight = mDisplayHeight; + mSurface(surface) { + int32_t tmp; + CHECK(meta->findInt32(kKeyColorFormat, &tmp)); + mColorFormat = (OMX_COLOR_FORMATTYPE)tmp; + + CHECK(meta->findInt32(kKeyWidth, &mWidth)); + CHECK(meta->findInt32(kKeyHeight, &mHeight)); + + if (!meta->findRect( + kKeyCropRect, + &mCropLeft, &mCropTop, &mCropRight, &mCropBottom)) { + mCropLeft = mCropTop = 0; + mCropRight = mWidth - 1; + mCropBottom = mHeight - 1; + } + + int32_t rotationDegrees; + if (!meta->findInt32(kKeyRotation, &rotationDegrees)) { + rotationDegrees = 0; + } int halFormat; switch (mColorFormat) { -#if HAS_YCBCR420_SP_ADRENO - case OMX_COLOR_FormatYUV420Planar: - { - halFormat = HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO; - mYUVMode = YUV420ToYUV420sp; - break; - } - - case 0x7fa30c00: - { - halFormat = HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO; - mYUVMode = YUV420spToYUV420sp; - break; - } -#endif - default: halFormat = HAL_PIXEL_FORMAT_RGB_565; @@ -80,8 +66,8 @@ SoftwareRenderer::SoftwareRenderer( } CHECK(mSurface.get() != NULL); - CHECK(mDecodedWidth > 0); - CHECK(mDecodedHeight > 0); + CHECK(mWidth > 0); + CHECK(mHeight > 0); CHECK(mConverter == NULL || mConverter->isValid()); CHECK_EQ(0, @@ -94,7 +80,9 @@ SoftwareRenderer::SoftwareRenderer( // Width must be multiple of 32??? CHECK_EQ(0, native_window_set_buffers_geometry( - mSurface.get(), mDecodedWidth, mDecodedHeight, + mSurface.get(), + mCropRight - mCropLeft + 1, + mCropBottom - mCropTop + 1, halFormat)); uint32_t transform; @@ -117,10 +105,6 @@ SoftwareRenderer::~SoftwareRenderer() { mConverter = NULL; } -static inline size_t ALIGN(size_t x, size_t alignment) { - return (x + alignment - 1) & ~(alignment - 1); -} - void SoftwareRenderer::render( const void *data, size_t size, void *platformPrivate) { android_native_buffer_t *buf; @@ -134,7 +118,7 @@ void SoftwareRenderer::render( GraphicBufferMapper &mapper = GraphicBufferMapper::get(); - Rect bounds(mDecodedWidth, mDecodedHeight); + Rect bounds(mWidth, mHeight); void *dst; CHECK_EQ(0, mapper.lock( @@ -142,69 +126,16 @@ void SoftwareRenderer::render( if (mConverter) { mConverter->convert( - mDecodedWidth, mDecodedHeight, - data, 0, dst, buf->stride * 2); - } else if (mYUVMode == YUV420spToYUV420sp) { - // Input and output are both YUV420sp, but the alignment requirements - // are different. - size_t srcYStride = mDecodedWidth; - const uint8_t *srcY = (const uint8_t *)data; - uint8_t *dstY = (uint8_t *)dst; - for (size_t i = 0; i < mDecodedHeight; ++i) { - memcpy(dstY, srcY, mDecodedWidth); - srcY += srcYStride; - dstY += buf->stride; - } - - size_t srcUVStride = (mDecodedWidth + 1) & ~1; - size_t dstUVStride = ALIGN(mDecodedWidth / 2, 32) * 2; - - const uint8_t *srcUV = (const uint8_t *)data - + mDecodedHeight * mDecodedWidth; - - size_t dstUVOffset = ALIGN(ALIGN(mDecodedHeight, 32) * buf->stride, 4096); - uint8_t *dstUV = (uint8_t *)dst + dstUVOffset; - - for (size_t i = 0; i < (mDecodedHeight + 1) / 2; ++i) { - memcpy(dstUV, srcUV, (mDecodedWidth + 1) & ~1); - srcUV += srcUVStride; - dstUV += dstUVStride; - } - } else if (mYUVMode == YUV420ToYUV420sp) { - // Input is YUV420 planar, output is YUV420sp, adhere to proper - // alignment requirements. - size_t srcYStride = mDecodedWidth; - const uint8_t *srcY = (const uint8_t *)data; - uint8_t *dstY = (uint8_t *)dst; - for (size_t i = 0; i < mDecodedHeight; ++i) { - memcpy(dstY, srcY, mDecodedWidth); - srcY += srcYStride; - dstY += buf->stride; - } - - size_t srcUVStride = (mDecodedWidth + 1) / 2; - size_t dstUVStride = ALIGN(mDecodedWidth / 2, 32) * 2; - - const uint8_t *srcU = (const uint8_t *)data - + mDecodedHeight * mDecodedWidth; - - const uint8_t *srcV = - srcU + ((mDecodedWidth + 1) / 2) * ((mDecodedHeight + 1) / 2); - - size_t dstUVOffset = ALIGN(ALIGN(mDecodedHeight, 32) * buf->stride, 4096); - uint8_t *dstUV = (uint8_t *)dst + dstUVOffset; - - for (size_t i = 0; i < (mDecodedHeight + 1) / 2; ++i) { - for (size_t j = 0; j < (mDecodedWidth + 1) / 2; ++j) { - dstUV[2 * j + 1] = srcU[j]; - dstUV[2 * j] = srcV[j]; - } - srcU += srcUVStride; - srcV += srcUVStride; - dstUV += dstUVStride; - } + data, + mWidth, mHeight, + mCropLeft, mCropTop, mCropRight, mCropBottom, + dst, + buf->stride, buf->height, + 0, 0, + mCropRight - mCropLeft, + mCropBottom - mCropTop); } else { - memcpy(dst, data, size); + TRESPASS(); } CHECK_EQ(0, mapper.unlock(buf->handle)); diff --git a/media/libstagefright/include/AwesomePlayer.h b/media/libstagefright/include/AwesomePlayer.h index 4e63b7a..e33f467 100644 --- a/media/libstagefright/include/AwesomePlayer.h +++ b/media/libstagefright/include/AwesomePlayer.h @@ -88,11 +88,6 @@ struct AwesomePlayer { status_t seekTo(int64_t timeUs); - status_t getVideoDimensions(int32_t *width, int32_t *height) const; - - status_t suspend(); - status_t resume(); - // This is a mask of MediaExtractor::Flags. uint32_t flags() const; @@ -153,7 +148,6 @@ private: uint32_t mFlags; uint32_t mExtractorFlags; - int32_t mVideoWidth, mVideoHeight; int64_t mTimeSourceDeltaUs; int64_t mVideoTimeUs; @@ -187,7 +181,6 @@ private: void postCheckAudioStatusEvent_l(); status_t play_l(); - MediaBuffer *mLastVideoBuffer; MediaBuffer *mVideoBuffer; sp mConnectingDataSource; @@ -198,32 +191,6 @@ private: sp mRTPSession; sp mRTPPusher, mRTCPPusher; - struct SuspensionState { - String8 mUri; - KeyedVector mUriHeaders; - sp mFileSource; - - uint32_t mFlags; - int64_t mPositionUs; - - void *mLastVideoFrame; - size_t mLastVideoFrameSize; - int32_t mColorFormat; - int32_t mVideoWidth, mVideoHeight; - int32_t mDecodedWidth, mDecodedHeight; - - SuspensionState() - : mLastVideoFrame(NULL) { - } - - ~SuspensionState() { - if (mLastVideoFrame) { - free(mLastVideoFrame); - mLastVideoFrame = NULL; - } - } - } *mSuspensionState; - DrmManagerClient *mDrmManagerClient; DecryptHandle *mDecryptHandle; diff --git a/media/libstagefright/include/SoftwareRenderer.h b/media/libstagefright/include/SoftwareRenderer.h index 9cafc68..90d3fe1 100644 --- a/media/libstagefright/include/SoftwareRenderer.h +++ b/media/libstagefright/include/SoftwareRenderer.h @@ -23,16 +23,13 @@ namespace android { +struct MetaData; class Surface; class SoftwareRenderer { public: SoftwareRenderer( - OMX_COLOR_FORMATTYPE colorFormat, - const sp &surface, - size_t displayWidth, size_t displayHeight, - size_t decodedWidth, size_t decodedHeight, - int32_t rotationDegrees); + const sp &surface, const sp &meta); ~SoftwareRenderer(); @@ -42,16 +39,14 @@ public: private: enum YUVMode { None, - YUV420ToYUV420sp, - YUV420spToYUV420sp, }; OMX_COLOR_FORMATTYPE mColorFormat; ColorConverter *mConverter; YUVMode mYUVMode; sp mSurface; - size_t mDisplayWidth, mDisplayHeight; - size_t mDecodedWidth, mDecodedHeight; + int32_t mWidth, mHeight; + int32_t mCropLeft, mCropTop, mCropRight, mCropBottom; SoftwareRenderer(const SoftwareRenderer &); SoftwareRenderer &operator=(const SoftwareRenderer &); diff --git a/media/libstagefright/omx/Android.mk b/media/libstagefright/omx/Android.mk index ead1675..6e069c8 100644 --- a/media/libstagefright/omx/Android.mk +++ b/media/libstagefright/omx/Android.mk @@ -31,7 +31,6 @@ LOCAL_SHARED_LIBRARIES := \ libutils \ libui \ libcutils \ - libstagefright_color_conversion ifneq ($(BUILD_WITHOUT_PV),true) LOCAL_SHARED_LIBRARIES += \ -- cgit v1.1