QOMX_COLOR_FormatYUV420PackedSemiPlanar64x32Tile2m8ka 颜色格式 [英] QOMX_COLOR_FormatYUV420PackedSemiPlanar64x32Tile2m8ka color format

查看:18
本文介绍了QOMX_COLOR_FormatYUV420PackedSemiPlanar64x32Tile2m8ka 颜色格式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

全部

有谁知道QOMX_COLOR_FormatYUV420PackedSemiPlanar64x32Tile2m8ka格式的详细信息,这是qcom 7x30 h/w解码器的输出格式,数据是如何以这种颜色格式存储的?谢谢

Does anybody know details about QOMX_COLOR_FormatYUV420PackedSemiPlanar64x32Tile2m8ka format, it's the output format of qcom 7x30 h/w decoder, how data is stored in such color format? thanks

推荐答案

这是我的研究,关于QOMX_COLOR_FormatYUV420PackedSemiPlanar64x32Tile2m8ka 转换为YUV420Planar (I420).关于QOMX_COLOR_FormatYUV420PackedSemiPlanar64x32Tile2m8ka格式,可以参考($your_android_native_sdk_dir)/WORKING_DIRECTORY/hardware/qcom/media/mm-core/inc/QOMX_IVH 代码源代码.这个函数可能理想地支持通用分辨率,但是我只测试 CIF 大小,因为给定的源输入不可用.当然,您可以将其他大小的数据伪造为给定的输入.希望对您有所帮助.根据我的 CIF 测试,我看到颜色是正确的.代码很长,大约有 390 行,很沉重.包括步骤:构造yTileToMb、uvTileToMb,然后按如下转换y和u/v.

This is my research on this, about QOMX_COLOR_FormatYUV420PackedSemiPlanar64x32Tile2m8ka converting to YUV420Planar (I420). As far as QOMX_COLOR_FormatYUV420PackedSemiPlanar64x32Tile2m8ka format is concerned, you can refer to ($your_android_native_sdk_dir)/WORKING_DIRECTORY/hardware/qcom/media/mm-core/inc/QOMX_IVCommonExtensions.h source code. This function might idealy support generic resolution, however I only test on CIF size because unavailable given source input. Sure you can fake other size data as given input. Hope it is helpful if you are working on this. I have saw the color is correct per my CIF test. The code is so long about 390 lines, so heavy. Including steps: construct yTileToMb, uvTileToMb, then converting y and u/v as followed.

///////////////////////////////////////////////////////////////////////
/**
* Enumeration defining the extended uncompressed image/video
* formats.
*
* ENUMS:
*  YVU420PackedSemiPlanar       : Buffer containing all Y, and then V and U 
*                                 interleaved.
*  YVU420PackedSemiPlanar32m4ka : YUV planar format, similar to the 
*                                 YVU420PackedSemiPlanar format, but with the
*                                 following restrictions:
*
*                                 1. The width and height of both plane must 
*                                 be a multiple of 32 texels.
*
*                                 2. The base address of both planes must be 
*                                 aligned to a 4kB boundary.
* 
*  YUV420PackedSemiPlanar16m2ka : YUV planar format, similar to the
*                                 YUV420PackedSemiPlanar format, but with the
*                                 following restrictions:
*
*                                 1. The width of the luma plane must be a
*                                 multiple of 16 pixels.
*
*                                 2. The address of both planes must be 
*                                 aligned to a 2kB boundary.
* 
*  YUV420PackedSemiPlanar64x32Tile2m8ka : YUV planar format, similar to the 
*                                 YUV420PackedSemiPlanar format, but with the
*                                 following restrictions:
*
*                                 1. The data is laid out in a 4x2 MB tiling 
*                                 memory structure
*
*                                 2. The width of each plane is a multiple of
*                                 2 4x2 MB tiles.
*
*                                 3. The height of each plan is a multiple of
*                                 a 4x2 MB tile.
*
*                                 4. The base address of both planes must be 
*                                 aligned to an 8kB boundary.
*
*                                 5. The tiles are scanned in the order 
*                                 defined in the MFCV5.1 User's Manual.
*
*                                                                       i.e, CIF size in pysical location
*
*                                                                       Luma order(4x2 MB = 64x32 pix): 54 tiles:
*                                                                       0  1  6  7  8  9
*                                                                       2  3  4  5  10 11
*                                                                       12 13 18 19 20 21
*                                                                       14 15 16 17 22 23
*                                                                       24 25 30 31 32 33
*                                                                       26 27 28 29 34 35
*                                                                       36 37 42 43 44 45
*                                                                       38 39 40 41 46 47
*                                                                       48 49 50 51 52 53
*                                                                       MBs in a y tile:
*                                                                       0  1  2  3
*                                                                       22 23 24 25
*                                                                       Chromas order(64x32 pix):
*                                                                       0  1  6  7  8  9
*                                                                       2  3  4  5  10 11
*                                                                       12 13 18 19 20 21
*                                                                       14 15 16 17 22 23
*                                                                       24 25 26 27 28 29
*                                                                       MBs in a uv tile:
*                                                                       0  1  2  3
*                                                                       22 23 24 25
*                                                                       44 45 46 47
*                                                                       66 67 68 69
*
*/

// YUV420PackedSemiPlanar64x32Tile2m8ka,    // 12 bit, yyyyyyyy vuvu
// YUV420Planar, 12 bit, yyyyyyyy uu vv
#pragma pack(1)
typedef enum {
    Scan_Init       = 0,
    Scan_Hor,
    Scan_VerDown,
    Scan_VerUp
} ScanMode;
typedef struct{
    uint16_t    startMbIndex;
    uint8_t     numMBs;
//  bool        lastTileInHor;
    bool        lastTileInVer;
} MbGroup;
#pragma pack()

#define ALIGN_B(x,a)        (((x)+(a)-1) &(~((a)-1)))
#define MAX_RESOLUTION_X    1920    // 4096
#define MAX_RESOLUTION_Y    1088    // 3072
#define MAX_TILES_NUM       (((MAX_RESOLUTION_X+63)>>6) * ((MAX_RESOLUTION_Y+31)>>5))

int32_t ToI420::YUV420PackedSemiPlanar64x32Tile2m8kaToYUV420Planar( uint8_t* src, uint8_t* dst_y, uint8_t* dst_u, uint8_t* dst_v,
            const int32_t width, const int32_t height,
            const int32_t stride_y, const int32_t stride_u, const int32_t stride_v )
{
    const int32_t srcStrideY    = ALIGN_B( width, 128 );
    const int32_t srcHeightY    = ALIGN_B( height, 32 );
    const int32_t srcStrideUV   = srcStrideY;   // v/u interlaced
    const int32_t srcHeightUV   = ALIGN_B( (height>>1), 32 );
    const int32_t srcSizeY      = ALIGN_B( (srcStrideY * srcHeightY), 8192 );
    const int32_t srcSizeUV     = ALIGN_B( (srcStrideUV * srcHeightUV), 8192 );
    uint8_t* src_y              = src;
    uint8_t* src_uv             = src_y + srcSizeY;

    const int32_t wTiles        = (width+63)>>6;
    const int32_t hTilesY       = (height+31)>>5;
    const int32_t hTilesUV      = (height/2+31)>>5;
    const int32_t numTilesY     = wTiles*hTilesY;
    const int32_t numTilesUV    = wTiles*hTilesUV; 
    const int32_t wMacroblocks  = (width+15)>>4;
    const int32_t hMacroblocks  = (height+15)>>4;
    int32_t numMbInTile         = 4*2;  // y: 4*2; uv: 4*4
    const int32_t mbOffsetTileHor       = 4;
    int32_t mbOffsetTileVer             = (wMacroblocks<<1);    // y: (wMacroblocks<<1); uv: (wMacroblocks<<2)  
    MbGroup yTileToMb[MAX_TILES_NUM]    = {0};  // each Tile index storing according MB index
    MbGroup uvTileToMb[MAX_TILES_NUM]   = {0};  // each Tile index storing according MB index
    assert( numTilesY <= MAX_TILES_NUM && numTilesUV <= MAX_TILES_NUM );
    int32_t availableTilesY             = numTilesY;
    int32_t availableTilesUV            = numTilesUV;
    const int32_t numTilesYPerScanUnit  = (wTiles<<1);
    int32_t tileIndex                   = 0;
    ScanMode preMode                    = Scan_Init;
    ScanMode curMode                    = Scan_Hor;
    int32_t scanedTiles                 = 0;
    int32_t hMbMultiple                 = 0;
    int32_t cntScanTimesInPeriod        = 0;    // maximal scan times is up to 4
    int32_t cnt1stLineTiles             = 0;
    int32_t cnt2ndLineTiles             = 0;
    uint16_t mbPosition                 = 0;
    uint16_t lastMbIdx                  = mbPosition;
    uint16_t firstMbIdxUnit             = mbPosition;
    bool noEnoughMbInTile               = false;    

    // construct yTileToMb table
    while( availableTilesY > 0 ){       
        if ( availableTilesY >= numTilesYPerScanUnit ){         
            preMode                 = Scan_Init;
            curMode                 = Scan_Hor;
            lastMbIdx               = mbPosition;
            firstMbIdxUnit          = mbPosition;
            cntScanTimesInPeriod    = 0;    // maximal scan times is up to 4
            cnt1stLineTiles         = 0;
            cnt2ndLineTiles         = 0;
            noEnoughMbInTile        = false;
            scanedTiles             = 0;

            while ( scanedTiles < numTilesYPerScanUnit ){               
                if ( (tileIndex & 3) == 0 ){
                    firstMbIdxUnit = mbPosition;
                }
                noEnoughMbInTile = false;
                if ( curMode == Scan_Hor ){
                    if ( (preMode == Scan_VerUp && cnt1stLineTiles+1>= wTiles) || 
                         (preMode == Scan_VerDown && cnt2ndLineTiles+1>= wTiles) ){
                             noEnoughMbInTile = (ALIGN_B(width, 16) < srcStrideY);
//                           yTileToMb[tileIndex].lastTileInHor = true;
                    }
                    yTileToMb[tileIndex].startMbIndex   = mbPosition;
                    yTileToMb[tileIndex].numMBs         = noEnoughMbInTile ? ((4-((srcStrideY-ALIGN_B(width,16))>>4))<<1) : numMbInTile;
                    ++ tileIndex;                   
                    ++ cntScanTimesInPeriod;
                    if ( noEnoughMbInTile && cntScanTimesInPeriod  == 1){
                        if ( preMode == Scan_VerDown ){
                            preMode = curMode;  // scan mode change need upate preMode
                            curMode = Scan_VerUp;
                            ++ cnt2ndLineTiles;
                            mbPosition = firstMbIdxUnit - mbOffsetTileVer;
                        }else if ( preMode == Scan_VerUp ){
                            preMode = curMode;  // scan mode change need upate preMode
                            curMode = Scan_VerDown;
                            ++ cnt1stLineTiles;
                            mbPosition = firstMbIdxUnit + mbOffsetTileVer;
                        }
                    }else if ( cntScanTimesInPeriod == 2 ){
                        if ( preMode == Scan_Init || preMode == Scan_VerUp ){
                            preMode = curMode;  // scan mode change need upate preMode
                            curMode = Scan_VerDown;
                            ++ cnt1stLineTiles;
                            mbPosition = firstMbIdxUnit + mbOffsetTileVer;
                        }else if ( preMode == Scan_VerDown ){
                            preMode = curMode;  // scan mode change need upate preMode
                            curMode = Scan_VerUp;
                            ++ cnt2ndLineTiles;
                            mbPosition = firstMbIdxUnit - mbOffsetTileVer;
                        }
                    }else if ( cntScanTimesInPeriod == 4 ){                     
                        if ( preMode == Scan_VerDown ){
                            ++ cnt2ndLineTiles;
                            mbPosition += mbOffsetTileHor;
                        }else if ( preMode == Scan_VerUp ){
                            ++ cnt1stLineTiles;
                            mbPosition += mbOffsetTileHor;
                        }
                    }else{
                        if ( preMode == Scan_Init ){
                            ++ cnt1stLineTiles;
                        }else if ( preMode == Scan_VerDown ){
                            ++ cnt2ndLineTiles;
                        }else if ( preMode == Scan_VerUp ){
                            ++ cnt1stLineTiles;
                        }
                        if ( cnt2ndLineTiles >= wTiles && preMode == Scan_VerDown ){
                            preMode = curMode;  // scan mode change need upate preMode
                            curMode = Scan_VerUp;                           
                            mbPosition = firstMbIdxUnit - mbOffsetTileVer;
                        }else if ( cnt1stLineTiles >= wTiles && preMode == Scan_VerUp ){
                            preMode = curMode;  // scan mode change need upate preMode
                            curMode = Scan_VerDown;                         
                            mbPosition = firstMbIdxUnit + mbOffsetTileVer;
                        }else{
                            mbPosition += mbOffsetTileHor;
                        }
                    }
                }else if ( curMode == Scan_VerUp ){
                    if ( cnt1stLineTiles+1 >= wTiles ){
                        noEnoughMbInTile = (ALIGN_B(width, 16) < srcStrideY);
//                      yTileToMb[tileIndex].lastTileInHor  = true;
                    }
                    yTileToMb[tileIndex].startMbIndex= mbPosition;
                    yTileToMb[tileIndex].numMBs     = noEnoughMbInTile ? ((4-((srcStrideY-ALIGN_B(width,16))>>4))<<1) : numMbInTile;
                    ++ tileIndex;
                    mbPosition += mbOffsetTileHor;
                    ++ cntScanTimesInPeriod;
                    ++ cnt1stLineTiles;
                    preMode = curMode;  // scan mode change need upate preMode
                    curMode = Scan_Hor;
                }else if ( curMode == Scan_VerDown ){
                    if ( cnt2ndLineTiles+1 >= wTiles ){
                        noEnoughMbInTile = (ALIGN_B(width, 16) < srcStrideY);
//                      yTileToMb[tileIndex].lastTileInHor  = true;
                    }
                    yTileToMb[tileIndex].startMbIndex= mbPosition;
                    yTileToMb[tileIndex].numMBs     = noEnoughMbInTile ? ((4-((srcStrideY-ALIGN_B(width,16))>>4))<<1) : numMbInTile;
                    ++ tileIndex;
                    mbPosition += mbOffsetTileHor;
                    ++ cntScanTimesInPeriod;
                    ++ cnt2ndLineTiles;
                    preMode = curMode;  // scan mode change need upate preMode
                    curMode = Scan_Hor;
                }
                cntScanTimesInPeriod &= 0x03;
                ++ scanedTiles;
            }
            mbPosition = lastMbIdx + (mbOffsetTileVer<<1);
            availableTilesY -= numTilesYPerScanUnit;
        }else{
            scanedTiles = 0;
            hMbMultiple = hMacroblocks - (tileIndex/wTiles)*2;
            noEnoughMbInTile = false;
            while ( scanedTiles < wTiles ){
                yTileToMb[tileIndex].startMbIndex = mbPosition;
                yTileToMb[tileIndex].lastTileInVer= true;
                if ( scanedTiles+1 == wTiles ){
                    noEnoughMbInTile = (ALIGN_B(width, 16) < srcStrideY);
//                  yTileToMb[tileIndex].lastTileInHor  = true;
                }
                yTileToMb[tileIndex].numMBs = noEnoughMbInTile ? ((4-((srcStrideY-ALIGN_B(width,16))>>4))*hMbMultiple) : (4*hMbMultiple);
                ++ tileIndex;
                mbPosition += mbOffsetTileHor;
                ++ scanedTiles;
            }
            availableTilesY -= wTiles;
        }
    }

    numMbInTile = 4*4;  
    mbOffsetTileVer = (wMacroblocks<<2);
    mbPosition = 0;
    tileIndex = 0;
    // construct uvTileToMb table
    while( availableTilesUV > 0 ){      
        if ( availableTilesUV >= numTilesYPerScanUnit ){            
            preMode             = Scan_Init;
            curMode             = Scan_Hor;
            lastMbIdx           = mbPosition;
            firstMbIdxUnit      = mbPosition;
            cntScanTimesInPeriod= 0;    // maximal scan times is up to 4
            cnt1stLineTiles     = 0;
            cnt2ndLineTiles     = 0;
            noEnoughMbInTile    = false;
            scanedTiles         = 0;

            while ( scanedTiles < numTilesYPerScanUnit ){               
                if ( (tileIndex & 3) == 0 ){
                    firstMbIdxUnit = mbPosition;
                }
                noEnoughMbInTile = false;
                if ( curMode == Scan_Hor ){
                    if ( (preMode == Scan_VerUp && cnt1stLineTiles+1>= wTiles) || 
                         (preMode == Scan_VerDown && cnt2ndLineTiles+1>= wTiles) ){
                             noEnoughMbInTile = (ALIGN_B(width, 16) < srcStrideY);
//                           uvTileToMb[tileIndex].lastTileInHor    = true;
                    }
                    uvTileToMb[tileIndex].startMbIndex  = mbPosition;
                    uvTileToMb[tileIndex].numMBs        = noEnoughMbInTile ? ((4-((srcStrideY-ALIGN_B(width,16))>>4))<<2) : numMbInTile;
                    ++ tileIndex;                   
                    ++ cntScanTimesInPeriod;
                    if ( noEnoughMbInTile && cntScanTimesInPeriod  == 1){
                        if ( preMode == Scan_VerDown ){
                            preMode = curMode;  // scan mode change need upate preMode
                            curMode = Scan_VerUp;
                            ++ cnt2ndLineTiles;
                            mbPosition = firstMbIdxUnit - mbOffsetTileVer;
                        }else if ( preMode == Scan_VerUp ){
                            preMode = curMode;  // scan mode change need upate preMode
                            curMode = Scan_VerDown;
                            ++ cnt1stLineTiles;
                            mbPosition = firstMbIdxUnit + mbOffsetTileVer;
                        }
                    }else if ( cntScanTimesInPeriod == 2 ){
                        if ( preMode == Scan_Init || preMode == Scan_VerUp ){
                            preMode = curMode;  // scan mode change need upate preMode
                            curMode = Scan_VerDown;
                            ++ cnt1stLineTiles;
                            mbPosition = firstMbIdxUnit + mbOffsetTileVer;
                        }else if ( preMode == Scan_VerDown ){
                            preMode = curMode;  // scan mode change need upate preMode
                            curMode = Scan_VerUp;
                            ++ cnt2ndLineTiles;
                            mbPosition = firstMbIdxUnit - mbOffsetTileVer;
                        }
                    }else if ( cntScanTimesInPeriod == 4 ){                     
                        if ( preMode == Scan_VerDown ){
                            ++ cnt2ndLineTiles;
                            mbPosition += mbOffsetTileHor;
                        }else if ( preMode == Scan_VerUp ){
                            ++ cnt1stLineTiles;
                            mbPosition += mbOffsetTileHor;
                        }
                    }else{
                        if ( preMode == Scan_Init ){
                            ++ cnt1stLineTiles;
                        }else if ( preMode == Scan_VerDown ){
                            ++ cnt2ndLineTiles;
                        }else if ( preMode == Scan_VerUp ){
                            ++ cnt1stLineTiles;
                        }
                        if ( cnt2ndLineTiles >= wTiles && preMode == Scan_VerDown ){
                            preMode = curMode;  // scan mode change need upate preMode
                            curMode = Scan_VerUp;                           
                            mbPosition = firstMbIdxUnit - mbOffsetTileVer;
                        }else if ( cnt1stLineTiles >= wTiles && preMode == Scan_VerUp ){
                            preMode = curMode;  // scan mode change need upate preMode
                            curMode = Scan_VerDown;                         
                            mbPosition = firstMbIdxUnit + mbOffsetTileVer;
                        }else{
                            mbPosition += mbOffsetTileHor;
                        }
                    }
                }else if ( curMode == Scan_VerUp ){
                    if ( cnt1stLineTiles+1 >= wTiles ){
                        noEnoughMbInTile = (ALIGN_B(width, 16) < srcStrideY);
//                      uvTileToMb[tileIndex].lastTileInHor = true;
                    }
                    uvTileToMb[tileIndex].startMbIndex  = mbPosition;
                    uvTileToMb[tileIndex].numMBs        = noEnoughMbInTile ? ((4-((srcStrideY-ALIGN_B(width,16))>>4))<<2) : numMbInTile;
                    ++ tileIndex;
                    mbPosition += mbOffsetTileHor;
                    ++ cntScanTimesInPeriod;
                    ++ cnt1stLineTiles;
                    preMode = curMode;  // scan mode change need upate preMode
                    curMode = Scan_Hor;
                }else if ( curMode == Scan_VerDown ){
                    if ( cnt2ndLineTiles+1 >= wTiles ){
                        noEnoughMbInTile = (ALIGN_B(width, 16) < srcStrideY);
//                      uvTileToMb[tileIndex].lastTileInHor = true;
                    }
                    uvTileToMb[tileIndex].startMbIndex  = mbPosition;
                    uvTileToMb[tileIndex].numMBs        = noEnoughMbInTile ? ((4-((srcStrideY-ALIGN_B(width,16))>>4))<<2) : numMbInTile;
                    ++ tileIndex;
                    mbPosition += mbOffsetTileHor;
                    ++ cntScanTimesInPeriod;
                    ++ cnt2ndLineTiles;
                    preMode = curMode;  // scan mode change need upate preMode
                    curMode = Scan_Hor;
                }
                cntScanTimesInPeriod &= 0x03;
                ++ scanedTiles;
            }
            mbPosition = lastMbIdx + (mbOffsetTileVer<<1);
            availableTilesUV -= numTilesYPerScanUnit;
        }else{
            scanedTiles = 0;
            hMbMultiple = hMacroblocks - (tileIndex/wTiles)*4;
            noEnoughMbInTile = false;
            while ( scanedTiles < wTiles ){
                uvTileToMb[tileIndex].startMbIndex = mbPosition;
                uvTileToMb[tileIndex].lastTileInVer = true;
                if ( scanedTiles+1 == wTiles ){
                    noEnoughMbInTile = (ALIGN_B(width, 16) < srcStrideY);
//                  uvTileToMb[tileIndex].lastTileInHor = true;
                }
                uvTileToMb[tileIndex].numMBs    = noEnoughMbInTile ? ((4-((srcStrideY-ALIGN_B(width,16))>>4))*hMbMultiple) : (4*hMbMultiple);
                ++ tileIndex;
                mbPosition += mbOffsetTileHor;
                ++ scanedTiles;
            }
            availableTilesUV -= wTiles;
        }
    }

    uint8_t* py     = src_y;    
    tileIndex = 0;
    // converting luma componet with yTileToMb
    while ( tileIndex < numTilesY ){
        uint16_t startMbIndex = yTileToMb[tileIndex].startMbIndex;
        const int32_t startMbX = (startMbIndex % wMacroblocks);
        const int32_t startMbY = (startMbIndex / wMacroblocks);

        int32_t mb_x = startMbX;
        int32_t mb_y = startMbY;
        const int32_t cntMbLines = yTileToMb[tileIndex].lastTileInVer ? (hMacroblocks - (tileIndex/wTiles)*2) : 2;      
        const int32_t numMbPerLine = yTileToMb[tileIndex].numMBs / cntMbLines;
        const int32_t sizePixelLine = (numMbPerLine << 4);
        int32_t mbLine = 0;
        while ( mbLine < cntMbLines ){
            assert( mb_y < hMacroblocks && mb_x < wMacroblocks );
            const int32_t dstOffsetY = (mb_y * stride_y + mb_x)<<4;
            int32_t _l = 0;
            // luma
            while( _l < 16 ){
                memcpy( dst_y + dstOffsetY + _l * stride_y, py, sizePixelLine );
                py += 64; // eliminate padding (64-sizePixelLine)
                ++ _l;
            }
            mb_x = startMbX;
            ++ mb_y;
            ++ mbLine;
        }       
        ++ tileIndex;
    }

    uint8_t* puv    = src_uv;
    tileIndex = 0;
    // convering cb/cr componets with uvTileToMb
    while ( tileIndex < numTilesUV ){
        uint16_t startMbIndex = uvTileToMb[tileIndex].startMbIndex;
        const int32_t startMbX = (startMbIndex % wMacroblocks);
        const int32_t startMbY = (startMbIndex / wMacroblocks);

        int32_t mb_x = startMbX;
        int32_t mb_y = startMbY;
        const int32_t cntMbLines = uvTileToMb[tileIndex].lastTileInVer ? (hMacroblocks - (tileIndex/wTiles)*4) : 4;
        const int32_t numMbPerLine = uvTileToMb[tileIndex].numMBs / cntMbLines;     
        int32_t mbLine = 0;
        while ( mbLine < cntMbLines ){
            assert( mb_y < hMacroblocks && mb_x < wMacroblocks );           
            // cb/cr
            int32_t mbIndex = 0;
            while ( mbIndex < numMbPerLine ){
                assert( mb_y < hMacroblocks && mb_x < wMacroblocks );
                const int32_t dstOffsetUV = (mb_y * stride_u + mb_x)<<3;            
                int32_t _l = 0;
                while( _l < 8 ){
                    const int32_t _offset = dstOffsetUV + _l * stride_u;
                    uint8_t* _u = dst_u + _offset;
                    uint8_t* _v = dst_v + _offset;
                    uint8_t* _src_vu = puv+(mbIndex<<4)+(_l<<6);
                    int32_t _interlace = 0;
                    for ( int32_t ichroma = 0; ichroma < 8; ++ichroma ){
                        _u[ichroma] = _src_vu[_interlace++];
                        _v[ichroma] = _src_vu[_interlace++];
                    }
                    ++ _l;
                }
                ++ mb_x;
                ++ mbIndex;
            }
            puv += 64*8;
            mb_x = startMbX;
            ++ mb_y;
            ++ mbLine;
        }
        if ( cntMbLines < 4 ){
            puv += 64*(4-cntMbLines)*8;
        }
        ++ tileIndex;
    }

    return 0;
}

///////////////////////////////////////////////////////////////////////

这篇关于QOMX_COLOR_FormatYUV420PackedSemiPlanar64x32Tile2m8ka 颜色格式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆