qn1573466792

qn1573466792

0个粉丝

2

问答

0

专栏

0

资料

qn1573466792  发布于  2020-01-03 16:16:42
采纳率 0%
2个问答
3798

YUV文件转换成VIDEO_FRAME_INFO_S格式的转换问题

 
本帖最后由 qn1573466792 于 2020-1-3 16:20 编辑

怎么把NV21 的YUV文件转换成VIDEO_FRAME_INFO_S格式啊

我自己写了一个转换的函数,但是转换出来YUV文件是中间变灰了,整个画面有着蓝绿点

源YUV文件用ffplay播放没有问题,格式也是NV21的,应该是转换过程出现问题

实在找不到解决办法了,有人能够帮我吗????:'( :'( :'(

转换后的图片:


代码如下:
[code]HI_S32 HISI_VB_FileToFrame(FILE* file, VIDEO_FRAME_INFO_S *frame_info, int w, int h)
{
    HI_S32 i;
    HI_S32 size, luma_size, chrm_size;
    HI_U8 *file_image;

    memset(frame_info, 0, sizeof(VIDEO_FRAME_INFO_S));

    frame_info->enModId                         = HI_ID_VI;
    frame_info->stVFrame.u32Width               = w;
    frame_info->stVFrame.u32Height              = h;
    frame_info->stVFrame.enField                = VIDEO_FIELD_FRAME;
    frame_info->stVFrame.enPixelFormat          = PIXEL_FORMAT_YVU_SEMIPLANAR_420;
    frame_info->stVFrame.enVideoFormat          = VIDEO_FORMAT_LINEAR;
    frame_info->stVFrame.enCompressMode         = COMPRESS_MODE_NONE;
    frame_info->stVFrame.enDynamicRange         = DYNAMIC_RANGE_SDR8;
    frame_info->stVFrame.enColorGamut           = COLOR_GAMUT_BT601;
    frame_info->stVFrame.u32Stride[0]           = HISI_CalcStride(frame_info->stVFrame.u32Width, USER_HISI_MD_ALIGN);
    frame_info->stVFrame.u32Stride[1]           = HISI_CalcStride(frame_info->stVFrame.u32Width, USER_HISI_MD_ALIGN);
    frame_info->stVFrame.u32Stride[2]           = HISI_CalcStride(frame_info->stVFrame.u32Width, USER_HISI_MD_ALIGN);
    frame_info->stVFrame.u64HeaderPhyAddr[0]    = 0;
    frame_info->stVFrame.u64HeaderPhyAddr[1]    = 0;
    frame_info->stVFrame.u64HeaderPhyAddr[2]    = 0;
    //frame_info->stVFrame.u32TimeRef           = 0;
    //frame_info->stVFrame.u64PTS               = 0;

    size     = HISI_CalcStride(frame_info->stVFrame.u32Width, USER_HISI_MD_ALIGN) * frame_info->stVFrame.u32Height * 2;
    luma_size = HISI_CalcStride(frame_info->stVFrame.u32Width, USER_HISI_MD_ALIGN) * frame_info->stVFrame.u32Height;
    chrm_size = luma_size >> 2;

    USER_HISI_VB_BLK_HANDLE = HI_MPI_VB_GetBlock(USER_HISI_VB_POOL, size, NULL);
    if(VB_INVALID_HANDLE == USER_HISI_VB_BLK_HANDLE) {
        HISI_PRT("HI_MPI_VB_GetBlock fail\n");
                sleep(10);
        return HI_FAILURE;
    }

    frame_info->u32PoolId               = HI_MPI_VB_Handle2PoolId(USER_HISI_VB_BLK_HANDLE);
    frame_info->stVFrame.u64PhyAddr[0]  = HI_MPI_VB_Handle2PhysAddr(USER_HISI_VB_BLK_HANDLE);
    frame_info->stVFrame.u64PhyAddr[1]  = frame_info->stVFrame.u64PhyAddr[0] + luma_size;
    frame_info->stVFrame.u64PhyAddr[2]  = frame_info->stVFrame.u64PhyAddr[1] + chrm_size;
    frame_info->stVFrame.u64VirAddr[0]  = (HI_UL)HI_MPI_SYS_Mmap(frame_info->stVFrame.u64PhyAddr[0], size);
    frame_info->stVFrame.u64VirAddr[1]  = frame_info->stVFrame.u64VirAddr[0] + luma_size;
    frame_info->stVFrame.u64VirAddr[2]  = frame_info->stVFrame.u64VirAddr[1] + chrm_size;
    // frame_info->stVFrame.u32TimeRef     += 40000;
    // frame_info->stVFrame.u64PTS         += 40000;

    file_image = (HI_U8 *)(HI_UL)frame_info->stVFrame.u64VirAddr[0];
    for(i = 0; i < frame_info->stVFrame.u32Height; i++) {
        fread(file_image, frame_info->stVFrame.u32Width, 1, file);
        file_image += frame_info->stVFrame.u32Stride[0];
    }

    file_image = (HI_U8 *)(HI_UL)frame_info->stVFrame.u64VirAddr[1];
    for(i = 0; i < frame_info->stVFrame.u32Height/2; i++) {
        fread(file_image, frame_info->stVFrame.u32Width, 1, file);
        file_image += frame_info->stVFrame.u32Stride[1];
    }

    return HI_SUCCESS;
}[/code]
我来回答
回答10个
时间排序
认可量排序

jugg

4个粉丝

15

问答

0

专栏

2

资料

jugg 2020-01-03 17:10:30
认可0
sample_comm_vi.c 文件里面有函数从yuv文件读入 SAMPLE_COMM_VI_GetVFrameFromYUV

qn1567564800

0个粉丝

36

问答

0

专栏

0

资料

qn1567564800 2020-01-03 20:43:06
认可0
[quote][url=forum.php?mod=redirect&goto=findpost&pid=152126&ptid=77290]jugg_kai 发表于 2020-1-3 17:10[/url]
sample_comm_vi.c 文件里面有函数从yuv文件读入 SAMPLE_COMM_VI_GetVFrameFromYUV[/quote]

没看着这个函数啊

yangguang

0个粉丝

4

问答

0

专栏

0

资料

yangguang 2020-01-04 10:27:17
认可0
1
我记得以前看过一个帖子
不要直接使用frame_info->stVFrame.u64VirAddr[0]  = (HI_UL)HI_MPI_SYS_Mmap(frame_info->stVFrame.u64PhyAddr[0], size);  中的frame_info->stVFrame.u64VirAddr[0]
最好新建一个指针
unsigned char * pVirAddr = (unsigned char *)HI_MPI_SYS_Mmap( ... );
然后对 unsigned char * pVirAddr进行操作
你试一下

2
打印一下 你图像的长宽 size   luma_size  chrm_size   以及u32Stride[0] u32Stride[1]看看

qn1573466792

0个粉丝

2

问答

0

专栏

0

资料

qn1573466792 2020-01-07 11:46:28
认可0
[quote][url=forum.php?mod=redirect&goto=findpost&pid=152126&ptid=77290]jugg_kai 发表于 2020-1-3 17:10[/url]
sample_comm_vi.c 文件里面有函数从yuv文件读入 SAMPLE_COMM_VI_GetVFrameFromYUV[/quote]

我的sample里面没有找到这个函数

qn1573466792

0个粉丝

2

问答

0

专栏

0

资料

qn1573466792 2020-01-07 11:51:27
认可0
[quote][url=forum.php?mod=redirect&goto=findpost&pid=152144&ptid=77290]yangguang 发表于 2020-1-4 10:27[/url]
1
我记得以前看过一个帖子
不要直接使用frame_info->stVFrame.u64VirAddr[0]  = (HI_UL)HI_MPI_SYS_Mmap ...[/quote]

我把u64PhyAddr[0]和u64PhyAddr[1]都用HI_MPI_SYS_Mmap转换,还是一样的结果

图片的宽高是1920x1080的, 这几个参数也没有错误
[code]size = 4147200
luma_size = 2073600
chrm_size = 518400
stride[0] = 1920
stride[1] = 1920[/code]

mylx2010

0个粉丝

2

问答

0

专栏

0

资料

mylx2010 2020-01-07 14:25:01
认可0
[quote][url=forum.php?mod=redirect&goto=findpost&pid=152240&ptid=77290]qn1573466792 发表于 2020-1-7 11:51[/url]
我把u64PhyAddr[0]和u64PhyAddr[1]都用HI_MPI_SYS_Mmap转换,还是一样的结果

图片的宽高是1920x1080的 ...[/quote]

chrm_size 改为 luma_size >> 4 试试?

jugg

4个粉丝

15

问答

0

专栏

2

资料

jugg 2020-01-08 09:09:59
认可1
[code]/******************************************************************************
* function : read frame
******************************************************************************/
HI_VOID SAMPLE_COMM_VI_ReadFrame(FILE * fp, HI_U8 * pY, HI_U8 * pU, HI_U8 * pV, HI_U32 width, HI_U32 height, HI_U32 stride, HI_U32 stride2)
{
    HI_U8 * pDst;

    HI_U32 u32Row;

    pDst = pY;
    for ( u32Row = 0; u32Row < height; u32Row++ )
    {
        fread( pDst, width, 1, fp );
        pDst += stride;
    }

    pDst = pU;
    for ( u32Row = 0; u32Row < height/2; u32Row++ )
    {
        fread( pDst, width/2, 1, fp );
        pDst += stride2;
    }

    pDst = pV;
    for ( u32Row = 0; u32Row < height/2; u32Row++ )
    {
        fread( pDst, width/2, 1, fp );
        pDst += stride2;
    }
}

/******************************************************************************
* function : Plan to Semi
******************************************************************************/
HI_S32 SAMPLE_COMM_VI_PlanToSemi(HI_U8 *pY, HI_S32 yStride,
                       HI_U8 *pU, HI_S32 uStride,
                       HI_U8 *pV, HI_S32 vStride,
                       HI_S32 picWidth, HI_S32 picHeight)
{
    HI_S32 i;
    HI_U8* pTmpU, *ptu;
    HI_U8* pTmpV, *ptv;
    HI_S32 s32HafW = uStride >>1 ;
    HI_S32 s32HafH = picHeight >>1 ;
    HI_S32 s32Size = s32HafW*s32HafH;

    if(!s32Size)
    {
        return HI_FAILURE;
    }
    pTmpU = malloc( s32Size ); ptu = pTmpU;
    pTmpV = malloc( s32Size ); ptv = pTmpV;

    if(NULL == pTmpU || NULL == pTmpV)
    {
        free( ptu );
        free( ptv );
        return HI_FAILURE;
    }
   
    memcpy(pTmpU,pU,s32Size);
    memcpy(pTmpV,pV,s32Size);

    for(i = 0;i>1;i++)
    {
        *pU++ = *pTmpV++;
        *pU++ = *pTmpU++;

    }
    for(i = 0;i>1;i++)
    {
        *pV++ = *pTmpV++;
        *pV++ = *pTmpU++;
    }

    free( ptu );
    free( ptv );

    return HI_SUCCESS;
}

/******************************************************************************
* function : Get from YUV
******************************************************************************/
HI_S32 SAMPLE_COMM_VI_GetVFrameFromYUV(FILE *pYUVFile, HI_U32 u32Width, HI_U32 u32Height,HI_U32 u32Stride, VIDEO_FRAME_INFO_S *pstVFrameInfo)
{
    HI_U32             u32LStride;
    HI_U32             u32CStride;
    HI_U32             u32LumaSize;
    HI_U32             u32ChrmSize;
    HI_U32             u32Size;
    VB_BLK VbBlk;
    HI_U32 u32PhyAddr;
    HI_U8 *pVirAddr;

    u32LStride  = u32Stride;
    u32CStride  = u32Stride;

    u32LumaSize = (u32LStride * u32Height);
    u32ChrmSize = (u32CStride * u32Height) >> 2;/* YUV 420 */
    u32Size = u32LumaSize + (u32ChrmSize << 1);

    /* alloc video buffer block ---------------------------------------------------------- */
    VbBlk = HI_MPI_VB_GetBlock(VB_INVALID_POOLID, u32Size, NULL);
    if (VB_INVALID_HANDLE == VbBlk)
    {
        SAMPLE_PRT("HI_MPI_VB_GetBlock err! size:%d\n",u32Size);
        return -1;
    }
    u32PhyAddr = HI_MPI_VB_Handle2PhysAddr(VbBlk);
    if (0 == u32PhyAddr)
    {
        return -1;
    }

    pVirAddr = (HI_U8 *) HI_MPI_SYS_Mmap(u32PhyAddr, u32Size);
    if (NULL == pVirAddr)
    {
        return -1;
    }

    pstVFrameInfo->u32PoolId = HI_MPI_VB_Handle2PoolId(VbBlk);
    if (VB_INVALID_POOLID == pstVFrameInfo->u32PoolId)
    {   
        HI_MPI_SYS_Munmap(pVirAddr, u32Size);
        return -1;
    }
    SAMPLE_PRT("pool id :%d, phyAddr:%x,virAddr:%x\n" ,pstVFrameInfo->u32PoolId,u32PhyAddr,(int)pVirAddr);

    pstVFrameInfo->stVFrame.u32PhyAddr[0] = u32PhyAddr;
    pstVFrameInfo->stVFrame.u32PhyAddr[1] = pstVFrameInfo->stVFrame.u32PhyAddr[0] + u32LumaSize;
    pstVFrameInfo->stVFrame.u32PhyAddr[2] = pstVFrameInfo->stVFrame.u32PhyAddr[1] + u32ChrmSize;

    pstVFrameInfo->stVFrame.pVirAddr[0] = pVirAddr;
    pstVFrameInfo->stVFrame.pVirAddr[1] = pstVFrameInfo->stVFrame.pVirAddr[0] + u32LumaSize;
    pstVFrameInfo->stVFrame.pVirAddr[2] = pstVFrameInfo->stVFrame.pVirAddr[1] + u32ChrmSize;

    pstVFrameInfo->stVFrame.u32Width  = u32Width;
    pstVFrameInfo->stVFrame.u32Height = u32Height;
    pstVFrameInfo->stVFrame.u32Stride[0] = u32LStride;
    pstVFrameInfo->stVFrame.u32Stride[1] = u32CStride;
    pstVFrameInfo->stVFrame.u32Stride[2] = u32CStride;
    pstVFrameInfo->stVFrame.enPixelFormat = PIXEL_FORMAT_YUV_SEMIPLANAR_420;
    pstVFrameInfo->stVFrame.u32Field = VIDEO_FIELD_INTERLACED;/* Intelaced D1,otherwise VIDEO_FIELD_FRAME */

    /* read Y U V data from file to the addr ----------------------------------------------*/
    SAMPLE_COMM_VI_ReadFrame(pYUVFile, pstVFrameInfo->stVFrame.pVirAddr[0],
       pstVFrameInfo->stVFrame.pVirAddr[1], pstVFrameInfo->stVFrame.pVirAddr[2],
       pstVFrameInfo->stVFrame.u32Width, pstVFrameInfo->stVFrame.u32Height,
       pstVFrameInfo->stVFrame.u32Stride[0], pstVFrameInfo->stVFrame.u32Stride[1] >> 1 );

    /* convert planar YUV420 to sem-planar YUV420 -----------------------------------------*/
    SAMPLE_COMM_VI_PlanToSemi(pstVFrameInfo->stVFrame.pVirAddr[0], pstVFrameInfo->stVFrame.u32Stride[0],
      pstVFrameInfo->stVFrame.pVirAddr[1], pstVFrameInfo->stVFrame.u32Stride[1],
      pstVFrameInfo->stVFrame.pVirAddr[2], pstVFrameInfo->stVFrame.u32Stride[1],
      pstVFrameInfo->stVFrame.u32Width, pstVFrameInfo->stVFrame.u32Height);

    HI_MPI_SYS_Munmap(pVirAddr, u32Size);
    return 0;
}[/code]

yangguang

0个粉丝

4

问答

0

专栏

0

资料

yangguang 2020-01-08 14:30:46
认可0
[quote][url=forum.php?mod=redirect&goto=findpost&pid=152240&ptid=77290]qn1573466792 发表于 2020-1-7 11:51[/url]
我把u64PhyAddr[0]和u64PhyAddr[1]都用HI_MPI_SYS_Mmap转换,还是一样的结果

图片的宽高是1920x1080的 ...[/quote]

420sp格式的么?

size = 1920*1080*1.5
u64PhyAddr[2] = u64PhyAddr[1]
u64VirAddr[2]  =  u64VirAddr[1]

试试

None

0个粉丝

1

问答

0

专栏

0

资料

None 2022-06-30 20:13:36
认可0

引用 @jugg_kai “[code]/*

感谢,可以用

虽万人吾往矣

3个粉丝

17

问答

42

专栏

86

资料

虽万人吾往矣 2022-07-01 10:19:27
认可0

感谢分享~~

或将文件直接拖到这里
悬赏:
E币
网盘
* 网盘链接:
* 提取码:
悬赏:
E币

Markdown 语法

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

Markdown 语法

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

举报类型

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

详细说明

易百纳技术社区