dazhazha

dazhazha

0个粉丝

6

问答

0

专栏

0

资料

dazhazha  发布于  2016-11-23 12:09:13
采纳率 0%
6个问答
6310

一个海思SDK包中保存YUV数据的函数疑问

 
本帖最后由 dazhazha 于 2016-11-23 12:13 编辑

在海思SDK包中,有个保存YUV数据的函数,如下:
/* sp420 转存为 p420 ; sp422 转存为 p422  */
[code]void hisi_comm_save_one_frame(VIDEO_FRAME_S * pVBuf, FILE *pfd)
{
    unsigned int w, h;
    char * pVBufVirt_Y;
    char * pVBufVirt_C;
    char * pMemContent;
    unsigned char TmpBuff[MAX_FRM_WIDTH];                //如果这个值太小,图像很大的话存不了
    HI_U32 phy_addr,size;
    HI_CHAR *pUserPageAddr[2];
    PIXEL_FORMAT_E  enPixelFormat = pVBuf->enPixelFormat;
    HI_U32 u32UvHeight;/* 存为planar 格式时的UV分量的高度 */

    if (pVBuf->u32Width > MAX_FRM_WIDTH)
    {
        printf("Over max frame width: %d, can't support.\n", MAX_FRM_WIDTH);
        return;
    }

    if (PIXEL_FORMAT_YUV_SEMIPLANAR_420 == enPixelFormat)
    {
        size = (pVBuf->u32Stride[0])*(pVBuf->u32Height)*3/2;
        u32UvHeight = pVBuf->u32Height/2;
    }
    else
    {
        size = (pVBuf->u32Stride[0])*(pVBuf->u32Height)*2;
        u32UvHeight = pVBuf->u32Height;
    }

    phy_addr = pVBuf->u32PhyAddr[0];

    //printf("phy_addr:%x, size:%d\n", phy_addr, size);
    pUserPageAddr[0] = (HI_CHAR *) HI_MPI_SYS_Mmap(phy_addr, size);
    if (NULL == pUserPageAddr[0])
    {
        return;
    }
    printf("stride: %d,%d\n",pVBuf->u32Stride[0],pVBuf->u32Stride[1]);
        printf("u32Width: %d,u32Height: %d\n", pVBuf->u32Width, pVBuf->u32Height);

    pVBufVirt_Y = pUserPageAddr[0];
    pVBufVirt_C = pVBufVirt_Y + (pVBuf->u32Stride[0])*(pVBuf->u32Height);

    /* save Y ----------------------------------------------------------------*/
    fprintf(stderr, "saving......Y......");
    fflush(stderr);
    for(h=0; hu32Height; h++)
    {
        pMemContent = pVBufVirt_Y + h*pVBuf->u32Stride[0];
        fwrite(pMemContent, pVBuf->u32Width, 1, pfd);
    }
    fflush(pfd);


    /* save U ----------------------------------------------------------------*/
    fprintf(stderr, "U......");
    fflush(stderr);
    for(h=0; h     {
        pMemContent = pVBufVirt_C + h*pVBuf->u32Stride[1];

      pMemContent += 1;

        for(w=0; wu32Width/2; w++)
        {
            TmpBuff[w] = *pMemContent;
            pMemContent += 2;
        }
        fwrite(TmpBuff, pVBuf->u32Width/2, 1, pfd);
    }
    fflush(pfd);

    /* save V ----------------------------------------------------------------*/
    fprintf(stderr, "V......");
    fflush(stderr);
    for(h=0; h     {
        pMemContent = pVBufVirt_C + h*pVBuf->u32Stride[1];

        for(w=0; wu32Width/2; w++)
        {
            TmpBuff[w] = *pMemContent;
            pMemContent += 2;
        }
        fwrite(TmpBuff, pVBuf->u32Width/2, 1, pfd);
    }
    fflush(pfd);

    fprintf(stderr, "done %d!\n", pVBuf->u32TimeRef);
    fflush(stderr);

    HI_MPI_SYS_Munmap(pUserPageAddr[0], size);
}[/code]
我看了好久,这里将yuv420sp转化为yuv420p,在保存U分量的时候有个+1操作,即pMemContent += 1;
sp格式是按照uvuv序列存放,这个+1操作,不是将指针指向了V分量吗?我尝试不做+1操作,保存V分量的时候做+1操作,图像又不正确了,这是为什么了?
我来回答
回答8个
时间排序
认可量排序

dazhazha

0个粉丝

6

问答

0

专栏

0

资料

dazhazha 2016-11-23 13:31:16
认可0
有人吗,有人吗

zhuangweiye

8个粉丝

0

问答

0

专栏

0

资料

zhuangweiye 2016-11-23 13:40:31
认可0
[quote][url=forum.php?mod=redirect&goto=findpost&pid=41728&ptid=13458]dazhazha 发表于 2016-11-23 13:31[/url]
有人吗,有人吗[/quote]

从代码上看, 这个yuv420sp的格式是 vuvu, 而不是 uvuv

dazhazha

0个粉丝

6

问答

0

专栏

0

资料

dazhazha 2016-11-23 13:54:53
认可0
[quote][url=forum.php?mod=redirect&goto=findpost&pid=41729&ptid=13458]zhuangweiye 发表于 2016-11-23 13:40[/url]
从代码上看, 这个yuv420sp的格式是 vuvu, 而不是 uvuv[/quote]

谢谢你的回答,我大概知道是为什么了,我从SDK的VI设置用户图片那里,看到一句这样的:“注意只支持
semi-planarYUV420、 semi-planarYUV422 的格式,因此填充数据时需要遵循先
存 Y 分量数据,再存 UV 分量间插数据的存储顺序(小端字节序先 V 后 U)”,所以我估计就是小端模式的原因,至于为什么会这样真不知道。。。

hanfei69882

2个粉丝

26

问答

0

专栏

2

资料

hanfei69882 2016-11-23 15:51:06
认可0
本帖最后由 hanfei69882 于 2016-11-23 15:54 编辑

YUV420p,和YUV420SP又各分为两种,目前来看海思使用的是YUV420SP分类的NV21(暂时没有发现官方手册依据),之前有一个简单的讨论[url=http://www.ebaina.com/bbs/thread-12467-1-1.html][求助] HI3520D获取的帧格式是YUV420SP时,究竟是NV12还是NV21?[/url]
[quote]YUV420P,Y,U,V三个分量都是平面格式,分为I420和YV12。I420格式和YV12格式的不同处在U平面和V平面的位置不同。在I420格式中,U平面紧跟在Y平面之后,然后才是V平面(即:YUV);但YV12则是相反(即:YVU)。
YUV420SP, Y分量平面格式,UV打包格式, 即NV12。 NV12与NV21类似,U 和 V 交错排列,不同在于UV顺序。
I420: YYYYYYYY UU VV    =>YUV420P
YV12: YYYYYYYY VV UU    =>YUV420P
NV12: YYYYYYYY UVUV     =>YUV420SP
NV21: YYYYYYYY VUVU     =>YUV420SP[/quote]

dazhazha

0个粉丝

6

问答

0

专栏

0

资料

dazhazha 2016-11-23 16:41:22
认可0
[quote][url=forum.php?mod=redirect&goto=findpost&pid=41749&ptid=13458]hanfei69882 发表于 2016-11-23 15:51[/url]
YUV420p,和YUV420SP又各分为两种,目前来看海思使用的是YUV420SP分类的NV21(暂时没有发现官方手册依据) ...[/quote]

Soga,学习到了 谢谢

tgwfcc

1个粉丝

13

问答

0

专栏

0

资料

tgwfcc 2016-11-24 11:58:12
认可0
虽然不懂,帮顶一下

yuexiaoban

0个粉丝

1

问答

0

专栏

0

资料

yuexiaoban 2016-12-10 12:57:48
认可0
虽然不了解 鼎鼎

applepen

0个粉丝

11

问答

0

专栏

11

资料

applepen 2017-02-27 18:31:11
认可0
NV12: YYYYYYYY UVUV     =>YUV420SP
NV21: YYYYYYYY VUVU     =>YUV420SP
嗯,这两种常用
或将文件直接拖到这里
悬赏:
E币
网盘
* 网盘链接:
* 提取码:
悬赏:
E币

Markdown 语法

  • 加粗**内容**
  • 斜体*内容*
  • 删除线~~内容~~
  • 引用> 引用内容
  • 代码`代码`
  • 代码块```编程语言↵代码```
  • 链接[链接标题](url)
  • 无序列表- 内容
  • 有序列表1. 内容
  • 缩进内容
  • 图片![alt](url)
+ 添加网盘链接/附件

Markdown 语法

  • 加粗**内容**
  • 斜体*内容*
  • 删除线~~内容~~
  • 引用> 引用内容
  • 代码`代码`
  • 代码块```编程语言↵代码```
  • 链接[链接标题](url)
  • 无序列表- 内容
  • 有序列表1. 内容
  • 缩进内容
  • 图片![alt](url)
举报反馈

举报类型

  • 内容涉黄/赌/毒
  • 内容侵权/抄袭
  • 政治相关
  • 涉嫌广告
  • 侮辱谩骂
  • 其他

详细说明

易百纳技术社区