📄 omxipcs_ycbcr422toycbcr420rotate_u8_p3r.c
字号:
/** * * * File Name: omxIPCS_YCbCr422ToYCbCr420Rotate_U8_P3R.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. Both the * source and desitnation are in three-channel format and planar domain. * */#include "omxtypes.h"#include "armOMX.h"#include "omxIP.h"#include "armCOMM.h"#include "armIP.h"/** * Function: omxIPCS_YCbCr422ToYCbCr420Rotate_U8_P3R (4.4.3.6.2) * * Description: * This function decimates the color space of the input image from YCbCr 422 * planar data to YCbCr 420 planar data, and then applies an optional rotation * of -90, +90, or 180 degrees. The difference between this function and * omxIPCS_CbYCrY422ToYCbCr420Rotate_U8_C2P3R is that this function supports * the input YCbCr422 format in planar order. * * * If the size of the output image, roiSize.width or roiSize.height, cannot * be divided by 8 exactly, it will be cut to be multiple of 8. * * Input Arguments: * * pSrc - a 3-element vector containing pointers to the start of each of * the YCbCr422 input planes. The pointer pSrc[0] must be aligned * on an 8-byte boundary; the pointers pSrc[1] and pSrc[2] must be * aligned on a 4-byte boundaries. * srcStep - a 3-element vector containing the distance, in bytes, between * the start of lines in each of the input image planes. The * parameter srcStep[0] must be a multiple of 8; the parameters * srcStep[1] and srcStep[2] must multiples of 4. * 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 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. * * 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 a 4-byte boundaries. * * Return Value: * If the function runs without error, it returns OMX_Sts_NoErr * The function returns OMX_Sts_BadArgErr if one or more of the * following occurs: * - any pointer is NULL * - pSrc[0] or pDst[0] is not aligned on an 8-byte boundary * - pSrc[1], pSrc[2], pDst[1] or pDst[2] is not aligned on * a 4-byte boundary * - any of the steps is less than 1 * - srcStep[0] or dstStep[0] is not multiple of 8 * - srcStep[1], srcStep[2], dstStep[1] or dstStep[2] is not multiple of 4 * - roiSize.width is larger than srcStep[0] * - roiSize.width is larger than twice srcStep[1] or twice srcStep[2] * - rotation contains an invalid value * - dstStep[0] is less than roiSize.width of downscaled, color-converted * and rotated image * - dstStep[1] or dstStep[2] is less than half roiSize.width * - roiSize.width or roiSize.height is less than 8. * */ OMXResult omxIPCS_YCbCr422ToYCbCr420Rotate_U8_P3R( const OMX_U8* pSrc[3], OMX_INT srcStep[3], OMX_U8 *pDst[3], OMX_INT dstStep[3], OMXSize roiSize, OMXIPRotation rotation ){ OMX_INT chroma, i, j; OMX_INT outWidthY, outHeightY, outWidthUV, outHeightUV; OMX_U8 *pDstRef; const OMX_U8 *pSrcRef, *pSrcRef2;#if ARM_IPCS_INTERP_BILINEAR OMX_S16 interpPix;#endif armRetArgErrIf(!pSrc, OMX_Sts_BadArgErr); armRetArgErrIf(!pDst, OMX_Sts_BadArgErr); armRetArgErrIf(!pSrc[0], OMX_Sts_BadArgErr); armRetArgErrIf(!pSrc[1], OMX_Sts_BadArgErr); armRetArgErrIf(!pSrc[2], OMX_Sts_BadArgErr); armRetArgErrIf(!pDst[0], OMX_Sts_BadArgErr); armRetArgErrIf(!pDst[1], OMX_Sts_BadArgErr); armRetArgErrIf(!pDst[2], OMX_Sts_BadArgErr); armRetArgErrIf(!srcStep, OMX_Sts_BadArgErr); armRetArgErrIf(!dstStep, OMX_Sts_BadArgErr); armRetArgErrIf(!armIs8ByteAligned(pSrc[0]), OMX_Sts_BadArgErr); armRetArgErrIf(!armIs4ByteAligned(pSrc[1]), OMX_Sts_BadArgErr); armRetArgErrIf(!armIs4ByteAligned(pSrc[2]), 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[0] < 1, OMX_Sts_BadArgErr); armRetArgErrIf(srcStep[1] < 1, OMX_Sts_BadArgErr); armRetArgErrIf(srcStep[2] < 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[0]), OMX_Sts_BadArgErr); armRetArgErrIf(!armIs4ByteAligned(srcStep[1]), OMX_Sts_BadArgErr); armRetArgErrIf(!armIs4ByteAligned(srcStep[2]), 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[0] , OMX_Sts_BadArgErr); armRetArgErrIf(roiSize.width > 2*srcStep[1], OMX_Sts_BadArgErr); armRetArgErrIf(roiSize.width > 2*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; 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 global. 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[0]; pDstRef = pDst[0] + outWidthY - 1; for(i = 0; i < outHeightY; i++) { for(j = 0; j < outWidthY; j++) { pDstRef[dstStep[0] * j] = pSrcRef[j]; } pSrcRef += srcStep[0]; pDstRef--; } for(chroma = 1; chroma <= 2; chroma++) { pSrcRef = pSrc[chroma]; pSrcRef2 = pSrc[chroma] + srcStep[chroma]; 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[j];#elif ARM_IPCS_INTERP_BILINEAR interpPix = armRoundFloatToS16(((OMX_F32)pSrcRef[j] + (OMX_F32)pSrcRef2[j]) / 2); pDstRef[dstStep[chroma] * j] = armClip(OMX_MIN_U8, OMX_MAX_U8, interpPix);#endif } pSrcRef += 2*srcStep[chroma]; pSrcRef2 += 2*srcStep[chroma]; pDstRef--; } } } else if(rotation == OMX_IP_ROTATE90L) { pSrcRef = pSrc[0]; pDstRef = pDst[0]; for(i = 0; i < outHeightY; i++) { for(j = 0; j < outWidthY; j++) { pDstRef[dstStep[0] * j] = pSrcRef[outWidthY - 1 - j]; } pSrcRef += srcStep[0]; pDstRef++; } for(chroma = 1; chroma <= 2; chroma++) { pSrcRef = pSrc[chroma]; pSrcRef2 = pSrc[chroma] + srcStep[chroma]; 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[outWidthUV - 1 - j];#elif ARM_IPCS_INTERP_BILINEAR interpPix = armRoundFloatToS16(((OMX_F32)pSrcRef[outWidthUV - 1 - j] + (OMX_F32)pSrcRef2[outWidthUV - 1 - j]) / 2); pDstRef[dstStep[chroma] * j] = armClip(OMX_MIN_U8, OMX_MAX_U8, interpPix);#endif } pSrcRef += 2*srcStep[chroma]; pSrcRef2 += 2*srcStep[chroma]; pDstRef++; } } } else if(rotation == OMX_IP_ROTATE180) { pSrcRef = pSrc[0]; pDstRef = pDst[0] + (outHeightY-1) * dstStep[0]; for(i = 0; i < outHeightY; i++) { for(j = 0; j < outWidthY; j++) { pDstRef[outWidthY - 1 - j] = pSrcRef[j]; } pSrcRef += srcStep[0]; pDstRef -= dstStep[0]; } for(chroma = 1; chroma <= 2; chroma++) { pSrcRef = pSrc[chroma]; pSrcRef2 = pSrc[chroma] + srcStep[chroma]; 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 - 1 - j] = pSrcRef[j];#elif ARM_IPCS_INTERP_BILINEAR interpPix = armRoundFloatToS16(((OMX_F32)pSrcRef[j] + (OMX_F32)pSrcRef2[j]) / 2); pDstRef[outWidthUV - 1 - j] = armClip(OMX_MIN_U8, OMX_MAX_U8, interpPix);#endif } pSrcRef += 2*srcStep[chroma]; pSrcRef2 += 2*srcStep[chroma]; pDstRef -= dstStep[chroma]; } } } else if(rotation == OMX_IP_DISABLE) { pSrcRef = pSrc[0]; pDstRef = pDst[0]; for(i = 0; i < outHeightY; i++) { for(j = 0; j < outWidthY; j++) { pDstRef[j] = pSrcRef[j]; } pSrcRef += srcStep[0]; pDstRef += dstStep[0]; } for(chroma = 1; chroma <= 2; chroma++) { pSrcRef = pSrc[chroma]; pSrcRef2 = pSrc[chroma] + srcStep[chroma]; pDstRef = pDst[chroma]; for(i = 0; i < outHeightUV; i++) { for(j = 0; j < outWidthUV; j++) {#if ARM_IPCS_INTERP_NEAREST pDstRef[j] = pSrcRef[j];#elif ARM_IPCS_INTERP_BILINEAR interpPix = armRoundFloatToS16(((OMX_F32)pSrcRef[j] + (OMX_F32)pSrcRef2[j]) / 2); pDstRef[j] = armClip(OMX_MIN_U8, OMX_MAX_U8, interpPix);#endif } pSrcRef += 2*srcStep[chroma]; pSrcRef2 += 2*srcStep[chroma]; pDstRef += dstStep[chroma]; } } } return OMX_Sts_NoErr;}/* End of file */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -