普希金的笔

普希金的笔

0个粉丝

5

问答

0

专栏

0

资料

普希金的笔  发布于  2025-08-28 16:25:46
采纳率 0%
5个问答
360

HI3516dv500 ss_mpi_ive_csc接口错误码:0xa01d8007

这是我的代码:

static int ive_yuv420sp_to_rgb_package(uint64_t phys_y, uint64_t phys_c,
                                       int stride_y, int stride_c,
                                       int width, int height,
                                       uint8_t *out_rgb, uint64_t *out_cost_us)
{
    if (!out_rgb) return -1;
    if (width <= 0 || height <= 0) return -1;

    uint64_t t0 = prof_now_us();  /* 记录开始时间 */

    /* 目标RGB行跨度:按16字节对齐(IVE硬件要求) */
    td_u32 dst_stride = (td_u32)((width * 3 + 15) & ~15);
    td_u32 dst_size = dst_stride * (td_u32)height;  /* 目标缓冲区总大小 */

    /* 分配MMZ内存作为IVE的输出缓冲区(硬件可访问) */
    td_phys_addr_t dst_phys = 0;
    td_u8 *dst_vir = NULL;
    if (ss_mpi_sys_mmz_alloc(&dst_phys, (void**)&dst_vir, TD_NULL, TD_NULL, dst_size) != TD_SUCCESS) {
        printf("[IVE][ERR] mmz_alloc dst failed\n");
        return -2;
    }

    /* 初始化IVE输入/输出图像结构和控制参数 */
    ot_svp_src_img src_img;       /* 源图像(YUV420SP) */
    ot_svp_dst_img dst_img;       /* 目标图像(RGB打包格式) */
    ot_ive_csc_ctrl csc_ctrl;     /* 颜色空间转换控制参数 */
    memset(&src_img, 0, sizeof(src_img));
    memset(&dst_img, 0, sizeof(dst_img));
    memset(&csc_ctrl, 0, sizeof(csc_ctrl));

    /* 设置源图像类型(YUV420SP) */
#if defined(OT_SVP_IMG_TYPE_YVU_SEMIPLANAR_420)
    src_img.type = OT_SVP_IMG_TYPE_YVU_SEMIPLANAR_420;  /* SDK定义的YUV420SP类型 */
#elif defined(OT_SVP_IMG_TYPE_SP420_YVU)
    src_img.type = OT_SVP_IMG_TYPE_SP420_YVU;
#else
    src_img.type = 0;  /* 占位,需根据实际SDK修改 */
    #pragma message("IVE: src_img.type macro not found; using 0 as placeholder - please replace with SDK macro if needed.")
#endif

    src_img.width = (td_u32)width;    /* 源图像宽度 */
    src_img.height = (td_u32)height;  /* 源图像高度 */
    src_img.stride[0] = (td_u32)stride_y;  /* Y分量行跨度 */
    src_img.stride[1] = (td_u32)stride_c;  /* CbCr分量行跨度 */
    /* 设置源图像物理地址(Y和CbCr平面) */
#if defined(OT_SVP_IMG_HAS_PHYS_ADDR)
    src_img.phys_addr[0] = (td_u64)phys_y;
    src_img.phys_addr[1] = (td_u64)phys_c;
#else
    src_img.phys_addr[0] = (td_u64)phys_y;  /* 按常见字段设置,需根据SDK调整 */
    src_img.phys_addr[1] = (td_u64)phys_c;
#endif

    /* 设置目标图像类型(RGB打包格式) */
#if defined(OT_SVP_IMG_TYPE_U8C3_PACKAGE)
    dst_img.type = OT_SVP_IMG_TYPE_U8C3_PACKAGE;  /* 8位3通道打包格式(RGB) */
#elif defined(OT_SVP_IMG_TYPE_U8C3_PACK)
    dst_img.type = OT_SVP_IMG_TYPE_U8C3_PACK;
#else
    dst_img.type = 0;  /* 占位,需根据实际SDK修改 */
    #pragma message("IVE: dst_img.type macro not found; using 0 as placeholder - please replace with SDK macro if needed.")
#endif
    dst_img.width = (td_u32)width;    /* 目标图像宽度 */
    dst_img.height = (td_u32)height;  /* 目标图像高度 */
    dst_img.stride[0] = dst_stride;   /* 目标行跨度 */
    dst_img.phys_addr[0] = (td_u64)dst_phys;  /* 目标缓冲区物理地址 */

    /* 设置颜色空间转换模式(YUV420SP到RGB) */
#if defined(OT_IVE_CSC_MODE_NV21_TO_RGB)
    csc_ctrl.mode = OT_IVE_CSC_MODE_NV21_TO_RGB;  /* NV21(YUV420SP的一种)转RGB */
#elif defined(OT_IVE_CSC_MODE_SP420_TO_RGB)
    csc_ctrl.mode = OT_IVE_CSC_MODE_SP420_TO_RGB;
#elif defined(OT_IVE_CSC_MODE_YUV420SP_TO_RGB)
    csc_ctrl.mode = OT_IVE_CSC_MODE_YUV420SP_TO_RGB;
#elif defined(OT_IVE_CSC_MODE_PIC_BT601_YUV_TO_RGB)
    csc_ctrl.mode = OT_IVE_CSC_MODE_PIC_BT601_YUV_TO_RGB;  /* BT.601标准转换 */
#else
    csc_ctrl.mode = 0;  /* 占位,需根据实际SDK修改 */
    #pragma message("IVE: csc mode macro not found; csc_ctrl.mode set to 0 placeholder - please replace with SDK macro if needed.")
#endif

    /* 调用IVE颜色空间转换(阻塞模式) */
    ot_ive_handle handle = -1;
    td_s32 rc = ss_mpi_ive_csc(&handle, &src_img, &dst_img, &csc_ctrl, TD_TRUE);
    if (rc != TD_SUCCESS) {
        printf("[IVE][ERR] ss_mpi_ive_csc failed rc=0x%x\n", rc);
        ss_mpi_sys_mmz_free(dst_phys, dst_vir);  /* 释放MMZ内存 */
        return -3;
    }

    /* 查询IVE任务是否完成 */
    td_bool finish = TD_FALSE;
    rc = ss_mpi_ive_query(handle, &finish, TD_TRUE);
    if (rc != TD_SUCCESS || !finish) {
        printf("[IVE][ERR] ss_mpi_ive_query failed rc=0x%x finish=%d\n", rc, (int)finish);
        ss_mpi_sys_mmz_free(dst_phys, dst_vir);
        return -4;
    }

    /* 将MMZ中的RGB数据拷贝到用户空间缓冲区 */
    memcpy(out_rgb, dst_vir, (size_t)dst_size);

    /* 释放MMZ内存 */
    if (ss_mpi_sys_mmz_free(dst_phys, dst_vir) != TD_SUCCESS) {
        printf("[IVE][WARN] mmz_free failed\n");
    }

    /* 计算耗时并输出 */
    uint64_t t1 = prof_now_us();
    if (out_cost_us) *out_cost_us = (t1 >= t0) ? (t1 - t0) : 0;
    return 0;
}

这个错误码怎么确定具体原因是什么,解决方法是什么‘

我来回答
回答3个
时间排序
认可量排序

普希金的笔

0个粉丝

5

问答

0

专栏

0

资料

普希金的笔 2025-08-28 20:16:03
认可0

我已经将YUV的格式从NV21改为了NV12,通道0输出我所需的400万像素通道1输出1080P的yuv,但还是报这样的错误:

[MPP] Version: [HI3519DV500_MPP_V2.0.2.0 B050 Release], Build Time[Dec 20 2024, 16:23:07]

[TDE] ss_tde_open ok
[IVE] USE_IVE enabled -- will try to convert CHN0 with IVE (or use CHN1 as 1080p fallback)
<sample_comm_vi_register_sensor_lib-1375> bus_id:3
linear mode
========================================================================
vi_pipe:0,== os04a10 24Mclk 4M30fps(MIPI) 12bit linear init success! ==
========================================================================
ISP Dev 0 running !
[INFO] default vpss_cfg->chn_attr[0].pixel_format=38, [1].pixel_format=38
[INFO] forced VPSS CHN1 pixel_format -> NV12 (YUV_SEMIPLANAR_420) size=1920x1080
[VPSS PROF] started on grp=0 chn=1
[VPSS PROF] grp=0 chn=0 frame=0 got_delay=67722us (w=2688 h=1520 fmt=41)
[IVE][DEBUG] call ive csc (NV12->RGB) w=1920 h=1080 stride_y=1920 stride_c=1920
[IVE][ERR] ss_mpi_ive_csc rc=0xa01d8007
[VPSS PROF][IVE FAIL] ive rc=-3 on CHN1 after mmz copy, fallback to SW
ss_mpi_sys_bind(VPSS-VENC) failed at sample_comm_vpss_bind_venc: LINE: 732 with 0xa002800d!
start vo dhd0.
mipi intf sync = 23
press enter to exit
[VPSS PROF] grp=0 CHN0 frame=0 get=67722us map=100us conv=1403625us total=1528739us EMA_get=67722.0 EMA_map=100.0 EMA_conv=1403625.0 EMA_tot=1528739.0
[VENC PROF] chn=0 frame=0 latency=0us encode=0us EMA_latency=0.0 EMA_encode=0.0
[IVE][DEBUG] call ive csc (NV12->RGB) w=1920 h=1080 stride_y=1920 stride_c=1920
[IVE][ERR] ss_mpi_ive_csc rc=0xa01d8007
[VPSS PROF][IVE FAIL] ive rc=-3 on CHN1 after mmz copy, fallback to SW
[sample_comm_venc_get_venc_stream_proc]-2463: get venc stream time out, exit thread
[IVE][DEBUG] call ive csc (NV12->RGB) w=1920 h=1080 stride_y=1920 stride_c=1920
[IVE][ERR] ss_mpi_ive_csc rc=0xa01d8007
[VPSS PROF][IVE FAIL] ive rc=-3 on CHN1 after mmz copy, fallback to SW
[sample_comm_venc_get_venc_stream_proc]-2463: get venc stream time out, exit thread
[IVE][DEBUG] call ive csc (NV12->RGB) w=1920 h=1080 stride_y=1920 stride_c=1920
[IVE][ERR] ss_mpi_ive_csc rc=0xa01d8007
[VPSS PROF][IVE FAIL] ive rc=-3 on CHN1 after mmz copy, fallback to SW
[sample_comm_venc_get_venc_stream_proc]-2463: get venc stream time out, exit thread
[IVE][DEBUG] call ive csc (NV12->RGB) w=1920 h=1080 stride_y=1920 stride_c=1920
[IVE][ERR] ss_mpi_ive_csc rc=0xa01d8007
[VPSS PROF][IVE FAIL] ive rc=-3 on CHN1 after mmz copy, fallback to SW
^C[sample_signal_handler]-1174: catch signal 2, stop...

[sample_comm_venc_get_venc_stream_proc]-2463: get venc stream time out, exit thread
Sample VIO Exit

这是目前的代码:

#ifdef USE_IVE
static int ive_yuv420sp_to_rgb_package(uint64_t phys_y, uint64_t phys_c,
                                       int stride_y, int stride_c,
                                       int width, int height,
                                       uint8_t *out_rgb, uint64_t *out_cost_us,
                                       const uint8_t *virt_y, const uint8_t *virt_c,
                                       int pixel_fmt)
{
    if (out_rgb == NULL) {
        printf("[IVE][ERR] out_rgb NULL\n");
        return -1;
    }
    if (width <= 0 || height <= 0 || (width % 16 != 0) || (height % 2 != 0)) {
        printf("[IVE][ERR] invalid resolution %dx%d\n", width, height);
        return -1;
    }
    if (stride_y <= 0 || stride_c <= 0 || (stride_y % 16 != 0) || (stride_c % 16 != 0)) {
        printf("[IVE][ERR] stride not aligned Y:%d C:%d\n", stride_y, stride_c);
        return -1;
    }
    if (phys_y == 0 || phys_c == 0) {
        printf("[IVE][ERR] phys addr zero\n");
        return -1;
    }
    if (pixel_fmt != (int)OT_PIXEL_FORMAT_YUV_SEMIPLANAR_420) {
        printf("[IVE][ERR] expecting NV12 (YUV_SEMIPLANAR_420), got fmt=%d\n", pixel_fmt);
        return -1;
    }

    uint64_t t0 = prof_now_us();

    td_u32 dst_width = (td_u32)width;
    td_u32 dst_height = (td_u32)height;
    td_u32 dst_stride = (td_u32)((dst_width * 3 + 15) & ~15);
    td_u32 dst_size = dst_stride * dst_height;

    td_phys_addr_t dst_phys = 0;
    td_u8 *dst_vir = NULL;
    if (ss_mpi_sys_mmz_alloc(&dst_phys, (void**)&dst_vir, TD_NULL, TD_NULL, dst_size) != TD_SUCCESS) {
        printf("[IVE][ERR] mmz alloc failed size=%u\n", dst_size);
        return -2;
    }

    ot_svp_src_img src_img;
    memset(&src_img, 0, sizeof(ot_svp_src_img));
    src_img.type = OT_SVP_IMG_TYPE_YUV420SP;
    src_img.width = dst_width;
    src_img.height = dst_height;
    src_img.stride[0] = (td_u32)stride_y;
    src_img.stride[1] = (td_u32)stride_c;
    src_img.phys_addr[0] = (td_u64)phys_y;
    src_img.phys_addr[1] = (td_u64)phys_c;
    if (virt_y != NULL && virt_c != NULL) {
        src_img.virt_addr[0] = (td_u64)(uintptr_t)virt_y;
        src_img.virt_addr[1] = (td_u64)(uintptr_t)virt_c;
    }

    ot_svp_dst_img dst_img;
    memset(&dst_img, 0, sizeof(ot_svp_dst_img));
    dst_img.type = OT_SVP_IMG_TYPE_U8C3_PLANAR;
    dst_img.width = dst_width;
    dst_img.height = dst_height;
    dst_img.stride[0] = dst_stride;
    dst_img.phys_addr[0] = (td_u64)dst_phys;
    dst_img.virt_addr[0] = (td_u64)(uintptr_t)dst_vir;

    ot_ive_csc_ctrl csc_ctrl;
    memset(&csc_ctrl, 0, sizeof(ot_ive_csc_ctrl));
    csc_ctrl.mode = OT_IVE_CSC_MODE_PIC_BT601_YUV_TO_RGB;

    if (src_img.type != OT_SVP_IMG_TYPE_YUV420SP || dst_img.type != OT_SVP_IMG_TYPE_U8C3_PLANAR) {
        printf("[IVE][ERR] param mismatch src=%d dst=%d\n", src_img.type, dst_img.type);
        ss_mpi_sys_mmz_free(dst_phys, dst_vir);
        return -5;
    }

    printf("[IVE][DEBUG] call ive csc (NV12->RGB) w=%u h=%u stride_y=%u stride_c=%u\n",
           dst_width, dst_height, src_img.stride[0], src_img.stride[1]);

    ot_ive_handle ive_handle = -1;
    td_s32 rc = ss_mpi_ive_csc(&ive_handle, &src_img, &dst_img, &csc_ctrl, TD_TRUE);
    if (rc != TD_SUCCESS) {
        printf("[IVE][ERR] ss_mpi_ive_csc rc=0x%x\n", rc);
        ss_mpi_sys_mmz_free(dst_phys, dst_vir);
        return -3;
    }

    td_bool task_finish = TD_FALSE;
    rc = ss_mpi_ive_query(ive_handle, &task_finish, TD_TRUE);
    if (rc != TD_SUCCESS || !task_finish) {
        printf("[IVE][ERR] ive query fail rc=0x%x finish=%d\n", rc, (int)task_finish);
        ss_mpi_sys_mmz_free(dst_phys, dst_vir);
        return -4;
    }

    memcpy(out_rgb, dst_vir, (size_t)dst_size);

    if (ss_mpi_sys_mmz_free(dst_phys, dst_vir) != TD_SUCCESS) {
        printf("[IVE][WARN] mmz free warn phys=0x%llx\n", (unsigned long long)dst_phys);
    }

    uint64_t t1 = prof_now_us();
    if (out_cost_us != NULL) *out_cost_us = (t1 >= t0) ? (t1 - t0) : 0;
    printf("[IVE][DEBUG] ive success cost=%" PRIu64 "us out_bytes=%u\n", (t1 - t0), dst_size);
    return 0;
}
#endif /* USE_IVE */

UncleRoderick

59个粉丝

16

问答

4

专栏

20

资料

UncleRoderick 2025-08-29 08:38:25
认可2

参数要写全,比如目标的数据参数这么改,源的参数自己改下
dst_img.width = dst_width;
dst_img.height = dst_height;
dst_img.stride[0] = dst_stride;
dst_img.stride[1] = dst_stride;
dst_img.stride[2] = dst_stride;
dst_img.phys_addr[0] = (td_u64)dst_phys;
dst_img.phys_addr[1] = (td_u64)dst_phys+dst_widthdst_height;
dst_img.phys_addr[2] = (td_u64)dst_phys+dst_widthdst_height2;
dst_img.virt_addr[0] = (td_u64)(uintptr_t)dst_vir;
dst_img.virt_addr[1] = (td_u64)(uintptr_t)dst_vir+dst_widthdst_height;
dst_img.virt_addr[2] = (td_u64)(uintptr_t)dst_vir+dst_widthdst_height2;

普希金的笔
普希金的笔   回复   UncleRoderick  2025-08-29 09:27:03
1

感谢,确实是您说的这个问题,目前解决了
我把目标(dst)图像的所有平面参数填全(stride / phys_addr / virt_addr 三平面),并且把 dst mmz 分配的 size 修正为三平面大小之和

或将文件直接拖到这里
悬赏:
E币
网盘
* 网盘链接:
* 提取码:
悬赏:
E币

Markdown 语法

  • 加粗**内容**
  • 斜体*内容*
  • 删除线~~内容~~
  • 引用> 引用内容
  • 代码`代码`
  • 代码块```编程语言↵代码```
  • 链接[链接标题](url)
  • 无序列表- 内容
  • 有序列表1. 内容
  • 缩进内容
  • 图片![alt](url)
+ 添加网盘链接/附件

Markdown 语法

  • 加粗**内容**
  • 斜体*内容*
  • 删除线~~内容~~
  • 引用> 引用内容
  • 代码`代码`
  • 代码块```编程语言↵代码```
  • 链接[链接标题](url)
  • 无序列表- 内容
  • 有序列表1. 内容
  • 缩进内容
  • 图片![alt](url)
举报反馈

举报类型

  • 内容涉黄/赌/毒
  • 内容侵权/抄袭
  • 政治相关
  • 涉嫌广告
  • 侮辱谩骂
  • 其他

详细说明

易百纳技术社区