2025年读取pcap文件中的csi(pcapng文件怎么解析读取)

读取pcap文件中的csi(pcapng文件怎么解析读取)本文档适用于本店所有海思 国科开发板 包括 GK7205Hi3516 等 从 SampleSource 目录将 mpp xxx tgz 拷贝至虚拟机 ubuntu 的 nfs 服务器目录 home swann nfs 或 root hisi 中的任意目录 并在虚拟机中解压 编译 生成 sample venc 可执行程序

大家好,我是讯享网,很高兴认识大家。



本文档适用于本店所有海思、国科开发板,包括GK7205Hi3516Hi3518Hi3519Hi3520Hi3521Hi3531等

从“SampleSourceCode”目录将mpp_xxx.tgz拷贝至虚拟机ubuntu的nfs服务器目录/home/swann/nfs或/root/hisi,中的任意目录,并在虚拟机中解压、编译

零基础玩转IPC之——海思VENC例程源码详解(sample_venc)_文件描述符
讯享网

生成sample_venc可执行程序

零基础玩转IPC之——海思VENC例程源码详解(sample_venc)_SYS_02

零基础玩转IPC之——海思VENC例程源码详解(sample_venc)_SYS_03

在开发板linux系统下运行该程序

零基础玩转IPC之——海思VENC例程源码详解(sample_venc)_文件描述符_04

开始录制视频,等待十秒左右后按2次回车退出录制,可以看到在当前目录生成H264和H265视频裸流文件。

零基础玩转IPC之——海思VENC例程源码详解(sample_venc)_文件描述符_05

我们将他们拷贝到Windows下,用播放器打开查看

零基础玩转IPC之——海思VENC例程源码详解(sample_venc)_SYS_06

零基础玩转IPC之——海思VENC例程源码详解(sample_venc)_文件描述符_07

零基础玩转IPC之——海思VENC例程源码详解(sample_venc)_文件描述符_08

PS:我也想学习,如何获得开发板?逃保搜索“海思开发板总店”,仅此一家,其他都是假冒的哦

至此实验成功,接下来我们进入源代码解析

 VENC流程

1.根据sensor type获得尺寸大小,缓冲池参数,将 u32BlkSize 写入  stVbConf

   /

    step  1: init sys variable  

   */

   SAMPLE_COMM_VI_GetSizeBySensor(&enSize[0]);

    u32BlkSize = SAMPLE_COMM_SYS_CalcPicVbBlkSize(gs_enNorm,enSize[0], SAMPLE_PIXEL_FORMAT, SAMPLE_SYS_ALIGN_WIDTH);

    stVbConf.astCommPool[0].u32BlkSize = u32BlkSize;

2.调用海思SDK,将上面的参数 stVbConf 写入硬件vediobuf ,完成 VB和SYS init

/*

    step 2: mpp system init.  

   */

   SAMPLE_COMM_SYS_Init(&stVbConf);

 HI_MPI_VB_SetConf(pstVbConf)

 s32Ret = HI_MPI_VB_Init();

 HI_MPI_SYS_SetConf(&stSysConf);

 HI_MPI_SYS_Init();

3.初始化 海思的VI模块和 sensor硬件

   /*

    step 3: start vi dev & chn to capture

   */

SAMPLE_COMM_VI_StartVi(&stViConfig);

 SAMPLE_COMM_VI_StartIspAndVi

4.调用海思MPI,开启vpss同时绑定vi ch 和 vpss ch

/*

    step 4: start vpss and vi bind vpss

   */

SAMPLE_COMM_SYS_GetPicSize(gs_enNorm, enSize[0], &stSize)//从SYS系统获取pic size参数写入 stSize

VpssGrp = 0;

SAMPLE_COMM_VPSS_StartGroup(VpssGrp, &stVpssGrpAttr)//开启vpss group 0

 HI_MPI_VPSS_CreateGrp(VpssGrp, pstVpssGrpAttr);

 HI_MPI_VPSS_StartGrp(VpssGrp);

SAMPLE_COMM_VI_BindVpss(stViConfig.enViMode)

 SAMPLE_COMM_VI_Mode2Param(enViMode, &stViParam); //根据enViMode,填充stViParam 的s32ViDevCnt s32ViDevInterval s32ViChnCnt s32ViChnInterval参数为1

 HI_MPI_SYS_Bind(&stSrcChn, &stDestChn);    //调用海思MPI绑定 Videv0的Chn0 和 VpssGrp0的chn0

VpssChn = 0;

SAMPLE_COMM_VPSS_EnableChn(VpssGrp, VpssChn, &stVpssChnAttr, &stVpssChnMode, HI_NULL);

 HI_MPI_VPSS_EnableChn(VpssGrp, VpssChn);   //调用海思MPI使能VpssGrp0和VpssChn0

SAMPLE_COMM_SYS_GetPicSize(gs_enNorm, enSize[1], &stSize);

VpssChn = 1;

SAMPLE_COMM_VPSS_EnableChn(VpssGrp, VpssChn, &stVpssChnAttr, &stVpssChnMode, HI_NULL);

 HI_MPI_VPSS_EnableChn(VpssGrp, VpssChn);

5.绑定venc和vpss对应通道,开始编码

/*

    step 5: start stream venc

   */

/ enSize[0] /

VpssGrp = 0;

VpssChn = 0;              //VpssGrp0-Chn0

VencChn = 0;              //VencDev0-VencCh0 ,IPC has only 1 VencDev

SAMPLE_COMM_VENC_GetGopAttr(enGopMode[0],&stGopAttr,gs_enNorm);  //配置venc参数

SAMPLE_COMM_VENC_Start(VencChn, enPayLoad[0], gs_enNorm, enSize[0], enRcMode,u32Profile,&stGopAttr);//开启venc模块

 SAMPLE_COMM_SYS_GetPicSize(enNorm, enSize, &stPicSize);   //获取尺寸,在下面写入 stVencChnAttr

 HI_MPI_VENC_CreateChn(VencChn, &stVencChnAttr);     //填充 stVencChnAttr,再创建 Venc Channel

 HI_MPI_VENC_StartRecvPic(VencChn);        //Start Recv Venc Pictures

SAMPLE_COMM_VENC_BindVpss(VencChn, VpssGrp, VpssChn);    //调用海思MPI绑定 VencDev0 的Chn0 和 VpssGrp0 的chn0

/* enSize[1] /

VpssChn = 1;              //VpssGrp0-Chn1

VencChn = 1;              //VencDev0-VencCh1 ,IPC has only 1 VencDev

s32Ret = SAMPLE_COMM_VENC_GetGopAttr(enGopMode[1],&stGopAttr,gs_enNorm);

s32Ret = SAMPLE_COMM_VENC_Start(VencChn, enPayLoad[1],gs_enNorm, enSize[1], enRcMode,u32Profile,&stGopAttr);

s32Ret = SAMPLE_COMM_VENC_BindVpss(VencChn, VpssGrp, VpssChn);

6.调用海思MPI获取2路venc码流,并保存文件

   /

    step 6: stream venc process – get stream, then save it to file.  

   /

   SAMPLE_COMM_VENC_StartGetStream(s32ChnNum);

    gs_stPara.bThreadStart = HI_TRUE;

 gs_stPara.s32Cnt = s32Cnt;

 pthread_create(&gs_VencPid, 0, SAMPLE_COMM_VENC_GetVencStreamProc, (HI_VOID*)&gs_stPara);

     /

   step 1:  check & prepare save-file & venc-fd

  /

  for (i = 0; i < s32ChnTotal; i++)

  {

   /* decide the stream file name, and open file to save stream /

   VencChn = i;

   HI_MPI_VENC_GetChnAttr(VencChn, &stVencChnAttr);

   SAMPLE_COMM_VENC_GetFilePostfix(enPayLoadType[i], szFilePostfix);

   pFile[i] = fopen(aszFileName[i], “wb”);

   / Set Venc Fd. */

   VencFd[i] = HI_MPI_VENC_GetFd(i);

   HI_MPI_VENC_GetStreamBufInfo (i, &stStreamBufInfo[i]);

  }

  /

   step 2:  Start to get streams of each channel.

  /

  while (HI_TRUE == pstPara->bThreadStart)

  {    

   s32Ret = select(maxfd + 1, &read_fds, NULL, NULL, &TimeoutVal);    

   for (i = 0; i < s32ChnTotal; i++)

   {

    if (FD_ISSET(VencFd[i], &read_fds))

    {

     memset(&stStream, 0, sizeof(stStream));

     HI_MPI_VENC_Query(i, &stStat);               //step 2.1 : query how many packs in one-frame stream.

      //此接口用于查询此函数调用时刻的编码器状态,stStat包含四个主要的信息,在编码通道状态结构体中,u32CurPacks 表示当前帧的码流包个数。在调用

      //HI_MPI_VENC_GetStream 之前应确保 u32CurPacks 大于 0。 按帧获取时表示当前一个完整帧的包个数(如果没有一帧数据则为 0)。用户在需要按帧获取码

      //流时,需要查询一个完整帧的包个数,在这种情况下,通常可以在 select 成功后执行 query 操作,此时 u32CurPacks 是当前完整帧中包的个数。

     if(0 == stStat.u32CurPacks)SAMPLE_PRT(“NOTE: Current  frame is NULL! “);continue;   //step 2.2 : check u32CurPacks  

      //u32CurPacks 表示当前帧的码流包个数

     stStream.pstPack = (VENC_PACK_S*)malloc(sizeof(VENC_PACK_S) * stStat.u32CurPacks);  //step 2.3 : malloc corresponding number of pack nodes.

      //码流包信息指针 pstPack ,指向一组 VENC_PACK_S 的内存空间,该空间由调用者分配。

      //如果按帧获取,则此空间不小于 N × sizeof(VENC_PACK_S)的大小,其中 N 代表当前帧之中的包的个数

     stStream.u32PackCount = stStat.u32CurPacks;

     HI_MPI_VENC_GetStream(i, &stStream, HI_TRUE);           //step 2.4 : call mpi to get one-frame stream

      //码流包个数 u32PackCount 在输入时,此值指定 stStream 中 VENC_PACK_S 的个数。按帧获取时,u32PackCount 必须不小于当前帧的包个数。

      //在函数调用成功后, u32PackCount 返回实际填充 stStream 的包的个数。

     SAMPLE_COMM_VENC_SaveStream(enPayLoadType[i], pFile[i], &stStream);      //step 2.5 : save frame to file

      SAMPLE_COMM_VENC_SaveH264(pFd, pstStream);

          for (i = 0; i < pstStream->u32PackCount; i++)

       { /每个数据包的首地址 + 每个数据包的有效数据相对于首地址的偏移量/ /每个数据包的长度 - 每个数据包的有效数据相对于首地址的偏移量 = 有效数据长度/ //写入一次

        fwrite(pstStream->pstPack[i].pu8Addr + pstStream->pstPack[i].u32Offset , pstStream->pstPack[i].u32Len - pstStream->pstPack[i].u32Offset, 1, fpH264File);

        fflush(fpH264File);  //表示立即将输出缓冲区的数据写入该文件中

       }

      SAMPLE_COMM_VENC_SaveMJpeg(pFd, pstStream);

      SAMPLE_COMM_VENC_SaveH265(pFd, pstStream);

     HI_MPI_VENC_ReleaseStream(i, &stStream);            //step 2.6 : release stream  

     free(stStream.pstPack);                 //step 2.7 : free pack nodes

     stStream.pstPack = NULL;

    }

   }

  }

  /*

  * step 3 : close save-file

  */

  for (i = 0; i < s32ChnTotal; i++)

  {

   fclose(pFile[i]);

  }

Linux中select的用法:

在Linux中,select 函数是用于监控多个文件描述符(file descriptors)的系统调用

#include <sys/select.h>

int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);

参数解释:

nfds:指定监控的文件描述符数量。它应该是所有监控的文件描述符集合中最大值加1,因为文件描述符是从0开始计数的。

readfds:指向一个文件描述符集合,用于监控是否有文件可读。可以使用宏函数 FD_SET() 将描述符添加到集合。

writefds:指向一个文件描述符集合,用于监控是否有文件可写。

exceptfds:指向一个文件描述符集合,用于监控异常状态。

timeout:指定 select 等待的时间,可以是:

 NULL:select 将无限期等待,直到有文件描述符准备好。

 0秒的时间:表示非阻塞模式,select 立即返回。

 自定义时间:例如等待5秒,可以通过 struct timeval 指定。

返回值:

返回值为大于0的数值表示有多少文件描述符准备好。

返回0表示超时。

返回-1表示出错,并且设置 errno。

使用步骤:

清空文件描述符集合: 在使用 select 之前,首先需要初始化或清空文件描述符集合。

 FD_ZERO(&readfds);

 FD_ZERO(&writefds);

 FD_ZERO(&exceptfds);

设置需要监控的文件描述符: 使用 FD_SET() 函数将需要监控的文件描述符加入到集合中。

 FD_SET(fd, &readfds);

调用 select 函数: 通过调用 select 来监控多个文件描述符。

 int ready = select(nfds, &readfds, &writefds, &exceptfds, &timeout);

检查哪些文件描述符已准备好: select 返回后,可以使用 FD_ISSET() 函数检查哪些文件描述符已经准备好。

 if (FD_ISSET(fd, &readfds)) { // 该文件描述符可读 }

文件描述符集合的操作:

为了管理 select 函数的文件描述符集合,使用了以下几个宏:

FD_ZERO(fd_set *set):清空集合。

FD_SET(int fd, fd_set *set):将文件描述符 fd 添加到集合中。

FD_CLR(int fd, fd_set *set):将文件描述符 fd 从集合中移除。

FD_ISSET(int fd, fd_set *set):判断文件描述符 fd 是否在集合中,返回非0值表示在集合中。

关于VPSS的Group和Channel

GROUP  

VPSS 对用户提供组( GROUP )的概念。最大可用数为 VPSS_MAX_GRP_NUM

个,各芯片的最大组数目有所不同,各 GROUP 分时复用 VPSS 硬件。每个 VPSS  

GROUP 包含多个通道,通道数目视方案实现有所不同,具体描述请参见CHANNEL 。  

CHANNEL  

VPSS 组的通道。通道分为 2 种:物理通道和扩展通道。 VPSS 硬件提供多个物理

通道,每个通道具有缩放、裁剪等功能。扩展通道具备缩放功能,它通过绑定物

理通道,将物理通道输出作为自己的输入,把图像缩放成用户设置的目标分辨率

输出。需要特别注意的是, USER 模式主要用于对同一通道图像进行多路编码的

场景,此模式下播放控制不生效,因此预览和回放场景下不建议使用 USER 模式。  

Hi3516A/Hi3518EV200/Hi3519V100/Hi3519V101/Hi3516CV300 仅支持 USER 工作模式

CHANNEL 0为原尺寸不支持裁剪缩放,CHANNEL 1可以

主要的结构体VENC_STREAM_S和VENC_PACK_S:

//帧码流结构体VENC_STREAM_S, 表示一帧图像对应的码流

typedef struct hiVENC_STREAM_S

{

   VENC_PACK_S *pstPack; //指向帧码流包的指针

   HI_U32      u32PackCount; //帧码流的所有包的个数

   HI_U32      u32Seq; //码流序列号,按帧获取则表示帧序号,按包获取则表示包序号                            

 

   union

   {   //码流特征信息

       VENC_STREAM_INFO_H264_S  stH264Info;         /the stream info of h264/

       VENC_STREAM_INFO_JPEG_S  stJpegInfo;         /the stream info of jpeg/

       VENC_STREAM_INFO_MPEG4_S stMpeg4Info;       /the stream info of mpeg4/

       VENC_STREAM_INFO_H265_S  stH265Info;        /the stream info of h265/

   };

}VENC_STREAM_S;

//帧码流包结构体VENC_PACK_S, 表示一帧图像的每个包对应的码流。(一帧图像可以有多个包)

typedef struct hiVENC_PACK_S

{

   HI_U32   u32PhyAddr; //每个码流包的物理地址       /the physics address of stream/

   HI_U8   *pu8Addr;  //每个码流包首地址             /the virtual address of stream/

   HI_U32   u32Len;   //每个码流包长度               /the length of stream/

   

   HI_U64   u64PTS; //时间戳,单位us                 /PTS/

   HI_BOOL  bFrameEnd; //帧结束标识                 /frame end/(1)关于帧结束标志 HI_TRUE 表示该码流包是该帧的最后一个包, HI_FALSE 表示该码流包不是该帧的最后一个包。

                     //码流类型,支持 H.264/JPEG/MPEG-4 协议类型的数据包。

   VENC_DATA_TYPE_U  DataType;                     /the type of stream/

                     

   HI_U32   u32Offset;//每个码流包中有效数据与码流包首地址 pu8Addr 的偏移。

 

HI_U32 u32DataNum;//当前码流包(类型由 DataType 指定)数据中包含其他类型码流包的个数。

VENC_PACK_INFO_S stPackInfo[8];//当前码流包数据中包含其他类型码流包数据信息

}VENC_PACK_S;

小讯
上一篇 2025-05-26 16:01
下一篇 2025-05-02 12:55

相关推荐

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/143320.html