OpenHarmony开源社区
直播中

羁傲不驯

3年用户 24经验值
擅长:嵌入式技术
私信 关注
[经验]

【ROC-RK3568-PC开发板试用体验】rockit视频处理接口第二弹

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

需要明确一点的是在ARM中的视频处理链路?什么是链路?ARM中视频是怎么样的?

这些基础我们以后再谈,相信做过驱动适配的朋友都知道,各个厂家都有各个厂家的玩法,接口也不尽相同,还需要不断兼容向上提供接口。

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

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

本节程序如下:

demo程序

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

rockit使用的第一步首先是:RK_MPI_SYS_Init 初始化RK MPI系统。

之后进入vi系统,RK平台下vi系统如下:

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


代码大概流程如下:

TEST_VI_CTX_S *ctx;
ctx = reinterpret_cast<TEST_VI_CTX_S *>(malloc(sizeof(TEST_VI_CTX_S)));
memset(ctx, 0, sizeof(TEST_VI_CTX_S));
ctx->width = 1920;
ctx->height = 1080;
ctx->devId = 0;
ctx->pipeId = ctx->devId;
ctx->channelId = 1;
ctx->loopCountSet = 100;
//0. get dev config status
s32Ret = RK_MPI_VI_GetDevAttr(ctx->devId, &ctx->stDevAttr);
if (s32Ret == RK_ERR_VI_NOT_CONFIG) {
//0-1.config dev
s32Ret = RK_MPI_VI_SetDevAttr(ctx->devId, &ctx->stDevAttr);
if (s32Ret != RK_SUCCESS) {
  ctx->stChnAttr.stSize.u32Height = ctx->height;
  s32Ret = RK_MPI_VI_SetChnAttr(ctx->pipeId, ctx->channelId, &ctx->stChnAttr);
  if (s32Ret != RK_SUCCESS) {
  RK_LOGE("RK_MPI_VI_SetChnAttr %x", s32Ret);
  goto __FAILED2;
  } /
  /3.enable channel
  s32Ret = RK_MPI_VI_EnableChn(ctx->pipeId, ctx->channelId);
  if (s32Ret != RK_SUCCESS) {
    RK_LOGE("RK_MPI_VI_EnableChn %x", s32Ret);
    goto __FAILED2;
} /
/4.save debug file
if (ctx->stDebugFile.bCfg) {
  s32Ret = RK_MPI_VI_ChnSaveFile(ctx->pipeId, ctx->channelId, &ctx->stDebugFile);
  RK_LOGE("RK_MPI_VI_ChnSaveFile %x", s32Ret);
} 
while (loopCount < ctx->loopCountSet) {
//5.get the frame
  s32Ret = RK_MPI_VI_GetChnFrame(ctx->pipeId, ctx->channelId, &ctx->stViFrame,waitTime);
if (s32Ret == RK_SUCCESS) {
  void *data = RK_MPI_MB_Handle2VirAddr(ctx->stViFrame.pMbBlk);
  //6.get the channel status
  s32Ret = RK_MPI_VI_QueryChnStatus(ctx->pipeId, ctx->channelId, &ctx->stChnStatus);
  //7.release the frame
  s32Ret = RK_MPI_VI_ReleaseChnFrame(ctx->pipeId, ctx->channelId, &ctx-
>stViFrame);
if (s32Ret != RK_SUCCESS) {
RK_LOGE("RK_MPI_VI_ReleaseChnFrame fail %x", s32Ret);
} l
oopCount ++;
} else {
RK_LOGE("RK_MPI_VI_GetChnFrame timeout %x", s32Ret);
} u
sleep(10*1000);
} /
/8. disable one chn
s32Ret = RK_MPI_VI_DisableChn(ctx->pipeId, ctx->channelId);
RK_LOGE("RK_MPI_VI_DisableChn %x", s32Ret);
//9.disable dev(will diabled all chn)
__FAILED2:
s32Ret = RK_MPI_VI_DisableDev(ctx->devId);
RK_LOGE("RK_MPI_VI_DisableDev %x", s32Ret);

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

  • RK_MPI_SYS_Bind

我的test程序就将这个接口关联到了VENC模块中,可以直接进行视频的编码。实现如下:

// bind vi to venc
        stSrcChn.enModId    = RK_ID_VI;
        stSrcChn.s32DevId   = ctx->devId;
        stSrcChn.s32ChnId   = ctx->channelId;

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

        s32Ret = RK_MPI_SYS_Bind(&stSrcChn, &stDestChn[i]);
        if (s32Ret != RK_SUCCESS) {
            RK_LOGE("create %d ch venc failed", ctx->stVencCfg[i].s32ChnId);
            goto __FAILED2;
        }

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

更多回帖

发帖
×
20
完善资料,
赚取积分