Page 1 of 1

opencv+yolov5运行时 DMA 报错

Posted: 2024-03-04 8:46
by quqi
memset(&src_image, 0, sizeof(image_buffer_t));
cap >> bgr;
cv::resize(bgr, bgr, cv::Size(640,640), 0, 0, cv::INTER_LINEAR);
ret = mat_to_image_buffer(bgr, &src_image);

//RV1106 rga requires that input and output bufs are memory allocated by dma
ret = dma_buf_alloc(RV1106_CMA_HEAP_PATH, src_image.size, &rknn_app_ctx.img_dma_buf.dma_buf_fd,
(void **) & (rknn_app_ctx.img_dma_buf.dma_buf_virt_addr));
memcpy(rknn_app_ctx.img_dma_buf.dma_buf_virt_addr, src_image.virt_addr, src_image.size);
dma_sync_cpu_to_device(rknn_app_ctx.img_dma_buf.dma_buf_fd);
free(src_image.virt_addr);
src_image.virt_addr = (unsigned char *)rknn_app_ctx.img_dma_buf.dma_buf_virt_addr;

if (ret != 0)
{
printf("read image fail! ret=%d image_path=%s\n", ret, image_path);
goto out;
}

object_detect_result_list od_results;

ret = inference_yolov5_model(&rknn_app_ctx, &src_image, &od_results);
if (ret != 0)
{
printf("init_yolov5_model fail! ret=%d\n", ret);
goto out;
}

// 画框和概率
char text[256];
for (int i = 0; i < od_results.count; i++)
{
object_detect_result *det_result = &(od_results.results);
printf("%s @ (%d %d %d %d) %.3f\n", coco_cls_to_name(det_result->cls_id),
det_result->box.left, det_result->box.top,
det_result->box.right, det_result->box.bottom,
det_result->prop);
/*
int x1 = det_result->box.left;
int y1 = det_result->box.top;
int x2 = det_result->box.right;
int y2 = det_result->box.bottom;

draw_rectangle(&src_image, x1, y1, x2 - x1, y2 - y1, COLOR_BLUE, 3);

sprintf(text, "%s %.1f%%", coco_cls_to_name(det_result->cls_id), det_result->prop * 100);
draw_text(&src_image, text, x1, y1 - 20, COLOR_RED, 10);
*/
}

dma_buf_free(rknn_app_ctx.img_dma_buf.size, &rknn_app_ctx.img_dma_buf.dma_buf_fd,
rknn_app_ctx.img_dma_buf.dma_buf_virt_addr);

您好,我想循环通过opencv获取帧到MAT然后yolov5识别,但循环两次就会报错RK_DMA_HEAP_ALLOC_BUFFER failed,我查了一下好像是DMA 堆中可用的内存不足以满足请求,但我在最后应该用dma_buf_free清理了,是哪里不对吗,以上是我循环中的代码

Re: opencv+yolov5运行时 DMA 报错

Posted: 2024-03-05 2:09
by Crocodile
quqi wrote: 2024-03-04 8:46 memset(&src_image, 0, sizeof(image_buffer_t));
cap >> bgr;
cv::resize(bgr, bgr, cv::Size(640,640), 0, 0, cv::INTER_LINEAR);
ret = mat_to_image_buffer(bgr, &src_image);

//RV1106 rga requires that input and output bufs are memory allocated by dma
ret = dma_buf_alloc(RV1106_CMA_HEAP_PATH, src_image.size, &rknn_app_ctx.img_dma_buf.dma_buf_fd,
(void **) & (rknn_app_ctx.img_dma_buf.dma_buf_virt_addr));
memcpy(rknn_app_ctx.img_dma_buf.dma_buf_virt_addr, src_image.virt_addr, src_image.size);
dma_sync_cpu_to_device(rknn_app_ctx.img_dma_buf.dma_buf_fd);
free(src_image.virt_addr);
src_image.virt_addr = (unsigned char *)rknn_app_ctx.img_dma_buf.dma_buf_virt_addr;

if (ret != 0)
{
printf("read image fail! ret=%d image_path=%s\n", ret, image_path);
goto out;
}

object_detect_result_list od_results;

ret = inference_yolov5_model(&rknn_app_ctx, &src_image, &od_results);
if (ret != 0)
{
printf("init_yolov5_model fail! ret=%d\n", ret);
goto out;
}

// 画框和概率
char text[256];
for (int i = 0; i < od_results.count; i++)
{
object_detect_result *det_result = &(od_results.results);
printf("%s @ (%d %d %d %d) %.3f\n", coco_cls_to_name(det_result->cls_id),
det_result->box.left, det_result->box.top,
det_result->box.right, det_result->box.bottom,
det_result->prop);
/*
int x1 = det_result->box.left;
int y1 = det_result->box.top;
int x2 = det_result->box.right;
int y2 = det_result->box.bottom;

draw_rectangle(&src_image, x1, y1, x2 - x1, y2 - y1, COLOR_BLUE, 3);

sprintf(text, "%s %.1f%%", coco_cls_to_name(det_result->cls_id), det_result->prop * 100);
draw_text(&src_image, text, x1, y1 - 20, COLOR_RED, 10);
*/
}

dma_buf_free(rknn_app_ctx.img_dma_buf.size, &rknn_app_ctx.img_dma_buf.dma_buf_fd,
rknn_app_ctx.img_dma_buf.dma_buf_virt_addr);

您好,我想循环通过opencv获取帧到MAT然后yolov5识别,但循环两次就会报错RK_DMA_HEAP_ALLOC_BUFFER failed,我查了一下好像是DMA 堆中可用的内存不足以满足请求,但我在最后应该用dma_buf_free清理了,是哪里不对吗,以上是我循环中的代码


您好,很遗憾我没能复现您的问题,您可以尝试优化一下代码,将dma heap 内存的申请和释放放在循环外面来避免出现问题,这里是一个使用dma的yolov5识别例程
https://github.com/luckfox-eng29/luckfox_yolov5_dma
例程中使用 dma 将数据传入 rknn 模型中,对应的虚拟地址为 rknn_app_ctx.input_mems[0]->virt_addr ,您可以参考例程对您的代码进行优化。

Re: opencv+yolov5运行时 DMA 报错

Posted: 2024-03-05 7:07
by quqi
Crocodile wrote: 2024-03-05 2:09
quqi wrote: 2024-03-04 8:46 memset(&src_image, 0, sizeof(image_buffer_t));
cap >> bgr;
cv::resize(bgr, bgr, cv::Size(640,640), 0, 0, cv::INTER_LINEAR);
ret = mat_to_image_buffer(bgr, &src_image);

//RV1106 rga requires that input and output bufs are memory allocated by dma
ret = dma_buf_alloc(RV1106_CMA_HEAP_PATH, src_image.size, &rknn_app_ctx.img_dma_buf.dma_buf_fd,
(void **) & (rknn_app_ctx.img_dma_buf.dma_buf_virt_addr));
memcpy(rknn_app_ctx.img_dma_buf.dma_buf_virt_addr, src_image.virt_addr, src_image.size);
dma_sync_cpu_to_device(rknn_app_ctx.img_dma_buf.dma_buf_fd);
free(src_image.virt_addr);
src_image.virt_addr = (unsigned char *)rknn_app_ctx.img_dma_buf.dma_buf_virt_addr;

if (ret != 0)
{
printf("read image fail! ret=%d image_path=%s\n", ret, image_path);
goto out;
}

object_detect_result_list od_results;

ret = inference_yolov5_model(&rknn_app_ctx, &src_image, &od_results);
if (ret != 0)
{
printf("init_yolov5_model fail! ret=%d\n", ret);
goto out;
}

// 画框和概率
char text[256];
for (int i = 0; i < od_results.count; i++)
{
object_detect_result *det_result = &(od_results.results);
printf("%s @ (%d %d %d %d) %.3f\n", coco_cls_to_name(det_result->cls_id),
det_result->box.left, det_result->box.top,
det_result->box.right, det_result->box.bottom,
det_result->prop);
/*
int x1 = det_result->box.left;
int y1 = det_result->box.top;
int x2 = det_result->box.right;
int y2 = det_result->box.bottom;

draw_rectangle(&src_image, x1, y1, x2 - x1, y2 - y1, COLOR_BLUE, 3);

sprintf(text, "%s %.1f%%", coco_cls_to_name(det_result->cls_id), det_result->prop * 100);
draw_text(&src_image, text, x1, y1 - 20, COLOR_RED, 10);
*/
}

dma_buf_free(rknn_app_ctx.img_dma_buf.size, &rknn_app_ctx.img_dma_buf.dma_buf_fd,
rknn_app_ctx.img_dma_buf.dma_buf_virt_addr);

您好,我想循环通过opencv获取帧到MAT然后yolov5识别,但循环两次就会报错RK_DMA_HEAP_ALLOC_BUFFER failed,我查了一下好像是DMA 堆中可用的内存不足以满足请求,但我在最后应该用dma_buf_free清理了,是哪里不对吗,以上是我循环中的代码


您好,很遗憾我没能复现您的问题,您可以尝试优化一下代码,将dma heap 内存的申请和释放放在循环外面来避免出现问题,这里是一个使用dma的yolov5识别例程
https://github.com/luckfox-eng29/luckfox_yolov5_dma
例程中使用 dma 将数据传入 rknn 模型中,对应的虚拟地址为 rknn_app_ctx.input_mems[0]->virt_addr ,您可以参考例程对您的代码进行优化。

您好,根据您的代码我成功运行了,还想问一个问题,我sd卡内存是32g,但是显示只有3g是什么情况

Re: opencv+yolov5运行时 DMA 报错

Posted: 2024-03-05 8:36
by Crocodile
quqi wrote: 2024-03-05 7:07
Crocodile wrote: 2024-03-05 2:09
quqi wrote: 2024-03-04 8:46 memset(&src_image, 0, sizeof(image_buffer_t));
cap >> bgr;
cv::resize(bgr, bgr, cv::Size(640,640), 0, 0, cv::INTER_LINEAR);
ret = mat_to_image_buffer(bgr, &src_image);

//RV1106 rga requires that input and output bufs are memory allocated by dma
ret = dma_buf_alloc(RV1106_CMA_HEAP_PATH, src_image.size, &rknn_app_ctx.img_dma_buf.dma_buf_fd,
(void **) & (rknn_app_ctx.img_dma_buf.dma_buf_virt_addr));
memcpy(rknn_app_ctx.img_dma_buf.dma_buf_virt_addr, src_image.virt_addr, src_image.size);
dma_sync_cpu_to_device(rknn_app_ctx.img_dma_buf.dma_buf_fd);
free(src_image.virt_addr);
src_image.virt_addr = (unsigned char *)rknn_app_ctx.img_dma_buf.dma_buf_virt_addr;

if (ret != 0)
{
printf("read image fail! ret=%d image_path=%s\n", ret, image_path);
goto out;
}

object_detect_result_list od_results;

ret = inference_yolov5_model(&rknn_app_ctx, &src_image, &od_results);
if (ret != 0)
{
printf("init_yolov5_model fail! ret=%d\n", ret);
goto out;
}

// 画框和概率
char text[256];
for (int i = 0; i < od_results.count; i++)
{
object_detect_result *det_result = &(od_results.results);
printf("%s @ (%d %d %d %d) %.3f\n", coco_cls_to_name(det_result->cls_id),
det_result->box.left, det_result->box.top,
det_result->box.right, det_result->box.bottom,
det_result->prop);
/*
int x1 = det_result->box.left;
int y1 = det_result->box.top;
int x2 = det_result->box.right;
int y2 = det_result->box.bottom;

draw_rectangle(&src_image, x1, y1, x2 - x1, y2 - y1, COLOR_BLUE, 3);

sprintf(text, "%s %.1f%%", coco_cls_to_name(det_result->cls_id), det_result->prop * 100);
draw_text(&src_image, text, x1, y1 - 20, COLOR_RED, 10);
*/
}

dma_buf_free(rknn_app_ctx.img_dma_buf.size, &rknn_app_ctx.img_dma_buf.dma_buf_fd,
rknn_app_ctx.img_dma_buf.dma_buf_virt_addr);

您好,我想循环通过opencv获取帧到MAT然后yolov5识别,但循环两次就会报错RK_DMA_HEAP_ALLOC_BUFFER failed,我查了一下好像是DMA 堆中可用的内存不足以满足请求,但我在最后应该用dma_buf_free清理了,是哪里不对吗,以上是我循环中的代码


您好,很遗憾我没能复现您的问题,您可以尝试优化一下代码,将dma heap 内存的申请和释放放在循环外面来避免出现问题,这里是一个使用dma的yolov5识别例程
https://github.com/luckfox-eng29/luckfox_yolov5_dma
例程中使用 dma 将数据传入 rknn 模型中,对应的虚拟地址为 rknn_app_ctx.input_mems[0]->virt_addr ,您可以参考例程对您的代码进行优化。

您好,根据您的代码我成功运行了,还想问一个问题,我sd卡内存是32g,但是显示只有3g是什么情况


您好,正常情况下使用 build.sh 构建镜像时对 rootfs (根文件系统)的分区大小设置为6G,并不是完全使用所有储存空间,显示为 3g 的情况目前还没有遇到过,您可以尝试烧录官方镜像来排除 sd 卡的问题。
希望这对您有帮助,欢迎您开新的主题阐述您在镜像上遇到的问题。

Re: opencv+yolov5运行时 DMA 报错

Posted: 2024-03-06 1:15
by chenmodegaoyang
想问这样用dma的方式的话可以节省cpu的利用率是吗,但是如果还想进行处理推流那就不能用vi进行输入(因为已经用了opencv获取了输入),那能直接vpss后直接编码发送rtsp可以吗

Re: opencv+yolov5运行时 DMA 报错

Posted: 2024-03-06 2:14
by Crocodile
chenmodegaoyang wrote: 2024-03-06 1:15 想问这样用dma的方式的话可以节省cpu的利用率是吗,但是如果还想进行处理推流那就不能用vi进行输入(因为已经用了opencv获取了输入),那能直接vpss后直接编码发送rtsp可以吗
使用 dma 的方式可以节省 cpu 的利用率。

使用 VI 和 opencv-mobile 捕获都不会影响 DMA 的使用,两种那个视频捕获方式都需要将图像数据取出进行处理,都需要把数据拷贝到模型数据内存的过程。

如果用 VI 进行输入时还可以将获取图像的内存空间用 DMA 申请,优化 opencv-mobile 处理后写回 VPSS 帧数据缓冲块的过程。

Re: opencv+yolov5运行时 DMA 报错

Posted: 2024-03-06 7:36
by chenmodegaoyang
Crocodile wrote: 2024-03-06 2:14
chenmodegaoyang wrote: 2024-03-06 1:15 想问这样用dma的方式的话可以节省cpu的利用率是吗,但是如果还想进行处理推流那就不能用vi进行输入(因为已经用了opencv获取了输入),那能直接vpss后直接编码发送rtsp可以吗
使用 dma 的方式可以节省 cpu 的利用率。

使用 VI 和 opencv-mobile 捕获都不会影响 DMA 的使用,两种那个视频捕获方式都需要将图像数据取出进行处理,都需要把数据拷贝到模型数据内存的过程。

如果用 VI 进行输入时还可以将获取图像的内存空间用 DMA 申请,优化 opencv-mobile 处理后写回 VPSS 帧数据缓冲块的过程。
对于这个板子DMA的使用有相关手册吗,我在官网上貌似没有看到有关DMA使用,可以给个链接吗,可以用于存储图像帧数据的DMA方法使用

Re: opencv+yolov5运行时 DMA 报错

Posted: 2024-03-06 8:08
by Crocodile
chenmodegaoyang wrote: 2024-03-06 7:36
Crocodile wrote: 2024-03-06 2:14
chenmodegaoyang wrote: 2024-03-06 1:15 想问这样用dma的方式的话可以节省cpu的利用率是吗,但是如果还想进行处理推流那就不能用vi进行输入(因为已经用了opencv获取了输入),那能直接vpss后直接编码发送rtsp可以吗
使用 dma 的方式可以节省 cpu 的利用率。

使用 VI 和 opencv-mobile 捕获都不会影响 DMA 的使用,两种那个视频捕获方式都需要将图像数据取出进行处理,都需要把数据拷贝到模型数据内存的过程。

如果用 VI 进行输入时还可以将获取图像的内存空间用 DMA 申请,优化 opencv-mobile 处理后写回 VPSS 帧数据缓冲块的过程。
对于这个板子DMA的使用有相关手册吗,我在官网上貌似没有看到有关DMA使用,可以给个链接吗,可以用于存储图像帧数据的DMA方法使用
您好,DMA 的使用主要参考 rknn-model-zoo 中的 example 中的使用,内部主要调用 ioctl 对/dev/rk_dma_heap/rk-dma-heap-cma 进行操作,对应的软件接口源码都有公开,您可以自行查阅学习。