Loading media/libmedia/include/media/IDataSource.h +3 −1 Original line number Diff line number Diff line Loading @@ -35,7 +35,9 @@ public: // Get the memory that readAt writes into. virtual sp<IMemory> getIMemory() = 0; // Read up to |size| bytes into the memory returned by getIMemory(). Returns // the number of bytes read, or -1 on error. |size| must not be larger than // the number of bytes read, or negative value on error (eg. // ERROR_END_OF_STREAM indicating EOS. This is needed by CallbackDataSource // to properly handle reading of last chunk). |size| must not be larger than // the buffer. virtual ssize_t readAt(off64_t offset, size_t size) = 0; // Get the size, or -1 if the size is unknown. Loading media/libstagefright/CallbackDataSource.cpp +3 −4 Original line number Diff line number Diff line Loading @@ -127,10 +127,6 @@ status_t TinyCacheSource::initCheck() const { } ssize_t TinyCacheSource::readAt(off64_t offset, void* data, size_t size) { if (size >= kCacheSize) { return mSource->readAt(offset, data, size); } // Check if the cache satisfies the read. if (mCachedOffset <= offset && offset < (off64_t) (mCachedOffset + mCachedSize)) { Loading @@ -154,6 +150,9 @@ ssize_t TinyCacheSource::readAt(off64_t offset, void* data, size_t size) { } } if (size >= kCacheSize) { return mSource->readAt(offset, data, size); } // Fill the cache and copy to the caller. const ssize_t numRead = mSource->readAt(offset, mCache, kCacheSize); Loading media/libstagefright/MPEG4Extractor.cpp +9 −51 Original line number Diff line number Diff line Loading @@ -36,6 +36,7 @@ #include <media/stagefright/foundation/AMessage.h> #include <media/stagefright/foundation/AUtils.h> #include <media/stagefright/foundation/ColorUtils.h> #include <media/stagefright/foundation/hexdump.h> #include <media/stagefright/MediaBuffer.h> #include <media/stagefright/MediaBufferGroup.h> #include <media/stagefright/MediaDefs.h> Loading Loading @@ -285,45 +286,6 @@ status_t MPEG4DataSource::setCachedRange(off64_t offset, size_t size) { static const bool kUseHexDump = false; static void hexdump(const void *_data, size_t size) { const uint8_t *data = (const uint8_t *)_data; size_t offset = 0; while (offset < size) { printf("0x%04zx ", offset); size_t n = size - offset; if (n > 16) { n = 16; } for (size_t i = 0; i < 16; ++i) { if (i == 8) { printf(" "); } if (offset + i < size) { printf("%02x ", data[offset + i]); } else { printf(" "); } } printf(" "); for (size_t i = 0; i < n; ++i) { if (isprint(data[offset + i])) { printf("%c", data[offset + i]); } else { printf("."); } } printf("\n"); offset += 16; } } static const char *FourCC2MIME(uint32_t fourcc) { switch (fourcc) { case FOURCC('m', 'p', '4', 'a'): Loading Loading @@ -512,14 +474,6 @@ sp<MetaData> MPEG4Extractor::getTrackMetaData( return track->meta; } static void MakeFourCCString(uint32_t x, char *s) { s[0] = x >> 24; s[1] = (x >> 16) & 0xff; s[2] = (x >> 8) & 0xff; s[3] = x & 0xff; s[4] = '\0'; } status_t MPEG4Extractor::readMetaData() { if (mInitCheck != NO_INIT) { return mInitCheck; Loading Loading @@ -967,8 +921,9 @@ status_t MPEG4Extractor::parseChunk(off64_t *offset, int depth) { } } if (mLastTrack == NULL) if (mLastTrack == NULL) { return ERROR_MALFORMED; } mLastTrack->sampleTable = new SampleTable(mDataSource); } Loading Loading @@ -1140,8 +1095,9 @@ status_t MPEG4Extractor::parseChunk(off64_t *offset, int depth) { original_fourcc = ntohl(original_fourcc); ALOGV("read original format: %d", original_fourcc); if (mLastTrack == NULL) if (mLastTrack == NULL) { return ERROR_MALFORMED; } mLastTrack->meta->setCString(kKeyMIMEType, FourCC2MIME(original_fourcc)); uint32_t num_channels = 0; Loading Loading @@ -1581,8 +1537,9 @@ status_t MPEG4Extractor::parseChunk(off64_t *offset, int depth) { case FOURCC('s', 't', 'c', 'o'): case FOURCC('c', 'o', '6', '4'): { if ((mLastTrack == NULL) || (mLastTrack->sampleTable == NULL)) if ((mLastTrack == NULL) || (mLastTrack->sampleTable == NULL)) { return ERROR_MALFORMED; } status_t err = mLastTrack->sampleTable->setChunkOffsetParams( Loading Loading @@ -1618,8 +1575,9 @@ status_t MPEG4Extractor::parseChunk(off64_t *offset, int depth) { case FOURCC('s', 't', 's', 'z'): case FOURCC('s', 't', 'z', '2'): { if ((mLastTrack == NULL) || (mLastTrack->sampleTable == NULL)) if ((mLastTrack == NULL) || (mLastTrack->sampleTable == NULL)) { return ERROR_MALFORMED; } status_t err = mLastTrack->sampleTable->setSampleSizeParams( Loading media/libstagefright/Utils.cpp +8 −0 Original line number Diff line number Diff line Loading @@ -1874,5 +1874,13 @@ AString nameForFd(int fd) { return result; } void MakeFourCCString(uint32_t x, char *s) { s[0] = x >> 24; s[1] = (x >> 16) & 0xff; s[2] = (x >> 8) & 0xff; s[3] = x & 0xff; s[4] = '\0'; } } // namespace android media/libstagefright/colorconversion/ColorConverter.cpp +137 −45 Original line number Diff line number Diff line Loading @@ -23,6 +23,7 @@ #include <media/stagefright/MediaErrors.h> #include "libyuv/convert_from.h" #include "libyuv/video_common.h" #define USE_LIBYUV Loading @@ -41,17 +42,17 @@ ColorConverter::~ColorConverter() { } bool ColorConverter::isValid() const { if (mDstFormat != OMX_COLOR_Format16bitRGB565) { return false; } switch (mSrcFormat) { case OMX_COLOR_FormatYUV420Planar: return mDstFormat == OMX_COLOR_Format16bitRGB565 || mDstFormat == OMX_COLOR_Format32BitRGBA8888 || mDstFormat == OMX_COLOR_Format32bitBGRA8888; case OMX_COLOR_FormatCbYCrY: case OMX_QCOM_COLOR_FormatYVU420SemiPlanar: case OMX_COLOR_FormatYUV420SemiPlanar: case OMX_TI_COLOR_FormatYUV420PackedSemiPlanar: return true; return mDstFormat == OMX_COLOR_Format16bitRGB565; default: return false; Loading @@ -62,14 +63,43 @@ ColorConverter::BitmapParams::BitmapParams( void *bits, size_t width, size_t height, size_t cropLeft, size_t cropTop, size_t cropRight, size_t cropBottom) size_t cropRight, size_t cropBottom, OMX_COLOR_FORMATTYPE colorFromat) : mBits(bits), mColorFormat(colorFromat), mWidth(width), mHeight(height), mCropLeft(cropLeft), mCropTop(cropTop), mCropRight(cropRight), mCropBottom(cropBottom) { switch(mColorFormat) { case OMX_COLOR_Format16bitRGB565: mBpp = 2; mStride = 2 * mWidth; break; case OMX_COLOR_Format32bitBGRA8888: case OMX_COLOR_Format32BitRGBA8888: mBpp = 4; mStride = 4 * mWidth; break; case OMX_COLOR_FormatYUV420Planar: case OMX_COLOR_FormatCbYCrY: case OMX_QCOM_COLOR_FormatYVU420SemiPlanar: case OMX_COLOR_FormatYUV420SemiPlanar: case OMX_TI_COLOR_FormatYUV420PackedSemiPlanar: mBpp = 1; mStride = mWidth; break; default: ALOGE("Unsupported color format %d", mColorFormat); mBpp = 1; mStride = mWidth; break; } } size_t ColorConverter::BitmapParams::cropWidth() const { Loading @@ -89,19 +119,15 @@ status_t ColorConverter::convert( size_t dstWidth, size_t dstHeight, size_t dstCropLeft, size_t dstCropTop, size_t dstCropRight, size_t dstCropBottom) { if (mDstFormat != OMX_COLOR_Format16bitRGB565) { return ERROR_UNSUPPORTED; } BitmapParams src( const_cast<void *>(srcBits), srcWidth, srcHeight, srcCropLeft, srcCropTop, srcCropRight, srcCropBottom); srcCropLeft, srcCropTop, srcCropRight, srcCropBottom, mSrcFormat); BitmapParams dst( dstBits, dstWidth, dstHeight, dstCropLeft, dstCropTop, dstCropRight, dstCropBottom); dstCropLeft, dstCropTop, dstCropRight, dstCropBottom, mDstFormat); status_t err; Loading Loading @@ -212,26 +238,104 @@ status_t ColorConverter::convertYUV420PlanarUseLibYUV( return ERROR_UNSUPPORTED; } uint16_t *dst_ptr = (uint16_t *)dst.mBits + dst.mCropTop * dst.mWidth + dst.mCropLeft; uint8_t *dst_ptr = (uint8_t *)dst.mBits + dst.mCropTop * dst.mStride + dst.mCropLeft * dst.mBpp; const uint8_t *src_y = (const uint8_t *)src.mBits + src.mCropTop * src.mWidth + src.mCropLeft; (const uint8_t *)src.mBits + src.mCropTop * src.mStride + src.mCropLeft; const uint8_t *src_u = (const uint8_t *)src_y + src.mWidth * src.mHeight + src.mCropTop * (src.mWidth / 2) + src.mCropLeft / 2; (const uint8_t *)src.mBits + src.mStride * src.mHeight + (src.mCropTop / 2) * (src.mStride / 2) + (src.mCropLeft / 2); const uint8_t *src_v = src_u + (src.mWidth / 2) * (src.mHeight / 2); src_u + (src.mStride / 2) * (src.mHeight / 2); switch (mDstFormat) { case OMX_COLOR_Format16bitRGB565: libyuv::I420ToRGB565(src_y, src.mStride, src_u, src.mStride / 2, src_v, src.mStride / 2, (uint8 *)dst_ptr, dst.mStride, src.cropWidth(), src.cropHeight()); break; case OMX_COLOR_Format32BitRGBA8888: libyuv::ConvertFromI420(src_y, src.mStride, src_u, src.mStride / 2, src_v, src.mStride / 2, (uint8 *)dst_ptr, dst.mStride, src.cropWidth(), src.cropHeight(), libyuv::FOURCC_ABGR); break; libyuv::I420ToRGB565(src_y, src.mWidth, src_u, src.mWidth / 2, src_v, src.mWidth / 2, (uint8 *)dst_ptr, dst.mWidth * 2, dst.mWidth, dst.mHeight); case OMX_COLOR_Format32bitBGRA8888: libyuv::ConvertFromI420(src_y, src.mStride, src_u, src.mStride / 2, src_v, src.mStride / 2, (uint8 *)dst_ptr, dst.mStride, src.cropWidth(), src.cropHeight(), libyuv::FOURCC_ARGB); break; default: return ERROR_UNSUPPORTED; } return OK; } void ColorConverter::writeToDst( void *dst_ptr, uint8_t *kAdjustedClip, bool uncropped, signed r1, signed g1, signed b1, signed r2, signed g2, signed b2) { switch (mDstFormat) { case OMX_COLOR_Format16bitRGB565: { uint32_t rgb1 = ((kAdjustedClip[r1] >> 3) << 11) | ((kAdjustedClip[g1] >> 2) << 5) | (kAdjustedClip[b1] >> 3); if (uncropped) { uint32_t rgb2 = ((kAdjustedClip[r2] >> 3) << 11) | ((kAdjustedClip[g2] >> 2) << 5) | (kAdjustedClip[b2] >> 3); *(uint32_t *)dst_ptr = (rgb2 << 16) | rgb1; } else { *(uint16_t *)dst_ptr = rgb1; } break; } case OMX_COLOR_Format32BitRGBA8888: { ((uint32_t *)dst_ptr)[0] = (kAdjustedClip[r1]) | (kAdjustedClip[g1] << 8) | (kAdjustedClip[b1] << 16) | (0xFF << 24); if (uncropped) { ((uint32_t *)dst_ptr)[1] = (kAdjustedClip[r2]) | (kAdjustedClip[g2] << 8) | (kAdjustedClip[b2] << 16) | (0xFF << 24); } break; } case OMX_COLOR_Format32bitBGRA8888: { ((uint32_t *)dst_ptr)[0] = (kAdjustedClip[b1]) | (kAdjustedClip[g1] << 8) | (kAdjustedClip[r1] << 16) | (0xFF << 24); if (uncropped) { ((uint32_t *)dst_ptr)[1] = (kAdjustedClip[b2]) | (kAdjustedClip[g2] << 8) | (kAdjustedClip[r2] << 16) | (0xFF << 24); } break; } default: break; } } status_t ColorConverter::convertYUV420Planar( const BitmapParams &src, const BitmapParams &dst) { if (!((src.mCropLeft & 1) == 0 Loading @@ -242,18 +346,18 @@ status_t ColorConverter::convertYUV420Planar( uint8_t *kAdjustedClip = initClip(); uint16_t *dst_ptr = (uint16_t *)dst.mBits + dst.mCropTop * dst.mWidth + dst.mCropLeft; uint8_t *dst_ptr = (uint8_t *)dst.mBits + dst.mCropTop * dst.mStride + dst.mCropLeft * dst.mBpp; const uint8_t *src_y = (const uint8_t *)src.mBits + src.mCropTop * src.mWidth + src.mCropLeft; (const uint8_t *)src.mBits + src.mCropTop * src.mStride + src.mCropLeft; const uint8_t *src_u = (const uint8_t *)src_y + src.mWidth * src.mHeight + src.mCropTop * (src.mWidth / 2) + src.mCropLeft / 2; (const uint8_t *)src.mBits + src.mStride * src.mHeight + (src.mCropTop / 2) * (src.mStride / 2) + src.mCropLeft / 2; const uint8_t *src_v = src_u + (src.mWidth / 2) * (src.mHeight / 2); src_u + (src.mStride / 2) * (src.mHeight / 2); for (size_t y = 0; y < src.cropHeight(); ++y) { for (size_t x = 0; x < src.cropWidth(); x += 2) { Loading Loading @@ -296,31 +400,19 @@ status_t ColorConverter::convertYUV420Planar( signed g2 = (tmp2 + v_g + u_g) / 256; signed r2 = (tmp2 + v_r) / 256; uint32_t rgb1 = ((kAdjustedClip[r1] >> 3) << 11) | ((kAdjustedClip[g1] >> 2) << 5) | (kAdjustedClip[b1] >> 3); uint32_t rgb2 = ((kAdjustedClip[r2] >> 3) << 11) | ((kAdjustedClip[g2] >> 2) << 5) | (kAdjustedClip[b2] >> 3); if (x + 1 < src.cropWidth()) { *(uint32_t *)(&dst_ptr[x]) = (rgb2 << 16) | rgb1; } else { dst_ptr[x] = rgb1; } bool uncropped = x + 1 < src.cropWidth(); (void)writeToDst(dst_ptr + x * dst.mBpp, kAdjustedClip, uncropped, r1, g1, b1, r2, g2, b2); } src_y += src.mWidth; src_y += src.mStride; if (y & 1) { src_u += src.mWidth / 2; src_v += src.mWidth / 2; src_u += src.mStride / 2; src_v += src.mStride / 2; } dst_ptr += dst.mWidth; dst_ptr += dst.mStride; } return OK; Loading Loading
media/libmedia/include/media/IDataSource.h +3 −1 Original line number Diff line number Diff line Loading @@ -35,7 +35,9 @@ public: // Get the memory that readAt writes into. virtual sp<IMemory> getIMemory() = 0; // Read up to |size| bytes into the memory returned by getIMemory(). Returns // the number of bytes read, or -1 on error. |size| must not be larger than // the number of bytes read, or negative value on error (eg. // ERROR_END_OF_STREAM indicating EOS. This is needed by CallbackDataSource // to properly handle reading of last chunk). |size| must not be larger than // the buffer. virtual ssize_t readAt(off64_t offset, size_t size) = 0; // Get the size, or -1 if the size is unknown. Loading
media/libstagefright/CallbackDataSource.cpp +3 −4 Original line number Diff line number Diff line Loading @@ -127,10 +127,6 @@ status_t TinyCacheSource::initCheck() const { } ssize_t TinyCacheSource::readAt(off64_t offset, void* data, size_t size) { if (size >= kCacheSize) { return mSource->readAt(offset, data, size); } // Check if the cache satisfies the read. if (mCachedOffset <= offset && offset < (off64_t) (mCachedOffset + mCachedSize)) { Loading @@ -154,6 +150,9 @@ ssize_t TinyCacheSource::readAt(off64_t offset, void* data, size_t size) { } } if (size >= kCacheSize) { return mSource->readAt(offset, data, size); } // Fill the cache and copy to the caller. const ssize_t numRead = mSource->readAt(offset, mCache, kCacheSize); Loading
media/libstagefright/MPEG4Extractor.cpp +9 −51 Original line number Diff line number Diff line Loading @@ -36,6 +36,7 @@ #include <media/stagefright/foundation/AMessage.h> #include <media/stagefright/foundation/AUtils.h> #include <media/stagefright/foundation/ColorUtils.h> #include <media/stagefright/foundation/hexdump.h> #include <media/stagefright/MediaBuffer.h> #include <media/stagefright/MediaBufferGroup.h> #include <media/stagefright/MediaDefs.h> Loading Loading @@ -285,45 +286,6 @@ status_t MPEG4DataSource::setCachedRange(off64_t offset, size_t size) { static const bool kUseHexDump = false; static void hexdump(const void *_data, size_t size) { const uint8_t *data = (const uint8_t *)_data; size_t offset = 0; while (offset < size) { printf("0x%04zx ", offset); size_t n = size - offset; if (n > 16) { n = 16; } for (size_t i = 0; i < 16; ++i) { if (i == 8) { printf(" "); } if (offset + i < size) { printf("%02x ", data[offset + i]); } else { printf(" "); } } printf(" "); for (size_t i = 0; i < n; ++i) { if (isprint(data[offset + i])) { printf("%c", data[offset + i]); } else { printf("."); } } printf("\n"); offset += 16; } } static const char *FourCC2MIME(uint32_t fourcc) { switch (fourcc) { case FOURCC('m', 'p', '4', 'a'): Loading Loading @@ -512,14 +474,6 @@ sp<MetaData> MPEG4Extractor::getTrackMetaData( return track->meta; } static void MakeFourCCString(uint32_t x, char *s) { s[0] = x >> 24; s[1] = (x >> 16) & 0xff; s[2] = (x >> 8) & 0xff; s[3] = x & 0xff; s[4] = '\0'; } status_t MPEG4Extractor::readMetaData() { if (mInitCheck != NO_INIT) { return mInitCheck; Loading Loading @@ -967,8 +921,9 @@ status_t MPEG4Extractor::parseChunk(off64_t *offset, int depth) { } } if (mLastTrack == NULL) if (mLastTrack == NULL) { return ERROR_MALFORMED; } mLastTrack->sampleTable = new SampleTable(mDataSource); } Loading Loading @@ -1140,8 +1095,9 @@ status_t MPEG4Extractor::parseChunk(off64_t *offset, int depth) { original_fourcc = ntohl(original_fourcc); ALOGV("read original format: %d", original_fourcc); if (mLastTrack == NULL) if (mLastTrack == NULL) { return ERROR_MALFORMED; } mLastTrack->meta->setCString(kKeyMIMEType, FourCC2MIME(original_fourcc)); uint32_t num_channels = 0; Loading Loading @@ -1581,8 +1537,9 @@ status_t MPEG4Extractor::parseChunk(off64_t *offset, int depth) { case FOURCC('s', 't', 'c', 'o'): case FOURCC('c', 'o', '6', '4'): { if ((mLastTrack == NULL) || (mLastTrack->sampleTable == NULL)) if ((mLastTrack == NULL) || (mLastTrack->sampleTable == NULL)) { return ERROR_MALFORMED; } status_t err = mLastTrack->sampleTable->setChunkOffsetParams( Loading Loading @@ -1618,8 +1575,9 @@ status_t MPEG4Extractor::parseChunk(off64_t *offset, int depth) { case FOURCC('s', 't', 's', 'z'): case FOURCC('s', 't', 'z', '2'): { if ((mLastTrack == NULL) || (mLastTrack->sampleTable == NULL)) if ((mLastTrack == NULL) || (mLastTrack->sampleTable == NULL)) { return ERROR_MALFORMED; } status_t err = mLastTrack->sampleTable->setSampleSizeParams( Loading
media/libstagefright/Utils.cpp +8 −0 Original line number Diff line number Diff line Loading @@ -1874,5 +1874,13 @@ AString nameForFd(int fd) { return result; } void MakeFourCCString(uint32_t x, char *s) { s[0] = x >> 24; s[1] = (x >> 16) & 0xff; s[2] = (x >> 8) & 0xff; s[3] = x & 0xff; s[4] = '\0'; } } // namespace android
media/libstagefright/colorconversion/ColorConverter.cpp +137 −45 Original line number Diff line number Diff line Loading @@ -23,6 +23,7 @@ #include <media/stagefright/MediaErrors.h> #include "libyuv/convert_from.h" #include "libyuv/video_common.h" #define USE_LIBYUV Loading @@ -41,17 +42,17 @@ ColorConverter::~ColorConverter() { } bool ColorConverter::isValid() const { if (mDstFormat != OMX_COLOR_Format16bitRGB565) { return false; } switch (mSrcFormat) { case OMX_COLOR_FormatYUV420Planar: return mDstFormat == OMX_COLOR_Format16bitRGB565 || mDstFormat == OMX_COLOR_Format32BitRGBA8888 || mDstFormat == OMX_COLOR_Format32bitBGRA8888; case OMX_COLOR_FormatCbYCrY: case OMX_QCOM_COLOR_FormatYVU420SemiPlanar: case OMX_COLOR_FormatYUV420SemiPlanar: case OMX_TI_COLOR_FormatYUV420PackedSemiPlanar: return true; return mDstFormat == OMX_COLOR_Format16bitRGB565; default: return false; Loading @@ -62,14 +63,43 @@ ColorConverter::BitmapParams::BitmapParams( void *bits, size_t width, size_t height, size_t cropLeft, size_t cropTop, size_t cropRight, size_t cropBottom) size_t cropRight, size_t cropBottom, OMX_COLOR_FORMATTYPE colorFromat) : mBits(bits), mColorFormat(colorFromat), mWidth(width), mHeight(height), mCropLeft(cropLeft), mCropTop(cropTop), mCropRight(cropRight), mCropBottom(cropBottom) { switch(mColorFormat) { case OMX_COLOR_Format16bitRGB565: mBpp = 2; mStride = 2 * mWidth; break; case OMX_COLOR_Format32bitBGRA8888: case OMX_COLOR_Format32BitRGBA8888: mBpp = 4; mStride = 4 * mWidth; break; case OMX_COLOR_FormatYUV420Planar: case OMX_COLOR_FormatCbYCrY: case OMX_QCOM_COLOR_FormatYVU420SemiPlanar: case OMX_COLOR_FormatYUV420SemiPlanar: case OMX_TI_COLOR_FormatYUV420PackedSemiPlanar: mBpp = 1; mStride = mWidth; break; default: ALOGE("Unsupported color format %d", mColorFormat); mBpp = 1; mStride = mWidth; break; } } size_t ColorConverter::BitmapParams::cropWidth() const { Loading @@ -89,19 +119,15 @@ status_t ColorConverter::convert( size_t dstWidth, size_t dstHeight, size_t dstCropLeft, size_t dstCropTop, size_t dstCropRight, size_t dstCropBottom) { if (mDstFormat != OMX_COLOR_Format16bitRGB565) { return ERROR_UNSUPPORTED; } BitmapParams src( const_cast<void *>(srcBits), srcWidth, srcHeight, srcCropLeft, srcCropTop, srcCropRight, srcCropBottom); srcCropLeft, srcCropTop, srcCropRight, srcCropBottom, mSrcFormat); BitmapParams dst( dstBits, dstWidth, dstHeight, dstCropLeft, dstCropTop, dstCropRight, dstCropBottom); dstCropLeft, dstCropTop, dstCropRight, dstCropBottom, mDstFormat); status_t err; Loading Loading @@ -212,26 +238,104 @@ status_t ColorConverter::convertYUV420PlanarUseLibYUV( return ERROR_UNSUPPORTED; } uint16_t *dst_ptr = (uint16_t *)dst.mBits + dst.mCropTop * dst.mWidth + dst.mCropLeft; uint8_t *dst_ptr = (uint8_t *)dst.mBits + dst.mCropTop * dst.mStride + dst.mCropLeft * dst.mBpp; const uint8_t *src_y = (const uint8_t *)src.mBits + src.mCropTop * src.mWidth + src.mCropLeft; (const uint8_t *)src.mBits + src.mCropTop * src.mStride + src.mCropLeft; const uint8_t *src_u = (const uint8_t *)src_y + src.mWidth * src.mHeight + src.mCropTop * (src.mWidth / 2) + src.mCropLeft / 2; (const uint8_t *)src.mBits + src.mStride * src.mHeight + (src.mCropTop / 2) * (src.mStride / 2) + (src.mCropLeft / 2); const uint8_t *src_v = src_u + (src.mWidth / 2) * (src.mHeight / 2); src_u + (src.mStride / 2) * (src.mHeight / 2); switch (mDstFormat) { case OMX_COLOR_Format16bitRGB565: libyuv::I420ToRGB565(src_y, src.mStride, src_u, src.mStride / 2, src_v, src.mStride / 2, (uint8 *)dst_ptr, dst.mStride, src.cropWidth(), src.cropHeight()); break; case OMX_COLOR_Format32BitRGBA8888: libyuv::ConvertFromI420(src_y, src.mStride, src_u, src.mStride / 2, src_v, src.mStride / 2, (uint8 *)dst_ptr, dst.mStride, src.cropWidth(), src.cropHeight(), libyuv::FOURCC_ABGR); break; libyuv::I420ToRGB565(src_y, src.mWidth, src_u, src.mWidth / 2, src_v, src.mWidth / 2, (uint8 *)dst_ptr, dst.mWidth * 2, dst.mWidth, dst.mHeight); case OMX_COLOR_Format32bitBGRA8888: libyuv::ConvertFromI420(src_y, src.mStride, src_u, src.mStride / 2, src_v, src.mStride / 2, (uint8 *)dst_ptr, dst.mStride, src.cropWidth(), src.cropHeight(), libyuv::FOURCC_ARGB); break; default: return ERROR_UNSUPPORTED; } return OK; } void ColorConverter::writeToDst( void *dst_ptr, uint8_t *kAdjustedClip, bool uncropped, signed r1, signed g1, signed b1, signed r2, signed g2, signed b2) { switch (mDstFormat) { case OMX_COLOR_Format16bitRGB565: { uint32_t rgb1 = ((kAdjustedClip[r1] >> 3) << 11) | ((kAdjustedClip[g1] >> 2) << 5) | (kAdjustedClip[b1] >> 3); if (uncropped) { uint32_t rgb2 = ((kAdjustedClip[r2] >> 3) << 11) | ((kAdjustedClip[g2] >> 2) << 5) | (kAdjustedClip[b2] >> 3); *(uint32_t *)dst_ptr = (rgb2 << 16) | rgb1; } else { *(uint16_t *)dst_ptr = rgb1; } break; } case OMX_COLOR_Format32BitRGBA8888: { ((uint32_t *)dst_ptr)[0] = (kAdjustedClip[r1]) | (kAdjustedClip[g1] << 8) | (kAdjustedClip[b1] << 16) | (0xFF << 24); if (uncropped) { ((uint32_t *)dst_ptr)[1] = (kAdjustedClip[r2]) | (kAdjustedClip[g2] << 8) | (kAdjustedClip[b2] << 16) | (0xFF << 24); } break; } case OMX_COLOR_Format32bitBGRA8888: { ((uint32_t *)dst_ptr)[0] = (kAdjustedClip[b1]) | (kAdjustedClip[g1] << 8) | (kAdjustedClip[r1] << 16) | (0xFF << 24); if (uncropped) { ((uint32_t *)dst_ptr)[1] = (kAdjustedClip[b2]) | (kAdjustedClip[g2] << 8) | (kAdjustedClip[r2] << 16) | (0xFF << 24); } break; } default: break; } } status_t ColorConverter::convertYUV420Planar( const BitmapParams &src, const BitmapParams &dst) { if (!((src.mCropLeft & 1) == 0 Loading @@ -242,18 +346,18 @@ status_t ColorConverter::convertYUV420Planar( uint8_t *kAdjustedClip = initClip(); uint16_t *dst_ptr = (uint16_t *)dst.mBits + dst.mCropTop * dst.mWidth + dst.mCropLeft; uint8_t *dst_ptr = (uint8_t *)dst.mBits + dst.mCropTop * dst.mStride + dst.mCropLeft * dst.mBpp; const uint8_t *src_y = (const uint8_t *)src.mBits + src.mCropTop * src.mWidth + src.mCropLeft; (const uint8_t *)src.mBits + src.mCropTop * src.mStride + src.mCropLeft; const uint8_t *src_u = (const uint8_t *)src_y + src.mWidth * src.mHeight + src.mCropTop * (src.mWidth / 2) + src.mCropLeft / 2; (const uint8_t *)src.mBits + src.mStride * src.mHeight + (src.mCropTop / 2) * (src.mStride / 2) + src.mCropLeft / 2; const uint8_t *src_v = src_u + (src.mWidth / 2) * (src.mHeight / 2); src_u + (src.mStride / 2) * (src.mHeight / 2); for (size_t y = 0; y < src.cropHeight(); ++y) { for (size_t x = 0; x < src.cropWidth(); x += 2) { Loading Loading @@ -296,31 +400,19 @@ status_t ColorConverter::convertYUV420Planar( signed g2 = (tmp2 + v_g + u_g) / 256; signed r2 = (tmp2 + v_r) / 256; uint32_t rgb1 = ((kAdjustedClip[r1] >> 3) << 11) | ((kAdjustedClip[g1] >> 2) << 5) | (kAdjustedClip[b1] >> 3); uint32_t rgb2 = ((kAdjustedClip[r2] >> 3) << 11) | ((kAdjustedClip[g2] >> 2) << 5) | (kAdjustedClip[b2] >> 3); if (x + 1 < src.cropWidth()) { *(uint32_t *)(&dst_ptr[x]) = (rgb2 << 16) | rgb1; } else { dst_ptr[x] = rgb1; } bool uncropped = x + 1 < src.cropWidth(); (void)writeToDst(dst_ptr + x * dst.mBpp, kAdjustedClip, uncropped, r1, g1, b1, r2, g2, b2); } src_y += src.mWidth; src_y += src.mStride; if (y & 1) { src_u += src.mWidth / 2; src_v += src.mWidth / 2; src_u += src.mStride / 2; src_v += src.mStride / 2; } dst_ptr += dst.mWidth; dst_ptr += dst.mStride; } return OK; Loading