summaryrefslogtreecommitdiffstats
path: root/media
diff options
context:
space:
mode:
authorAnu Sundararajan <sanuradha@ti.com>2011-06-22 12:24:46 -0500
committerIliyan Malchev <malchev@google.com>2011-06-23 18:35:24 -0700
commitcb62bc3fe54222cf05824e6f98fefafee552049a (patch)
tree8d46602d08923ea8b04f2a8e6d23a8cfeafba9b7 /media
parent8e51d58fca9b7669f271378f9245e180f4360cbc (diff)
downloadframeworks_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>
Diffstat (limited to 'media')
-rw-r--r--media/libstagefright/OMXCodec.cpp13
-rw-r--r--media/libstagefright/colorconversion/ColorConverter.cpp101
2 files changed, 112 insertions, 2 deletions
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;