文档章节

NV12T转换成NV12算法公式

luoshi129
 luoshi129
发布于 2013/12/21 11:04
字数 598
阅读 241
收藏 0

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

        }
    }
}

© 著作权归作者所有

luoshi129
粉丝 6
博文 10
码字总数 19674
作品 0
深圳
程序员
私信 提问
Android实现基于肤色的皮肤检测

在android上实现 基于肤色的皮肤检测的几个技术要点: (1)android上使用相机预览,包括相机api的使用和surfaceview的应用。 (2)android上相机使用的色彩空间NV12. (3)NV12是YCrCb的色彩空...

老崔No1
2013/04/22
1K
7
RGB、YUV和YCrCb之间的关系

YUV和YCbCr之间的差异 一、和rgb之间换算公式的差异 yuv<-->rgb Y'= 0.299R' + 0.587G' + 0.114B' [0~255] U'= -0.147R' - 0.289G' + 0.436B' = 0.492(B'- Y') [-111.18~111.18] V'= 0.615R'......

国仔饼
2015/06/13
89
0
一款开源的 Android YUV 格式查看工具

1. YUVDroidTools 最近项目比较忙,好久没有写文章了,也没有为开源社区贡献点啥了,这个周末抽空整理了一下自己一直维护的一份基于 ffmpeg 的 YUV 格式转换代码,写了一个简单的 Android YU...

Jhuster
2016/06/25
0
0
图文详解 YUV420 数据格式

YUV 格式有两大类:planar 和 packed。 对于 planar 的 YUV 格式,先连续存储所有像素点的 Y,紧接着存储所有像素点的 U,随后是所有像素点的 V。 对于 packed 的 YUV 格式,每个像素点的 Y,...

Jerikc
2015/10/03
307
0
图文详解YUV420数据格式

完整的链接: http://www.xuebuyuan.com/1541892.html YUV格式有两大类:planar和packed。 对于planar的YUV格式,先连续存储所有像素点的Y,紧接着存储所有像素点的U,随后是所有像素点的V。...

aspirs
2016/01/24
97
0

没有更多内容

加载失败,请刷新页面

加载更多

JAVA--高级基础开发

//定义两个线程,一个线程输出偶数,一个线程输出奇数,并且是交替输出 public class Test08 { public static void main(String[]args){ //创建当前类的对象 Life num = new L...

李文杰-yaya
19分钟前
16
0
[开源] .NETCore websocket 即时通讯组件---ImCore

ImCore 利用 webSocket 协议实现简易、高性能、集群即时通讯组件,支持点对点通讯、群聊通讯、上线下线事件消息等众多实用性功能。 Quick Start dotnet add package ImCore IM服务端 public...

2881099
23分钟前
1
0
java保留小数点后几位,不足的用0补

在 java 中,如果小数点最后位是0,double类型会把这个0去掉,比如4.30变成了4.3,这样导致有的界面显示不好看。 所以要转换下,如下方法 /** * 将double格式化为指定小数位的String,...

Gotcha_
27分钟前
2
0
spring boot 1.x升2.x的注意事项

记录升级过程中的一些错误。 本次升级为1.5.x 升级为2.1.4 ---------------------------------------------- 如果java版本低于8请不要升级,spring boot 2.0需要至少java 8才行。 ----------...

玄影镜心
28分钟前
4
0
关于Spring

Spring整体架构: Core Container Core Container(核心容器)包含Beans、Core、Context、EspL四个模块 Core和Beans是Spring的基础部分,提供IOC(控制反转)和DI(依赖注入) Core模块 该模...

java后端开发
35分钟前
4
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部