rkmedia 中的行人检测

RKMedia 是瑞芯微提供的媒体处理方案,可支持应用软件快速开发。rkmedia为 C 接口,其实现均在easymedia中。后者提供 C++ 接口。
rkmedia中的行人检测示例,执行的操作为:

  • 配置两个 RTSP 会话,初始化媒体处理平台;
  • GetMediaBuffer 线程获取缓存并调用 rockx 进行检测跟踪;
  • MainStream 线程绘制结果。

rkmedia_vi_person_detect_venc_rtsp_test.c

Created with Raphaël 2.2.0 main argv load_cfg create_rtsp_demo RK_MPI_SYS_Init SAMPLE_COMMON_VI_Start SAMPLE_COMMON_VENC_Start RK_MPI_VI_StartStream RK_MPI_SYS_Bind rtsp_set_video rtsp_get_reltime rtsp_get_ntptime rtsp_sync_video_ts create_rknn_list GetMediaBuffer MainStream sig_proc RK_MPI_SYS_GetMediaBuffer rtsp_tx_video RK_MPI_MB_ReleaseBuffer rtsp_do_event RK_MPI_SYS_UnBind RK_MPI_VI_DisableChn RK_MPI_VENC_DestroyChn rtsp_del_demo destory_rknn_list End

通过命令行传入配置文件。
load_cfg 加载 RTSP 会话配置。

  if (argc != 2) {
   
    printf("You must input the file of cfg.\n");
    printf("example file: oem/usr/share/rtsp-nn.cfg.\n");
    return -1;
  }
  load_cfg(argv[1]);

create_rtsp_demo 初始化 rtsp。
RK_MPI_SYS_Init 初始化各种类型的通道数组。

  // init rtsp
  printf("init rtsp\n");
  g_rtsplive = create_rtsp_demo(554);

  // init mpi
  printf("init mpi\n");
  RK_MPI_SYS_Init();

逐一创建会话,绑定输入通道。
其中第二个通道设置为VI_WORK_MODE_GOD_MODE用于 RKNN 处理。
SAMPLE_COMMON_VI_Start 设置通道属性并启动。
SAMPLE_COMMON_VENC_Start 启动视频流编码,海思中对应函数为SAMPLE_COMM_VENC_Start
调用 RK_MPI_VI_StartStream 开启视频流,或者调用 RK_MPI_SYS_Bind 将数据源绑定到数据接收者。
rtsp_set_video 设置编码信息。
rtsp_get_reltime
rtsp_get_ntptime
rtsp_sync_video_ts

  // create session
  for (int i = 0; i < cfg.session_count; i++) {
   
    cfg.session_cfg[i].session =
        rtsp_new_session(g_rtsplive, cfg.session_cfg[i].path);

    // VI create
    printf("VI create\n");
    cfg.session_cfg[i].stViChn.enModId = RK_ID_VI;
    cfg.session_cfg[i].stViChn.s32ChnId = i;
    if (i == RK_NN_INDEX)
      SAMPLE_COMMON_VI_Start(&cfg.session_cfg[i], VI_WORK_MODE_GOD_MODE);
    else
      SAMPLE_COMMON_VI_Start(&cfg.session_cfg[i], VI_WORK_MODE_NORMAL);
    // VENC create
    printf("VENC create\n");
    cfg.session_cfg[i].stVenChn.enModId = RK_ID_VENC;
    cfg.session_cfg[i].stVenChn.s32ChnId = i;
    SAMPLE_COMMON_VENC_Start(&cfg.session_cfg[i]);
    if (i == DRAW_INDEX)
      RK_MPI_VI_StartStream(0, cfg.session_cfg[i].stViChn.s32ChnId);
    else
      RK_MPI_SYS_Bind(&cfg.session_cfg[i].stViChn,
                      &cfg.session_cfg[i].stVenChn);

    // rtsp video
    printf("rtsp video\n");
    switch (cfg.session_cfg[i].video_type) {
   
    case RK_CODEC_TYPE_H264:
      rtsp_set_video(cfg.session_cfg[i].session, RTSP_CODEC_ID_VIDEO_H264, NULL,
                     0);
      break;
    case RK_CODEC_TYPE_H265:
      rtsp_set_video(cfg.session_cfg[i].session, RTSP_CODEC_ID_VIDEO_H265, NULL,
                     0);
      break;
    default:
      printf("video codec not support.\n");
      break;
    }

    rtsp_sync_video_ts(cfg.session_cfg[i].session, rtsp_get_reltime(),
                       rtsp_get_ntptime());
  }

create_rknn_list 创建 rknn_list 列表。
在线程中调用 GetMediaBuffer 获取缓存并调用 rockx 进行检测跟踪。
另一线程中调用 MainStream 绘制结果。

  create_rknn_list(&rknn_list_);
  // Get the sub-stream buffer for humanoid recognition
  pthread_t read_thread;
  pthread_create(&read_thread, NULL, GetMediaBuffer, NULL);
  // The mainstream draws a box asynchronously based on the recognition result
  pthread_t main_stream_thread;
  pthread_create(&main_stream_thread, NULL, MainStream, NULL);

设置SIGINT信号的处理函数为 sig_proc。
调用 RK_MPI_SYS_GetMediaBuffer 获得 MEDIA_BUFFER。
rtsp_tx_video
RK_MPI_MB_ReleaseBuffer 释放缓存。
rtsp_do_event

  signal(SIGINT, sig_proc);
  while (g_flag_run) {
   
    for (int i = 0; i < cfg.session_count; i++) {
   
      MEDIA_BUFFER buffer;
      // send video buffer
      buffer = RK_MPI_SYS_GetMediaBuffer(
          RK_ID_VENC, cfg.session_cfg[i].stVenChn.s32ChnId, 0);
      if (buffer) {
   
        rtsp_tx_video(cfg.session_cfg[i].session, RK_MPI_MB_GetPtr(buffer),
                      RK_MPI_MB_GetSize(buffer),
                      RK_MPI_MB_GetTimestamp(buffer));
        RK_MPI_MB_ReleaseBuffer(buffer);
      }
    }
    rtsp_do_event(g_rtsplive);
  }

RK_MPI_SYS_UnBind 解除通道间的绑定。
RK_MPI_VI_DisableChn 关闭输入通道。
RK_MPI_VENC_DestroyChn 销毁编码通道。
rtsp_del_demo
destory_rknn_list

  for (int i = 0; i < cfg.session_count; i++) {
   
    if (i != DRAW_INDEX)
      RK_MPI_SYS_UnBind(&cfg.session_cfg[i].stViChn,
                        &cfg.session_cfg[i].stVenChn);
    RK_MPI_VI_DisableChn(0, cfg.session_cfg[i].stViChn.s32ChnId);
    RK_MPI_VENC_DestroyChn(cfg.session_cfg[i].stVenChn.s32ChnId);
  }
  rtsp_del_demo(g_rtsplive);
  destory_rknn_list(&rknn_list_);
  return 0;

load_cfg

cfg为全局变量,demo_cfg 类型,保存多个 Session 信息。MPP_CHN_S

  // cfgline:
  // path=%s video_type=%d width=%u height=%u
  FILE *fp &#

你可能感兴趣的:(DeepLearning,Rockchip,瑞芯微,NPU,人工智能,嵌入式)