6145
- 收藏
- 点赞
- 分享
- 举报
海思MMZ剩余内存,利用起来,怎么会cpu占用高呢
本帖最后由 ngswfx 于 2018-2-3 03:40 编辑
做解码,实际现场使用,情况多变,有1分割需求,有16分割需求,还有更大的,现有MMZ的分配体系,会导致某些时候MMZ大量剩余,但是操作系统内存不够,很难做到自适应。例如极端的几种情况就是,最大1画面分割,解码1路1080P。这个时候,海思底层MMZ部分内存极大浪费,当分割数逐渐增大,例如对于3536片子,如果是4分割,要支持4个4K,或者到了16路1080P,还想支持16路500万非实时,MMZ内存将会超级紧张,因为为了满足VPSS以及解码显示视频帧需要,MMZ使用了大量内存。当3536到了64分割,情况又来了个大反转,由于全部都是D1图像,MMZ出现极大剩余,但此时操作系统的情况和前面1分割和16分割就完全不一样了,因为操作系统APP层面,为了得到或者解析出逐帧的264 265数据,通常需要缓冲的协助,这个时候即便分配64路500K缓冲,都32M内存占用了,为此1-4-16-64各个分割情况下,内存使用紧张在MMZ层面以及操作系统APP层面之间来回转换,要么时操作系统紧张,要么是MMZ紧张。
前几天我想把海思的MMZ内存充分利用起来,因为MMZ一旦分配,内存就固定了,当系统内存不足时(例如64M系统使用),有的情况下MMZ还很多,我就通过海思的MMZ分配给程序直接使用,来代替比较大的内存需求,例如视频流缓冲块,整个流程下来,也都正常,而且数据也都不大,也就是16个300K-500K左右的缓冲,算下来也就10M左右,只不过是在操作系统环境下使用的,对于整个内存体系而言,10M不算什么,但对于系统环境而言,总共才64M或者96M或者128M,突然多了10M其实很可观了,使用频率大概每秒16×25×2次,16路视频数据写入读取,都已经定版了,开卖了,结果突然发现CPU居高不下,分析了好多原因,最后发现是这么使用不行,只要使用操作系统正常new出来的就没事,mmz搞出来的就不行。
我当时想法就是通过探测操作系统剩余内存,以及MMZ剩余内存,大概10-30秒探测一次,并根据当前系统分割数量,综合考虑,动态使用操作系统部分的内存还是临时借用MMZ内存。
/////////////////////以下是部分实现代码,实际流程已经完毕,解码以及各个部分基本正常,就是cpu高,最后发现就是这里出现问题,只要不是用这种机制,3520D cpu 整体占用通常在10%以内,一旦使用,很可能超过40%。系统很卡。最后没有办法,把3536这些也都临时暂停不是用这种机制了。
通过定义如下接口,代替应用程序APP里面比较大的buffer=new char[300*1024];
int IVHI_MmzAlloc(HI_U32 *pu32PhyAddr, void **ppVitAddr, const HI_CHAR *pstrMmb, const HI_CHAR *pstrZone, HI_U32 u32Len)
{
if(HI_SUCCESS==HI_MPI_SYS_MmzAlloc(pu32PhyAddr, ppVitAddr, pstrMmb,pstrZone,u32Len))
return true;
else return false;
}
int IVHI_MmzFree(HI_U32 u32PhyAddr, HI_VOID *pVirtAddr)
{
if(HI_SUCCESS==HI_MPI_SYS_MmzFree(u32PhyAddr, pVirtAddr))
return true;
else
return false;
}
简单删除内存实现替换:
#ifdef SUPPORT_USE_MMZ_MEM_RTSP
if(_MmzFreeCallBack_RTSPEx&&bUseMMZ_265Nal){
_MmzFreeCallBack_RTSPEx((unsigned int )pu32PhyAddr_265Nal,(void *)(m_pNaluBuf));
m_pNaluBuf=NULL;
pu32PhyAddr_265Nal=0;
bUseMMZ_265Nal=false;
}else{
delete [] m_pNaluBuf;
m_pNaluBuf=NULL;
bUseMMZ_265Nal=false;
}
#else
delete [] m_pNaluBuf;
#endif
创建内存实现替换: 注意底下的_MmzAllocCallBack_RTSPEx其实就是HI_MPI_SYS_MmzAlloc,只不过函数接口通过回调赋值而已
if(0 == m_uNaluBufSize)
m_uNaluBufSize = 256*1024;
else
m_uNaluBufSize *= 2;
char * pTemp = m_pNaluBuf;
unsigned int old_pu32PhyAddr_265Nal=pu32PhyAddr_265Nal;
bool old_bUseMMZ_265Nal=bUseMMZ_265Nal;
#ifdef SUPPORT_USE_MMZ_MEM_RTSP
bUseMMZ_265Nal=false;
if(_MmzAllocCallBack_RTSPEx&&bCanUseMMZ_Memory_RTSP){
char pstrMmb[32];
memset(pstrMmb,0,sizeof pstrMmb);
sprintf(pstrMmb,"RTSP_265Nal");
if( _MmzAllocCallBack_RTSPEx((unsigned int *)&(pu32PhyAddr_265Nal),(void **)&(m_pNaluBuf),(const char *)pstrMmb,NULL,m_uNaluBufSize))
bUseMMZ_265Nal=true;
}
//如果MMZ没有分配成功
if(!bUseMMZ_265Nal&&!m_pNaluBuf){
m_pNaluBuf=new char[m_uNaluBufSize];
}
#else
m_pNaluBuf = new char[m_uNaluBufSize];
#endif
////////一旦分配完毕,使用内存的时候,都是针对m_pNaluBuf进行memcpy这类常规操作包括考入或者考出。突然想起来,有一个地方好像忽略了使用频次,在进行单帧解析时,好像是对这个内存进行了逐字节处理的。但想不通这个和普通new出来的内存有啥区别。
//////////////大家谁这么用过,有过经验或者想法的,可以讨论一下。当然3798M没这个问题,因为都是抢总内存用。
做解码,实际现场使用,情况多变,有1分割需求,有16分割需求,还有更大的,现有MMZ的分配体系,会导致某些时候MMZ大量剩余,但是操作系统内存不够,很难做到自适应。例如极端的几种情况就是,最大1画面分割,解码1路1080P。这个时候,海思底层MMZ部分内存极大浪费,当分割数逐渐增大,例如对于3536片子,如果是4分割,要支持4个4K,或者到了16路1080P,还想支持16路500万非实时,MMZ内存将会超级紧张,因为为了满足VPSS以及解码显示视频帧需要,MMZ使用了大量内存。当3536到了64分割,情况又来了个大反转,由于全部都是D1图像,MMZ出现极大剩余,但此时操作系统的情况和前面1分割和16分割就完全不一样了,因为操作系统APP层面,为了得到或者解析出逐帧的264 265数据,通常需要缓冲的协助,这个时候即便分配64路500K缓冲,都32M内存占用了,为此1-4-16-64各个分割情况下,内存使用紧张在MMZ层面以及操作系统APP层面之间来回转换,要么时操作系统紧张,要么是MMZ紧张。
前几天我想把海思的MMZ内存充分利用起来,因为MMZ一旦分配,内存就固定了,当系统内存不足时(例如64M系统使用),有的情况下MMZ还很多,我就通过海思的MMZ分配给程序直接使用,来代替比较大的内存需求,例如视频流缓冲块,整个流程下来,也都正常,而且数据也都不大,也就是16个300K-500K左右的缓冲,算下来也就10M左右,只不过是在操作系统环境下使用的,对于整个内存体系而言,10M不算什么,但对于系统环境而言,总共才64M或者96M或者128M,突然多了10M其实很可观了,使用频率大概每秒16×25×2次,16路视频数据写入读取,都已经定版了,开卖了,结果突然发现CPU居高不下,分析了好多原因,最后发现是这么使用不行,只要使用操作系统正常new出来的就没事,mmz搞出来的就不行。
我当时想法就是通过探测操作系统剩余内存,以及MMZ剩余内存,大概10-30秒探测一次,并根据当前系统分割数量,综合考虑,动态使用操作系统部分的内存还是临时借用MMZ内存。
/////////////////////以下是部分实现代码,实际流程已经完毕,解码以及各个部分基本正常,就是cpu高,最后发现就是这里出现问题,只要不是用这种机制,3520D cpu 整体占用通常在10%以内,一旦使用,很可能超过40%。系统很卡。最后没有办法,把3536这些也都临时暂停不是用这种机制了。
通过定义如下接口,代替应用程序APP里面比较大的buffer=new char[300*1024];
int IVHI_MmzAlloc(HI_U32 *pu32PhyAddr, void **ppVitAddr, const HI_CHAR *pstrMmb, const HI_CHAR *pstrZone, HI_U32 u32Len)
{
if(HI_SUCCESS==HI_MPI_SYS_MmzAlloc(pu32PhyAddr, ppVitAddr, pstrMmb,pstrZone,u32Len))
return true;
else return false;
}
int IVHI_MmzFree(HI_U32 u32PhyAddr, HI_VOID *pVirtAddr)
{
if(HI_SUCCESS==HI_MPI_SYS_MmzFree(u32PhyAddr, pVirtAddr))
return true;
else
return false;
}
简单删除内存实现替换:
#ifdef SUPPORT_USE_MMZ_MEM_RTSP
if(_MmzFreeCallBack_RTSPEx&&bUseMMZ_265Nal){
_MmzFreeCallBack_RTSPEx((unsigned int )pu32PhyAddr_265Nal,(void *)(m_pNaluBuf));
m_pNaluBuf=NULL;
pu32PhyAddr_265Nal=0;
bUseMMZ_265Nal=false;
}else{
delete [] m_pNaluBuf;
m_pNaluBuf=NULL;
bUseMMZ_265Nal=false;
}
#else
delete [] m_pNaluBuf;
#endif
创建内存实现替换: 注意底下的_MmzAllocCallBack_RTSPEx其实就是HI_MPI_SYS_MmzAlloc,只不过函数接口通过回调赋值而已
if(0 == m_uNaluBufSize)
m_uNaluBufSize = 256*1024;
else
m_uNaluBufSize *= 2;
char * pTemp = m_pNaluBuf;
unsigned int old_pu32PhyAddr_265Nal=pu32PhyAddr_265Nal;
bool old_bUseMMZ_265Nal=bUseMMZ_265Nal;
#ifdef SUPPORT_USE_MMZ_MEM_RTSP
bUseMMZ_265Nal=false;
if(_MmzAllocCallBack_RTSPEx&&bCanUseMMZ_Memory_RTSP){
char pstrMmb[32];
memset(pstrMmb,0,sizeof pstrMmb);
sprintf(pstrMmb,"RTSP_265Nal");
if( _MmzAllocCallBack_RTSPEx((unsigned int *)&(pu32PhyAddr_265Nal),(void **)&(m_pNaluBuf),(const char *)pstrMmb,NULL,m_uNaluBufSize))
bUseMMZ_265Nal=true;
}
//如果MMZ没有分配成功
if(!bUseMMZ_265Nal&&!m_pNaluBuf){
m_pNaluBuf=new char[m_uNaluBufSize];
}
#else
m_pNaluBuf = new char[m_uNaluBufSize];
#endif
////////一旦分配完毕,使用内存的时候,都是针对m_pNaluBuf进行memcpy这类常规操作包括考入或者考出。突然想起来,有一个地方好像忽略了使用频次,在进行单帧解析时,好像是对这个内存进行了逐字节处理的。但想不通这个和普通new出来的内存有啥区别。
//////////////大家谁这么用过,有过经验或者想法的,可以讨论一下。当然3798M没这个问题,因为都是抢总内存用。
我来回答
回答4个
时间排序
认可量排序
认可0
认可0
认可0
认可0
或将文件直接拖到这里
悬赏:
E币
网盘
* 网盘链接:
* 提取码:
悬赏:
E币
Markdown 语法
- 加粗**内容**
- 斜体*内容*
- 删除线~~内容~~
- 引用> 引用内容
- 代码`代码`
- 代码块```编程语言↵代码```
- 链接[链接标题](url)
- 无序列表- 内容
- 有序列表1. 内容
- 缩进内容
- 图片![alt](url)
相关问答
-
2020-02-29 18:29:17
-
2024-01-16 12:27:31
-
2017-11-28 11:46:30
-
2014-08-28 09:27:05
-
2020-11-18 17:41:06
-
2020-11-11 15:15:02
-
2018-08-26 10:26:28
-
2020-12-24 15:43:00
-
2020-12-02 08:29:27
-
2020-09-29 10:56:52
-
2022-07-28 10:45:51
-
42020-05-14 09:15:37
-
2020-10-30 11:02:35
-
2018-01-31 15:49:58
-
2024-10-29 09:10:26
-
132015-08-06 17:33:01
-
2016-08-02 11:00:41
-
2016-08-02 17:38:22
-
2019-12-06 18:44:32
无更多相似问答 去提问
点击登录
-- 积分
-- E币
提问
—
收益
—
被采纳
—
我要提问
切换马甲
上一页
下一页
悬赏问答
-
5Hi3516CV610 如何使用SD卡升级固件
-
5cat /dev/logmpp 报错 <3>[ vi] [func]:vi_send_frame_node [line]:99 [info]:vi pic queue is full!
-
50如何获取vpss chn的图像修改后发送至vo
-
5FPGA通过Bt1120传YUV422数据过来,vi接收不到数据——3516dv500
-
50SS928 运行PQtools 拼接 推到设备里有一半画面会异常
-
53536AV100的sample_vdec输出到CVBS显示
-
10海思板子mpp怎么在vi阶段改变视频数据尺寸
-
10HI3559AV100 多摄像头同步模式
-
9海思ss928单路摄像头vio中加入opencv处理并显示
-
10EB-RV1126-BC-191板子运行自己编码的程序
举报反馈
举报类型
- 内容涉黄/赌/毒
- 内容侵权/抄袭
- 政治相关
- 涉嫌广告
- 侮辱谩骂
- 其他
详细说明
提醒
你的问题还没有最佳答案,是否结题,结题后将扣除20%的悬赏金
取消
确认
提醒
你的问题还没有最佳答案,是否结题,结题后将根据回答情况扣除相应悬赏金(1回答=1E币)
取消
确认