Hi3519DV500 上如何在 VPSS Grp0 的多个 Chn 同时创建 Mosaic:排坑指南
Hi3519DV500 上如何在 VPSS Grp0 的多个 Chn 同时创建 Mosaic:排坑指南
关键词:海思、Hi3519DV500、VPSS、RGN、Mosaic、参数超出合法范围(0xa0038007)
一、背景与需求
在视频监控、智慧安防等场景中,我们常常需要在主码流(高分辨率)和子码流(较低分辨率)上对指定区域进行马赛克处理(又称“打码”)。马赛克处理在海思平台上通常是通过 RGN(Region) 模块实现的——也就是创建一个 Mosaic 类型的 RGN,然后将其叠加到对应的通道上。
常见的应用场景包括:
人脸打码:出于隐私保护,在公共视频中将人物面部进行马赛克。
敏感区域打码:在监控画面中遮挡一些不适宜的区域。
可配置场景打码:动态给用户指定的区域进行马赛克处理等。
然而,在实际开发时,我们很容易遇到一个典型问题:在 VPSS Grp0 下,如果要在 Chn0、Chn1 上分别叠加 Mosaic,ss_mpi_rgn_attach_to_chn 可能会返回 0xa0038007(参数超出合法范围),主码流可以成功显示马赛克,但给子码流或其他通道绑定时却失败。本文就针对这个问题做一次系统的排查和解决思路分享。
二、问题重现
- 环境描述
平台:Hi3519DV500(海思)
工程配置:
VI pipe0 chn0 -> VPSS grp0 chn0(主码流)
VI pipe0 chn0 -> VPSS grp0 chn1(子码流)
VI pipe0 chn0 -> VPSS grp0 chn2(JPEG) 需求描述
希望在 主子码流(VPSS Grp0 的 Chn0 和 Chn1)甚至 Chn2(JPEG)上都呈现相同或相似的 Mosaic 效果。根据海思文档,Mosaic 类型的 RGN 只支持在 VPSS 上叠加,所以我们就为同一个 VPSS grp0 下的三个 Chn,都各自创建并 attach 一个 Mosaic 的 region。代码片段示例
(简化示意)int ret; int maxWidth, maxHeight; int px, py, pw, ph; ot_rgn_handle rgnHd; mpp_rgn_t *rgn; gsf_vmask_t *vmask = (gsf_vmask_t *) param; // rgn mosaic do not support venc, but support vpss // vi pipe0 chn0 -> vpss grp0 chn0 for main stream // vi pipe0 chn0 -> vpss grp0 chn1 for sub stream // vi pipe0 chn0 -> vpss grp0 chn2 for jpeg for (int c = 0; c < VPSS_CHN_NUM; c++) { rgnHd = RGN_VMASK_START_INDEX + c * MAX_IPC_VMASK_NUM + vmask->idx; rgn = &s_context.vmask[c][vmask->idx]; rgn->hd = rgnHd; maxWidth = s_context.vpss_cfg.chn_attr[c].width; maxHeight = s_context.vpss_cfg.chn_attr[c].height; rgn->stRegion.type = OT_RGN_MOSAIC; ret = ss_mpi_rgn_create(rgn->hd, &rgn->stRegion); if (ret != TD_SUCCESS) { sample_print("ss_mpi_rgn_create(%d) failed %#x\n", rgn->hd, ret); return ret; } rgn->stChn.mod_id = OT_ID_VPSS; rgn->stChn.dev_id = 0; rgn->stChn.chn_id = c; pw = vmask->rect[2] * maxWidth; ph = vmask->rect[3] * maxHeight; pw = pw >= maxWidth ? maxWidth : pw; ph = ph >= maxHeight ? maxHeight : ph; pw = ALIGN_UP(pw, 4); ph = ALIGN_UP(ph, 2); px = vmask->rect[0] * maxWidth; py = vmask->rect[1] * maxHeight; px = px + pw >= maxWidth ? maxWidth - pw - 5 : px; py = py + ph >= maxHeight ? maxHeight - ph - 5 : py; px = px < 0 ? 5 : px; py = py < 0 ? 5 : py; px = ALIGN_UP(px, 4); py = ALIGN_UP(py, 2); rgn->stChnAttr.is_show = vmask->enable; rgn->stChnAttr.type = OT_RGN_MOSAIC; rgn->stChnAttr.attr.mosaic_chn.rect.x = px; rgn->stChnAttr.attr.mosaic_chn.rect.y = py; rgn->stChnAttr.attr.mosaic_chn.rect.width = pw; rgn->stChnAttr.attr.mosaic_chn.rect.height = ph; rgn->stChnAttr.attr.mosaic_chn.blk_size = OT_MOSAIC_BLK_SIZE_64; rgn->stChnAttr.attr.mosaic_chn.layer = 0; // -1610383348 = a0038007 = 参数超出合法范围 ret = ss_mpi_rgn_attach_to_chn(rgn->hd, &rgn->stChn, &rgn->stChnAttr); if (ret != TD_SUCCESS) { sample_print("ss_mpi_rgn_attach_to_chn(%d) failed with %#x\n", rgn->hd, ret); return ret; } ret = ss_mpi_rgn_set_chn_display_attr(rgn->hd, &rgn->stChn, &rgn->stChnAttr); if (ret != TD_SUCCESS) { sample_print("ss_mpi_rgn_set_chn_display_attr failed with %#x\n", ret); return ret; } } return ret;
当我们先在 c=0(主码流)时,一切都能成功执行,但到 c=1(子码流)时,ss_mpi_rgn_attach_to_chn 却报错 0xa0038007。
三、常见原因分析
海思 SDK 中,如果出现 0xa0038007,其含义通常是参数超出合法范围。结合 Mosaic 这一类型,最常见的原因包括:
坐标或尺寸越界
在子码流中,如果我们直接使用与主码流相同的相对位置和大小,可能会导致 px + pw 或 py + ph 超出子码流的分辨率范围。
此时,内部检查到坐标越界,就会抛出参数不合法的错误。
对齐(Alignment)不符合要求
不同的海思版本,对 Mosaic 类型的 rect.x / rect.y / rect.width / rect.height 有不同的对齐要求。
当使用 OT_MOSAIC_BLK_SIZE_64 时,通常要求 X/Y/Width/Height 要按照 16 或 64 对齐(视官方文档及 SDK 要求而定)。简单的对 4 或 2 进行对齐,可能不够。
如果马赛克区域未满足必须的对齐边界,也会出现参数非法报错。
blk_size 设置不匹配
OT_MOSAIC_BLK_SIZE_64 代表单个马赛克小块是 64×64 像素。
如果你的子码流分辨率很小,或需要高精度打码,就要根据实际需求将 blk_size 调整为 16 或 32 等更合适的大小,否则很可能因为宽高太小不符合最小块要求,导致 attach 失败。
重复创建 RGN 或 Handle 重复使用
如果在子码流上使用了与主码流相同的 RGN handle(没有重新申请),则也会出现冲突。
在示例代码中,你已经按照不同 c 值(通道号)去计算 RGN_VMASK_START_INDEX + c * MAX_IPC_VMASK_NUM + vmask->idx,所以该问题大概率已经规避了。但依旧要确保 handle 不重复被复用。
四、排查和解决思路
- 检查子码流的分辨率和马赛克区域大小
打印调试信息:输出 px, py, pw, ph 在子码流时的实际数值,确认它们没有超出 [0, width/height] 的范围。
对齐策略:如果 SDK 要求 Mosaic 的 width 和 height 必须是 16 或 64 的倍数,那么你的对齐操作需要从 ALIGN_UP(… , 4) 改成 ALIGN_UP(… , 16) 或者 ALIGN_UP(… , 64)。
边界处理:如果做完对齐后发现又超出分辨率,需要重新缩放或减小区域,避免越界。 - 自行计算缩放后的打码区域
如果你希望“主码流和子码流打码区域在视觉上是同一位置”,而不是同一像素坐标,就需要根据主码流与子码流的分辨率比做比例缩放。
举个例子:主码流是 1920×1080,子码流是 640×360。若主码流的打码区域是 (x=100, y=50, w=200, h=100),要保持相对画面位置相同,那么子码流就应该在 (x=100(640/1920), y=50(360/1080), …) 做相应缩放。 - 测试不同的 OT_MOSAIC_BLK_SIZE_X 值
试着将 OT_MOSAIC_BLK_SIZE_64 调成 OT_MOSAIC_BLK_SIZE_16 或 OT_MOSAIC_BLK_SIZE_32,看看能否通过 attach。
一些情况下,如果你的子码流特别小,blk_size 太大时就会导致越界或无法满足 SDK 要求的最小块数目、对齐规则等。 只 attach 子码流看是否正常
可以先注释掉主码流部分的创建和 attach,只给子码流 attach Mosaic,看是否仍然报错。
如果单独给子码流 attach 成功,说明 handle 重复或者区域坐标之间有冲突。
如果单独子码流依旧失败,则更能确定问题在于它本身的坐标/对齐/blk_size 等细节。五、示例代码优化与小技巧
假设我们要让主码流(1920×1080)和子码流(640×360)都打相似位置的马赛克,使用 blk_size=16。伪代码示例如下:
for (int c = 0; c < 2; c++) // 只演示主码流和子码流 { int ch_width = (c == 0) ? 1920 : 640; int ch_height = (c == 0) ? 1080 : 360; // 创建 RGN handle ot_rgn_handle rgn_handle = RGN_VMASK_START_INDEX + c * MAX_IPC_VMASK_NUM + vmask->idx; // Mosaic 区域参数 int px = (int)(vmask->rect[0] * ch_width); int py = (int)(vmask->rect[1] * ch_height); int pw = (int)(vmask->rect[2] * ch_width); int ph = (int)(vmask->rect[3] * ch_height); // 保证对齐 px = ALIGN_UP(px, 16); py = ALIGN_UP(py, 16); pw = ALIGN_UP(pw, 16); ph = ALIGN_UP(ph, 16); // 边界处理:如果越界就缩小 if (px + pw > ch_width) pw = ALIGN_DOWN(ch_width - px, 16); if (py + ph > ch_height) ph = ALIGN_DOWN(ch_height - py, 16); // 后面就是 ss_mpi_rgn_create, attach, set_display 等 // ... }
这样就可以避免因对齐、越界而导致的报错。当然,具体对齐要求要根据海思官方手册或 SDK 提示来做最终确认。
六、总结
在 Hi3519DV500 平台上,为 VPSS Grp0 下的多个通道(chn0、chn1、chn2)同时创建 Mosaic RGN 并不复杂,但也隐藏了一些细节坑点。最常见的问题就是参数越界和对齐不符合要求。只要我们在计算 Mosaic 区域时,认真对待子码流和主码流之间的分辨率差异、马赛克块大小的对齐要求,并做好越界保护,就能顺利实现多通道 Mosaic 功能。
排查思路:先单独测试单通道,确认区域参数,使用恰当的对齐方式;
打码缩放:若要多通道保持“相同视觉区域”,需根据分辨率比进行缩放;
blk_size 调整:根据画面大小和马赛克颗粒度需求,选合适的块大小;
精细调试:多打印调试信息,查看实际算出来的 px、py、pw、ph,对齐和边界是否符合硬件限制。
希望本文的分享能帮助你快速排查 Mosaic 创建和 attach 到子码流(chn1、chn2)失败的问题,让你的海思方案更稳定地支持多路马赛克叠加。祝开发顺利!
如果你在实际开发中碰到了更复杂的情况,例如多路 VI 输入、多级 VPSS 转发、或是需要对接 AI 分析模块,请根据海思 SDK 文档和你自己的应用需求,灵活扩展思路。
- 分享
- 举报
-
浏览量:3522次2023-03-17 10:21:08
-
浏览量:3431次2023-07-12 10:54:09
-
浏览量:2553次2023-11-09 16:39:11
-
浏览量:882次2024-11-13 14:14:36
-
浏览量:3996次2023-11-10 17:05:37
-
浏览量:2985次2023-07-12 17:02:05
-
浏览量:3050次2023-07-13 15:07:51
-
浏览量:2817次2023-03-17 10:25:53
-
浏览量:2974次2023-03-17 18:38:40
-
浏览量:2669次2023-03-17 10:04:01
-
浏览量:3157次2023-03-17 09:53:59
-
浏览量:4963次2023-03-20 14:01:27
-
浏览量:1626次2023-03-20 14:39:03
-
2023-07-22 13:41:13
-
2023-07-21 09:13:37
-
2023-10-10 12:37:57
-
2024-01-11 15:44:19
-
浏览量:2692次2023-03-17 10:12:15
-
浏览量:5536次2023-03-06 19:47:18
-
广告/SPAM
-
恶意灌水
-
违规内容
-
文不对题
-
重复发帖
%
感谢您的打赏,如若您也想被打赏,可前往 发表专栏 哦~
举报类型
- 内容涉黄/赌/毒
- 内容侵权/抄袭
- 政治相关
- 涉嫌广告
- 侮辱谩骂
- 其他
详细说明