一种按行交错划分任务和数据的多核并行视频解码方法
技术领域
本发明涉及视频编码技术领域,特别涉及运用多核数字信号处理器DSP芯片完成高清视频编解码及传输的多核并行视频解码方法以及多核并行时负荷分摊、执行等待和阻塞以及高速缓存的优化措施。
背景技术
上世纪80年代3C(Computers,Communications,Consumer Electronics)的相互渗透与融合催生了多媒体技术并且推动多媒体技术飞速发展与普及。视频编码是多媒体技术中的关键技术。近年传输视频清晰度不断提升,同时视频编码标准频繁更新换代,还不断涌现新内容。2002年CIF H.263在会议电视设备中尚占据主流。2005年就出现了720P H.264。到2009年1080P会议电视设备已为市场主推产品。这个时刻离1080P随Sony PS2游戏机和蓝光产品上市的时刻并不遥远。存储介质和双向实时网络传输两类应用对视频编码提出的压缩比和实时性要求相差甚远,仅单纯实时解码和实时编解码就相差2倍以上运算量。这么短时间一下迈上这么高台阶,完全得益于处理器芯片技术的飞跃!目前实时传输双向的三路1080P@60Hz H.264达到Sony PS3高清晰度的会议电视终端上市后,接下来的内容自然是4K、8K超高清视频和最新视频编码标准HEVC/H.265。
一路1080P@30Hz视频的图像数据量达到746,496,000bit/s。以ITU-RBT.1120格式传输时速率达1.485Gbit/s。压缩为1~8Mbit/s的H.264码流,编码、解码各需要2片、1片32位定点处理能力96亿次/秒的TI C6455@1.2GHz数字信号处理器DSP芯片。视频编码技术对于处理器芯片性能要求不断跃进。Intel Pentium 4@4GHz处理器芯片上市失败后,传统的提升处理器芯片性能的手段遇到阻滞,多核结构包括同构多核和异构多核已经成为提升处理器芯片性能的最主要手段。在DSP芯片领域数麻省理工学院MIT教授Anant Agarwal创立的Tilera公司推出的64核心DSP芯片Tile64最引人注目。其中最显著优势为iMesh片内核间高速互连网络,呈8x8网格状,网格节点为64个相同的64位定点处理器核心,包含5套独立物理线路,包交换,支持数据包组播和广播。TI公司则在C6455芯片达到传统单核心DSP性能顶峰后推出3核心TCI6487/6488和6核心TCI6486芯片,片内分别包含3个、6个C6455核心,虽然没有Tile64那么引人注目,但是牢牢占据高端DSP芯片市场。TI最新最强的DSP为C6678,包含8个浮点处理器核心以及TeraNet片内高速互连网络。
在硅片上复制n份处理器核心简单易行。难度和关键在于如何让n个核心在应用中表现出期待的n倍性能!除了依靠核间通信技术,最主要还是依赖软件包括操作系统OS和应用软件。现时DSP所用实时操作系统RTOS包括Linux嵌入式发行版本和TI DSP/BIOS。版本号高于2.6.10的Linux支持对称多处理器SMP,具有调度多核间负荷分布的能力。鉴于目前计算机应用领域内标量过程的单一任务在多处理上均衡的技术解决状况,运用RTOS提供的多进程和多线程设置多任务是RTOS有效均衡多核负荷的情景和前提条件。也就是现有RTOS对标量过程的单一任务运行于多核的自动调度负荷分布的作用很微弱。
本发明涉及领域恰恰正是这种情况:一路高清视频数据量巨大,编码和解码运算量巨大,双向实时网络传输时更甚,需要拿出多个核心去应付;视频编码和解码都是顺序执行的上下文的标量过程,前一步未完就走不到后一步;在时间、空间上也存在很强的运算与数据的关联与依赖。缘于视频编码本身就是 计算时间、空间相关性以去除表达冗余减少数据量。视频编码技术的压缩比越高,时间、空间相关的范围和程度也越大,相应运算量据增。此时RTOS已无意义,唯有依靠应用软件。n个核心表现出n倍性能即要求并行加速比达到n。在软件上提高并行加速比的途径、措施是调整负荷在多核的分布达到均衡、减少并行等待和相互阻塞、优化高速缓存。
多核并行在视频解码上的难度大于编码。因为编码输入为规整原始图像数据,可任意划分、随机存取,便于数据划分;解码输入为压缩码流,不仅表达图像内容的效率非常高,常常1个二进制位就表达了一个图像块,而且一段码流内不可再划分与定位,码流划分单位与定位位置只能到包含任意整数个码流基本单元的片slice一层,在实际网络传输常见码流中片由数据包长不超过网络最大传输单元MTU的规则而定,位置不定,难以进行数据划分。
视频解码过程的划分不宜多于3(3个顺接的子过程),而且分出的子过程运算量难以均等,更增大数据存储量和吞吐量。解码核心数大于3就必须考虑一帧图像以内的任务划分。相邻图像块的空间依赖性使任务均衡划分的难度徒然增大。迄今比较有效的一帧图像内图像块并行的解码方法为水边线Waterfront并行解码方法如图1所示,同时在垂直方向上展开多个行扫描处理,而非通常光栅扫描线处理。图1中5x5的16x16宏块阵列的H.264解码于T1~T13时刻完成,其中T3~T11时刻可同时处理多个宏块。视频编解码的空间依赖性使这样的处理形似空中俯瞰的地面与水面间分界线,因而得名。详情见于文献一(ErikB.van der Tol,et al.Mapping of H.264decoding on a multiprocessorarchitecture.Proceedings of SPIE Conference on Image and VideoCommuincations,Vol.5022,PP.707一718,Jan.2003)和是文献二(Arnaldo Azevedo,etal.Parallel H.264 Decoding on an Embedded Multicore Processor. http:// ce.et.tudelft.nl/publicationfiles/1590_752_54090404.pdf)。
图1所示二维水边线Waterfront多核并行解码方法在Tile64上的首次尝试见于文献三(管辉.基于同构多核处理器的H.264并行解码算法研究.哈尔滨工业大学硕士学位论文.2009.下载于中国知网www.cnki.net),步骤简述如下:
(1)安排Tile64的1个核心#0处理一帧图像码流解析,5个核心#1~5处理一帧图像重建以及去方块环路滤波。
(2)核心#0在共享内存中为全部共享图像数据、图像重建队列和去方块滤波队列的结构体变量开辟空间malloc,对这些队列和处理状态数组所带的互斥锁Mutex做初始化,把位于左上顶点坐标(0,0)的第一个宏块排入图像重建队列。
(3)用双缓冲区方法(也称乒乓缓冲方法)使核心#0的码流解析与核心#1~5的图像重建以及去方块环路滤波并行执行。即从核心#0操作缓冲区#0开始。核心#0完成后把缓冲区#0交给核心#1~5操作,接着操作缓冲区#1;缓冲区#0和#1的操作都完成后,通过指针轮换交换缓冲区,核心#0操作缓冲区#0同时核心#1~5操作缓冲区#1;…。
(4)核心#1~5每个核心执行以下步骤:
(41)循环读先进先出FIFO的队列queue直到从中取出一个宏块(mb_y,mb_x)为止,每次循环先读带互斥锁的图像重建队列,如果遇空再读带互斥锁的去方块环路滤波队列;
(42)宏块(mb_y,mb_x)图像重建或者去方块环路滤波,完成后写带互斥锁的宏块(mb_y,mb_x)的处理状态为已完成图像重建或者已完成去方块环路滤波;
(43)读带互斥锁的下一行相邻的左下宏块(mb_y+1,mb_x-1)和下方宏块 (mb_y+1,mb_x)的处理状态,判断能否执行图像重建或者去方块环路滤波;
(44)更新带互斥锁的图像重建队列和去方块环路滤波队列,把可处理的0/1/2个宏块排入队列;
(45)处理完一帧图像全部宏块的图像重建以及去方块环路滤波,退出循环;否则,跳到(41)继续循环执行。
(5)核心#0码流解析完成与核心#1~5的图像重建以及去方块环路滤波完成的同步。
(6)跳到(4)继续循环执行下一帧图像码流的解码,直到码流终止。
以上方法和程序的效果十分糟糕:对于Foreman序列CIF H.264码流,Tile64单核运行PC机算法验证模型的H.264解码软件C代码(未经任何针对Tile64平台的优化),解码平均帧频20多ms/f;分摊到6个核后慢得非常多;最后完成代码优化工作,主要包括32位单指令多数据操作SIMD、循环拆解、条件分支替代等措施,也仅达到23ms/f。也就是说优化后在6个核上跑,比未优化在一个核上跑还慢。曾经将解码软件的可执行文件交给Tilera公司分析,答复是片内高速缓存cache缓存的数据绝大部分为非母核数据,数据存取效率过低。
Tile64片内高速缓存Cahce分散到64个核心内部,每个核心配备全速的8K字节一级数据缓存L1D和8K字节一级指令缓存L1P,还有半速的64K字节二级缓存L2Cache。L1D和L2Cache只缓存由本核心开辟空间malloc的片外主内存数据,称为母核Cache-homing,不缓存其它核心开辟空间的片外主内存数据。当核心A访问非母核数据时,首先由该数据的母核B缓存至L2Cache,再由核心A通过iMesh片内核间高速互连网络与核心B传输数据包,实现自核心B的L2Cache读入数据或者更新核心B的L2Cache内数据。即使n次重复的访问也 需要n次经过iMesh网的数据包传输。所以访问非母核数据比访问母核数据效率低得多。曾经做过一试验,把H.264解码任务分成两部分A和B。A为开辟空间malloc并码流解析,B为余下的图像重建及环路滤波,在Tile64上单核运行,1080P@30Hz大运动码流的解码帧频300ms/f;让一个核心处理A,另外一个核心处理B,A处理完才处理B,1080P@30Hz大运动码流的解码帧频达1200ms/f。
Tile64的后代芯片Tile64pro有所突破,读非母核数据时会在数据包传输后把数据缓存于自己核心的一级缓存L1D。这样n次重复读只需要一次经过iMesh网的数据包传输,读数据的效率大大改善!但是Tile64pro写非母核数据仍然与Tile64一样,n次重复的写需要n次经过iMesh网的数据包传输。因为高速缓存cache原理是把一大块内存空间映射到很小的一块,如果同时映射到多块小空间,多读尚可多写就不行更谈不上同时随机多读写。同理新出多核处理器的可供多核共享的高速缓存也解决不了多核并行缓存问题。虽然Intel和AMD用于PC机的x86体系多核处理器芯片和TI C6678DSP芯片配备的可供多核共享的大容量三级缓存与Tile64的高速缓存区别明显,但是因为无法缓存对片外主内存相同地址数据的同时多访问,所以同样会出现Tile64的上述H.264解码糟糕的情况,差别仅在程度。这样的共享三级缓存的意义限于拉近CPU寄存器与片外主内存之间距离,提高二级缓存缺失Cache Miss时的存取效率。此外再多便是引出吓人价格。
既然传统的一体化共享数据不适合Tile64的分布式高速缓存而出现上述Tile64H.264解码糟糕情况,思路是划分数据,把原来一体的数据分摊到多核,数据也呈分布式,从而使数据缓存在多核间均衡,各个核心主要作为母核访问 数据完成处理。
发明内容
本发明要解决的技术问题是文献三在Tile64上的6个核心H.264并行解码所遇到的6个核心并行解码速度比单个核心解码还慢2倍以上的问题,显著提高并行加速比,最终实现达到业界领先水平的高清视频解码。本发明之前的业界最高水平是用Tile64片内6个核心一组实时解码一路1~8Mbit/s的1080P@30Hz的H.264视频码流,单片完成10路1080P@30Hz的H.264视频实时解码。
提高并行加速比的总体途径如前所述,包括调整负荷在多核的分布达到均衡、减少并行等待和相互阻塞、优化高速缓存。具体措施需要先找出文献三方法存在问题。水边线方法使得文献三方法在多核负荷分布均衡上达到完满,可谓大家全在忙无片刻偷闲。在并行等待上也达到竭尽可能的最佳,多核间同步一帧仅有一次,就是核心#0码流解析完成后与核心#1~5的图像重建以及去方块环路滤波完成后的同步,核心#1~5间最大等待时间为一个16×16宏块的图像重建或者去方块滤波的时长。问题在于数据存取效率过低。具体缺陷如下:
(1)首要问题是多核并行缓存失衡问题,即在Tile64的分布式高速缓存不能为多核并行缓存数据的情况下仍然沿用传统的一体化共享数据,5个核心#1~5访问的共享数据全由核心#0开辟空间、以核心#0为母核、缓存于核心#0的二级缓存中,每次访问都需要核心间传输数据包,哪怕重复访问也需要重复传输数据包,存取效率非常低;此时核心#0内部二级缓存实际用作6个核心的缓存,区区64K字节容量根本不堪6个核心高速处理的总数据吞吐量,所以缓存缺失Cache Miss机会也剧增。缓存亟待分摊到多核!
(2)其次,这么多核心密集访问带互斥锁的共享数据,一旦访问的共享数据被锁住就阻塞直到先入的核心开锁,多个访问同时遇锁时阻塞时间加长,哪怕访问的共享数据空间分布遥远,造成并行间阻塞严重。
本发明的具体措施就是克服上述缺陷。本发明提供一种按行交错划分任务和数据的多核并行视频解码方法,其特征在于,按以下步骤划分共享图像数据以及相应的数据处理:
(11)把HxW图像的数据及其处理任务按码流基本单元行交错划分给m个核心,m等分为最佳,其中第0行分给核心0、第1行分给核心1、第2行分给核心2、。。。,核心i处理第行码流基本单元,如图2所示,每个核心处理hxW子图像的视频解码,([]为取整数运算符号),如图3所示;
(12)划分后完整图像全局行坐标到核心序号及其子图像局部行坐标的映射关系为:
图像Y分量行坐标映射:global_y=核心序号×16k+local_y×m
图像U、V分量行坐标映射:global_y=核心序号×8k+local_y×m
码流基本单元行坐标映射:global_mb_y=核心序号+local_mb_y×m
本发明提供的一种按行交错划分任务和数据的多核并行视频解码方法,其特征在于,步骤(11)所述图像数据包括过去时刻和当前时刻的重建图像YUV分量数据、一帧图像所有码流基本单元的视频编码标准定义的语法符号和解码需要的处理状态。其中语法符号包括且不限于码流基本单元的编码类型、参考帧号、运动矢量预测残差和运动矢量、帧内预测模式、亮度量化参数和色差量化参数、方块编码模式、变换系数行程符号。在最新视频编码国际标准HEVC/H.265 之前,所有视频编码标准和私有技术均以16×16宏块为码流基本单元;HEVC/H.265新增32×32和64×64作码流基本单元。此后统一记为16k×16k。
本发明提供的一种按行交错划分任务和数据的多核并行视频解码方法,其特征在于,按以下步骤创建访问共享图像数据的数据结构,如图4所示:
(31)m个核心调用多核DSP软件开发环境SDK提供的共享内存开辟方法在共享内存中开辟一段连续存储空间,长度为分给本核心的子图像的数据在相对二级缓存行宽对齐时的数据总长度,也就是全体图像数据总长度的1/m,然后把系统返回的一块数据区首地址通过核间消息发到组内任意一个指定核心A;
如果核心A不在m个核心中,核心A接收m个核心发来的数据区首地址并且按照[0,m-1]序号存放于同一指针数组中;否则,核心A接收m个核心中除本核心以外的其它核心发来的数据区首地址,然后连同本核心开辟的数据区首地址一起按照[0,m-1]序号存放于同一指针数组中;
(32)所有核心调用多核DSP软件开发环境提供的私有内存开辟方法在私有内存中开辟一段连续内存空间,长度为访问全体图像数据所用的按行存储的p维数组的第1~p-1级表在相对二级缓存行宽对齐时的数据总长度,并且从系统返回的一块数据区首地址开始设置,使p维数组的第1~p-1级表内容指向这块私有内存区域;
p维数组分为p个数据表分开存放,每个数据表占据一段连续内存空间,如图5所示的按行存储的二维数组的一种二级表结构。其中除最高的第p级表数据外,数组变量和较低级表指针全部能被64或者128的二级缓存行宽整除,成为相对二级缓存行宽对齐。这是适应高速缓存的优化措施。64、128字节对齐的调整方法分别是header=(header+63)&(~63)、header=(header+127)&(~127)。
(33)核心A从步骤(31)所述的m个核心开辟的数据区首地址开始依次设置图像数据所有p维数组的第p-1级表内容,使每个地址依据步骤(12)的完整图像全局行坐标到核心序号及其子图像局部行坐标的映射关系指向共享内存中的一行数据,如图6所示;
(34)核心A把图像数据所有p维数组的第p-1级表内容通过组内广播经过核间高速互连网络送达所有核心。
本发明的提供一种按行交错划分任务和数据的多核并行视频解码方法,其特征在于,按以下步骤访问共享图像数据、输出重建图像:
(41)只能用数组名[行坐标][列坐标]或者数组名[行坐标]+列坐标访问共享的图像数据,不能用图像数据首地址+行坐标×一行数据长度+列坐标访问共享的图像数据;
(42)输出重建图像时先用数组名[行坐标]的方法取得重建图像YUV分量每个像素行首地址,再逐行从m个核心的子图像转存到正常存储的一帧输出图像。
本发明提供的一种按行交错划分任务和数据的多核并行视频解码方法,其特征在于,m个核心在纵向同时展开多个码流基本单元行的行扫描处理,形成水边线Waterfront,如图7所示,具体步骤如下:
(51)从上到下检查每个码流基本单元行的最左未处理图像块的相邻图像块处理状态,判断处理是否满足视频编码标准规定的相邻码流基本单元图像块依赖条件;
(52)不满足,跳转到步骤(51)继续寻找;否则,找到可处理图像块,跳转到步骤(53);
(53)一个码流基本单元图像块的处理,更新该图像块处理状态和所在码流 基本单元行最左未处理图像块;
(54)循环执行步骤(51)~(53)直到处理完子图像。
本发明的技术效果如下:
本发明划分视频解码任务和共享图像数据后使两者均适应多核DSP分布式缓存的特性,所有核心可以同等访问全体图像数据,同时并行访问的缓存均衡分布于多个核心内部的高速缓存内。在相应的视频解码的任务划分下多个核心访问的共享数据绝大部分是分给自己的母核数据,可以缓存于自己的二级缓存内。需要访问的非母核共享数据很少,在H.264解码的实施例中最多仅为上一行宏块和下一行宏块的4个像素行Y分量和2个像素行U和V分量。于是在任务分摊到多核后数据缓存也相应分摊到多核,并且都达到均衡,共享数据存取效率显著提高,从而解决了多核并行解码的最关键问题——高速缓存均衡问题。
其次,本发明无任何互斥锁和互斥条件。这是因为划分后多核任务范围不重叠。图像中某个码流基本单元的处理状态由负责这一行的核心写、再由负责下一行的核心读时不需要加锁。相反在文献三中多核任务范围一致的情况下如果不加锁就会发生同一个宏块被一个以上核心抢去处理。无互斥锁和互斥条件,也就无并行间阻塞。最后水边线方法也比习惯的光栅扫描线方法减少并行间等待、停滞。
实际情况与上面理论分析一致。应用本发明后,在Tile64上的1080P@30Hz的H.264解码在并行加速比上已经接近理想值,4个核心并行处理耗时已经接近单核的1/4。再经过本发明以外的优化措施,最后实现用主频800Mhz的Tile64芯片内5个核心一组实时解码一路1~8Mbit/s的1080P@30Hz的H.264视频码流,超越从Tilera公司处了解到的当时业界最高水平。
本发明适用范围为使用Tilera公司(已被EZchip公司收购,主页仍为www.tilera.com)的Tile64、Tile64pro、Tile-Gx、Tile-Mx等一系列多核DSP芯片于视频编码和解码。至于其它多核处理器尤其是TI的多核DSP芯片,与Tile64一样,片外主内存同一地址不能同时被多核缓存并且自动保持缓存一致性Cache Coherence。如TI C6678位于8个核心内部的一级、二级缓存只能为各自核心缓存并且自动保持缓存一致性,不能为其它核心缓存;片内4M字节共享存储器在用作三级缓存时不能自动保持缓存一致性。这些多核处理器也会像Tile64那样需要解决共享数据的缓存分摊到多核的问题。只是能否直接运用本发明,取决于分布式缓存是否依据开辟空间的那个核心?如果是,可以直接运用并且取得显著效果;否则,通过其它途径实现分布式缓存,就不需要先划分共享数据分开开辟空间,本发明仅有参考价值。
附图说明
图1示意图是图像块并行解码的二维水边线Waterfront多核并行视频解码方法;
图2示意图是解码任务以及图像数据按行交错划分到多核;
图3示意图是一帧图像为4个核心按行交错划分为4个子图像,分别占据4段连续内存空间;
图4流程图是创建访问共享图像数据数据结构的过程;
图5示意图是按行存储的二维数组x[][]的一种二级表结构;
图6示意图是设置访问共享图像数据的p维数组的第p-1级表的方法;
图7示意图是多个核心同时展开多个宏块行的行扫描处理;
图8流程图是实施例的打开解码器的初始化过程;
图9流程图是实施例的多核并行解码过程。
具体实施例
本发明实施例为在Tile64上的1080P@30Hz的H.264视频解码。下面参考图1~9作详细说明。
本发明所用H.264解码软件源自JVT官方参考编解码软件JM6.1e。在本发明实施前已针对会议电视应用需求进行了简化和优化。其中对本发明最有意义的改动,就是把JM6.1e解码软件中语法符号的结构和存储量从一个宏块扩大到一帧图像,把按宏块处理的码流解析和图像重建改为先完成一帧图像码流解析再完成一帧图像重建,最后完成一帧图像的去方块环路滤波。此为组织多核并行解码算法的基础、起点。该软件移植到Tile64上首次运行时对一1080P@30Hz大运动码流的H.264解码帧频为300ms/f。
(1)划分任务和数据
对于一路1~8Mbit/s的1080P@30Hz的H.264视频码流,安排Tile64一个核心处理一帧图像码流解析即熵解码,另外4个核心依次处理一帧图像重建和去方块环路滤波。H.264定义的求运动矢量预测值的过程放在核心#1~4的图像重建中,而不是如文献三那样放在核心#0的码流解析中,即核心#0向核心#1~4传递的是直接解析码流的运动矢量预测残差。
指定Tile64片内第二行开头5个核心(1,0)~(1,4)分摊视频解码,然后令这些核心加载各自的程序文件h264vld.tilexe或者h264dec.tilexe运行,C代码如下:
采用图2的按16×16宏块行交错分布的方法划分1920x1088的图像、对应位置图像数据及其图像重建和去方块环路滤波到4个核心#1~4。注意图中核心序号0,1,2,3具体到实施例为核心#1,#2,#3,#4。于是1920x1088的图像等分为4部分,核心#1~4中每个核心处理17个宏块行、1920x272子图像,如图3所示隔16行(Y分量)交错分布,任务和数据均等,成为一种最佳情况。
实施例所用的图像数据包括过去时刻和当前时刻的重建图像YUV分量数据、一帧图像所有宏块的语法符号和解码需要的处理状态。其中H.264语法符号包括宏块编码类型mb_type、参考帧号refframe、运动矢量预测残差/运动矢量block_mv、帧内预测模式ipredmode、亮度量化参数qp和色差量化参数qpc、方块编码模式cbp、变换系数行程符号run-level。其中过去时刻和当前时刻的重建图像YUV分量数据分别存储于三维参考帧数组img->mref和img->mcef中。
(2)打开解码器的初始化过程
Tile64每个核心内部二级缓存行宽64字节。所以在设置数组变量及其低级表的指针时要求能被64整除,称64对齐。调整方法是pointer=(pointer+63)&(~63)。
打开解码器的初始化流程图如图8所示,具体步骤如下:
(21)核心#1~4计算分到本核心的1920x272子图像的共享图像数据在数据行长度64对齐时的数据总长度size。其中核心#0的码流解析与核心#1~4的图像重建以及去方块环路滤波并行执行的双缓冲区方法要求一帧图像所有宏块的语法符号和处理状态为双份,即两个缓冲区。
(22)核心#1~4用tmc_cmem_memalign(64,size)在共享内存中开辟一段连续内存空间,然后用ilib_msg_send发送系统返回的一块YUV分量区、两个语法符号区共三个首地址至核心#0。
同时核心#0用ilib_msg_receive接收核心#1~4发来的三个首地址并且按照[0,3]序号存放于同一指针数组中。
(23)所有核心#0~4计算访问1920x1088图像的共享图像数据所用到的所有p维数组第1~p-1级表在数据行长度64对齐时的数据总长度size1。
(24)所有核心#0~4用memalign(64,size1)在私有内存中开辟一段连续内存空间,并且从系统返回的一块数据区首地址privatebuffer_header开始,使用空区首地址void_header,依次设置共享图像数据各个p维数组第1~p-2级表内容,使其指向这块私有内存区域,具体步骤如下:
(241)上一数组设置完后void_buffer内容已64对齐,把void_buffer赋给当前p维数组变量x,并且令void_buffer增加第一级表64对齐的长度;
(242)如果p=2,结束;否则,把void_buffer赋给p维数组变量x[0],并且令void_buffer增加第二级表64对齐的长度;设置第一级表的内容x[q]=x[q-1]+第二级表每段数据长度;
(243)如果p=3,结束;否则如步骤(242)设置更高级表;直到设置完第 p-2级表,因为组内只有一个核心汇齐了设置第p-1级表所需内存空间信息。
其中设置参考帧三维数组img->mref的C代码如下:
(25)核心#0从步骤(22)接收的核心#1~4发来的数据区首地址sharedbuffer_header[i](核心序号i从0→3)开始,使用相应的空区首地址void_buffer[i],依次设置共享图像数据各个p维数组第p-1级表内容,使每个地址依据发明内容步骤(12)的全局图像行坐标到核心序号及其子图像局部行坐标的映射关系指向共享内存中的一行数据,如图6所示,其中语法符号和处理状态的数组都是双份的,具体步骤如下:
(251)上一数组设置完后,核心#1~4的空区首地址void_buffer[i]已全部64对齐,按照核心序号i从0→3的顺序把void_buffer[i]赋给当前p维数组第p-1级表内偏移i×行数(Y分量16行,U和V分量8行,语法符号1行)的指针,使其指向共享内存中该核心的首行数据,并且令void_buffer[i]增加该核心64对齐的数据长度,即当前p维数组数据总长度的接着按照核心序号0→3交替设置当前p维数组第p-1级表后续地址,使每个地址依据发明内容步骤(12)的全局图像行坐标到核心序号及其子图像局部行坐标的映射关系指向共享内存中的一行数据,如图6所示;其中Y分量设16个分别指向16个像素行的指针,U或者V分量设8个分别指向8个像素行的指针,语法符号或者处理状态设一个指向一个宏块行的指针;
(252)循环执行步骤(251),直到完成当前p维数组第p-1级表。
其中设置参考帧三维数组img->mref的C代码如下:
(27)核心#0用ilib_msg_broadcast通过组内广播经过iMesh网发送共享图像数据所有p维数组第p-1级表内容,同时核心#1~4用ilib_msg_broadcast接收共享图像数据所有p维数组第p-1级表内容。
(3)多核并行解码
运用双缓冲区法(也称乒乓缓冲方法)使核心#0码流解析与核心#1~4图像重 建以及去方块环路滤波并行执行。即从核心#0操作缓冲区#0开始。核心#0完成后把缓冲区#0交给核心#1~4操作,接着操作缓冲区#1;缓冲区#0和#1的操作都完成后,通过作为缓冲区指针数组下标的索引号的0与1倒换(执行与1的异或运算)交换缓冲区,核心#0操作缓冲区#0同时核心#1~4操作缓冲区#1;…。核心#1~4在纵向同时展开多个码流基本单元行的行扫描处理,图像重建和去方块滤波放置于一个循环体内。下面结合图7、9说明。
多核并行解码流程图如图9所示,具体步骤如下:
(3101)核心#0用ilib_msg_broadcast通过组内广播经过iMesh网发送20个字节的解码参数,包括EOS、图像宽高、语法符号处理状态索引号(0或1)、重建图像帧计数、H.264参数集部分内容;
(3102)核心#0把语法符号处理状态索引号与1异或,即0→1或者1→0,从而换用另外一块语法符号和处理状态缓冲区;
(3103)核心#0开始解析码流,如果遇到码流终止标志如传输中EOS数据包或者文件结束符,用ilib_msg_broadcast通过组内广播发送步骤(3101)所述的20个字节的解码参数,结束;否则,跳转到步骤(3104);
(3104)核心#0把语法符号处理状态索引号与1异或,即0→1或者1→0,从而换用另外一块语法符号和处理状态缓冲区;
(3105)核心#0根据Slice指示确定一个宏块的序号(0~8159),为该宏块处理状态赋全0初值,即未图像重建、未去方块滤波;
(3106)核心#0解析一个宏块码流;
(3107)跳转到步骤(3103)循环执行宏块码流解析,直到完成整个片、整帧码流;
(3108)核心#0用ilib_msg_receive接收4个核心发来的处理时长,作为同步;将4个核心的处理时长求和、取平均,得到图像重建以及去方块环路滤波的处理时长;
(3109)同步后输出重建图像;
(3110)跳转到步骤(3101)循环执行一帧码流解析。
(3201)核心#1~4用ilib_msg_broadcast从组内广播接收核心#0于步骤(3101)和(3103)发来的20个字节的解码参数,包括EOS、图像宽高、语法符号处理状态索引号(0或1)、重建图像帧计数、H.264参数集部分内容;
(3202)EOS=1,结束;否则,跳转到步骤(3203);
(3203)核心#1~4开始重建图像以及去方块环路滤波,根据语法符号处理状态索引号(0或1)使用核心#0另外的一块语法符号处理状态缓冲区,从上到下检查每行宏块中最左未重建图像宏块是否满足重建图像条件;
H.264规定包括求运动矢量预测值和帧内预测等操作的宏块重建图像条件是:左上、上方、右上、左边四个宏块已经完成图像重建。因为水平方向为行扫描处理,所以用发明内容步骤(12)求出的全局纵坐标读出上一行右上宏块的处理状态便可确定是否满足条件。
(3204)如果当前宏块满足重建图像条件,即找到可重建图像宏块,跳转到步骤(3207);否则,跳转到步骤(3205);
(3205)核心#1~4从上到下检查每行宏块中最左未去方块滤波宏块是否满足去方块滤波条件;
H.264规定当前宏块可执行去方块环路滤波的条件是:上方、右上、左边三个宏块已经完成去方块环路滤波,同时下方宏块已经完成图像重建。行扫描 下用全局纵坐标读出上一行右上宏块和下一行下方宏块的处理状态便可确定是否满足条件。
(3206)如果当前宏块满足去方块环路滤波条件,即找到可去方块滤波宏块,跳转到步骤(3207);否则,跳转到步骤(3203)继续寻找;
(3207)找到可重建图像宏块时,一个宏块图像重建,更新该宏块处理状态和该行最左未重建图像宏块;否则,找到可去方块滤波宏块时,一个宏块去方块环路滤波,更新该宏块处理状态和该行最左未去方块滤波宏块;
(3208)跳转到步骤(3103)循环执行宏块重建图像和去方块环路滤波,直到完成核心分到的子图像所有宏块的重建图像和去方块环路滤波;
(3209)核心#1~4用ilib_msg_send发送处理时长到步骤(3108)核心#0,作为同步;
(3210)同步后跳转到步骤(3201)循环执行一帧图像的重建和去方块环路滤波。
以上解码中只能用数组名[行坐标][列坐标]或者数组名[行坐标]+列坐标访问共享图像数据。其中用三维数组img->mref[参考帧号][像素行坐标][像素列坐标]或者img->mref[参考帧号][像素行坐标]+像素列坐标访问参考帧。用子图像局部行坐标访问图像数据时需要先用发明内容步骤(12)的映射关系把局部行坐标转换为全局行坐标。
步骤(3109)输出重建图像的伪C代码如下:
步骤(3203)和(3205)在图7右侧子图像中用从上到下检查每行最左未处理宏 块是否满足处理条件的方法寻找可处理宏块,C代码如下:
。