嘉楠科技
直播中

陈燕

8年用户 1168经验值
私信 关注
[问答]

使用nonai_2d的CRC功能进行图像类型转换,nonai_2d模块的要如何使用?

我希望使用nonai_2d的CRC功能进行图像类型转换,参考sample_mcm例程添加了对应的start和exit,并且做了sys_bind,也申请了vb,但是运行之后系统一直提示类似没有缓冲区的报错,请教一下nonai_2d模块的要如何使用,vb的申请有什么原则吗
重现步骤
在sample_face_detect中添加的nonai_2d的相关代码
1.include和define
#include "mpi_nonai_2d_api.h"#include "k_nonai_2d_comm.h"#define VICAP_OUTPUT_BUF_NUM        10#define NONAI_2D_BUF_NUM            10#define TOTAL_ENABLE_2D_CH_NUMS     6#define NONAI_2D_RGB_CH             4#define NONAI_2D_BIND_CH_0          0#define NONAI_2D_BIND_CH_1          1#define NONAI_2D_BIND_CH_2          22.系统的绑定解绑
int sample_unbind(void){    k_s32 ret;    k_mpp_chn vicap_mpp_chn;    k_mpp_chn nonai_2d_mpp_chn;    k_mpp_chn vo_mpp_chn;    vicap_mpp_chn.mod_id = K_ID_VI;    vicap_mpp_chn.dev_id = vicap_dev;    vicap_mpp_chn.chn_id = vicap_chn;    nonai_2d_mpp_chn.mod_id = K_ID_NONAI_2D;    nonai_2d_mpp_chn.dev_id = 0;    nonai_2d_mpp_chn.chn_id = NONAI_2D_BIND_CH_0;    vo_mpp_chn.mod_id = K_ID_VO;    vo_mpp_chn.dev_id = K_VO_DISPLAY_DEV_ID;    vo_mpp_chn.chn_id = K_VO_DISPLAY_CHN_ID1;    ret = kd_mpi_sys_unbind(&vicap_mpp_chn, &nonai_2d_mpp_chn);    CHECK_RET(ret, __func__, __LINE__);    ret = kd_mpi_sys_unbind(&vicap_mpp_chn, &vo_mpp_chn);    CHECK_RET(ret, __func__, __LINE__);    return ret;}int sample_sys_bind_init(void){    k_s32 ret = 0;    k_mpp_chn vicap_mpp_chn;    k_mpp_chn nonai_2d_mpp_chn;    k_mpp_chn vo_mpp_chn;    vicap_mpp_chn.mod_id = K_ID_VI;    vicap_mpp_chn.dev_id = vicap_dev;    vicap_mpp_chn.chn_id = vicap_chn;    nonai_2d_mpp_chn.mod_id = K_ID_NONAI_2D;    nonai_2d_mpp_chn.dev_id = 0;    nonai_2d_mpp_chn.chn_id = NONAI_2D_BIND_CH_0;    vo_mpp_chn.mod_id = K_ID_VO;    vo_mpp_chn.dev_id = K_VO_DISPLAY_DEV_ID;    vo_mpp_chn.chn_id = K_VO_DISPLAY_CHN_ID1;    ret = kd_mpi_sys_bind(&vicap_mpp_chn, &nonai_2d_mpp_chn);    CHECK_RET(ret, __func__, __LINE__);    ret = kd_mpi_sys_bind(&vicap_mpp_chn, &vo_mpp_chn);    CHECK_RET(ret, __func__, __LINE__);    return ret;}3.vb申请
int sample_vb_init(void){    k_s32 ret;    k_vb_config config;    memset(&config, 0, sizeof(config));    config.max_pool_cnt = 64;    //VB for YUV420SP output    config.comm_pool[0].blk_cnt = 4;    config.comm_pool[0].mode = VB_REMAP_MODE_NOCACHE;    config.comm_pool[0].blk_size = VICAP_ALIGN_UP((ISP_CHN0_WIDTH * ISP_CHN0_HEIGHT * 3 / 2), VICAP_ALIGN_1K);    //VB for RGB888 output    config.comm_pool[1].blk_cnt = 2;    config.comm_pool[1].mode = VB_REMAP_MODE_NOCACHE;    config.comm_pool[1].blk_size = VICAP_ALIGN_UP((ISP_CHN1_HEIGHT * ISP_CHN1_WIDTH * 3 ), VICAP_ALIGN_1K);    //VB for nonai_2d    config.comm_pool[2].blk_cnt = NONAI_2D_BUF_NUM;    config.comm_pool[2].mode = VB_REMAP_MODE_NOCACHE;    config.comm_pool[2].blk_size = VICAP_ALIGN_UP((ISP_CHN0_WIDTH * ISP_CHN0_HEIGHT * 3), 0x1000);    ret = kd_mpi_vb_set_config(&config);    if (ret) {        printf("vb_set_config failed ret:%dn", ret);        return ret;    }    k_vb_supplement_config supplement_config;    memset(&supplement_config, 0, sizeof(supplement_config));    supplement_config.supplement_config |= VB_SUPPLEMENT_JPEG_MASK;    ret = kd_mpi_vb_set_supplement_config(&supplement_config);    if (ret) {        printf("vb_set_supplement_config failed ret:%dn", ret);        return ret;    }    ret = kd_mpi_vb_init();    if (ret) {        printf("vb_init failed ret:%dn", ret);    }    return ret;}4.nonai_2d的初始化与退出
int nonai_2d_start(void){    int i, ret;    k_nonai_2d_chn_attr attr_2d;    for(i = 0; i < TOTAL_ENABLE_2D_CH_NUMS; i++)    {        attr_2d.mode = K_NONAI_2D_CALC_MODE_CSC;        if(i == NONAI_2D_RGB_CH)        {            attr_2d.dst_fmt = PIXEL_FORMAT_RGB_888_PLANAR;        }        else        {            attr_2d.dst_fmt = PIXEL_FORMAT_YUV_SEMIPLANAR_420;        }        ret = kd_mpi_nonai_2d_create_chn(i, &attr_2d);        CHECK_RET(ret, __func__, __LINE__);        ret = kd_mpi_nonai_2d_start_chn(i);        CHECK_RET(ret, __func__, __LINE__);        printf("nonai_2d_start_chn[%d] successn",i);    }    return K_SUCCESS;}int nonai_2d_exit(void){    int ret = 0;    int i;    for(i = 0; i < TOTAL_ENABLE_2D_CH_NUMS; i++)    {        kd_mpi_nonai_2d_stop_chn(i);        kd_mpi_nonai_2d_destroy_chn(i);    }    ret = kd_mpi_nonai_2d_close();    CHECK_RET(ret, __func__, __LINE__);    return K_SUCCESS;}期待结果和实际结果
一直在提示
<3>[24] [Func]:config_job [Line]:1391 [Info]:config_job>no blk, blk_size 3112960
软硬件版本信息
东山PI
错误日志
这是大核运行的log
msh /sharefs/app>./sample_face_detect.elf test.kmodelpress 'q' to exit application!!mirror mirror is 0 , sensor tpye is 52[D/lt9611] vtotal 1125 vactive 1080 htotal_sys 400<0>[6] [vi] wait stop timeout[tuning] dev: 0acq_win.width: 1920acq_win.height: 1080pipe_ctrl: 4261412857sensor_fd: 10sensor_type: 52sensor_name: gc2093_csi2database_name: gc2093-1920x1080buffer_num: 0buffer_size: 0[tuning] chn: 0out_win.width: 1920out_win.height: 1080bit_width: 0pix_format: 5buffer_num: 10buffer_size: 3110912yraw_size: 0uv_size: 0v_size: 0block_type: 1wait_time: 500chn_enable: 1VsiCamDeviceCreate hw:0-vt:0 created!kd_mpi_isp_set_output_chn_format, width(1920), height(1080), pix_format(5)kd_mpi_isp_set_output_chn_format, width(1280), height(720), pix_format(16)[dw] init, version Nov  6 2024 14:31:08nonai_2d_start_chn[0] successnonai_2d_start_chn[1] successnonai_2d_start_chn[2] successnonai_2d_start_chn[3] successnonai_2d_start_chn[4] successnonai_2d_start_chn[5] success<3>[24] [Func]:config_job [Line]:1391 [Info]:config_job>no blk, blk_size 3112960<3>[24] [Func]:config_job [Line]:1391 [Info]:config_job>no blk, blk_size 3112960<3>[24] [Func]:config_job [Line]:1391 [Info]:config_job>no blk, blk_size 3112960<3>[24] [Func]:config_job [Line]:1391 [Info]:config_job>no blk, blk_size 3112960<3>[24] [Func]:config_job [Line]:1391 [Info]:config_job>no blk, blk_size 3112960<3>[24] [Func]:config_job [Line]:1391 [Info]:config_job>no blk, blk_size 3112960<3>[24] [Func]:config_job [Line]:1391 [Info]:config_job>no blk, blk_size 3112960<3>[24] [Func]:config_job [Line]:1391 [Info]:config_job>no blk, blk_size 3112960<3>[24] [Func]:config_job [Line]:1391 [Info]:config_job>no blk, blk_size 3112960<3>[24] [Func]:config_job [Line]:1391 [Info]:config_job>no blk, blk_size 3112960<3>[24] [Func]:config_job [Line]:1391 [Info]:config_job>no blk, blk_size 3112960<3>[24] [Func]:config_job [Line]:1391 [Info]:config_job>no blk, blk_size 3112960<3>[24] [Func]:config_job [Line]:1391 [Info]:config_job>no blk, blk_size 3112960<3>[24] [Func]:config_job [Line]:1391 [Info]:config_job>no blk, blk_size 3112960<3>[24] [Func]:config_job [Line]:1391 [Info]:config_job>no blk, blk_size 3112960<3>[24] [Func]:config_job [Line]:1391 [Info]:config_job>no blk, blk_size 3112960<3>[24] [Func]:config_job [Line]:1391 [Info]:config_job>no blk, blk_size 3112960q<3>[24] [Func]:config_job [Line]:1391 [Info]:config_job>no blk, blk_size 3112960<3>[24] [Func]:config_job [Line]:1391 [Info]:config_job>no blk, blk_size 3112960<3>[24] [Func]:config_job [Line]:1391 [Info]:config_job>no blk, blk_size 3112960<3>[24] [Func]:config_job [Line]:1391 [Info]:config_job>no blk, blk_size 3112960kd_mpi_isp_stop_stream chn enable is 1kd_mpi_isp_stop_stream chn enable is 1kd_mpi_isp_stop_stream chn enable is 0release reserved vb 272513024release reserved vb 0<3>[4] [Func]:__vb_destory_pool [Line]:368 [Info]:Blk in this pool(2) occupied by someone, please release it first!<3>[4] [Func]:vb_do_exit [Line]:1592 [Info]:destory pool [2] failedfastboot_app, kd_mpi_vb_exit failed.尝试解决过程
我在没有将vi与nonai绑定的时候运行程序,是可以正常运行的,绑定之后就开始报错了
补充材料
完整的mian.cc文件如下
// #include #include #include #include #include #include #include #include "mobile_retinaface.h"#include "mpi_sys_api.h"using namespace nncase;using namespace nncase::runtime;using namespace nncase::runtime::detail;/* vicap */#include #include #include #include #include #include #include #include #include #include #include #include "k_module.h"#include "k_type.h"#include "k_vb_comm.h"#include "k_video_comm.h"#include "k_sys_comm.h"#include "mpi_vb_api.h"#include "mpi_vicap_api.h"#include "mpi_isp_api.h"#include "mpi_sys_api.h"#include "k_vo_comm.h"#include "mpi_vo_api.h"#include "vo_test_case.h"#include "mpi_vo_api.h"#include "sys/ioctl.h"#include "k_connector_comm.h"#include "mpi_connector_api.h"#include "k_autoconf_comm.h"#include "mpi_nonai_2d_api.h"#include "k_nonai_2d_comm.h"#define VICAP_OUTPUT_BUF_NUM        10#define NONAI_2D_BUF_NUM            10#define TOTAL_ENABLE_2D_CH_NUMS     6#define NONAI_2D_RGB_CH             4#define NONAI_2D_BIND_CH_0          0#define NONAI_2D_BIND_CH_1          1#define NONAI_2D_BIND_CH_2          2#define CHANNEL 3#define ISP_CHN1_HEIGHT (720)#define ISP_CHN1_WIDTH  (1280)#define ISP_CHN0_WIDTH  (1920)#define ISP_CHN0_HEIGHT (1080)#define ISP_INPUT_WIDTH (1920)#define ISP_INPUT_HEIGHT (1080)#define LCD_WIDTH       (1920)#define LCD_HEIGHT      (1080)static inline void CHECK_RET(k_s32 ret, const char *func, const int line){    if (ret)        printf("error ret %d, func %s line %dn", ret, func, line);}int sample_sys_bind_init(void);std::atomic quit(true);bool app_run = true;uint64_t perf_get_smodecycles(void){    uint64_t cnt;    __asm__ __volatile__(        "rdcycle %0" : "=r"(cnt)    );    return cnt;}k_vo_draw_frame vo_frame = (k_vo_draw_frame) {    1,    16,    16,    128,    128,    1};int vo_creat_layer_test(k_vo_layer chn_id, layer_info *info){    k_vo_video_layer_attr attr;    // check layer    if ((chn_id >= K_MAX_VO_LAYER_NUM) || ((info->func & K_VO_SCALER_ENABLE) && (chn_id != K_VO_LAYER0))            || ((info->func != 0) && (chn_id == K_VO_LAYER2)))    {        printf("input layer num failed n");        return -1 ;    }    memset(&attr, 0, sizeof(attr));    // set offset    attr.display_rect = info->offset;    // set act    attr.img_size = info->act_size;    // sget size    info->size = info->act_size.height * info->act_size.width * 3 / 2;    //set pixel format    attr.pixel_format = info->format;    if (info->format != PIXEL_FORMAT_YVU_PLANAR_420)    {        printf("input pix format failed n");        return -1;    }    // set stride    attr.stride = (info->act_size.width / 8 - 1) + ((info->act_size.height - 1) << 16);    // set function    attr.func = info->func;    // set scaler attr    attr.scaler_attr = info->attr;    // set video layer atrr    kd_mpi_vo_set_video_layer_attr(chn_id, &attr);    // enable layer    kd_mpi_vo_enable_video_layer(chn_id);    return 0;}k_s32 sample_connector_init(void){    k_u32 ret = 0;    k_s32 connector_fd;    k_connector_type connector_type = LT9611_MIPI_4LAN_1920X1080_30FPS;        k_connector_info connector_info;    memset(&connector_info, 0, sizeof(k_connector_info));    //connector get sensor info    ret = kd_mpi_get_connector_info(connector_type, &connector_info);    if (ret) {        printf("sample_vicap, the sensor type not supported!n");        return ret;    }    connector_fd = kd_mpi_connector_open(connector_info.connector_name);    if (connector_fd < 0) {        printf("%s, connector open failed.n", __func__);        return K_ERR_VO_NOTREADY;    }    // set connect power    kd_mpi_connector_power_set(connector_fd, K_TRUE);    // connector init    kd_mpi_connector_init(connector_fd, connector_info);    return 0;}static k_s32 vo_layer_vdss_bind_vo_config(void){    layer_info info;    k_vo_layer chn_id = K_VO_LAYER1;    memset(&info, 0, sizeof(info));    sample_connector_init();    info.act_size.width = LCD_WIDTH;    info.act_size.height = LCD_HEIGHT;    info.format = PIXEL_FORMAT_YVU_PLANAR_420;    info.func = K_ROTATION_0;    info.global_alptha = 0xff;    info.offset.x = 0;    info.offset.y = 0;    vo_creat_layer_test(chn_id, &info);    return 0;}static void sample_vo_fn(void *arg){    usleep(10000);    vo_layer_vdss_bind_vo_config();    sample_sys_bind_init();    return;}static void *sample_vo_thread(void *arg){    sample_vo_fn(arg);    return NULL;}k_vicap_dev vicap_dev;k_vicap_chn vicap_chn;k_vicap_dev_attr dev_attr;k_vicap_chn_attr chn_attr;k_vicap_sensor_info sensor_info;k_vicap_sensor_type sensor_type;k_video_frame_info dump_info;int sample_unbind(void){    k_s32 ret;    k_mpp_chn vicap_mpp_chn;    k_mpp_chn nonai_2d_mpp_chn;    k_mpp_chn vo_mpp_chn;    vicap_mpp_chn.mod_id = K_ID_VI;    vicap_mpp_chn.dev_id = vicap_dev;    vicap_mpp_chn.chn_id = vicap_chn;    nonai_2d_mpp_chn.mod_id = K_ID_NONAI_2D;    nonai_2d_mpp_chn.dev_id = 0;    nonai_2d_mpp_chn.chn_id = NONAI_2D_BIND_CH_0;    vo_mpp_chn.mod_id = K_ID_VO;    vo_mpp_chn.dev_id = K_VO_DISPLAY_DEV_ID;    vo_mpp_chn.chn_id = K_VO_DISPLAY_CHN_ID1;    ret = kd_mpi_sys_unbind(&vicap_mpp_chn, &nonai_2d_mpp_chn);    CHECK_RET(ret, __func__, __LINE__);    ret = kd_mpi_sys_unbind(&vicap_mpp_chn, &vo_mpp_chn);    CHECK_RET(ret, __func__, __LINE__);    return ret;}int sample_sys_bind_init(void){    k_s32 ret = 0;    k_mpp_chn vicap_mpp_chn;    k_mpp_chn nonai_2d_mpp_chn;    k_mpp_chn vo_mpp_chn;    vicap_mpp_chn.mod_id = K_ID_VI;    vicap_mpp_chn.dev_id = vicap_dev;    vicap_mpp_chn.chn_id = vicap_chn;    nonai_2d_mpp_chn.mod_id = K_ID_NONAI_2D;    nonai_2d_mpp_chn.dev_id = 0;    nonai_2d_mpp_chn.chn_id = NONAI_2D_BIND_CH_0;    vo_mpp_chn.mod_id = K_ID_VO;    vo_mpp_chn.dev_id = K_VO_DISPLAY_DEV_ID;    vo_mpp_chn.chn_id = K_VO_DISPLAY_CHN_ID1;    ret = kd_mpi_sys_bind(&vicap_mpp_chn, &nonai_2d_mpp_chn);    CHECK_RET(ret, __func__, __LINE__);    ret = kd_mpi_sys_bind(&vicap_mpp_chn, &vo_mpp_chn);    CHECK_RET(ret, __func__, __LINE__);    return ret;}int sample_vb_init(void){    k_s32 ret;    k_vb_config config;    memset(&config, 0, sizeof(config));    config.max_pool_cnt = 64;    //VB for YUV420SP output    config.comm_pool[0].blk_cnt = 4;    config.comm_pool[0].mode = VB_REMAP_MODE_NOCACHE;    config.comm_pool[0].blk_size = VICAP_ALIGN_UP((ISP_CHN0_WIDTH * ISP_CHN0_HEIGHT * 3 / 2), VICAP_ALIGN_1K);    //VB for RGB888 output    config.comm_pool[1].blk_cnt = 2;    config.comm_pool[1].mode = VB_REMAP_MODE_NOCACHE;    config.comm_pool[1].blk_size = VICAP_ALIGN_UP((ISP_CHN1_HEIGHT * ISP_CHN1_WIDTH * 3 ), VICAP_ALIGN_1K);    //VB for nonai_2d    config.comm_pool[2].blk_cnt = NONAI_2D_BUF_NUM;    config.comm_pool[2].mode = VB_REMAP_MODE_NOCACHE;    config.comm_pool[2].blk_size = VICAP_ALIGN_UP((ISP_CHN0_WIDTH * ISP_CHN0_HEIGHT * 3), 0x1000);    ret = kd_mpi_vb_set_config(&config);    if (ret) {        printf("vb_set_config failed ret:%dn", ret);        return ret;    }    k_vb_supplement_config supplement_config;    memset(&supplement_config, 0, sizeof(supplement_config));    supplement_config.supplement_config |= VB_SUPPLEMENT_JPEG_MASK;    ret = kd_mpi_vb_set_supplement_config(&supplement_config);    if (ret) {        printf("vb_set_supplement_config failed ret:%dn", ret);        return ret;    }    ret = kd_mpi_vb_init();    if (ret) {        printf("vb_init failed ret:%dn", ret);    }    return ret;}int sample_vivcap_init( void ){    k_s32 ret = 0;    // sensor_type = OV_OV5647_MIPI_CSI0_1920X1080_30FPS_10BIT_LINEAR;    sensor_type = GC2093_MIPI_CSI2_1920X1080_30FPS_10BIT_LINEAR;    vicap_dev = VICAP_DEV_ID_0;    memset(&sensor_info, 0, sizeof(k_vicap_sensor_info));    ret = kd_mpi_vicap_get_sensor_info(sensor_type, &sensor_info);    if (ret) {        printf("sample_vicap, the sensor type not supported!n");        return ret;    }    memset(&dev_attr, 0, sizeof(k_vicap_dev_attr));    dev_attr.acq_win.h_start = 0;    dev_attr.acq_win.v_start = 0;    dev_attr.acq_win.width = ISP_INPUT_WIDTH;    dev_attr.acq_win.height = ISP_INPUT_HEIGHT;    dev_attr.mode = VICAP_WORK_ONLINE_MODE;    dev_attr.pipe_ctrl.data = 0xFFFFFFFF;    dev_attr.pipe_ctrl.bits.af_enable = 0;    dev_attr.pipe_ctrl.bits.ahdr_enable = 0;    dev_attr.pipe_ctrl.bits.dnr3_enable = 0;    dev_attr.cpature_frame = 0;    memcpy(&dev_attr.sensor_info, &sensor_info, sizeof(k_vicap_sensor_info));    ret = kd_mpi_vicap_set_dev_attr(vicap_dev, dev_attr);    if (ret) {        printf("sample_vicap, kd_mpi_vicap_set_dev_attr failed.n");        return ret;    }    memset(&chn_attr, 0, sizeof(k_vicap_chn_attr));    //set chn0 output yuv420sp    // chn_attr.out_win = dev_attr.acq_win;    // chn_attr.crop_win = chn_attr.out_win;    chn_attr.out_win.h_start = 0;    chn_attr.out_win.v_start = 0;    chn_attr.out_win.width = ISP_CHN0_WIDTH;    chn_attr.out_win.height = ISP_CHN0_HEIGHT;    chn_attr.crop_win = dev_attr.acq_win;    chn_attr.scale_win = chn_attr.out_win;    chn_attr.crop_enable = K_FALSE;    chn_attr.scale_enable = K_FALSE;    // chn_attr.dw_enable = K_FALSE;    chn_attr.chn_enable = K_TRUE;    chn_attr.pix_format = PIXEL_FORMAT_YVU_PLANAR_420;    chn_attr.buffer_num = VICAP_MAX_FRAME_COUNT;//at least 3 buffers for isp    chn_attr.buffer_size = VICAP_ALIGN_UP((ISP_CHN0_WIDTH * ISP_CHN0_HEIGHT * 3 / 2), VICAP_ALIGN_1K);;    vicap_chn = VICAP_CHN_ID_0;    // printf("sample_vicap ...kd_mpi_vicap_set_chn_attr, buffer_size[%d]n", chn_attr.buffer_size);    ret = kd_mpi_vicap_set_chn_attr(vicap_dev, vicap_chn, chn_attr);    if (ret) {        printf("sample_vicap, kd_mpi_vicap_set_chn_attr failed.n");        return ret;    }    //set chn1 output rgb888p    chn_attr.out_win.h_start = 0;    chn_attr.out_win.v_start = 0;    chn_attr.out_win.width = ISP_CHN1_WIDTH ;    chn_attr.out_win.height = ISP_CHN1_HEIGHT;    chn_attr.crop_win = dev_attr.acq_win;    chn_attr.scale_win = chn_attr.out_win;    chn_attr.crop_enable = K_FALSE;    chn_attr.scale_enable = K_FALSE;    // chn_attr.dw_enable = K_FALSE;    chn_attr.chn_enable = K_TRUE;    chn_attr.pix_format = PIXEL_FORMAT_BGR_888_PLANAR;    chn_attr.buffer_num = VICAP_MAX_FRAME_COUNT;//at least 3 buffers for isp    chn_attr.buffer_size = VICAP_ALIGN_UP((ISP_CHN1_HEIGHT * ISP_CHN1_WIDTH * 3 ), VICAP_ALIGN_1K);    // printf("sample_vicap ...kd_mpi_vicap_set_chn_attr, buffer_size[%d]n", chn_attr.buffer_size);    ret = kd_mpi_vicap_set_chn_attr(vicap_dev, VICAP_CHN_ID_1, chn_attr);    if (ret) {        printf("sample_vicap, kd_mpi_vicap_set_chn_attr failed.n");        return ret;    }    // set to header file database parse mode    ret = kd_mpi_vicap_set_database_parse_mode(vicap_dev, VICAP_DATABASE_PARSE_XML_JSON);    if (ret) {        printf("sample_vicap, kd_mpi_vicap_set_database_parse_mode failed.n");        return ret;    }    // printf("sample_vicap ...kd_mpi_vicap_initn");    ret = kd_mpi_vicap_init(vicap_dev);    if (ret) {        printf("sample_vicap, kd_mpi_vicap_init failed.n");        return ret;    }    ret = kd_mpi_vicap_start_stream(vicap_dev);    if (ret) {        printf("sample_vicap, kd_mpi_vicap_start_stream failed.n");        return ret;    }    return ret;}int nonai_2d_start(void){    int i, ret;    k_nonai_2d_chn_attr attr_2d;    for(i = 0; i < TOTAL_ENABLE_2D_CH_NUMS; i++)    {        attr_2d.mode = K_NONAI_2D_CALC_MODE_CSC;        if(i == NONAI_2D_RGB_CH)        {            attr_2d.dst_fmt = PIXEL_FORMAT_RGB_888_PLANAR;        }        else        {            attr_2d.dst_fmt = PIXEL_FORMAT_YUV_SEMIPLANAR_420;        }        ret = kd_mpi_nonai_2d_create_chn(i, &attr_2d);        CHECK_RET(ret, __func__, __LINE__);        ret = kd_mpi_nonai_2d_start_chn(i);        CHECK_RET(ret, __func__, __LINE__);        printf("nonai_2d_start_chn[%d] successn",i);    }    return K_SUCCESS;}int nonai_2d_exit(void){    int ret = 0;    int i;    for(i = 0; i < TOTAL_ENABLE_2D_CH_NUMS; i++)    {        kd_mpi_nonai_2d_stop_chn(i);        kd_mpi_nonai_2d_destroy_chn(i);    }    ret = kd_mpi_nonai_2d_close();    CHECK_RET(ret, __func__, __LINE__);    return K_SUCCESS;}static void *exit_app(void *arg){    printf("press 'q' to exit application!!n");    while(getchar() != 'q')    {        usleep(10000);    }    app_run = false;    return NULL;}int main(int argc, char *argv[]){    /*Allow one frame time for the VO to release the VB block*/    k_u32 display_ms = 1000 / 33;    int face_count = 1;    int num = 0;    int ret;    if (argc != 2)    {        std::cerr << "Usage: " << argv[0] << " " << std::endl;        return -1;    }    pthread_t vo_thread_handle;    pthread_t exit_thread_handle;    pthread_create(&exit_thread_handle, NULL, exit_app, NULL);    size_t size = CHANNEL * ISP_CHN1_HEIGHT * ISP_CHN1_WIDTH;;    MobileRetinaface model(argv[1], CHANNEL, ISP_CHN1_HEIGHT, ISP_CHN1_WIDTH);    DetectResult box_result;    std::vector boxes;    ret = sample_vb_init();    if(ret) {        goto vb_init_error;    }    pthread_create(&vo_thread_handle, NULL, sample_vo_thread, NULL);    ret = sample_vivcap_init();    pthread_join(vo_thread_handle, NULL);    if(ret) {        goto vicap_init_error;    }    nonai_2d_start();    while(app_run)    {        memset(&dump_info, 0 , sizeof(k_video_frame_info));        ret = kd_mpi_vicap_dump_frame(vicap_dev, VICAP_CHN_ID_1, VICAP_DUMP_YUV, &dump_info, 1000);        if (ret) {            quit.store(false);            printf("sample_vicap...kd_mpi_vicap_dump_frame failed.n");            break;        }        auto vbvaddr = kd_mpi_sys_mmap(dump_info.v_frame.phys_addr[0], size);        // memcpy(vaddr, (void *)vbvaddr, ISP_CHN1_HEIGHT * ISP_CHN1_WIDTH * 3);        boxes.clear();        model.run(reinterpret_cast(vbvaddr), reinterpret_cast(dump_info.v_frame.phys_addr[0]));        kd_mpi_sys_munmap(vbvaddr, size);        // get face boxes        box_result = model.get_result();        boxes = box_result.boxes;        if(boxes.size() < face_count)        {            for (size_t i = boxes.size(); i < face_count; i++)            {                vo_frame.draw_en = 0;                vo_frame.frame_num = i + 1;                kd_mpi_vo_draw_frame(&vo_frame);            }        }        for (size_t i = 0, j = 0; i < boxes.size(); i += 1)        {            // std::cout << "[" << boxes.x1 << ", " << boxes.y1 << ", " << boxes.x2 <<", " << boxes.y2 << "]" << std::endl;            vo_frame.draw_en = 1;            /* vo rotation 270 */            vo_frame.line_x_start = ((uint32_t)boxes.y1) * ISP_CHN0_HEIGHT / ISP_CHN1_HEIGHT;            vo_frame.line_y_start = 1920 - (((uint32_t)boxes.x2) * ISP_CHN0_WIDTH / ISP_CHN1_WIDTH);            vo_frame.line_x_end = ((uint32_t)boxes.y2) * ISP_CHN0_HEIGHT / ISP_CHN1_HEIGHT;            vo_frame.line_y_end = 1920 - (((uint32_t)boxes.x1) * ISP_CHN0_WIDTH / ISP_CHN1_WIDTH);            vo_frame.frame_num = ++j;            kd_mpi_vo_draw_frame(&vo_frame);        }        face_count = boxes.size();        ret = kd_mpi_vicap_dump_release(vicap_dev, VICAP_CHN_ID_1, &dump_info);        if (ret) {            printf("sample_vicap...kd_mpi_vicap_dump_release failed.n");        }    }app_exit:    pthread_join(exit_thread_handle, NULL);    for(size_t i = 0;i < boxes.size();i++)    {        vo_frame.draw_en = 0;        vo_frame.frame_num = i + 1;        kd_mpi_vo_draw_frame(&vo_frame);    }    boxes.clear();    ret = kd_mpi_vicap_stop_stream(vicap_dev);    if (ret) {        printf("sample_vicap, stop stream failed.n");    }    ret = kd_mpi_vicap_deinit(vicap_dev);    if (ret) {        printf("sample_vicap, kd_mpi_vicap_deinit failed.n");        return ret;    }vicap_init_error:    kd_mpi_vo_disable_video_layer(K_VO_LAYER1);    nonai_2d_exit();    sample_unbind();    usleep(1000 * display_ms);    ret = kd_mpi_vb_exit();    if (ret) {        printf("fastboot_app, kd_mpi_vb_exit failed.n");        return ret;    }vb_init_error:    return 0;}        请问您的代码里使用nonai_2d的目的是什么?
通过您的代码,我了解到您从sensor获取两路数据流:一路是用于VO显示的yuv420sp格式,另一路是用于AI分析的rgbp888格式。
如果您的需求是这样,不需要使用nonai_2d进行格式转换,因为sensor支持yuv420sp和rgbp888格式输出。
        nonai_2d的具体使用方法:
请仔细阅读 sample_mcm 代码,里面已经包含了 nonai_2d 的详细使用方法。
以下是 sample_mcm 代码中 nonai_2d 的具体使用思路。更详细的内容需要阅读 API 接口文档和 demo 来掌握。
1. 初始化 nonai_2d 通道

参照 nonai_2d_start 函数,内部会创建并启用 nonai_2d 通道:
kd_mpi_nonai_2d_create_chnkd_mpi_nonai_2d_start_chn2. 启动 nonai_2d 数据转换

2.1 绑定模式

如果 nonai_2d 仅用于处理 pipeline 数据流,且用户层不需要获取转换后的数据,则可以使用绑定模式。例如:

  • 在内核态实现 sensor 数据显示到 VO:vicap(yuv422) -> nonai_2d(yuv420sp) -> vo
  • 在内核态实现 sensor 数据编码:vicap(yuv422) -> nonai_2d(yuv420sp) -> venc
使用 kd_mpi_sys_bind 实现此功能。
2.2 非绑定模式

如果用户层需要获取 nonai_2d 转换后的数据流,则不能使用绑定模式。例如:

  • 在 sample_mcm 代码中,如何把 sensor 数据传输给 AI 模块,参照 nonai_2d_work 函数,NONAI_2D_RGB_CH 通道用于此功能。
  • 将 vicap(yuv422) 数据流通过 nonai_2d 转换为 rgbp888,并在用户层传输给 AI 模块使用:vicap(yuv422) -> nonai_2d(rgbp888)
  • 使用以下接口发送和获取转换后的图形数据:kd_mpi_nonai_2d_send_framekd_mpi_nonai_2d_get_frame
        您的代码问题:
int sample_sys_bind_init(void){    k_s32 ret = 0;    k_mpp_chn vicap_mpp_chn;    k_mpp_chn nonai_2d_mpp_chn;    k_mpp_chn vo_mpp_chn;    vicap_mpp_chn.mod_id = K_ID_VI;    vicap_mpp_chn.dev_id = vicap_dev;    vicap_mpp_chn.chn_id = vicap_chn;    nonai_2d_mpp_chn.mod_id = K_ID_NONAI_2D;    nonai_2d_mpp_chn.dev_id = 0;    nonai_2d_mpp_chn.chn_id = NONAI_2D_BIND_CH_0;    vo_mpp_chn.mod_id = K_ID_VO;    vo_mpp_chn.dev_id = K_VO_DISPLAY_DEV_ID;    vo_mpp_chn.chn_id = K_VO_DISPLAY_CHN_ID1;    ret = kd_mpi_sys_bind(&vicap_mpp_chn, &nonai_2d_mpp_chn);    CHECK_RET(ret, __func__, __LINE__);    ret = kd_mpi_sys_bind(&vicap_mpp_chn, &vo_mpp_chn);    CHECK_RET(ret, __func__, __LINE__);    return ret;}需修改为将nonai_2d的输出作为VO的输入,此处绑定错误。其他部分如有问题请对照demo修改。

回帖(1)

李芳

2025-3-12 17:41:25

在使用 nonai_2d 模块的 CRC 功能进行图像类型转换时,确保正确配置和使用缓冲区是非常重要的。以下是一些关键步骤和注意事项,帮助你解决可能遇到的问题。


1. 包含头文件和定义常量


你已经正确包含了 mpi_nonai_2d_api.hk_nonai_2d_comm.h 头文件,并定义了 VICAP_OUTPUT_BUF_NUMNONAI_2D_BUF_NUM 常量。确保这些定义与你的系统配置一致。


#include "mpi_nonai_2d_api.h"
#include "k_nonai_2d_comm.h"

#define VICAP_OUTPUT_BUF_NUM    10
#define NONAI_2D_BUF_NUM        10

2. 初始化和退出 nonai_2d 模块


确保你已经正确初始化和退出了 nonai_2d 模块。通常,你需要在程序的开始和结束时调用相应的函数。


// 初始化 nonai_2d 模块
k_s32 ret = kd_mpi_nonai_2d_init();
if (ret != K_SUCCESS) {
    printf("Failed to initialize nonai_2d module: %dn", ret);
    return -1;
}

// 退出 nonai_2d 模块
ret = kd_mpi_nonai_2d_exit();
if (ret != K_SUCCESS) {
    printf("Failed to exit nonai_2d module: %dn", ret);
    return -1;
}

3. 申请和绑定视频缓冲区 (VB)


申请和绑定视频缓冲区是关键步骤。你需要确保申请了足够的缓冲区,并且这些缓冲区能够被 nonai_2d 模块正确使用。


// 申请视频缓冲区
k_vb_config config;
memset(&config, 0, sizeof(config));
config.max_pool_cnt = VICAP_OUTPUT_BUF_NUM + NONAI_2D_BUF_NUM;
ret = kd_mpi_vb_set_config(&config);
if (ret != K_SUCCESS) {
    printf("Failed to set VB config: %dn", ret);
    return -1;
}

ret = kd_mpi_vb_init();
if (ret != K_SUCCESS) {
    printf("Failed to initialize VB: %dn", ret);
    return -1;
}

// 绑定视频缓冲区
k_vb_blk_attr attr;
memset(&attr, 0, sizeof(attr));
attr.size = 1920 * 1080 * 3; // 根据实际图像大小调整
ret = kd_mpi_vb_create_pool(&attr, NONAI_2D_BUF_NUM);
if (ret != K_SUCCESS) {
    printf("Failed to create VB pool: %dn", ret);
    return -1;
}

4. 配置和启动 nonai_2d 模块


在配置 nonai_2d 模块时,确保你正确设置了输入和输出缓冲区的参数。


k_nonai_2d_chn_attr attr;
memset(&attr, 0, sizeof(attr));
attr.width = 1920; // 根据实际图像宽度调整
attr.height = 1080; // 根据实际图像高度调整
attr.format = K_FMT_RGB888; // 根据实际图像格式调整

ret = kd_mpi_nonai_2d_set_chn_attr(0, &attr);
if (ret != K_SUCCESS) {
    printf("Failed to set nonai_2d channel attribute: %dn", ret);
    return -1;
}

ret = kd_mpi_nonai_2d_start(0);
if (ret != K_SUCCESS) {
    printf("Failed to start nonai_2d channel: %dn", ret);
    return -1;
}

5. 处理图像数据


nonai_2d 模块启动后,你可以通过 kd_mpi_nonai_2d_send_frame 发送图像数据,并通过 kd_mpi_nonai_2d_get_frame 获取处理后的图像数据。


k_video_frame_info frame;
memset(&frame, 0, sizeof(frame));
frame.vb_blk = kd_mpi_vb_get_block(attr.size);
if (frame.vb_blk == K_VB_INVALID_HANDLE) {
    printf("Failed to get VB blockn");
    return -1;
}

// 发送图像数据
ret = kd_mpi_nonai_2d_send_frame(0, &frame);
if (ret != K_SUCCESS) {
    printf("Failed to send frame to nonai_2d channel: %dn", ret);
    return -1;
}

// 获取处理后的图像数据
ret = kd_mpi_nonai_2d_get_frame(0, &frame);
if (ret != K_SUCCESS) {
    printf("Failed to get frame from nonai_2d channel: %dn", ret);
    return -1;
}

6. 释放资源


在程序结束时,确保释放所有申请的资源。


// 释放 VB 块
kd_mpi_vb_release_block(frame.vb_blk);

// 销毁 VB 池
kd_mpi_vb_destroy_pool(attr.pool_id);

// 退出 VB
kd_mpi_vb_exit();

7. 调试和排查错误


如果系统仍然提示没有缓冲区的错误,检查以下几点:



  • 确保申请了足够的缓冲区,并且缓冲区大小与实际图像数据匹配。

  • 确保 nonai_2d 模块的输入和输出缓冲区配置正确。

  • 检查 kd_mpi_vb_create_poolkd_mpi_vb_get_block 的返回值,确保没有错误。


通过以上步骤,你应该能够正确使用 nonai_2d 模块的 CRC 功能进行图像类型转换。如果问题仍然存在,建议查阅相关模块的文档或联系技术支持。

举报

更多回帖

×
20
完善资料,
赚取积分