omxipcs_ycbcr420rszcscrotbgr_u8_p3c3r.c

来自「The OpenMAX DL (Development Layer) APIs 」· C语言 代码 · 共 427 行 · 第 1/2 页

C
427
字号
    armRetArgErrIf((colorConversion == OMX_IP_BGR888) && armNot2ByteAligned(dstStep), OMX_Sts_BadArgErr);    armRetArgErrIf((colorConversion != OMX_IP_BGR888) && armNot8ByteAligned(dstStep), 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    < 1, OMX_Sts_BadArgErr);    armRetArgErrIf(srcSize.width > srcStep[0],        OMX_Sts_BadArgErr);    armRetArgErrIf((srcSize.width >> 1) > srcStep[1], OMX_Sts_BadArgErr);    armRetArgErrIf((srcSize.width >> 1) > srcStep[2], OMX_Sts_BadArgErr);    armRetArgErrIf((interpolation != OMX_IP_NEAREST) &&                    (interpolation != OMX_IP_BILINEAR), OMX_Sts_BadArgErr);    armRetArgErrIf((rotation != OMX_IP_ROTATE90L) &&                    (rotation != OMX_IP_ROTATE90R) &&                   (rotation != OMX_IP_ROTATE180) &&                    (rotation != OMX_IP_DISABLE) &&                   (rotation != OMX_IP_FLIP_HORIZONTAL) &&                    (rotation != OMX_IP_FLIP_VERTICAL), OMX_Sts_BadArgErr);    armRetArgErrIf((colorConversion != OMX_IP_BGR555) &&                    (colorConversion != OMX_IP_BGR565) &&                   (colorConversion != OMX_IP_BGR444) &&                    (colorConversion != OMX_IP_BGR888), OMX_Sts_BadArgErr);    if((rotation == OMX_IP_ROTATE90L) || (rotation == OMX_IP_ROTATE90R))    {        armRetArgErrIf((dstSize.height * bytesPerOutPix) > dstStep, OMX_Sts_BadArgErr);    }    else    {        armRetArgErrIf((dstSize.width * bytesPerOutPix) > dstStep, OMX_Sts_BadArgErr);    }    /*    ----------------------------------------------------------------------------------    In this reference implementation, resize and colour space conversion are clubbed     together.  In this part of algorithm, ROTATE90 cases are handled differently (as    the output buffer may not be big enough to hold the resized and colour converted     input) - the image is flipped along the major diagonal, after resizing & colour     conversion, and before writing to the output buffer.        Resize:    Resizing is easier, if we have a have a unified grid containing both input and    rescaled images. The pixel (0,0) of the input image co-incides with the pixel     (0,0) of the output image.  We can compute the relative position of rescaled     pixels on the original image grid using the formula -    PIXnew(x,y) = PIXold(x*gridRatioH, y*gridRatioV),    where gridRatioH = SourceWidth/DestWidth and gridRatioV = SourceHeight/DestHeight    Then we apply either the Nearest Neighbour or Bilinear interpolation accordingly.        It is important to note that if DstWidth and DstHeight are not big enough to hold     the interpolated data, the interpolated image gets clipped such that we get the     top-left portion of the interpolated image in the output buffer.        Each iteration of the loop creates two rows (or columns) of interpolation output     pixels. This fits well as the YUV420 format works in multiples of 2x2 data blocks.        Colour Space Conversion:    CSC is clubbed with scale reduction and hence doesn't have to be done in-place.    A function armIPCS_BGRConvertAndPack() is called, after reading the scaled     input pixels. This function calls the relevant macros to perform YUV422->RGB    conversion and then pixel packing (BGR565 or BGR555).    ----------------------------------------------------------------------------------    */        pSrcY       = pSrc[0];    pSrcU       = pSrc[1];    pSrcV       = pSrc[2];    srcStepY    = srcStep[0];    srcStepU    = srcStep[1];    srcStepV    = srcStep[2];        if((rotation == OMX_IP_ROTATE90L) || (rotation == OMX_IP_ROTATE90R))    {        pDstRGBRef1 = (OMX_U8 *)pDst;        pDstRGBRef2 = (OMX_U8 *)pDst + bytesPerOutPix;        dstPixStep  = dstStep;        dstRowStep  = bytesPerOutPix;    }    else    {        pDstRGBRef1 = (OMX_U8 *)pDst;        pDstRGBRef2 = (OMX_U8 *)pDst + dstStep;        dstPixStep  = bytesPerOutPix;        dstRowStep  = dstStep;    }    if(interpolation == OMX_IP_NEAREST)    {        for(i = 0; i < dstSize.height; i += 2)        {            yPosLuma1   = armRoundFloatToS32(i * gridRatioV);            yPosLuma2   = armRoundFloatToS32((i + 1)  * gridRatioV);            yPosChroma  = armRoundFloatToS32((i >> 1) * gridRatioV);            pDstRGB1    = (OMX_U8 *)pDstRGBRef1 + (dstRowStep * i);            pDstRGB2    = (OMX_U8 *)pDstRGBRef2 + (dstRowStep * i);            lumaPix     = chromaPix = 0;                        for(j = 0; j < dstSize.width; j += 2)            {                xPosLuma1   = armRoundFloatToS32(lumaPix++   * gridRatioH);                xPosLuma2   = armRoundFloatToS32(lumaPix++   * gridRatioH);                xPosChroma  = armRoundFloatToS32(chromaPix++ * gridRatioH);                                Y00data     = pSrcY[xPosLuma1  + (yPosLuma1  * srcStepY)];                Y01data     = pSrcY[xPosLuma2  + (yPosLuma1  * srcStepY)];                Udata       = pSrcU[xPosChroma + (yPosChroma * srcStepU)];                Vdata       = pSrcV[xPosChroma + (yPosChroma * srcStepV)];                Y10data     = pSrcY[xPosLuma1  + (yPosLuma2  * srcStepY)];                Y11data     = pSrcY[xPosLuma2  + (yPosLuma2  * srcStepY)];                                armIPCS_BGRConvertAndPack(Y00data, Udata, Vdata, colorConversion, (void *)pDstRGB1);                pDstRGB1 += dstPixStep;                armIPCS_BGRConvertAndPack(Y01data, Udata, Vdata, colorConversion, (void *)pDstRGB1);                pDstRGB1 += dstPixStep;                                armIPCS_BGRConvertAndPack(Y10data, Udata, Vdata, colorConversion, (void *)pDstRGB2);                pDstRGB2 += dstPixStep;                armIPCS_BGRConvertAndPack(Y11data, Udata, Vdata, colorConversion, (void *)pDstRGB2);                pDstRGB2 += dstPixStep;            }        }    }        else if(interpolation == OMX_IP_BILINEAR)    {        for(i = 0; i < dstSize.height; i += 2)        {            yPosLuma1   = (OMX_INT)(i * gridRatioV);            yPosLuma2   = (OMX_INT)((i + 1)  * gridRatioV);            yPosChroma  = (OMX_INT)((i >> 1) * gridRatioV);            yOffLuma1   = (i * gridRatioV) - yPosLuma1;            yOffLuma2   = ((i + 1)  * gridRatioV) - yPosLuma2;            yOffChroma  = ((i >> 1) * gridRatioV) - yPosChroma;            pDstRGB1    = (OMX_U8 *)pDstRGBRef1 + (dstRowStep * i);            pDstRGB2    = (OMX_U8 *)pDstRGBRef2 + (dstRowStep * i);            lumaPix     = chromaPix = 0;                        for(j = 0; j < dstSize.width; j += 2)            {                xPos    = (OMX_INT)(lumaPix * gridRatioH);                xOff    = (lumaPix * gridRatioH) - xPos;                armIPCS_InterpPixel_Bilinear(pSrcY, srcStepY, xPos, yPosLuma1, xOff, yOffLuma1, &Y00data);                armIPCS_InterpPixel_Bilinear(pSrcY, srcStepY, xPos, yPosLuma2, xOff, yOffLuma2, &Y10data);                lumaPix++;                                xPos    = (OMX_INT)(lumaPix * gridRatioH);                xOff    = (lumaPix * gridRatioH) - xPos;                armIPCS_InterpPixel_Bilinear(pSrcY, srcStepY, xPos, yPosLuma1, xOff, yOffLuma1, &Y01data);                armIPCS_InterpPixel_Bilinear(pSrcY, srcStepY, xPos, yPosLuma2, xOff, yOffLuma2, &Y11data);                lumaPix++;                                xPos    = (OMX_INT)(chromaPix * gridRatioH);                xOff    = (chromaPix * gridRatioH) - xPos;                armIPCS_InterpPixel_Bilinear(pSrcU, srcStepU, xPos, yPosChroma, xOff, yOffChroma, &Udata);                armIPCS_InterpPixel_Bilinear(pSrcV, srcStepV, xPos, yPosChroma, xOff, yOffChroma, &Vdata);                chromaPix++;                                armIPCS_BGRConvertAndPack(Y00data, Udata, Vdata, colorConversion, (void *)pDstRGB1);                pDstRGB1 += dstPixStep;                armIPCS_BGRConvertAndPack(Y01data, Udata, Vdata, colorConversion, (void *)pDstRGB1);                pDstRGB1 += dstPixStep;                                armIPCS_BGRConvertAndPack(Y10data, Udata, Vdata, colorConversion, (void *)pDstRGB2);                pDstRGB2 += dstPixStep;                armIPCS_BGRConvertAndPack(Y11data, Udata, Vdata, colorConversion, (void *)pDstRGB2);                pDstRGB2 += dstPixStep;            }        }    }        /*    ---------------------------------------------------------------------------------    Rotation:    The Rotation operation follows the Resize-CSC and is to be done in-place.    The formulae for different flavours of rotation -    H flip: OutPix(x,y) = InPix(width-x,y),    V flip: OutPix(x,y) = InPix(x,height-y),    180 is: OutPix(x,y) = InPix(width-x,height-y),    90L is: OutPix(y,x) = InPix(x,height-y),    90R is: OutPix(y,x) = InPix(width-x,y),        The formulae for rotation by 90R and 90L listed above can't be implemented     in-place elegantly, in single looping through the image, and hence it is done    in two iterations (both of which can be done in-place, easily):    [1] The input is transformed according to the formulae OutPix(y,x) = InPix(x,y).        This is equivalent to flipping the image along the major diagonal and is         already performed during the Resize-Csc phase.    [2] Then we flip it along HORIZ axis (for 90L) and VERT axis (for 90R).    ---------------------------------------------------------------------------------    */        outBufWidth   = dstSize.width;    outBufHeight  = dstSize.height;        switch(rotation)    {        case OMX_IP_FLIP_HORIZONTAL : armIPCS_FlipLeftRight_I(pDst, bytesPerOutPix, dstStep, outBufWidth, outBufHeight);                                      break;        case OMX_IP_FLIP_VERTICAL   : armIPCS_FlipTopBottom_I(pDst, bytesPerOutPix, dstStep, outBufWidth, outBufHeight);                                      break;        case OMX_IP_ROTATE180       : armIPCS_Rotate180_I(pDst, bytesPerOutPix, dstStep, outBufWidth, outBufHeight);                                      break;        case OMX_IP_ROTATE90L       : armIPCS_FlipTopBottom_I(pDst, bytesPerOutPix, dstStep, outBufHeight, outBufWidth);                                      break;        case OMX_IP_ROTATE90R       : armIPCS_FlipLeftRight_I(pDst, bytesPerOutPix, dstStep, outBufHeight, outBufWidth);                                      break;        default                     : break;    }    return OMX_Sts_NoErr;}/* End of file */

⌨️ 快捷键说明

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