⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 omxipcs_cbycry422toycbcr420rotate_u8_c2p3r.c

📁 The OpenMAX DL (Development Layer) APIs contain a comprehensive set of audio, video, signal processi
💻 C
字号:
/** * *  * File Name:  omxIPCS_CbYCrY422ToYCbCr420Rotate_U8_C2P3R.c * OpenMAX DL: v1.0.2 * Revision:   10586 * Date:       Wednesday, March 5, 2008 *  * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved. *  *  * * Description  : Integrated Colour Space Conversion and Rotate Routine. The Source is *                in two-channel pixel domain format and the destination is in  *                three-channel, planar domain format. *                 */#include "omxtypes.h"#include "armOMX.h"#include "omxIP.h"#include "armCOMM.h"#include "armIP.h"/** * Function:  omxIPCS_CbYCrY422ToYCbCr420Rotate_U8_C2P3R   (4.4.3.6.1) * * Description: * CbYCrY422 to YCbCr420 planar format conversion with rotation function.   * This function decimates the color space of the input image from CbYCrY 422  * to YCbCr 420, applies an optional rotation of -90, +90, or 180 degrees, and  * then rearranges the data from the pixel-oriented input format to a planar  * output format.  * The size of output image: if roiSize.width or roiSize.height cannot be  * divided by 8 exactly, it will be cut to be a multiple of 8.  * * Input Arguments: *    *   pSrc - pointer to the start of the buffer containing the pixel-oriented  *            CbYCrY422 input; must be aligned on an 8-byte boundary.  *   srcStep - distance, in bytes, between the start of lines in the source  *            image; must be a multiple of 8.  *   dstStep - a 3-element vector containing the distance, in bytes, between  *            the start of lines in each of the output image planes.  The  *            parameter dstStep[0] must be a multiple of 8; the parameters  *            dstStep[1] and dstStep[2] must be multiples of 4.  *   roiSize - dimensions, in pixels, of the source and destination regions  *            of interest  *   rotation - rotation control parameter; must be set to one of the  *            following pre-defined values: OMX_IP_DISABLE, OMX_IP_ROTATE90L,  *            OMX_IP_ROTATE90R, or OMX_IP_ROTATE180. OutputArguments  * * Output Arguments: *   pDst - a 3-element vector containing pointers to the start of each of  *            the YCbCr420 output planes. The pointer pDst[0] must be aligned  *            on an 8-byte boundary.  The pointers pDst[1] and pDst[2]must be  *            aligned on 4-byte boundaries.  * * Return Value: *    If the function runs without error, it returns OMX_Sts_NoErr  *    If any of the following cases occurs, the function returns  *    OMX_Sts_BadArgErr:  *    -   pSrc, pDst[0], pDst[1], or pDst[2] is NULL  *    -   pSrc or pDst[0] is not aligned at 8 bytes boundary  *    -   pDst[1] or pDst[2] is not aligned at 4-byte boundary  *    -   srcStep, dstStep[1], dstStep[2], or dstStep[3] is less than 1  *    -   srcStep or dstStep[0] is not multiple of 8  *    -   dstStep[1] or dstStep[2] is not multiple of 4  *    -   roiSize.width is larger than half of srcStep  *    -   rotation contains an invalid control parameter *    -   dstStep[0] is less than roiSize.width  *    -   dstStep[1] or dstStep[2] is less than half roiSize.width  *    -   roiSize.width or roiSize.height is less than 8  * */ OMXResult omxIPCS_CbYCrY422ToYCbCr420Rotate_U8_C2P3R(        const OMX_U8 *pSrc,        OMX_INT srcStep,        OMX_U8 *pDst[3],        OMX_INT dstStep[3],        OMXSize roiSize,        OMXIPRotation rotation       ){    const OMX_U8 *pSrcRef, *pSrcRef2;    OMX_INT chroma, chromaOffset, chromaOffsetRev, i, j;    OMX_INT inWidthYUV, outWidthY, outHeightY, outWidthUV, outHeightUV;    OMX_U8  *pDstRef;    #if ARM_IPCS_INTERP_BILINEAR    OMX_S16 interpPix;#endif    armRetArgErrIf(!pSrc, OMX_Sts_BadArgErr);    armRetArgErrIf(!pDst, OMX_Sts_BadArgErr);    armRetArgErrIf(!pDst[0], OMX_Sts_BadArgErr);    armRetArgErrIf(!pDst[1], OMX_Sts_BadArgErr);    armRetArgErrIf(!pDst[2], OMX_Sts_BadArgErr);    armRetArgErrIf(!dstStep, OMX_Sts_BadArgErr);    armRetArgErrIf(!armIs8ByteAligned(pSrc), OMX_Sts_BadArgErr);    armRetArgErrIf(!armIs8ByteAligned(pDst[0]), OMX_Sts_BadArgErr);    armRetArgErrIf(!armIs4ByteAligned(pDst[1]), OMX_Sts_BadArgErr);    armRetArgErrIf(!armIs4ByteAligned(pDst[2]), OMX_Sts_BadArgErr);    armRetArgErrIf(srcStep < 1, OMX_Sts_BadArgErr);    armRetArgErrIf(dstStep[0] < 1, OMX_Sts_BadArgErr);    armRetArgErrIf(dstStep[1] < 1, OMX_Sts_BadArgErr);    armRetArgErrIf(dstStep[2] < 1, OMX_Sts_BadArgErr);    armRetArgErrIf(!armIs8ByteAligned(srcStep), OMX_Sts_BadArgErr);    armRetArgErrIf(!armIs8ByteAligned(dstStep[0]), OMX_Sts_BadArgErr);    armRetArgErrIf(!armIs4ByteAligned(dstStep[1]), OMX_Sts_BadArgErr);    armRetArgErrIf(!armIs4ByteAligned(dstStep[2]), OMX_Sts_BadArgErr);    armRetArgErrIf(roiSize.width > srcStep/2, OMX_Sts_BadArgErr);    armRetArgErrIf(roiSize.width > dstStep[0], OMX_Sts_BadArgErr);    armRetArgErrIf(roiSize.width > 2*dstStep[1], OMX_Sts_BadArgErr);    armRetArgErrIf(roiSize.width > 2*dstStep[2], OMX_Sts_BadArgErr);    armRetArgErrIf(roiSize.width < 8, OMX_Sts_BadArgErr);    armRetArgErrIf(roiSize.height < 8, OMX_Sts_BadArgErr);    armRetArgErrIf((rotation != OMX_IP_ROTATE180) &&                   (rotation != OMX_IP_ROTATE90L) &&                   (rotation != OMX_IP_ROTATE90R) &&                   (rotation != OMX_IP_DISABLE), OMX_Sts_BadArgErr);        roiSize.height  = (roiSize.height >> 3) << 3;    roiSize.width   = (roiSize.width >> 3) << 3;        inWidthYUV      = roiSize.width * 2;    outHeightY      = roiSize.height;    outWidthY       = roiSize.width;    outHeightUV     = roiSize.height >> 1;    outWidthUV      = roiSize.width >> 1;    /*    ----------------------------------------------------------------------------------    The conversion from Colour Space YCbCr422 to YCbCr420 in planar domain is easier    as Y remains unchanged and it is a simple case of interpolation for Cb and Cr     planes. This function supports two interpolation methods (Not at the API level,     but internally) - namely Nearest Neighbour and Bilinear, by setting a static     global variable.        The Rotation operation if combined with interpolation, becomes easier to carry    out as we'll not have to do it in-place. The formulae for rotation by     180 is: OutPix(x,y) = InPix(width-x,height-y),    90R is: OutPix(y,x) = InPix(width-x,y) and     90L is: OutPix(y,x) = InPix(x,height-y).        For each type of rotation, the Luma plane is separately handled but the two     Chroma planes (having similar characteristics), are handled together in a loop.    ---------------------------------------------------------------------------------    */    if(rotation == OMX_IP_ROTATE90R)    {        pSrcRef = pSrc;        pDstRef = pDst[0] + outWidthY - 1;        for(i = 0; i < outHeightY; i++)        {            for(j = 0; j < outWidthY; j++)            {                pDstRef[dstStep[0] * j] = pSrcRef[2 * j+1]; /* changing from YCbYcr Src to CbYCrY */            }            pSrcRef += srcStep;            pDstRef--;        }                for(chroma = 1; chroma <= 2; chroma++)        {            chromaOffset    = (chroma == 1) ? 0 : 2;            pSrcRef         = pSrc + chromaOffset;            pSrcRef2        = pSrc + chromaOffset + srcStep;            pDstRef         = pDst[chroma] + outHeightUV - 1;                        for(i = 0; i < outHeightUV; i++)            {                for(j = 0; j < outWidthUV; j++)                {#if ARM_IPCS_INTERP_NEAREST                    pDstRef[dstStep[chroma] * j] = pSrcRef[4 * j];#elif ARM_IPCS_INTERP_BILINEAR                    interpPix = armRoundFloatToS16(((OMX_F32)pSrcRef[4 * j] + (OMX_F32)pSrcRef2[4 * j]) / 2);                    pDstRef[dstStep[chroma] * j] = armClip(OMX_MIN_U8, OMX_MAX_U8, interpPix);#endif                }                pSrcRef  += 2*srcStep;                pSrcRef2 += 2*srcStep;                pDstRef--;            }        }    }    else if(rotation == OMX_IP_ROTATE90L)    {        pSrcRef = pSrc;        pDstRef = pDst[0];        for(i = 0; i < outHeightY; i++)        {            for(j = 0; j < outWidthY; j++)            {                pDstRef[dstStep[0] * j] = pSrcRef[inWidthYUV - 1 - (2 * j)];            }            pSrcRef += srcStep;            pDstRef++;        }                for(chroma = 1; chroma <= 2; chroma++)        {            chromaOffsetRev    = (chroma == 1) ? 4 : 2;            pSrcRef         = pSrc;            pSrcRef2        = pSrc + srcStep;            pDstRef         = pDst[chroma];                        for(i = 0; i < outHeightUV; i++)            {                for(j = 0; j < outWidthUV; j++)                {#if ARM_IPCS_INTERP_NEAREST                    pDstRef[dstStep[chroma] * j] = pSrcRef[inWidthYUV - chromaOffsetRev - (4 * j)];#elif ARM_IPCS_INTERP_BILINEAR                     interpPix = armRoundFloatToS16(((OMX_F32)pSrcRef[inWidthYUV - chromaOffsetRev - (4 * j)] +                                                        (OMX_F32)pSrcRef2[inWidthYUV - chromaOffsetRev - (4 * j)]) / 2);                    pDstRef[dstStep[chroma] * j] = armClip(OMX_MIN_U8, OMX_MAX_U8, interpPix);#endif                }                pSrcRef  += 2*srcStep;                pSrcRef2 += 2*srcStep;                pDstRef++;            }        }    }        else if(rotation == OMX_IP_ROTATE180)    {        pSrcRef = pSrc;        pDstRef = pDst[0] + (outHeightY-1) * dstStep[0];        for(i = 0; i < outHeightY; i++)        {            for(j = 0; j < outWidthY; j++)            {                pDstRef[outWidthY - j - 1] = pSrcRef[2 * j + 1];            }            pSrcRef += srcStep;            pDstRef -= dstStep[0];        }                for(chroma = 1; chroma <= 2; chroma++)        {            chromaOffset    = (chroma == 1) ? 0 : 2;            pSrcRef         = pSrc + chromaOffset;            pSrcRef2        = pSrc + chromaOffset + srcStep;            pDstRef         = pDst[chroma] + (outHeightUV-1) * dstStep[chroma];                        for(i = 0; i < outHeightUV; i++)            {                for(j = 0; j < outWidthUV; j++)                {#if ARM_IPCS_INTERP_NEAREST                    pDstRef[outWidthUV - j - 1] = pSrcRef[4 * j];#elif ARM_IPCS_INTERP_BILINEAR                    interpPix = armRoundFloatToS16(((OMX_F32)pSrcRef[4 * j] + (OMX_F32)pSrcRef2[4 * j]) / 2);                    pDstRef[outWidthUV - j - 1] = armClip(OMX_MIN_U8, OMX_MAX_U8, interpPix);#endif                }                pSrcRef  += 2*srcStep;                pSrcRef2 += 2*srcStep;                pDstRef  -= dstStep[chroma];            }        }    }        else if(rotation == OMX_IP_DISABLE)    {        pSrcRef = pSrc;        pDstRef = pDst[0];        for(i = 0; i < outHeightY; i++)        {            for(j = 0; j < outWidthY; j++)            {                pDstRef[j] = pSrcRef[j * 2 + 1];            }            pSrcRef += srcStep;            pDstRef += dstStep[0];        }                for(chroma = 1; chroma <= 2; chroma++)        {            chromaOffset    = (chroma == 1) ? 0 : 2;            pSrcRef         = pSrc + chromaOffset;            pSrcRef2        = pSrc + chromaOffset + srcStep;            pDstRef         = pDst[chroma];                        for(i = 0; i < outHeightUV; i++)            {                for(j = 0; j < outWidthUV; j++)                {#if ARM_IPCS_INTERP_NEAREST                    pDstRef[j] = pSrcRef[4 * j];#elif ARM_IPCS_INTERP_BILINEAR                    interpPix  = armRoundFloatToS16(((OMX_F32)pSrcRef[4 * j] + (OMX_F32)pSrcRef2[4 * j]) / 2);                    pDstRef[j] = armClip(OMX_MIN_U8, OMX_MAX_U8, interpPix);#endif                }                pSrcRef  += 2*srcStep;                pSrcRef2 += 2*srcStep;                pDstRef  += dstStep[chroma];            }        }    }        return OMX_Sts_NoErr;}/* End of file */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -