RV1126学习笔记 一入四出rtsp网络视频流显示

A191型RV1126 摄像头:gc2053
首先感谢这位大佬的博文,其中的一些细节我就不细说了
可以参考以下博文:
https://blog.csdn.net/qq_36769014/article/details/128224487
建议先仔细阅读官方文档这块的内容

我的参考代码在最下面

vp模块的运用

主要是参考sdk包里面的例子 rkmedia_vi_vp_vo_test.c
例子里面有些如何调用

/*
 *                    -> VI2
 * VI0 -> VP0 -- ISPP -> VI3
 *                    -> VI4
 *                    -> VI5
 * How to use ISPP?
 * 1. add code to kernel dts:
 *    &rkispp_vir2 {
 *           status = "okay";
 *    };
 * 2. check new /dev/media*, as is my case: /dev/media5
 * 3. media-ctl -p -d /dev/media5
 *    check rkispp_input_image for VP0: as is my case: /dev/video45
 *    check rkispp_m_bypass for VI2: as is my case: /dev/video46
 *    check rkispp_scale0 for VI3: as is my case: /dev/video47
 *    check rkispp_scale1 for VI4: as is my case: /dev/video48
 *    check rkispp_scale2 for VI5: as is my case: /dev/video49
 * 4. config:
 *    media-ctl -d /dev/media5 -l '"rkispp_input_image":0->"rkispp-subdev":0[1]'
 *    media-ctl -d /dev/media5 --set-v4l2
 * '"rkispp-subdev":0[fmt:YUYV8_2X8/1920x1080]' media-ctl -d /dev/media5
 * --set-v4l2 '"rkispp-subdev":2[fmt:YUYV8_2X8/1920x1080]'
 * 5. enable VI2, VI3, VI4, VI5(one or more) before VP0
 */

这个也仅供参考,实际不同板子和摄像头的效果是不同的。

我是修改了dts中的
&rkispp_vir1 {
status = “okay”;
};
开启了media3

一些对应的映射关系

rv1109-38-v10-spi-nand.dts

&i2c1 mipi_in_ucam0 vicap模块
gc2053 -> csi_dphy0 -> mipi_csi2 -> rkcif_mipi_lvds

对应的关系是一样的
rkvicap_mipi_lvds----rkcif_mipi_lvds
rkvicap--------------rkcif
rkvicap_dvp----------rkcif_dvp

查询video节点

我们首先要调用把media-ctl这个指令把 每个media对应出来的jvideo节点去理解
media-ctl -p -d /dev/media* 查看对应版本 和对应接口

画出数据链路拓补图
Source和符号->表示输出
Sink和符号 <- 就表示输入
ink 表示连接,或者表示链路
仅供参考RV1126学习笔记 一入四出rtsp网络视频流显示_第1张图片
RV1126学习笔记 一入四出rtsp网络视频流显示_第2张图片

由此我们可以得到
/dev/media0 rkcif_mipi_lvds
/dev/media1 rkisp0
/dev/media2 rkispp0

当我添加上了rkispp_vir1之后 可以看到多了一个 /dev/media3,
仅供参考
input: /dev/video25, rkispp_input_image
output1: /dev/video26, rkispp_m_bypass
output2: /dev/video27, rkispp_scale0
output3: /dev/video28, rkispp_scale1
output4: /dev/video29 rkispp_scale2

再根据以上的 vp模块的运用中的第四点修改

最后加上rtsp的代码运行效果如下

参考代码

// Copyright 2020 Fuzhou Rockchip Electronics Co., Ltd. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

#include 
#include 

#include "sample_common.h"
#include "librtsp/rtsp_demo.h"
#include "rkmedia_api.h"
#include "rkmedia_venc.h"
/*
 *                    -> VI2
 * VI0 -> VP0 -- ISPP -> VI3
 *                    -> VI4
 *                    -> VI5
 * How to use ISPP?
 * 1. add code to kernel dts:
 *    &rkispp_vir2 {
 *           status = "okay";
 *    };
 * 2. check new /dev/media*, as is my case: /dev/media5
 * 3. media-ctl -p -d /dev/media5
 *    check rkispp_input_image for VP0: as is my case: /dev/video45
 *    check rkispp_m_bypass for VI2: as is my case: /dev/video46
 *    check rkispp_scale0 for VI3: as is my case: /dev/video47
 *    check rkispp_scale1 for VI4: as is my case: /dev/video48
 *    check rkispp_scale2 for VI5: as is my case: /dev/video49
 * 4. config:
 *    media-ctl -d /dev/media5 -l '"rkispp_input_image":0->"rkispp-subdev":0[1]'
 *    media-ctl -d /dev/media5 --set-v4l2
 * '"rkispp-subdev":0[fmt:YUYV8_2X8/1920x1080]' media-ctl -d /dev/media5
 * --set-v4l2 '"rkispp-subdev":2[fmt:YUYV8_2X8/1920x1080]'
 * 5. enable VI2, VI3, VI4, VI5(one or more) before VP0
 */
/*
================================================Myself===============================================
  A191-eb-rv1126    sensor: gc2053      vi venc vp rtsp   网络四路监控
  参考以上的官方提示
  通过dts 添加rkispp_virl  , 生成media3  对应映射出下面 video  节点
  kernel dts:       
 *    &rkispp_vir1 {
 *           status = "okay";
 *    };
media: /dev/media3, 

input: /dev/video25,        rkispp_input_image  打开
output1: /dev/video26,      rkispp_m_bypass
output2: /dev/video27,      rkispp_scale0
output3: /dev/video28,      rkispp_scale1
output4: /dev/video29       rkispp_scale2
  
  定义了四个(Video1GetVencBuffer)来分开四个线程rtsp,对应ip地址:video1 rtsp://192.168.101.36:554/live/video1_stream  rkispp_m_bypass
                                                           video2 rtsp://192.168.101.36:555/live/video2_stream  rkispp_scale0
                                                           video3 rtsp://192.168.101.36:556/live/video3_stream  rkispp_scale1
                                                           video4 rtsp://192.168.101.36:557/live/video4_stream  rkispp_scale2
  vi通道 和 venc通道  都分别对应1~4
  RK_MPI_SYS_GetMediaBuffer  函数调用后,还会打开视频流的,只用绑定好对应的vi和venc通道
  配置VI通道属性->RK_MPI_VI_SetChnAttr()->RK_MPI_VI_EnableChn()s
              往下分俩路走  1 RK_MPI_VI_StartStream()
			                    2 RK_MPI_SYS_Bind()->RM_MPI_SYS_UnBind()
			        俩条线路的作用一样
			        最后都会以 RK_MPI_VI_DisableChn() 结束视频流
================================================Myself==================================================
*/

static bool quit = false;
static void sigterm_handler(int sig) {
  fprintf(stderr, "signal %d\n", sig);
  quit = true;
}

static RK_CHAR optstr[] = "?::a::I:M:i:m:";
static const struct option long_options[] = {
    {"aiq", optional_argument, NULL, 'a'},
    {"camid", required_argument, NULL, 'I'},
    {"multictx", required_argument, NULL, 'M'},
    {"input", required_argument, NULL, 'i'},
    {"media", required_argument, NULL, 'm'},
    {"help", optional_argument, NULL, '?'},
    {NULL, 0, NULL, 0},
};

static void print_usage(const RK_CHAR *name) {
  printf("usage example:\n");
#ifdef RKAIQ
  printf("\t%s [-a [iqfiles_dir]]"
         "[-I 0] "
         "[-M 0] "
         "[-i 45] "
         "[-m 5] "
         "\n",
         name);
  printf("\t-a | --aiq: enable aiq with dirpath provided, eg:-a "
         "/oem/etc/iqfiles/, "
         "set dirpath empty to using path by default, without this option aiq "
         "should run in other application\n");
  printf("\t-M | --multictx: switch of multictx in isp, set 0 to disable, set "
         "1 to enable. Default: 0\n");
  printf("\t-i | --input: intput video of ISPP. Default: 45\n");
  printf("\t-m | --media: media of ISPP. Default: 5\n");
#else
  printf("\t%s [-I 0]\n", name);
#endif
  printf("\t-I | --camid: camera ctx id, Default 0\n");
}

static void *Video1GetVencBuffer(void *arg) {
  printf("# Video1 Start %s thread, arg:%p\n", __func__, arg);
  // init rtsp
  rtsp_demo_handle rtsplive = NULL;
  rtsp_session_handle session;
  rtsplive = create_rtsp_demo(554);
  session = rtsp_new_session(rtsplive, "/live/video1_stream");
  rtsp_set_video(session, RTSP_CODEC_ID_VIDEO_H264, NULL, 0);
  rtsp_sync_video_ts(session, rtsp_get_reltime(), rtsp_get_ntptime());

  MEDIA_BUFFER mb = NULL;
  while (!quit) {
    mb = RK_MPI_SYS_GetMediaBuffer(RK_ID_VENC, 1,
                                   -1);
    if (mb) {
      printf(
          "-Get Video1 Encoded packet():ptr:%p, fd:%d, size:%zu, mode:%d, time "
          "= %llu.\n",
          RK_MPI_MB_GetPtr(mb), RK_MPI_MB_GetFD(mb), RK_MPI_MB_GetSize(mb),
          RK_MPI_MB_GetModeID(mb), RK_MPI_MB_GetTimestamp(mb));
      rtsp_tx_video(session, RK_MPI_MB_GetPtr(mb), RK_MPI_MB_GetSize(mb),
                    RK_MPI_MB_GetTimestamp(mb));
      RK_MPI_MB_ReleaseBuffer(mb);
    }
    rtsp_do_event(rtsplive);
  }
  // release rtsp
  rtsp_del_demo(rtsplive);
  return NULL;
}

static void *Video2GetVencBuffer(void *arg) {
  printf("# Video2  Start %s thread, arg:%p\n", __func__, arg);
  // init rtsp
  rtsp_demo_handle rtsplive = NULL;
  rtsp_session_handle session;
  rtsplive = create_rtsp_demo(555);
  session = rtsp_new_session(rtsplive, "/live/video2_stream");
  rtsp_set_video(session, RTSP_CODEC_ID_VIDEO_H264, NULL, 0);
  rtsp_sync_video_ts(session, rtsp_get_reltime(), rtsp_get_ntptime());

  MEDIA_BUFFER mb = NULL;
  while (!quit) {
    mb = RK_MPI_SYS_GetMediaBuffer(RK_ID_VENC, 2,
                                   -1);
    if (mb) {
      printf(
          "-Get Video2 Encoded packet():ptr:%p, fd:%d, size:%zu, mode:%d, time "
          "= %llu.\n",
          RK_MPI_MB_GetPtr(mb), RK_MPI_MB_GetFD(mb), RK_MPI_MB_GetSize(mb),
          RK_MPI_MB_GetModeID(mb), RK_MPI_MB_GetTimestamp(mb));
      rtsp_tx_video(session, RK_MPI_MB_GetPtr(mb), RK_MPI_MB_GetSize(mb),
                    RK_MPI_MB_GetTimestamp(mb));
      RK_MPI_MB_ReleaseBuffer(mb);
    }
    rtsp_do_event(rtsplive);
  }
  // release rtsp
  rtsp_del_demo(rtsplive);
  return NULL;
}

static void *Video3GetVencBuffer(void *arg) {
  printf("# Video3  Start %s thread, arg:%p\n", __func__, arg);
  // init rtsp
  rtsp_demo_handle rtsplive = NULL;
  rtsp_session_handle session;
  rtsplive = create_rtsp_demo(556);
  session = rtsp_new_session(rtsplive, "/live/video3_stream");
  rtsp_set_video(session, RTSP_CODEC_ID_VIDEO_H264, NULL, 0);
  rtsp_sync_video_ts(session, rtsp_get_reltime(), rtsp_get_ntptime());

  MEDIA_BUFFER mb = NULL;
  while (!quit) {
    mb = RK_MPI_SYS_GetMediaBuffer(RK_ID_VENC, 3,
                                   -1);
    if (mb) {
      printf(
          "-Get Video3 Encoded packet():ptr:%p, fd:%d, size:%zu, mode:%d, time "
          "= %llu.\n",
          RK_MPI_MB_GetPtr(mb), RK_MPI_MB_GetFD(mb), RK_MPI_MB_GetSize(mb),
          RK_MPI_MB_GetModeID(mb), RK_MPI_MB_GetTimestamp(mb));
      rtsp_tx_video(session, RK_MPI_MB_GetPtr(mb), RK_MPI_MB_GetSize(mb),
                    RK_MPI_MB_GetTimestamp(mb));
      RK_MPI_MB_ReleaseBuffer(mb);
    }
    rtsp_do_event(rtsplive);
  }
  // release rtsp
  rtsp_del_demo(rtsplive);
  return NULL;
}

static void *Video4GetVencBuffer(void *arg) {
  printf("# Video4  Start %s thread, arg:%p\n", __func__, arg);
  // init rtsp
  rtsp_demo_handle rtsplive = NULL;
  rtsp_session_handle session;
  rtsplive = create_rtsp_demo(557);
  session = rtsp_new_session(rtsplive, "/live/video4_stream");
  rtsp_set_video(session, RTSP_CODEC_ID_VIDEO_H264, NULL, 0);
  rtsp_sync_video_ts(session, rtsp_get_reltime(), rtsp_get_ntptime());

  MEDIA_BUFFER mb = NULL;
  while (!quit) {
    mb = RK_MPI_SYS_GetMediaBuffer(RK_ID_VENC, 4,
                                   -1);
    if (mb) {
      printf(
          "-Get Video4 Encoded packet():ptr:%p, fd:%d, size:%zu, mode:%d, time "
          "= %llu.\n",
          RK_MPI_MB_GetPtr(mb), RK_MPI_MB_GetFD(mb), RK_MPI_MB_GetSize(mb),
          RK_MPI_MB_GetModeID(mb), RK_MPI_MB_GetTimestamp(mb));
      rtsp_tx_video(session, RK_MPI_MB_GetPtr(mb), RK_MPI_MB_GetSize(mb),
                    RK_MPI_MB_GetTimestamp(mb));
      RK_MPI_MB_ReleaseBuffer(mb);
    }
    rtsp_do_event(rtsplive);
  }
  // release rtsp
  rtsp_del_demo(rtsplive);
  return NULL;
}

//--------------------main------------------------  
int main(int argc, char *argv[]) {
  RK_U32 u32Width = 1920;
  RK_U32 u32Height = 1080;

  int ret = 0;
  int disp_width = 640;
  int disp_height = 360;
//sensor输入像素
  int video_width = 1920;  
  int video_height = 1080;
//sensor输出像素
  int video1_width = 1920;
  int video1_height = 1080;
  int video2_width = disp_width;
  int video2_height = disp_height;
  int video3_width = 640;
  int video3_height = 360;
  int video4_width = 640;
  int video4_height = 480;
//sensor venc 输出像素
  int video1_venc_width = 1920;
  int video1_venc_height = 1080;
  int video2_venc_width = disp_width;
  int video2_venc_height = disp_height;
  int video3_venc_width = 640;
  int video3_venc_height = 360;
  int video4_venc_width = 640;
  int video4_venc_height = 480;

  RK_S32 s32CamId = 0;
#ifdef RKAIQ
  RK_BOOL bMultictx = RK_FALSE;
#endif
  int media_id = 3;
  int input_id = 25;
  char media[128];
  char video_input[128];
  char video_output1[128];
  char video_output2[128];
  char video_output3[128];
  char video_output4[128];
  int c;
  char *iq_file_dir = NULL;
  while ((c = getopt_long(argc, argv, optstr, long_options, NULL)) != -1) {
    const char *tmp_optarg = optarg;
    switch (c) {
    case 'a':
      if (!optarg && NULL != argv[optind] && '-' != argv[optind][0]) {
        tmp_optarg = argv[optind++];
      }
      if (tmp_optarg) {
        iq_file_dir = (char *)tmp_optarg;
      } else {
        iq_file_dir = "/oem/etc/iqfiles";
      }
      break;
    case 'I':
      s32CamId = atoi(optarg);
      break;
#ifdef RKAIQ
    case 'M':
      if (atoi(optarg)) {
        bMultictx = RK_TRUE;
      }
      break;
#endif
    case 'i':
      input_id = atoi(optarg);
      break;
    case 'm':
      media_id = atoi(optarg);
      break;
    case '?':
    default:
      print_usage(argv[0]);
      return 0;
    }
  }

  snprintf(media, sizeof(media), "/dev/media%d", media_id);
  snprintf(video_input, sizeof(video_input), "/dev/video%d", input_id);
  snprintf(video_output1, sizeof(video_output1), "/dev/video%d", input_id + 1);
  snprintf(video_output2, sizeof(video_output2), "/dev/video%d", input_id + 2);
  snprintf(video_output3, sizeof(video_output3), "/dev/video%d", input_id + 3);
  snprintf(video_output4, sizeof(video_output4), "/dev/video%d", input_id + 4);

  printf("media: %s, input: %s, output1: %s, output2: %s, output3: %s, "
         "output4: %s\n",
         media, video_input, video_output1, video_output2, video_output3,
         video_output4);

  printf("#CameraIdx: %d\n\n", s32CamId);
  if (iq_file_dir) {
#ifdef RKAIQ
    printf("#Rkaiq XML DirPath: %s\n", iq_file_dir);
    printf("#bMultictx: %d\n\n", bMultictx);
    rk_aiq_working_mode_t hdr_mode = RK_AIQ_WORKING_MODE_NORMAL;
    int fps = 30;
    SAMPLE_COMM_ISP_Init(s32CamId, hdr_mode, bMultictx, iq_file_dir);
    SAMPLE_COMM_ISP_Run(s32CamId);
    SAMPLE_COMM_ISP_SetFrameRate(s32CamId, fps);
#endif
  }
//RK_MPI_SYS_Init 
  RK_MPI_SYS_Init(); // init
//设置media视频流
  char cmd[256];
  snprintf(
      cmd, sizeof(cmd),
      "media-ctl -d %s -l '\"rkispp_input_image\":0->\"rkispp-subdev\":0[1]'",
      media);
  system(cmd);
  snprintf(cmd, sizeof(cmd),
           "media-ctl -d %s --set-v4l2 "
           "'\"rkispp-subdev\":0[fmt:YUYV8_2X8/1920x1080]'",
           media);
  system(cmd);
  snprintf(cmd, sizeof(cmd),
           "media-ctl -d %s --set-v4l2 "
           "'\"rkispp-subdev\":2[fmt:YUYV8_2X8/1920x1080]'",
           media);
  system(cmd);

//配置rkmedia vi 节点初始化。(输出的四个节点初始化要在vp之前)
  VI_CHN_ATTR_S vi_chn_attr;
  vi_chn_attr.pcVideoNode = "rkispp_scale0";
  vi_chn_attr.u32BufCnt = 3;
  vi_chn_attr.u32Width = video_width;
  vi_chn_attr.u32Height = video_height;
  vi_chn_attr.enPixFmt = IMAGE_TYPE_NV12;
  vi_chn_attr.enWorkMode = VI_WORK_MODE_NORMAL;
  ret = RK_MPI_VI_SetChnAttr(s32CamId, 0, &vi_chn_attr);
  ret |= RK_MPI_VI_EnableChn(s32CamId, 0);
  if (ret) {
    printf("Create vi[0] failed! ret=%d\n", ret);
    return -1;
  }

  memset(&vi_chn_attr, 0, sizeof(vi_chn_attr));
  vi_chn_attr.pcVideoNode = video_output1;
  vi_chn_attr.u32BufCnt = 3;
  vi_chn_attr.u32Width = video1_width;
  vi_chn_attr.u32Height = video1_height;
  vi_chn_attr.enPixFmt = IMAGE_TYPE_NV12;
  vi_chn_attr.enWorkMode = VI_WORK_MODE_NORMAL;
  ret = RK_MPI_VI_SetChnAttr(1, 1, &vi_chn_attr);
  ret |= RK_MPI_VI_EnableChn(1, 1);
  if (ret) {
    printf("Create vi[1] failed! ret=%d\n", ret);
    return -1;
  }

  memset(&vi_chn_attr, 0, sizeof(vi_chn_attr));
  vi_chn_attr.pcVideoNode = video_output2;
  vi_chn_attr.u32BufCnt = 3;
  vi_chn_attr.u32Width = video2_width;
  vi_chn_attr.u32Height = video2_height;
  vi_chn_attr.enPixFmt = IMAGE_TYPE_NV12;
  vi_chn_attr.enWorkMode = VI_WORK_MODE_NORMAL;
  ret = RK_MPI_VI_SetChnAttr(2, 2, &vi_chn_attr);
  ret |= RK_MPI_VI_EnableChn(2, 2);
  if (ret) {
    printf("Create vi[2] failed! ret=%d\n", ret);
    return -1;
  }

  memset(&vi_chn_attr, 0, sizeof(vi_chn_attr));
  vi_chn_attr.pcVideoNode = video_output3;
  vi_chn_attr.u32BufCnt = 3;
  vi_chn_attr.u32Width = video3_width;
  vi_chn_attr.u32Height = video3_height;
  vi_chn_attr.enPixFmt = IMAGE_TYPE_NV12;
  vi_chn_attr.enWorkMode = VI_WORK_MODE_NORMAL;
  ret = RK_MPI_VI_SetChnAttr(3, 3, &vi_chn_attr);
  ret |= RK_MPI_VI_EnableChn(3, 3);
  if (ret) {
    printf("Create vi[3] failed! ret=%d\n", ret);
    return -1;
  }

  memset(&vi_chn_attr, 0, sizeof(vi_chn_attr));
  vi_chn_attr.pcVideoNode = video_output4;
  vi_chn_attr.u32BufCnt = 3;
  vi_chn_attr.u32Width = video4_width;
  vi_chn_attr.u32Height = video4_height;
  vi_chn_attr.enPixFmt = IMAGE_TYPE_NV12;
  vi_chn_attr.enWorkMode = VI_WORK_MODE_NORMAL;
  ret = RK_MPI_VI_SetChnAttr(4, 4, &vi_chn_attr);
  ret |= RK_MPI_VI_EnableChn(4, 4);
  if (ret) {
    printf("Create vi[4] failed! ret=%d\n", ret);
    return -1;
  }

//接着初始化vp,实际上就是初始化media中rkispp_input_image 节点video25

  VP_CHN_ATTR_S vp_chn_attr;
  vp_chn_attr.pcVideoNode = video_input;
  vp_chn_attr.u32BufCnt = 3;
  vp_chn_attr.u32Width = video_width;
  vp_chn_attr.u32Height = video_height;
  vp_chn_attr.enPixFmt = IMAGE_TYPE_NV12;
  vp_chn_attr.enWorkMode = VP_WORK_MODE_NORMAL;
  ret = RK_MPI_VP_SetChnAttr(0, 0, &vp_chn_attr);
  ret |= RK_MPI_VP_EnableChn(0, 0);
  if (ret) {
    printf("Create vp[0] failed! ret=%d\n", ret);
    return -1;
  }

//最后就是将video0 绑定到video25, 这样video26、video27就可以像正常的video节点取流、绑定
  MPP_CHN_S Vi_SrcChn = {0};
  MPP_CHN_S Vp_DestChn = {0};

  printf("#Bind VI[0] to VP[0]....\n");
  Vi_SrcChn.enModId = RK_ID_VI;
  Vi_SrcChn.s32ChnId = 0;
  Vp_DestChn.enModId = RK_ID_VP;
  Vp_DestChn.s32ChnId = 0;
  ret = RK_MPI_SYS_Bind(&Vi_SrcChn, &Vp_DestChn);
  if (ret) {
    printf("Bind vi[0] to vp[0] failed! ret=%d\n", ret);
    return -1;
  }


//创建venc通道
  //venc 1
  VENC_CHN_ATTR_S venc_chn_attr;
  memset(&venc_chn_attr, 0, sizeof(venc_chn_attr));
    venc_chn_attr.stVencAttr.enType = RK_CODEC_TYPE_H264;
    venc_chn_attr.stRcAttr.enRcMode = VENC_RC_MODE_H264CBR;
    venc_chn_attr.stRcAttr.stH264Cbr.u32Gop = 30;
    venc_chn_attr.stRcAttr.stH264Cbr.u32BitRate = video1_venc_width * video1_venc_height;
    // frame rate: in 30/1, out 30/1.
    venc_chn_attr.stRcAttr.stH264Cbr.fr32DstFrameRateDen = 1;
    venc_chn_attr.stRcAttr.stH264Cbr.fr32DstFrameRateNum = 30;
    venc_chn_attr.stRcAttr.stH264Cbr.u32SrcFrameRateDen = 1;
    venc_chn_attr.stRcAttr.stH264Cbr.u32SrcFrameRateNum = 30;

  venc_chn_attr.stVencAttr.imageType = IMAGE_TYPE_NV12;
  venc_chn_attr.stVencAttr.u32PicWidth = video1_venc_width;
  venc_chn_attr.stVencAttr.u32PicHeight = video1_venc_height;
  venc_chn_attr.stVencAttr.u32VirWidth = video1_venc_width;
  venc_chn_attr.stVencAttr.u32VirHeight = video1_venc_height;
  venc_chn_attr.stVencAttr.u32Profile = 77;
  ret = RK_MPI_VENC_CreateChn(1, &venc_chn_attr);
  if (ret) {
    printf("ERROR: create VENC[1] error! ret=%d\n", ret);
    return 0;
  }

  //venc 2
  memset(&venc_chn_attr, 0, sizeof(venc_chn_attr));
    venc_chn_attr.stVencAttr.enType = RK_CODEC_TYPE_H264;
    venc_chn_attr.stRcAttr.enRcMode = VENC_RC_MODE_H264CBR;
    venc_chn_attr.stRcAttr.stH264Cbr.u32Gop = 30;
    venc_chn_attr.stRcAttr.stH264Cbr.u32BitRate = video2_venc_width * video2_venc_height;
    // frame rate: in 30/1, out 30/1.
    venc_chn_attr.stRcAttr.stH264Cbr.fr32DstFrameRateDen = 1;
    venc_chn_attr.stRcAttr.stH264Cbr.fr32DstFrameRateNum = 30;
    venc_chn_attr.stRcAttr.stH264Cbr.u32SrcFrameRateDen = 1;
    venc_chn_attr.stRcAttr.stH264Cbr.u32SrcFrameRateNum = 30;

  venc_chn_attr.stVencAttr.imageType = IMAGE_TYPE_NV12;
  venc_chn_attr.stVencAttr.u32PicWidth = video2_venc_width;
  venc_chn_attr.stVencAttr.u32PicHeight = video2_venc_height;
  venc_chn_attr.stVencAttr.u32VirWidth = video2_venc_width;
  venc_chn_attr.stVencAttr.u32VirHeight = video2_venc_height;
  venc_chn_attr.stVencAttr.u32Profile = 77;
  ret = RK_MPI_VENC_CreateChn(2, &venc_chn_attr);
  if (ret) {
    printf("ERROR: create VENC[2] error! ret=%d\n", ret);
    return 0;
  }

  //venc 3
  memset(&venc_chn_attr, 0, sizeof(venc_chn_attr));
    venc_chn_attr.stVencAttr.enType = RK_CODEC_TYPE_H264;
    venc_chn_attr.stRcAttr.enRcMode = VENC_RC_MODE_H264CBR;
    venc_chn_attr.stRcAttr.stH264Cbr.u32Gop = 30;
    venc_chn_attr.stRcAttr.stH264Cbr.u32BitRate = video3_venc_width * video3_venc_height;
    // frame rate: in 30/1, out 30/1.
    venc_chn_attr.stRcAttr.stH264Cbr.fr32DstFrameRateDen = 1;
    venc_chn_attr.stRcAttr.stH264Cbr.fr32DstFrameRateNum = 30;
    venc_chn_attr.stRcAttr.stH264Cbr.u32SrcFrameRateDen = 1;
    venc_chn_attr.stRcAttr.stH264Cbr.u32SrcFrameRateNum = 30;

  venc_chn_attr.stVencAttr.imageType = IMAGE_TYPE_NV12;
  venc_chn_attr.stVencAttr.u32PicWidth = video3_venc_width;
  venc_chn_attr.stVencAttr.u32PicHeight = video3_venc_height;
  venc_chn_attr.stVencAttr.u32VirWidth = video3_venc_width;
  venc_chn_attr.stVencAttr.u32VirHeight = video3_venc_height;
  venc_chn_attr.stVencAttr.u32Profile = 77;
  ret = RK_MPI_VENC_CreateChn(3, &venc_chn_attr);
  if (ret) {
    printf("ERROR: create VENC[3] error! ret=%d\n", ret);
    return 0;
  }

  //venc 4
  memset(&venc_chn_attr, 0, sizeof(venc_chn_attr));
    venc_chn_attr.stVencAttr.enType = RK_CODEC_TYPE_H264;
    venc_chn_attr.stRcAttr.enRcMode = VENC_RC_MODE_H264CBR;
    venc_chn_attr.stRcAttr.stH264Cbr.u32Gop = 30;
    venc_chn_attr.stRcAttr.stH264Cbr.u32BitRate = video4_venc_width * video4_venc_height;
    // frame rate: in 30/1, out 30/1.
    venc_chn_attr.stRcAttr.stH264Cbr.fr32DstFrameRateDen = 1;
    venc_chn_attr.stRcAttr.stH264Cbr.fr32DstFrameRateNum = 30;
    venc_chn_attr.stRcAttr.stH264Cbr.u32SrcFrameRateDen = 1;
    venc_chn_attr.stRcAttr.stH264Cbr.u32SrcFrameRateNum = 30;

  venc_chn_attr.stVencAttr.imageType = IMAGE_TYPE_NV12;
  venc_chn_attr.stVencAttr.u32PicWidth = video4_venc_width;
  venc_chn_attr.stVencAttr.u32PicHeight = video4_venc_height;
  venc_chn_attr.stVencAttr.u32VirWidth = video4_venc_width;
  venc_chn_attr.stVencAttr.u32VirHeight = video4_venc_height;
  venc_chn_attr.stVencAttr.u32Profile = 77;
  ret = RK_MPI_VENC_CreateChn(4, &venc_chn_attr);
  if (ret) {
    printf("ERROR: create VENC[4] error! ret=%d\n", ret);
    return 0;
  }





//绑定vi venc通道
  MPP_CHN_S video1_rtspSrcChn;
  video1_rtspSrcChn.enModId = RK_ID_VI;
  video1_rtspSrcChn.s32ChnId = 1;
  MPP_CHN_S video1_rtspDestChn;
  video1_rtspDestChn.enModId = RK_ID_VENC;
  video1_rtspDestChn.s32ChnId = 1;
  ret = RK_MPI_SYS_Bind(&video1_rtspSrcChn, &video1_rtspDestChn);
  if (ret) {
    printf("ERROR: Bind VI[%d] and VENC[%d] error! ret=%d\n",video1_rtspSrcChn.s32ChnId,video1_rtspDestChn.s32ChnId,ret);
    return 0;
  }

  MPP_CHN_S video2_rtspSrcChn;
  video2_rtspSrcChn.enModId = RK_ID_VI;
  video2_rtspSrcChn.s32ChnId = 2;
  MPP_CHN_S video2_rtspDestChn;
  video2_rtspDestChn.enModId = RK_ID_VENC;
  video2_rtspDestChn.s32ChnId = 2;
  ret = RK_MPI_SYS_Bind(&video2_rtspSrcChn, &video2_rtspDestChn);
  if (ret) {
    printf("ERROR: Bind VI[%d] and VENC[%d] error! ret=%d\n",video2_rtspSrcChn.s32ChnId,video2_rtspDestChn.s32ChnId,ret);
    return 0;
  }

    MPP_CHN_S video3_rtspSrcChn;
  video3_rtspSrcChn.enModId = RK_ID_VI;
  video3_rtspSrcChn.s32ChnId = 3;
  MPP_CHN_S video3_rtspDestChn;
  video3_rtspDestChn.enModId = RK_ID_VENC;
  video3_rtspDestChn.s32ChnId = 3;
  ret = RK_MPI_SYS_Bind(&video3_rtspSrcChn, &video3_rtspDestChn);
  if (ret) {
    printf("ERROR: Bind VI[%d] and VENC[%d] error! ret=%d\n",video3_rtspSrcChn.s32ChnId,video3_rtspDestChn.s32ChnId,ret);
    return 0;
  }

    MPP_CHN_S video4_rtspSrcChn;
  video4_rtspSrcChn.enModId = RK_ID_VI;
  video4_rtspSrcChn.s32ChnId = 4;
  MPP_CHN_S video4_rtspDestChn;
  video4_rtspDestChn.enModId = RK_ID_VENC;
  video4_rtspDestChn.s32ChnId = 4;
  ret = RK_MPI_SYS_Bind(&video4_rtspSrcChn, &video4_rtspDestChn);
  if (ret) {
    printf("ERROR: Bind VI[%d] and VENC[%d] error! ret=%d\n",video4_rtspSrcChn.s32ChnId,video4_rtspDestChn.s32ChnId,ret);
    return 0;
  }


//---------------start pthread----------------------
  pthread_t th1,th2, th3 ,th4;
  int chn = 1;
  pthread_create(&th1, NULL, Video1GetVencBuffer, (void *)chn);
  usleep(1000); // wait for th1 ready.
  ret = RK_MPI_VI_StartStream(1, 1);
  if (ret) {
    printf("Start VI[1] failed! ret=%d\n", ret);
    return -1;
  }

  chn = 2;
  pthread_create(&th2, NULL, Video2GetVencBuffer, (void *)chn);
  usleep(1000); // wait for th1 ready.
  ret = RK_MPI_VI_StartStream(2, 2);
  if (ret) {
    printf("Start VI[2] failed! ret=%d\n", ret);
    return -1;
  }
  chn = 3;
  pthread_create(&th3, NULL, Video3GetVencBuffer, (void *)chn);
  ret = RK_MPI_VI_StartStream(3, 3);
  if (ret) {
    printf("Start VI[3] failed! ret=%d\n", ret);
    return -1;
  }
  chn = 4;
  pthread_create(&th4, NULL, Video4GetVencBuffer, (void *)chn);
  ret = RK_MPI_VI_StartStream(4, 4);
  if (ret) {
    printf("Start VI[4] failed! ret=%d\n", ret);
    return -1;
  }


//=========================================

  printf("%s initial finish\n", __func__);
  signal(SIGINT, sigterm_handler);
  while (!quit) {
    usleep(500000);
  }

  printf("%s exit!\n", __func__);
  // pthread_join(th1, NULL);
  // pthread_join(th2, NULL);
  // pthread_join(th3, NULL);
  // pthread_join(th4, NULL);


// unbind vi venc
  ret = RK_MPI_SYS_UnBind(&video1_rtspSrcChn, &video1_rtspDestChn);
  if (ret) {
    printf("ERROR: UNBind VI[1] and VENC[1] error! ret=%d\n",ret);
    return 0;
  }
  ret = RK_MPI_SYS_UnBind(&video2_rtspSrcChn, &video2_rtspDestChn);
  if (ret) {
    printf("ERROR: UNBind VI[2] and VENC[2] error! ret=%d\n",ret);
    return 0;
  }
  ret = RK_MPI_SYS_UnBind(&video3_rtspSrcChn, &video3_rtspDestChn);
  if (ret) {
    printf("ERROR: UNBind VI[3] and VENC[3] error! ret=%d\n",ret);
    return 0;
  }
  ret = RK_MPI_SYS_UnBind(&video4_rtspSrcChn, &video4_rtspDestChn);
  if (ret) {
    printf("ERROR: UNBind VI[4] and VENC[4] error! ret=%d\n",ret);
    return 0;
  }

// destroy venc before vi
  ret = RK_MPI_VENC_DestroyChn(4);
  if (ret) {
    printf("ERROR: Destroy VENC[4] error! ret=%d\n", ret);
    return 0;
  }
  ret = RK_MPI_VENC_DestroyChn(3);
  if (ret) {
    printf("ERROR: Destroy VENC[3] error! ret=%d\n", ret);
    return 0;
  }
  ret = RK_MPI_VENC_DestroyChn(2);
  if (ret) {
    printf("ERROR: Destroy VENC[2] error! ret=%d\n", ret);
    return 0;
  }
  ret = RK_MPI_VENC_DestroyChn(1);
  if (ret) {
    printf("ERROR: Destroy VENC[1] error! ret=%d\n", ret);
    return 0;
  }
// destroy vp before vi  

  Vi_SrcChn.enModId = RK_ID_VI;
  Vi_SrcChn.s32ChnId = 0;
  Vp_DestChn.enModId = RK_ID_VP;
  Vp_DestChn.s32ChnId = 0;
  ret = RK_MPI_SYS_UnBind(&Vi_SrcChn, &Vp_DestChn);
  if (ret) {
    printf("UnBind vi[0] to vp[0] failed! ret=%d\n", ret);
    return -1;
  }
// destroy  vi chn 

  RK_MPI_VI_DisableChn(2, 2);
  RK_MPI_VI_DisableChn(3, 3);
  RK_MPI_VI_DisableChn(4, 4);
  RK_MPI_VI_DisableChn(5, 5);


  RK_MPI_VP_DisableChn(0, 0);
  RK_MPI_VI_DisableChn(s32CamId, 0);

  if (iq_file_dir) {
#ifdef RKAIQ
    SAMPLE_COMM_ISP_Stop(s32CamId);
#endif
  }
  return 0;
}

你可能感兴趣的:(学习,笔记,网络,音视频)