Firefly开源社区

[技术讨论] 【ROC-RK3568-PC开发板试用体验】rockit视频处理接口第二弹

发表于 2022-9-19 14:57:38     
两个输出节点规格分别如下上节介绍了RK平台下的rockit视频处理接口的简单介绍,本期就针对rockit的一些简单介绍和理念作以具体的介绍。

需要明确一点的是在ARM中的视频处理链路?什么是链路?ARM中视频是怎么样的?
这些基础我们以后再谈,相信做过驱动适配的朋友都知道,各个厂家都有各个厂家的玩法,接口也不尽相同,还需要不断兼容向上提供接口。

rockit充分分离了这一点,他将我们所有的设备全部抽离出来,将每一个单独的功能都能使用一个类来进行使用。

本章节就介绍下rockit的 vi 与 venc模块,视频输入 与编码

本节程序如下:

本节代码基本上参考了官方的程序。

rockit使用的第一步首先是:RK_MPI_SYS_Init 初始化RK MPI系统。
之后进入vi系统,RK平台下vi系统如下:


两个输出节点规格分别如下:




代码大概流程如下:
  1. TEST_VI_CTX_S *ctx;
  2. ctx = reinterpret_cast<TEST_VI_CTX_S *>(malloc(sizeof(TEST_VI_CTX_S)));
  3. memset(ctx, 0, sizeof(TEST_VI_CTX_S));
  4. ctx->width = 1920;
  5. ctx->height = 1080;
  6. ctx->devId = 0;
  7. ctx->pipeId = ctx->devId;
  8. ctx->channelId = 1;
  9. ctx->loopCountSet = 100;
  10. //0. get dev config status
  11. s32Ret = RK_MPI_VI_GetDevAttr(ctx->devId, &ctx->stDevAttr);
  12. if (s32Ret == RK_ERR_VI_NOT_CONFIG) {
  13. //0-1.config dev
  14. s32Ret = RK_MPI_VI_SetDevAttr(ctx->devId, &ctx->stDevAttr);
  15. if (s32Ret != RK_SUCCESS) {
  16.   ctx->stChnAttr.stSize.u32Height = ctx->height;
  17.   s32Ret = RK_MPI_VI_SetChnAttr(ctx->pipeId, ctx->channelId, &ctx->stChnAttr);
  18.   if (s32Ret != RK_SUCCESS) {
  19.   RK_LOGE("RK_MPI_VI_SetChnAttr %x", s32Ret);
  20.   goto __FAILED2;
  21.   } /
  22.   /3.enable channel
  23.   s32Ret = RK_MPI_VI_EnableChn(ctx->pipeId, ctx->channelId);
  24.   if (s32Ret != RK_SUCCESS) {
  25.     RK_LOGE("RK_MPI_VI_EnableChn %x", s32Ret);
  26.     goto __FAILED2;
  27. } /
  28. /4.save debug file
  29. if (ctx->stDebugFile.bCfg) {
  30.   s32Ret = RK_MPI_VI_ChnSaveFile(ctx->pipeId, ctx->channelId, &ctx->stDebugFile);
  31.   RK_LOGE("RK_MPI_VI_ChnSaveFile %x", s32Ret);
  32. }
  33. while (loopCount < ctx->loopCountSet) {
  34. //5.get the frame
  35.   s32Ret = RK_MPI_VI_GetChnFrame(ctx->pipeId, ctx->channelId, &ctx->stViFrame,waitTime);
  36. if (s32Ret == RK_SUCCESS) {
  37.   void *data = RK_MPI_MB_Handle2VirAddr(ctx->stViFrame.pMbBlk);
  38.   //6.get the channel status
  39.   s32Ret = RK_MPI_VI_QueryChnStatus(ctx->pipeId, ctx->channelId, &ctx->stChnStatus);
  40.   //7.release the frame
  41.   s32Ret = RK_MPI_VI_ReleaseChnFrame(ctx->pipeId, ctx->channelId, &ctx-
  42. >stViFrame);
  43. if (s32Ret != RK_SUCCESS) {
  44. RK_LOGE("RK_MPI_VI_ReleaseChnFrame fail %x", s32Ret);
  45. } l
  46. oopCount ++;
  47. } else {
  48. RK_LOGE("RK_MPI_VI_GetChnFrame timeout %x", s32Ret);
  49. } u
  50. sleep(10*1000);
  51. } /
  52. /8. disable one chn
  53. s32Ret = RK_MPI_VI_DisableChn(ctx->pipeId, ctx->channelId);
  54. RK_LOGE("RK_MPI_VI_DisableChn %x", s32Ret);
  55. //9.disable dev(will diabled all chn)
  56. __FAILED2:
  57. s32Ret = RK_MPI_VI_DisableDev(ctx->devId);
  58. RK_LOGE("RK_MPI_VI_DisableDev %x", s32Ret);
复制代码

除了单独使用VI设备之外,VI设备还可以与其流程中关联的设备进行绑定,如VO、VENC,这样就不用在代码的流程中进行图像采集到内存,从内存在拷贝到其他设备中。关联的方式如下:
  • RK_MPI_SYS_Bind

我的test程序就将这个接口关联到了VENC模块中,可以直接进行视频的编码。实现如下:
  1. // bind vi to venc
  2.         stSrcChn.enModId    = RK_ID_VI;
  3.         stSrcChn.s32DevId   = ctx->devId;
  4.         stSrcChn.s32ChnId   = ctx->channelId;

  5.         stDestChn[i].enModId   = RK_ID_VENC;
  6.         stDestChn[i].s32DevId  = i;
  7.         stDestChn[i].s32ChnId  = ctx->stVencCfg[i].s32ChnId;

  8.         s32Ret = RK_MPI_SYS_Bind(&stSrcChn, &stDestChn[i]);
  9.         if (s32Ret != RK_SUCCESS) {
  10.             RK_LOGE("create %d ch venc failed", ctx->stVencCfg[i].s32ChnId);
  11.             goto __FAILED2;
  12.         }
复制代码

最终实现了可以将摄像头直接采集编码到H264文件中,可以使用播放器来打开啦。



回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

友情链接 : 爱板网 电子发烧友论坛 云汉电子社区 粤ICP备14022046号-2
快速回复 返回顶部 返回列表