瑞芯微关于RKMEDIA框架的RKNN例子解析(二)

接上回,接下来就到了大家关心的RKNN部分的操作啦,接下来看代码。

  create_rknn_list(&rknn_list_);

  // Get the sub-stream buffer for humanoid recognition
  pthread_t read_thread;
  pthread_create(&read_thread, NULL, GetMediaBuffer, NULL); //RKNN主线程
static void *GetMediaBuffer(void *arg) {
  printf("#Start %s thread, arg:%p\n", __func__, arg);

  rknn_context ctx;
  int ret;
  int model_len = 0;
  unsigned char *model;

  printf("Loading model ...\n");
  model = load_model(g_ssd_path, &model_len);
  ret = rknn_init(&ctx, model, model_len, 0);
  if (ret < 0) {
    printf("rknn_init fail! ret=%d\n", ret);
    return NULL;
  }

  // Get Model Input Output Info
  rknn_input_output_num io_num;
  ret = rknn_query(ctx, RKNN_QUERY_IN_OUT_NUM, &io_num, sizeof(io_num));
  if (ret != RKNN_SUCC) {
    printf("rknn_query fail! ret=%d\n", ret);
    return NULL;
  }
  printf("model input num: %d, output num: %d\n", io_num.n_input,
         io_num.n_output);

  printf("input tensors:\n");
  rknn_tensor_attr input_attrs[io_num.n_input];
  memset(input_attrs, 0, sizeof(input_attrs));
  for (unsigned int i = 0; i < io_num.n_input; i++) {
    input_attrs[i].index = i;
    ret = rknn_query(ctx, RKNN_QUERY_INPUT_ATTR, &(input_attrs[i]),
                     sizeof(rknn_tensor_attr));
    if (ret != RKNN_SUCC) {
      printf("rknn_query fail! ret=%d\n", ret);
      return NULL;
    }
    printRKNNTensor(&(input_attrs[i]));
  }

  printf("output tensors:\n");
  rknn_tensor_attr output_attrs[io_num.n_output];
  memset(output_attrs, 0, sizeof(output_attrs));
  for (unsigned int i = 0; i < io_num.n_output; i++) {
    output_attrs[i].index = i;
    ret = rknn_query(ctx, RKNN_QUERY_OUTPUT_ATTR, &(output_attrs[i]),
                     sizeof(rknn_tensor_attr));
    if (ret != RKNN_SUCC) {
      printf("rknn_query fail! ret=%d\n", ret);
      return NULL;
    }
    printRKNNTensor(&(output_attrs[i]));
  }

  MEDIA_BUFFER buffer = NULL;
  while (g_flag_run) {
    buffer = RK_MPI_SYS_GetMediaBuffer(RK_ID_VI, RK_NN_INDEX, -1);
    if (!buffer) {
      continue;
    }
    // printf("Get Frame:ptr:%p, fd:%d, size:%zu, mode:%d, channel:%d, "
    //        "timestamp:%lld\n",
    //        RK_MPI_MB_GetPtr(buffer), RK_MPI_MB_GetFD(buffer),
    //        RK_MPI_MB_GetSize(buffer),
    //        RK_MPI_MB_GetModeID(buffer), RK_MPI_MB_GetChannelID(buffer),
    //        RK_MPI_MB_GetTimestamp(buffer));

    // nv12 to rgb24 and resize
    int rga_buffer_size = cfg.session_cfg[RK_NN_INDEX].u32Width *
                          cfg.session_cfg[RK_NN_INDEX].u32Height *
                          3; // nv12 3/2, rgb 3
    int rga_buffer_model_input_size = MODEL_INPUT_SIZE * MODEL_INPUT_SIZE * 3;
    unsigned char *rga_buffer = malloc(rga_buffer_size);
    unsigned char *rga_buffer_model_input = malloc(rga_buffer_model_input_size);

    nv12_to_rgb24(RK_MPI_MB_GetPtr(buffer), rga_buffer,
                  cfg.session_cfg[RK_NN_INDEX].u32Width,
                  cfg.session_cfg[RK_NN_INDEX].u32Height);

    rgb24_resize(rga_buffer, rga_buffer_model_input,
                 cfg.session_cfg[RK_NN_INDEX].u32Width,
                 cfg.session_cfg[RK_NN_INDEX].u32Height, MODEL_INPUT_SIZE,
                 MODEL_INPUT_SIZE);

    // Set Input Data
    rknn_input inputs[1];
    memset(inputs, 0, sizeof(inputs));
    inputs[0].index = 0;
    inputs[0].type = RKNN_TENSOR_UINT8;
    inputs[0].size = rga_buffer_model_input_size;
    inputs[0].fmt = RKNN_TENSOR_NHWC;
    inputs[0].buf = rga_buffer_model_input;

    ret = rknn_inputs_set(ctx, io_num.n_input, inputs);
    if (ret < 0) {
      printf("rknn_input_set fail! ret=%d\n", ret);
      return NULL;
    }

    // Run
    printf("rknn_run\n");
    ret = rknn_run(ctx, NULL);
    if (ret < 0) {
      printf("rknn_run fail! ret=%d\n", ret);
      return NULL;
    }

    // Get Output
    rknn_output outputs[2];
    memset(outputs, 0, sizeof(outputs));
    outputs[0].want_float = 1;
    outputs[1].want_float = 1;
    ret = rknn_outputs_get(ctx, io_num.n_output, outputs, NULL);
    if (ret < 0) {
      printf("rknn_outputs_get fail! ret=%d\n", ret);
      return NULL;
    }

    // Post Process
    detect_result_group_t detect_result_group;
    postProcessSSD((float *)(outputs[0].buf), (float *)(outputs[1].buf),
                   MODEL_INPUT_SIZE, MODEL_INPUT_SIZE, &detect_result_group);
    // Release rknn_outputs
    rknn_outputs_release(ctx, 2, outputs);

    // Dump Objects
    // for (int i = 0; i < detect_result_group.count; i++) {
    //   detect_result_t *det_result = &(detect_result_group.results[i]);
    //   printf("%s @ (%d %d %d %d) %f\n", det_result->name,
    //   det_result->box.left,
    //          det_result->box.top, det_result->box.right,
    //          det_result->box.bottom,
    //          det_result->prop);
    // }

    if (detect_result_group.count > 0) {
      rknn_list_push(rknn_list_, getCurrentTimeMsec(), detect_result_group);
      int size = rknn_list_size(rknn_list_);
      if (size >= MAX_RKNN_LIST_NUM)
        rknn_list_drop(rknn_list_);
      // printf("size is %d\n", size);
    }

    RK_MPI_MB_ReleaseBuffer(buffer);
    if (rga_buffer)
      free(rga_buffer);
    if (rga_buffer_model_input)
      free(rga_buffer_model_input);
  }
  // release
  if (ctx)
    rknn_destroy(ctx);
  if (model)
    free(model);

  return NULL;
}

这部分代码我就不写注释了,大家先看英文注释吧,我在这理一下这部分做了什么。

总的来说,就是模型加载后一直循环,取VI的帧数据,这边有点不解,为啥在RGA有能力处理颜色转换的情况下要用软件处理?我想过内存拷贝速度的问题,但是应该软件和硬件处理没啥速度上的区别,有大佬清楚原因不? 

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值