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);
}
}
}