Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit cb62bc3f authored by Anu Sundararajan's avatar Anu Sundararajan Committed by Iliyan Malchev
Browse files

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: default avatarDevaraj Rangasamy <dev@ti.com>
Signed-off-by: default avatarSreenidhi Koti <sreenidhi@ti.com>
Signed-off-by: default avatarAnu Sundararajan <sanuradha@ti.com>
parent 8e51d58f
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -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 &);
};
+1 −0
Original line number Diff line number Diff line
@@ -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;
+11 −2
Original line number Diff line number Diff line
@@ -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";
+101 −0
Original line number Diff line number Diff line
@@ -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;