Loading include/media/stagefright/SoftwareRenderer.h +1 −0 Original line number Diff line number Diff line Loading @@ -45,6 +45,7 @@ private: void renderCbYCrY(const void *data, size_t size); void renderYUV420Planar(const void *data, size_t size); void renderQCOMYUV420SemiPlanar(const void *data, size_t size); OMX_COLOR_FORMATTYPE mColorFormat; sp<ISurface> mISurface; Loading media/libstagefright/omx/SoftwareRenderer.cpp +75 −0 Original line number Diff line number Diff line Loading @@ -65,6 +65,8 @@ SoftwareRenderer::~SoftwareRenderer() { void SoftwareRenderer::render( const void *data, size_t size, void *platformPrivate) { static const int OMX_QCOM_COLOR_FormatYVU420SemiPlanar = 0x7FA30C00; switch (mColorFormat) { case OMX_COLOR_FormatYUV420Planar: return renderYUV420Planar(data, size); Loading @@ -72,6 +74,9 @@ void SoftwareRenderer::render( case OMX_COLOR_FormatCbYCrY: return renderCbYCrY(data, size); case OMX_QCOM_COLOR_FormatYVU420SemiPlanar: return renderQCOMYUV420SemiPlanar(data, size); default: { LOGW("Cannot render color format %ld", mColorFormat); Loading Loading @@ -242,6 +247,76 @@ void SoftwareRenderer::renderCbYCrY( mIndex = 1 - mIndex; } void SoftwareRenderer::renderQCOMYUV420SemiPlanar( const void *data, size_t size) { if (size != (mDecodedHeight * mDecodedWidth * 3) / 2) { LOGE("size is %d, expected %d", size, (mDecodedHeight * mDecodedWidth * 3) / 2); } CHECK(size >= (mDecodedWidth * mDecodedHeight * 3) / 2); uint8_t *kAdjustedClip = initClip(); size_t offset = mIndex * mFrameSize; void *dst = (uint8_t *)mMemoryHeap->getBase() + offset; uint32_t *dst_ptr = (uint32_t *)dst; const uint8_t *src_y = (const uint8_t *)data; const uint8_t *src_u = (const uint8_t *)src_y + mDecodedWidth * mDecodedHeight; for (size_t y = 0; y < mDecodedHeight; ++y) { for (size_t x = 0; x < mDecodedWidth; x += 2) { signed y1 = (signed)src_y[x] - 16; signed y2 = (signed)src_y[x + 1] - 16; signed u = (signed)src_u[x & ~1] - 128; signed v = (signed)src_u[(x & ~1) + 1] - 128; signed u_b = u * 517; signed u_g = -u * 100; signed v_g = -v * 208; signed v_r = v * 409; signed tmp1 = y1 * 298; signed b1 = (tmp1 + u_b) / 256; signed g1 = (tmp1 + v_g + u_g) / 256; signed r1 = (tmp1 + v_r) / 256; signed tmp2 = y2 * 298; signed b2 = (tmp2 + u_b) / 256; signed g2 = (tmp2 + v_g + u_g) / 256; signed r2 = (tmp2 + v_r) / 256; uint32_t rgb1 = ((kAdjustedClip[b1] >> 3) << 11) | ((kAdjustedClip[g1] >> 2) << 5) | (kAdjustedClip[r1] >> 3); uint32_t rgb2 = ((kAdjustedClip[b2] >> 3) << 11) | ((kAdjustedClip[g2] >> 2) << 5) | (kAdjustedClip[r2] >> 3); dst_ptr[x / 2] = (rgb2 << 16) | rgb1; } src_y += mDecodedWidth; if (y & 1) { src_u += mDecodedWidth; } dst_ptr += mDecodedWidth / 2; } mISurface->postBuffer(offset); mIndex = 1 - mIndex; } uint8_t *SoftwareRenderer::initClip() { static const signed kClipMin = -278; static const signed kClipMax = 535; Loading Loading
include/media/stagefright/SoftwareRenderer.h +1 −0 Original line number Diff line number Diff line Loading @@ -45,6 +45,7 @@ private: void renderCbYCrY(const void *data, size_t size); void renderYUV420Planar(const void *data, size_t size); void renderQCOMYUV420SemiPlanar(const void *data, size_t size); OMX_COLOR_FORMATTYPE mColorFormat; sp<ISurface> mISurface; Loading
media/libstagefright/omx/SoftwareRenderer.cpp +75 −0 Original line number Diff line number Diff line Loading @@ -65,6 +65,8 @@ SoftwareRenderer::~SoftwareRenderer() { void SoftwareRenderer::render( const void *data, size_t size, void *platformPrivate) { static const int OMX_QCOM_COLOR_FormatYVU420SemiPlanar = 0x7FA30C00; switch (mColorFormat) { case OMX_COLOR_FormatYUV420Planar: return renderYUV420Planar(data, size); Loading @@ -72,6 +74,9 @@ void SoftwareRenderer::render( case OMX_COLOR_FormatCbYCrY: return renderCbYCrY(data, size); case OMX_QCOM_COLOR_FormatYVU420SemiPlanar: return renderQCOMYUV420SemiPlanar(data, size); default: { LOGW("Cannot render color format %ld", mColorFormat); Loading Loading @@ -242,6 +247,76 @@ void SoftwareRenderer::renderCbYCrY( mIndex = 1 - mIndex; } void SoftwareRenderer::renderQCOMYUV420SemiPlanar( const void *data, size_t size) { if (size != (mDecodedHeight * mDecodedWidth * 3) / 2) { LOGE("size is %d, expected %d", size, (mDecodedHeight * mDecodedWidth * 3) / 2); } CHECK(size >= (mDecodedWidth * mDecodedHeight * 3) / 2); uint8_t *kAdjustedClip = initClip(); size_t offset = mIndex * mFrameSize; void *dst = (uint8_t *)mMemoryHeap->getBase() + offset; uint32_t *dst_ptr = (uint32_t *)dst; const uint8_t *src_y = (const uint8_t *)data; const uint8_t *src_u = (const uint8_t *)src_y + mDecodedWidth * mDecodedHeight; for (size_t y = 0; y < mDecodedHeight; ++y) { for (size_t x = 0; x < mDecodedWidth; x += 2) { signed y1 = (signed)src_y[x] - 16; signed y2 = (signed)src_y[x + 1] - 16; signed u = (signed)src_u[x & ~1] - 128; signed v = (signed)src_u[(x & ~1) + 1] - 128; signed u_b = u * 517; signed u_g = -u * 100; signed v_g = -v * 208; signed v_r = v * 409; signed tmp1 = y1 * 298; signed b1 = (tmp1 + u_b) / 256; signed g1 = (tmp1 + v_g + u_g) / 256; signed r1 = (tmp1 + v_r) / 256; signed tmp2 = y2 * 298; signed b2 = (tmp2 + u_b) / 256; signed g2 = (tmp2 + v_g + u_g) / 256; signed r2 = (tmp2 + v_r) / 256; uint32_t rgb1 = ((kAdjustedClip[b1] >> 3) << 11) | ((kAdjustedClip[g1] >> 2) << 5) | (kAdjustedClip[r1] >> 3); uint32_t rgb2 = ((kAdjustedClip[b2] >> 3) << 11) | ((kAdjustedClip[g2] >> 2) << 5) | (kAdjustedClip[r2] >> 3); dst_ptr[x / 2] = (rgb2 << 16) | rgb1; } src_y += mDecodedWidth; if (y & 1) { src_u += mDecodedWidth; } dst_ptr += mDecodedWidth / 2; } mISurface->postBuffer(offset); mIndex = 1 - mIndex; } uint8_t *SoftwareRenderer::initClip() { static const signed kClipMin = -278; static const signed kClipMax = 535; Loading