VGS 是视频图形子系统,全称为 Video Graphics Sub-System。支持对一幅输入图像进行处理,如进行缩放、像素格式转换、视频存储格式转换、压缩/解压、打 COVER、打 OSD、画线、旋转、动态范围转换等处理。通常都是GPU来干的,以GPU要干一下用户指定的任务时是一批任务,每次需要完成的任务量又是不固定的,比如拿GPU来给一张输入图片做旋转、裁剪、拉伸、镜像、上下翻折、贴个LOGO、盖个色块、等操作,需要用一个内存块来记录一下这些任务。
- typedef struct _dsVGS_JOB_Task_S {
- GPU_NODE_WROK_TYPE_E enOpType;
-
- DS_S32 S32OsdNum;
- DS_S32 S32DrawLineNum;
- DS_S32 S32CoverNum;
-
- VGS_SCLCOEF_MODE_E enVgsSclCoefMode;
- ROTATION_E enRotationAngle;
- VGS_ADD_COVER_S *pstVgsAddCover;
- VGS_ADD_OSD_S *pstVgsAddOsd;
- VGS_DRAW_LINE_S *pstVgsDrawLine;
-
- VGS_TASK_ATTR_S stTaskAttr;
- }VGS_JOB_Task_S;
- typedef struct _dsVGS_JOB_S {
- TSM_BOOL bValid;
- VGS_HANDLE hHandle;
-
- DS_S32 s32TaskTotalNum;//VGS_JOB_TASK_MAX_NUMBER 200,task total sum.
- DS_U8 u8TaskArrayValidNum;//pstJobTask cur use pcs
- DS_U8 u8TaskArrayTotalNum;//pstJobTask total pcs
- VGS_JOB_Task_S **pstJobTask;
- }VGS_JOB_S;
对GPU来说,每一个操作都是一个task,我们用一个vgs job task来记录,enOpType记录了当前这个task是什么类型,而Job结构体中是存放task的,每次task的数量是不一定,因此设计了一个二维指针,也就是双指针来存储。用户在申请一个job的时候,我们默认先个这个pstJobTask申请可以存储10组task的数据块,这个10组可以自定义修改的;
- pstJobNode->pstJobTask = malloc(sizeof(VGS_JOB_Task_S *) * 10);
- if(DS_NULL == pstJobNode->pstJobTask){
- VGS_PRT("pstJobTask malloc fail!\n");
- return DS_ERR_VGS_NOBUF;
- }
-
- memset(pstJobNode->pstJobTask, 0, sizeof(sizeof(VGS_JOB_Task_S *) * 10));
因为每个job task占的数量也不大,一次分配10个,多数情况下是够用的了,所以免得申请小了又要频繁去修改这个内存,牺牲一点空间换效率;当这个10个task还不够存的情况下,我们就需要修改这个内存快,可以用realloc,
- if(pstJobNode->u8TaskArrayValidNum == pstJobNode->u8TaskArrayTotalNum
- && pstJobNode->u8TaskArrayValidNum > 0){
- _VGS_PRT("task is too full!Need remalloc\n");
- pstJobNode->pstJobTask = realloc(pstJobNode->pstJobTask,
- sizeof(VGS_JOB_Task_S *)*(pstJobNode->u8TaskArrayValidNum + 5));
-
- if(TSM_NULL == pstJobNode->pstJobTask[pstJobNode->u8TaskArrayValidNum]){
- _VGS_PRT("task is too full!Need remalloc\n");
- return TSM_FALSE;
- }
-
- memset(pstJobNode->pstJobTask[pstJobNode->u8TaskArrayValidNum], 0, sizeof(sizeof(VGS_JOB_Task_S *) * 5));
- pstJobNode->u8TaskArrayTotalNum += 5;
- }
每次添加任务的时候,检查一下存task的空间还够不够,不够了再增量重申请一下,这样就能保证用户需要就加多少,既能避免一次性申请过多内存实际上浪费了的情况,又考虑了频繁malloc和realloc内存快的系统执行效率。在代价不大的情况下,空间和效率兼顾。