diff options
author | Andreas Huber <andih@google.com> | 2010-02-11 10:58:05 -0800 |
---|---|---|
committer | Andreas Huber <andih@google.com> | 2010-02-11 10:58:05 -0800 |
commit | 5c64d74cc0e1506e287df1a7abd7b67ac3274d47 (patch) | |
tree | d0163e41c3166b98badde7ea43c9e67571d81ddc /libstagefrighthw | |
parent | 696f1c1dcc846f4e1ba6754776b3c4542a9c62a8 (diff) | |
download | omap3-5c64d74cc0e1506e287df1a7abd7b67ac3274d47.tar.gz |
Support for both OMX_COLOR_FormatCbYCrY and OMX_COLOR_FormatYUV420Planar in the overlay rendering code.
Diffstat (limited to 'libstagefrighthw')
-rw-r--r-- | libstagefrighthw/TIHardwareRenderer.cpp | 77 | ||||
-rw-r--r-- | libstagefrighthw/TIHardwareRenderer.h | 9 | ||||
-rw-r--r-- | libstagefrighthw/stagefright_overlay_output.cpp | 18 |
3 files changed, 94 insertions, 10 deletions
diff --git a/libstagefrighthw/TIHardwareRenderer.cpp b/libstagefrighthw/TIHardwareRenderer.cpp index 2a23585..c7494e2 100644 --- a/libstagefrighthw/TIHardwareRenderer.cpp +++ b/libstagefrighthw/TIHardwareRenderer.cpp @@ -34,12 +34,15 @@ namespace android { TIHardwareRenderer::TIHardwareRenderer( const sp<ISurface> &surface, size_t displayWidth, size_t displayHeight, - size_t decodedWidth, size_t decodedHeight) + size_t decodedWidth, size_t decodedHeight, + OMX_COLOR_FORMATTYPE colorFormat) : mISurface(surface), mDisplayWidth(displayWidth), mDisplayHeight(displayHeight), mDecodedWidth(decodedWidth), mDecodedHeight(decodedHeight), + mColorFormat(colorFormat), + mInitCheck(NO_INIT), mFrameSize(mDecodedWidth * mDecodedHeight * 2), mIsFirstFrame(true), mIndex(0) { @@ -47,6 +50,11 @@ TIHardwareRenderer::TIHardwareRenderer( CHECK(mDecodedWidth > 0); CHECK(mDecodedHeight > 0); + if (colorFormat != OMX_COLOR_FormatCbYCrY + && colorFormat != OMX_COLOR_FormatYUV420Planar) { + return; + } + sp<OverlayRef> ref = mISurface->createOverlay( mDecodedWidth, mDecodedHeight, OVERLAY_FORMAT_CbYCrY_422_I, 0); @@ -64,6 +72,8 @@ TIHardwareRenderer::TIHardwareRenderer( mOverlayAddresses.push(data->ptr); } + + mInitCheck = OK; } TIHardwareRenderer::~TIHardwareRenderer() { @@ -76,6 +86,62 @@ TIHardwareRenderer::~TIHardwareRenderer() { } } +// return a byte offset from any pointer +static inline const void *byteOffset(const void* p, size_t offset) { + return ((uint8_t*)p + offset); +} + +static void convertYuv420ToYuv422( + int width, int height, const void *src, void *dst) { + // calculate total number of pixels, and offsets to U and V planes + int pixelCount = height * width; + int srcLineLength = width / 4; + int destLineLength = width / 2; + uint32_t* ySrc = (uint32_t*) src; + const uint16_t* uSrc = (const uint16_t*) byteOffset(src, pixelCount); + const uint16_t* vSrc = (const uint16_t*) byteOffset(uSrc, pixelCount >> 2); + uint32_t *p = (uint32_t*) dst; + + // convert lines + for (int i = 0; i < height; i += 2) { + + // upsample by repeating the UV values on adjacent lines + // to save memory accesses, we handle 2 adjacent lines at a time + // convert 4 pixels in 2 adjacent lines at a time + for (int j = 0; j < srcLineLength; j++) { + + // fetch 4 Y values for each line + uint32_t y0 = ySrc[0]; + uint32_t y1 = ySrc[srcLineLength]; + ySrc++; + + // fetch 2 U/V values + uint32_t u = *uSrc++; + uint32_t v = *vSrc++; + + // assemble first U/V pair, leave holes for Y's + uint32_t uv = (u | (v << 16)) & 0x00ff00ff; + + // OR y values and write to memory + p[0] = ((y0 & 0xff) << 8) | ((y0 & 0xff00) << 16) | uv; + p[destLineLength] = ((y1 & 0xff) << 8) | ((y1 & 0xff00) << 16) | uv; + p++; + + // assemble second U/V pair, leave holes for Y's + uv = ((u >> 8) | (v << 8)) & 0x00ff00ff; + + // OR y values and write to memory + p[0] = ((y0 >> 8) & 0xff00) | (y0 & 0xff000000) | uv; + p[destLineLength] = ((y1 >> 8) & 0xff00) | (y1 & 0xff000000) | uv; + p++; + } + + // skip the next y line, we already converted it + ySrc += srcLineLength; + p += destLineLength; + } +} + void TIHardwareRenderer::render( const void *data, size_t size, void *platformPrivate) { // CHECK_EQ(size, mFrameSize); @@ -110,7 +176,14 @@ void TIHardwareRenderer::render( mIsFirstFrame = false; } #else - memcpy(mOverlayAddresses[mIndex], data, size); + if (mColorFormat == OMX_COLOR_FormatYUV420Planar) { + convertYuv420ToYuv422( + mDecodedWidth, mDecodedHeight, data, mOverlayAddresses[mIndex]); + } else { + CHECK_EQ(mColorFormat, OMX_COLOR_FormatCbYCrY); + + memcpy(mOverlayAddresses[mIndex], data, size); + } mOverlay->queueBuffer((void *)mIndex); diff --git a/libstagefrighthw/TIHardwareRenderer.h b/libstagefrighthw/TIHardwareRenderer.h index ef42648..86bab6b 100644 --- a/libstagefrighthw/TIHardwareRenderer.h +++ b/libstagefrighthw/TIHardwareRenderer.h @@ -22,6 +22,8 @@ #include <utils/RefBase.h> #include <utils/Vector.h> +#include <OMX_Component.h> + namespace android { class ISurface; @@ -32,10 +34,13 @@ public: TIHardwareRenderer( const sp<ISurface> &surface, size_t displayWidth, size_t displayHeight, - size_t decodedWidth, size_t decodedHeight); + size_t decodedWidth, size_t decodedHeight, + OMX_COLOR_FORMATTYPE colorFormat); virtual ~TIHardwareRenderer(); + status_t initCheck() const { return mInitCheck; } + virtual void render( const void *data, size_t size, void *platformPrivate); @@ -43,6 +48,8 @@ private: sp<ISurface> mISurface; size_t mDisplayWidth, mDisplayHeight; size_t mDecodedWidth, mDecodedHeight; + OMX_COLOR_FORMATTYPE mColorFormat; + status_t mInitCheck; size_t mFrameSize; sp<Overlay> mOverlay; Vector<void *> mOverlayAddresses; diff --git a/libstagefrighthw/stagefright_overlay_output.cpp b/libstagefrighthw/stagefright_overlay_output.cpp index 263d55f..5cd8606 100644 --- a/libstagefrighthw/stagefright_overlay_output.cpp +++ b/libstagefrighthw/stagefright_overlay_output.cpp @@ -1,7 +1,7 @@ -#include <media/stagefright/HardwareAPI.h> - #include "TIHardwareRenderer.h" +#include <media/stagefright/HardwareAPI.h> + using android::sp; using android::ISurface; using android::VideoRenderer; @@ -14,13 +14,17 @@ VideoRenderer *createRenderer( size_t decodedWidth, size_t decodedHeight) { using android::TIHardwareRenderer; - if (colorFormat == OMX_COLOR_FormatCbYCrY - && !strcmp(componentName, "OMX.TI.Video.Decoder")) { - return new TIHardwareRenderer( + TIHardwareRenderer *renderer = + new TIHardwareRenderer( surface, displayWidth, displayHeight, - decodedWidth, decodedHeight); + decodedWidth, decodedHeight, + colorFormat); + + if (renderer->initCheck() != android::OK) { + delete renderer; + renderer = NULL; } - return NULL; + return renderer; } |