NV12T转换成NV12算法公式

NV12T是以图块的形式存储数据。NV12T后面这个T就是Tile的缩写,NV12T就是tile版
本的NV12格式,NV12T的图块包含 64 × 32 pixels.和tile对应的就是linear,所以我们
可以称NV12为linear的NV12。以下是算法代码,基本就是重组数据存储方式的意思。

static void copy16(unsigned char *p_linear_addr, unsigned char *p_tiled_addr, int mm, int nn)
{
    p_linear_addr[mm]     = p_tiled_addr[nn];
    p_linear_addr[mm + 1]     = p_tiled_addr[nn+ 1];
    p_linear_addr[mm + 2]     = p_tiled_addr[nn+ 2];
    p_linear_addr[mm + 3]    = p_tiled_addr[nn+ 3];

    p_linear_addr[mm + 4]     = p_tiled_addr[nn+ 4];
    p_linear_addr[mm + 5]     = p_tiled_addr[nn+ 5];
    p_linear_addr[mm + 6]     = p_tiled_addr[nn+ 6];
    p_linear_addr[mm + 7]     = p_tiled_addr[nn+ 7];

    p_linear_addr[mm + 8]     = p_tiled_addr[nn+ 8];
    p_linear_addr[mm + 9]     = p_tiled_addr[nn+ 9];
    p_linear_addr[mm + 10]     = p_tiled_addr[nn+ 10];
    p_linear_addr[mm + 11]     = p_tiled_addr[nn+ 11];

    p_linear_addr[mm + 12]     = p_tiled_addr[nn+ 12];
    p_linear_addr[mm + 13]    = p_tiled_addr[nn+ 13];
    p_linear_addr[mm + 14]     = p_tiled_addr[nn+ 14];
    p_linear_addr[mm + 15]    = p_tiled_addr[nn+ 15];
}

static int tile_4x2_read(int x_size, int y_size, int x_pos, int y_pos)
{
    int pixel_x_m1, pixel_y_m1;
    int roundup_x, roundup_y;
    int linear_addr0, linear_addr1, bank_addr ;
    int x_addr;
    int trans_addr;

    pixel_x_m1 = x_size -1;
    pixel_y_m1 = y_size -1;

    roundup_x = ((pixel_x_m1 >> 7) + 1);
    roundup_y = ((pixel_x_m1 >> 6) + 1);

    x_addr = (x_pos >> 2);

    if ((y_size <= y_pos+32) && ( y_pos < y_size) &&
        (((pixel_y_m1 >> 5) & 0x1) == 0) && (((y_pos >> 5) & 0x1) == 0))
    {
        linear_addr0 = (((y_pos & 0x1f) <<4) | (x_addr & 0xf));
        linear_addr1 = (((y_pos >> 6) & 0xff) * roundup_x + ((x_addr >> 6) & 0x3f));

        if(((x_addr >> 5) & 0x1) == ((y_pos >> 5) & 0x1))
            bank_addr = ((x_addr >> 4) & 0x1);
        else
            bank_addr = 0x2 | ((x_addr >> 4) & 0x1);
    }
    else
    {
        linear_addr0 = (((y_pos & 0x1f) << 4) | (x_addr & 0xf));
        linear_addr1 = (((y_pos >> 6) & 0xff) * roundup_x + ((x_addr >> 5) & 0x7f));

        if(((x_addr >> 5) & 0x1) == ((y_pos >> 5) & 0x1))
            bank_addr = ((x_addr >> 4) & 0x1);
        else
            bank_addr = 0x2 | ((x_addr >> 4) & 0x1);
    }

    linear_addr0 = linear_addr0 << 2;
    trans_addr = (linear_addr1 <<13) | (bank_addr << 11) | linear_addr0;

    return trans_addr;
}


static void tile_to_linear_4x2(unsigned char *p_linear_addr, unsigned char *p_tiled_addr, unsigned int x_size, unsigned int y_size)
{
    int trans_addr;
    unsigned int i, j, k, nn, mm, index;

    // .. TILE 4x2 test
    for (i = 0; i < y_size; i = i + 16)
    {
        for (j = 0; j < x_size; j = j + 16)
        {
            trans_addr = tile_4x2_read(x_size, y_size, j, i);            
            index = i*x_size + j;

            k = 0;        nn = trans_addr + (k << 6);        mm = index;
            copy16(p_linear_addr, p_tiled_addr, mm, nn);

            k = 1;        nn = trans_addr + (k << 6);        mm += x_size;
            copy16(p_linear_addr, p_tiled_addr, mm, nn);

            k = 2;        nn = trans_addr + (k << 6);        mm += x_size;
            copy16(p_linear_addr, p_tiled_addr, mm, nn);

            k = 3;        nn = trans_addr + (k << 6);        mm += x_size;
            copy16(p_linear_addr, p_tiled_addr, mm, nn);

            k = 4;        nn = trans_addr + (k << 6);        mm += x_size;
            copy16(p_linear_addr, p_tiled_addr, mm, nn);

            k = 5;        nn = trans_addr + (k << 6);        mm += x_size;
            copy16(p_linear_addr, p_tiled_addr, mm, nn);

            k = 6;        nn = trans_addr + (k << 6);        mm += x_size;
            copy16(p_linear_addr, p_tiled_addr, mm, nn);

            k = 7;        nn = trans_addr + (k << 6);        mm += x_size;
            copy16(p_linear_addr, p_tiled_addr, mm, nn);

            k = 8;        nn = trans_addr + (k << 6);        mm += x_size;
            copy16(p_linear_addr, p_tiled_addr, mm, nn);

            k = 9;        nn = trans_addr + (k << 6);        mm += x_size;
            copy16(p_linear_addr, p_tiled_addr, mm, nn);

            k = 10;        nn = trans_addr + (k << 6);        mm += x_size;
            copy16(p_linear_addr, p_tiled_addr, mm, nn);

            k = 11;        nn = trans_addr + (k << 6);        mm += x_size;
            copy16(p_linear_addr, p_tiled_addr, mm, nn);

            k = 12;        nn = trans_addr + (k << 6);        mm += x_size;
            copy16(p_linear_addr, p_tiled_addr, mm, nn);

            k = 13;        nn = trans_addr + (k << 6);        mm += x_size;
            copy16(p_linear_addr, p_tiled_addr, mm, nn);

            k = 14;        nn = trans_addr + (k << 6);        mm += x_size;
            copy16(p_linear_addr, p_tiled_addr, mm, nn);

            k = 15;        nn = trans_addr + (k << 6);        mm += x_size;
            copy16(p_linear_addr, p_tiled_addr, mm, nn);

        }
    }
}

你可能感兴趣的:(NV12T转换成NV12算法公式)