编辑: lqwzrs 2019-07-04

另一方面对耗时较多的模块运用多媒体指令(MMX)进行优化. C代码优化 空间地址分配访问 RM52J中,函数decode_one_frame里的帧初始化函数(init_frame)开辟了3个帧图像大小的二维缓冲空间,用于帧间解码时参考帧和当前帧存储.每解码一帧图像都要进行一次动态内存分配,之后再释放一次,反复的内存操作大大消耗了CPU资源,程序运行效率低下;

另一方面图像数据以二维方式存储访问,每读取写入一个数据需要索引水平和垂直两个方向坐标分量,读写耗时翻倍,且缓冲尺寸大小刚好等于一帧不利于后续样本插值优化.针对这两个缺陷,本实验提出解决方法:一是将帧缓冲空间分配放在程序主函数(main)中读码流函数之前完成,全部视频序列解码完后释放该内存数据段;

二是采用一维存储方式并对尺寸边界扩展.改进的关键部分是将如下的程序片段 for(refnum=0;

refnumss.vertical_size,t->width);

else get_mem2D(&t->reference_frame[refnum][i], t->ss.vertical_size/2,t->width_cr);

} 改进为如下的片段. for(i=0;

iedged_width_p * t->edged_height_p + (t->edged_width_p * t->edged_height_p>> 1), CACHE_SIZE);

t->refp[i].Y = p + EDGED_HEIGHT_P * t->edged_width_p + EDGED_WIDTH_P;

t->refp[i].U = p + t->edged_width_p * t->edged_height_p + (t->edged_width_p * EDGED_HEIGHT_P >> 2) + (EDGED_WIDTH_P >> 1);

t->refp[i].V = p + t->edged_width_p * t->edged_height_p + (t->edged_width_p * t->edged_height_p >> 2) + (t->edged_width_p * EDGED_HEIGHT_P >> 2) + (EDGED_WIDTH_P >> 1);

} 改进后数据存储结构可用下面示意图1表示,将一维空间等效为二维图理解.程序中edged_width_p和edged_height_p分别表示边界扩展后存放亮度样本空间的宽度和高度,EDGED_WIDTH_P和EDGED_HEIGHT_P分别表示亮度边界扩展的宽度和高度.色度U、V空间相应数据均为亮度的一半.这样处理后,整个程序只进行一次对帧缓冲的分配,且用一维向量索引样本位置,大大提高了索引速率,同时做了边界尺寸扩展工作,为下一步样本插值优化打好了基础. 图1 存储结构示意图 Fig.1 Storage structure diagram 像素插值块 AVS解码中样本插值是整个解码中最耗时的部分,是优化的关键环节.依据运动矢量的横坐标dx和纵坐标dy为整像素、二分之一像素、四分之一像素位置的划分法,亮度样本插值分为九种情况,其中二分之一像素插值三种,四分之一像素插值五种,二分之一样本值通过四抽头滤波器(-1,5,5,-1)计算得到,四分之一样本值通过四抽头滤波器(1,7,7,1)计算得到. 参考软件RM52J中,亮度宏块是以8x8块大小进行样本插值的,由编码标准可知宏块的四个8x8块可拥有不同运动矢量,同一8x8块内像素共享同一运动矢量(dx,dy)[2],dx 为运动矢量水平方向小数分量,dy为运动矢量垂直方向小数分量.如果计算样本时用到的整像素位置超出图像边界,则像素值由最近的图像边界上的样本值取代.以水平和垂直运动矢量分量均为整像素位置为例,RM52J程序实现如下面所示: if (dx ==

0 && dy == 0) { for (j = 0;

j < B8_SIZE;

j++) for (i = 0;

i < B8_SIZE;

i++) block[h++]=ref_pic[max(0,min(maxold_y,y_pos+j))] [max(0,min(maxold_x,x_pos+i))];

} 程序中y_pos表示以参考帧图像左上角样本位置为中心参考块的运动矢量垂直小数分量, x_pos表示相应水平分量,ref_pic表示参考帧图像,maxoid_x表示所允许的最大运动矢量水平分量,block用来存放插值块,B8_SIZE取值8.由程序可知,RM52J中每计算一个插值样本,水平和垂直方向要各做两次max和min比较,以处理参考块超出图像边界的情况,一个8x8块要做4x64=256次,对于求取图像内部的插值样本,这样的比较函数完全是多于的,产生大量计算冗余,解决的方法有两种:一种是区分参考块在参考帧内部和参考块不完全在参考帧内部两种情况计算,修改后程序如下所示: if (y_pos>=0&&y_pos + B8_SIZE-1 =0&&x_pos+ B8_SIZE-1mb.pix_x+b8_x+xx]= (uint8_t)curr_blk[yy][xx];

下载(注:源文件不在本站服务器,都将跳转到源网站下载)
备用下载
发帖评论
相关话题
发布一个新话题