diff options
author | Anu Sundararajan <sanuradha@ti.com> | 2011-06-22 12:24:46 -0500 |
---|---|---|
committer | Iliyan Malchev <malchev@google.com> | 2011-06-23 18:35:24 -0700 |
commit | cb62bc3fe54222cf05824e6f98fefafee552049a (patch) | |
tree | 8d46602d08923ea8b04f2a8e6d23a8cfeafba9b7 | |
parent | 8e51d58fca9b7669f271378f9245e180f4360cbc (diff) | |
download | frameworks_av-cb62bc3fe54222cf05824e6f98fefafee552049a.zip frameworks_av-cb62bc3fe54222cf05824e6f98fefafee552049a.tar.gz frameworks_av-cb62bc3fe54222cf05824e6f98fefafee552049a.tar.bz2 |
Integrating TI OMAP4 Video Decoder
Added the video decoder component name to kDecoderInfo.
Set the quirks for the video decoder.
Add a new color format to OMX_IVCommon.h to denote TI OMAP4 NV12 color format.
Added a color conversion routine [ from NV12 to RGB ] for thumbnail generation.
Change-Id: I6b23c36441645ef65ec7406ba262d19f89cf64fd
Signed-off-by: Devaraj Rangasamy <dev@ti.com>
Signed-off-by: Sreenidhi Koti <sreenidhi@ti.com>
Signed-off-by: Anu Sundararajan <sanuradha@ti.com>
-rw-r--r-- | include/media/stagefright/ColorConverter.h | 3 | ||||
-rw-r--r-- | include/media/stagefright/openmax/OMX_IVCommon.h | 1 | ||||
-rw-r--r-- | media/libstagefright/OMXCodec.cpp | 13 | ||||
-rw-r--r-- | media/libstagefright/colorconversion/ColorConverter.cpp | 101 |
4 files changed, 116 insertions, 2 deletions
diff --git a/include/media/stagefright/ColorConverter.h b/include/media/stagefright/ColorConverter.h index 2ae8a5b..85ba920 100644 --- a/include/media/stagefright/ColorConverter.h +++ b/include/media/stagefright/ColorConverter.h @@ -76,6 +76,9 @@ private: status_t convertYUV420SemiPlanar( const BitmapParams &src, const BitmapParams &dst); + status_t convertTIYUV420PackedSemiPlanar( + const BitmapParams &src, const BitmapParams &dst); + ColorConverter(const ColorConverter &); ColorConverter &operator=(const ColorConverter &); }; diff --git a/include/media/stagefright/openmax/OMX_IVCommon.h b/include/media/stagefright/openmax/OMX_IVCommon.h index 12b4f93..7ed072b 100644 --- a/include/media/stagefright/openmax/OMX_IVCommon.h +++ b/include/media/stagefright/openmax/OMX_IVCommon.h @@ -149,6 +149,7 @@ typedef enum OMX_COLOR_FORMATTYPE { OMX_COLOR_Format24BitABGR6666, OMX_COLOR_FormatKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ OMX_COLOR_FormatVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_TI_COLOR_FormatYUV420PackedSemiPlanar = 0x7F000100, OMX_QCOM_COLOR_FormatYVU420SemiPlanar = 0x7FA30C00, OMX_COLOR_FormatMax = 0x7FFFFFFF } OMX_COLOR_FORMATTYPE; diff --git a/media/libstagefright/OMXCodec.cpp b/media/libstagefright/OMXCodec.cpp index bb8a8be..314425f 100644 --- a/media/libstagefright/OMXCodec.cpp +++ b/media/libstagefright/OMXCodec.cpp @@ -180,6 +180,7 @@ static const CodecInfo kDecoderInfo[] = { { MEDIA_MIMETYPE_AUDIO_G711_ALAW, "G711Decoder" }, { MEDIA_MIMETYPE_AUDIO_G711_MLAW, "OMX.google.g711.mlaw.decoder" }, { MEDIA_MIMETYPE_AUDIO_G711_MLAW, "G711Decoder" }, + { MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.TI.DUCATI1.VIDEO.DECODER" }, { MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.Nvidia.mp4.decode" }, { MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.qcom.7x30.video.decoder.mpeg4" }, { MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.qcom.video.decoder.mpeg4" }, @@ -187,12 +188,14 @@ static const CodecInfo kDecoderInfo[] = { { MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.SEC.MPEG4.Decoder" }, { MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.google.mpeg4.decoder" }, { MEDIA_MIMETYPE_VIDEO_MPEG4, "M4vH263Decoder" }, + { MEDIA_MIMETYPE_VIDEO_H263, "OMX.TI.DUCATI1.VIDEO.DECODER" }, { MEDIA_MIMETYPE_VIDEO_H263, "OMX.Nvidia.h263.decode" }, { MEDIA_MIMETYPE_VIDEO_H263, "OMX.qcom.7x30.video.decoder.h263" }, { MEDIA_MIMETYPE_VIDEO_H263, "OMX.qcom.video.decoder.h263" }, { MEDIA_MIMETYPE_VIDEO_H263, "OMX.SEC.H263.Decoder" }, { MEDIA_MIMETYPE_VIDEO_H263, "OMX.google.h263.decoder" }, { MEDIA_MIMETYPE_VIDEO_H263, "M4vH263Decoder" }, + { MEDIA_MIMETYPE_VIDEO_AVC, "OMX.TI.DUCATI1.VIDEO.DECODER" }, { MEDIA_MIMETYPE_VIDEO_AVC, "OMX.Nvidia.h264.decode" }, { MEDIA_MIMETYPE_VIDEO_AVC, "OMX.qcom.7x30.video.decoder.avc" }, { MEDIA_MIMETYPE_VIDEO_AVC, "OMX.qcom.video.decoder.avc" }, @@ -387,7 +390,10 @@ uint32_t OMXCodec::getComponentQuirks( quirks |= kDefersOutputBufferAllocation; } - if (!strncmp(componentName, "OMX.TI.", 7)) { + if (!strcmp(componentName, "OMX.TI.DUCATI1.VIDEO.DECODER")) { + quirks |= kRequiresAllocateBufferOnInputPorts; + quirks |= kRequiresAllocateBufferOnOutputPorts; + } else if (!strncmp(componentName, "OMX.TI.", 7)) { // Apparently I must not use OMX_UseBuffer on either input or // output ports on any of the TI components or quote: // "(I) may have unexpected problem (sic) which can be timing related @@ -1390,6 +1396,7 @@ status_t OMXCodec::setVideoOutputFormat( CHECK(format.eColorFormat == OMX_COLOR_FormatYUV420Planar || format.eColorFormat == OMX_COLOR_FormatYUV420SemiPlanar || format.eColorFormat == OMX_COLOR_FormatCbYCrY + || format.eColorFormat == OMX_TI_COLOR_FormatYUV420PackedSemiPlanar || format.eColorFormat == OMX_QCOM_COLOR_FormatYVU420SemiPlanar); err = mOMX->setParameter( @@ -3789,7 +3796,9 @@ static const char *colorFormatString(OMX_COLOR_FORMATTYPE type) { size_t numNames = sizeof(kNames) / sizeof(kNames[0]); - if (type == OMX_QCOM_COLOR_FormatYVU420SemiPlanar) { + if (type == OMX_TI_COLOR_FormatYUV420PackedSemiPlanar) { + return "OMX_TI_COLOR_FormatYUV420PackedSemiPlanar"; + } else if (type == OMX_QCOM_COLOR_FormatYVU420SemiPlanar) { return "OMX_QCOM_COLOR_FormatYVU420SemiPlanar"; } else if (type < 0 || (size_t)type >= numNames) { return "UNKNOWN"; diff --git a/media/libstagefright/colorconversion/ColorConverter.cpp b/media/libstagefright/colorconversion/ColorConverter.cpp index b28d947..fd933cc 100644 --- a/media/libstagefright/colorconversion/ColorConverter.cpp +++ b/media/libstagefright/colorconversion/ColorConverter.cpp @@ -42,6 +42,7 @@ bool ColorConverter::isValid() const { case OMX_COLOR_FormatCbYCrY: case OMX_QCOM_COLOR_FormatYVU420SemiPlanar: case OMX_COLOR_FormatYUV420SemiPlanar: + case OMX_TI_COLOR_FormatYUV420PackedSemiPlanar: return true; default: @@ -113,6 +114,10 @@ status_t ColorConverter::convert( err = convertYUV420SemiPlanar(src, dst); break; + case OMX_TI_COLOR_FormatYUV420PackedSemiPlanar: + err = convertTIYUV420PackedSemiPlanar(src, dst); + break; + default: { CHECK(!"Should not be here. Unknown color conversion."); @@ -417,6 +422,102 @@ status_t ColorConverter::convertYUV420SemiPlanar( return OK; } +status_t ColorConverter::convertTIYUV420PackedSemiPlanar( + const BitmapParams &src, const BitmapParams &dst) { + +/* +The TIYUV420PackedSemiPlanar format is same as YUV420PackedSemiPlanar but with +additional padding as shown in the diagram below. The padded width and padded +height is different for different compression formats and it is read from the +codec. In this color conversion routine, the padded resolution is obtained from +src bitmap. + + ------------------------------------ +| | +| | +| ------------------------- | +| | | | +| | | | +| | Y DATA | | +| | | | +| | | | +| | | | +| ------------------------- | +| | +| ------------ | +| | | | +| | | | +| | UV DATA | | +| | | | +| | | | +| | | | +| ------------ | +| | +| | + ------------------------------------ +*/ + + LOGV("src.mCropLeft = %d src.mCropTop =%d src.mWidth = %d src.mHeight = %d" + " dst.mWidth = %d dst.mHeight = %d", src.mCropLeft , src.mCropTop, + src.mWidth, src.mHeight, dst.mWidth, dst.mHeight); + + size_t offset = (src.mWidth * src.mCropTop) + src.mCropLeft; + + uint8_t *kAdjustedClip = initClip(); + + uint32_t *dst_ptr = (uint32_t *)dst.mBits; + const uint8_t *src_y = (const uint8_t *)src.mBits; + const uint8_t *src_u = (const uint8_t *)(src_y-offset) + (src.mWidth * src.mHeight); + src_u += ( ( src.mWidth * (src.mCropTop/2) ) + src.mCropLeft ); + const uint8_t *src_v = src_u + 1; + + for (size_t y = 0; y < dst.mHeight; ++y) { + for (size_t x = 0; x < dst.mWidth; x += 2) { + + signed y1 = (signed)src_y[x] - 16; //Y pixel + signed y2 = (signed)src_y[x + 1] - 16; //2nd Y pixel + + signed u = (signed)src_u[x & ~1] - 128; //U component + signed v = (signed)src_u[(x & ~1) + 1] - 128; //V component + + 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[r1] >> 3) << 11) + | ((kAdjustedClip[g1] >> 2) << 5) + | (kAdjustedClip[b1] >> 3); + + uint32_t rgb2 = + ((kAdjustedClip[r2] >> 3) << 11) + | ((kAdjustedClip[g1] >> 2) << 5) + | (kAdjustedClip[b1] >> 3); + + dst_ptr[x / 2] = (rgb2 << 16) | rgb1; + } + + src_y += src.mWidth; //increment Y-pixel line + if (y&1) { + src_u += src.mWidth; //increment U-V line + } + + dst_ptr += dst.mWidth / 2; + } + return OK; +} + uint8_t *ColorConverter::initClip() { static const signed kClipMin = -278; static const signed kClipMax = 535; |