新闻中心

EEPW首页 > 嵌入式系统 > 设计应用 > 在TMS320C6711 DSP上实现H.263视频编码器的EDMA数据存取策略

在TMS320C6711 DSP上实现H.263视频编码器的EDMA数据存取策略

作者:时间:2007-03-09来源:网络收藏
摘要:提出了在TMS320C6711 平台上实现H.263视频编码器的过程中,如何使用EDMA优化数据存取的策略,从而减少了CPU花费在数据搬移上的开销。 关键词:H.263 EDMA QDMA 数据存取策略 目前,将H.263算法在芯片上实现,已成为一种越来越广泛的应用趋势。采用DSP实现H.263算法,相对于以往的方案,具有更好的扩展性,可以很容易地将声音编解码和复用、通信协议添加进来,综合在一起DSP芯片中,具有很强的实用性。 本文采用TI公司的TMS320C6711 DSP实现H.263的编码,提出一种在DSP平台上充分合理使用片上EDMA控制器,进行数据存取优化的策略。 1 TMS320C6711的直接存储器访问控制器 直接存储器访问(DMA)是C6000 DSP的一种重要的数据访问方式,它可以在没有CPU参与的情况下,由DMA控制器完成DSP存储空间内的数据搬移,数据搬移的源/目的地址可以在片内存储器、片内外设和外设器件。 在TMS320C6711中,EDMA控制器负责片内存储器L2和外设之间的数据传输,其增强之处在于: %26;#183;提供了16个通道 %26;#183;通道间的优先级设置 %26;#183;支持不同结构数据传输的链接(QDMA除外) EDMA控制器是基于RAM结构的,EDMA的参数RAM(PaRAM)存放着传输控制参数。图1给出了一个PaRAM的内部结构,总共6个字(32bit/word)。选项参数内容如图2所示。 TMS320C6711 DSP还提供一种快速DMA(QDMA)传输方式。QDMA与EDMA相似,支持几乎所有的EDMA传输方式,但是提交传输申请的速度要快很多。在应用系统中,EDMA适合于固定周期的数据传输,但如果需要CPU干扰控制搬移数据,QDMA则比较适合。 QDMA的操作由两组寄存器进行控制。第一组的五个寄存器寄存了QDMA传输所需的参数,与EDMA的PaRAM类似,只是没重加载/链接参数。第二组的五个寄存器是第一组寄存器的“伪映射”。 下面就H.263编码的某些环节说明如何采用EDMA技术对编码数据数据进行优化存取。 2 原始图像的获取 由于待处理的原始图像都很大,即使QCIF格式的图像,也要占用38KB左右的存储空间,显然不能将待编码图像存放于片内RAM(L2)中。通常的方法是在CPU干预下,采用“读入-写出”的方式,从视频设备读取数据,然后存入片外SDRAM中。使用C6000 DSP强大的EDMA,亦可以实现原始图像帧的后台传输,EDMA无需CPU的干预便可独自将视频设备的输出图像直接送往片外SDRAM。这样,CPU就可以将搬移数据的时间用于图像编码的工作。 在这里使用C6000 DSP的EDMA控制器的QDMA功能。相对于EDMA的传输方式,QDMA的传输方式有着更快的申请提交速度。在片外SDRAM中开辟三块帧缓冲区Framel(首地址0xA00000000)、Frame2、Frame3。初始化阶段,先提交三个QDMA请求(此时也可使用通常的数据搬移手段),将视频序列的前三帧数据分别存入三块帧缓冲区内,填满帧缓冲区。接着开始对Frame1内的图像数据进行编码,该帧编码结束后,对Frame2内的图像数据进行编码,Frame2成为当前帧,而Frame1成为Frame2的先前帧,一旦Rrame2编码完毕,便对Frame3内的图像数据进行编码,同时立即提交一个新的QDMA请求,从视频外设读取一帧新的图像数据到Frame1中(因为对Frame3进行编码时,Frame2作为先前帧,Frame1已经不需要了)。待Frame3编码完毕后,Frame2又不需要了,此时再提交一个新的QDMA请求,读取新一帧图像数据到Frame2中。如此循环,每编码完毕一帧图像,就提交一个新的QDMA请求,依次在对应的帧缓冲区内存放新的一帧图像数据。这样,依次在对应的帧缓冲区内存放新一帧图像数据。这样,从外设获取当前编码图像的下一帧与当前图像的编码工作同时进行,DSP每次都直接对图像进行编码,而不需要再花费开销从外设读取。 要实现图3所示的QDMA传输,有两种等价的方式: %26;#183;1D-1D,帧同步传输 %26;#183;1D-2D,阵列同步传输 下面以图3为例,给出采用1D-2D传输方式,将图像数据送往Frame1中时所需提交的QDMA的具体参数设置。 Void submit_qdma(void) { EDMA_Config config; Config.opt=(unsigned int)0x28A00001; Config.src=(unsigned int)0x90010000;//视频外设的数据口地址 Config.cnt=(unsigned int)((288-1)<<16|352); Config.dst=(unsigned int)0xA00000000;//目的地址 Config.idx=(unsigned int)(352<<16);//数据单元索引忽略 EDMA_qdmaConfig(%26;amp;config); }图33 图像宏块编码 从上面已经知道,图像帧存放在片外SDRAM中。因此,在对I帧所有宏块和P帧INTRA宏块编码时,或对P帧INTER宏块进行运行估计时,每个宏块都要进行片外存储器访问,会占用很大的CPU开销。所以,最好将当前待编码的宏块存入于片内RAM中。这样,整个宏块的编码就始终是片内访问,宏块编码子函MB_Encode在效率上就能够提高12%左右。 最直接的做法就是在片内SRAM中事先开辟一个宏块缓部眍,待将编码图像当前位置处的现代战争宏块搬移到片内RAM中的宏块缓冲区,之后再调用宏块编码子函MB_Encode。但是这样仍然会浪费一定CPU时间在数据块的搬移上,所以还具有改进的余地。结合C6000 DSP强大的EDMA功能,提出了如下改进方案: 由于每次块组(GOB)共有8448个字节数据(CIF),因此可以在片内RAM中开辟两个块缓冲区,采用乒乓方式,通过启动EDMA块组数据,使用独立于CPU的EDMA数据通道,在后台从片外搬移到片内。这样一来,每次调用宏块编码时,数据都已经存放在指定缓冲区中,不仅无需做数据的搬移工作,而且还是在片内进行数据访问。 初始化时,可以采用普通的数据搬移手段(亦可使用EDMA),从片外存储器将第一帧图像的前面两个块组搬移到片内,充满块组缓冲区,然后即可开始图像编码。在进行图像编码的过程中,逐一对块组的乒缓冲区中的宏块进行编码,乒缓冲区宏块编码结束后,接着进行乓缓部眍的宏块编码,同时启动EDMA,从片外存储器搬移一个新的块组到乒缓部眍来,使得编码乓缓部冲区和向乒缓冲区搬移块组数据同时进行,一旦乓缓冲宏块也编码完毕,即可处理乒缓冲区中新的块组,如此循环。 C6000系列DSP的EDMA具有高效地从一帧图像中抽取子帧的能力。以CIF格式的图像为例,说明如何设置EDMA参数。 如图4所示左侧表示4:2:0亚采样的一帧YcrCb图像,亮度分量首地址为A000 0000h,色度分量首地址分别是A0001 8C00h和A001 EF00h;右侧表示块组的乒乓缓冲区,亮度分量y乒缓冲区首址在2000h,乓缓冲区首址为3600h,色度Cr分量的乒乓缓部冲区首址分别为4C00h和5700h,色度Cb分量的乒乓缓冲区首址分别为5180h和5C80h。 第一步,使用CPU启动EDMA通道,将一个GOB的亮度分量y传输到GOB亮度分量的乒缓冲区。CPU可以通过写事件置位寄存器ESR启动一个EDMA通道,向ESR的某一位写入“1”,强行触发对应事件,此时EDMA的PaRAM中的传输控制参数被送往地址发生器,开始对EMIF、L2和片外SDRAM进行访问。也可以使用QDMA进行第一步数据传输,通过设置QDMA的结束代码(选项参数的TCC字段)启动后续传输。 第二步,EDMA通道完成了对GOB亮度分量的传输后,重新加载下一次传输所需要的传输控制参数,将该GOB的色度分量Cr传磁室片内对应的Cr兵缓冲区。由于需要传输的原始数据,在空间上不是连续在存储的,这里使用了C6000系列DSP的EDMA链接功能。链接功能可以将不同的EDMA传输控制参数连接起来,组成一个参数链,为同一个通道服务。一次EDMA传输任务结束后,会自动从PaRAM中加载下一次传输所需要的参数。 第三步,同上,将该 GOB的Cb分量送入片内对应的Cb兵缓冲区。图4将GOB搬移到乒缓冲区对应的EDMA通道的PaRAM设置参数如图5所示。 选择帧同步、1D-2D数据传输数据,启动EDMA通道后,依次加载参数链,连续进行三次EDMA数据传输之后,待编码图像的一个GOB即搬移到片内的对应缓冲区中。注意参数链的最后一个PaRAM,选项参数的LINK字段要设置为0。 同样可以得到将GOB搬移到乓缓冲区对应的EDMA通道的PaRAM设置参数,如图6所示。 下面给出向编码块组乒缓冲区传输数据的EDMA通道PaRAM参数链的配置程序。 EDMA_Config config; EDMA_Handle hEdma_ping; //向乒缓冲区传输数据的EDMA通道句柄 EDMA_Handle hEdma_ping_tab1;//该通道的第一个链接PaRAM的句柄 EDMA_Handle hEdma_ping_tab2;//该通道的第二个链接PaRAM的句柄 Uint32 link_tab1,link_tab2;//该通道两个链接PaRAM的地址 if(EDMA_allocTableEx(1,%26;amp;hEdma_ping_tab1)) link_tab1=EDMA_getTableAddress(hEdma_ping_tab1); if(EDMA_allocTableEx(1,%26;amp;hEdma_ping_tab2)) link_tab2=EDMA_getTableAddress(hEdma_ping_tab2) hEdma_ping=EDMA_open(EDMA_CHA_ANY,EDMA_OPEN_RESET); config.opt=(Uint32)0x55200003;//第一个PaRAM的选项参数 config.ser=(Uint32)0xA0000000;//待传输块组Y分量的首地址 config.cnt=(Uint32)0x000f0160;//每行352像素,共16行 config.dst=(Uint32)0x00002000;//设置在片内的块组缓冲区 config.idx=(Uint32)0; //源采用帧同步、2-D传输 config.rld=(Uint32)(0x160<<16| link_tab1 %26;amp; 0xffff);//链接到下一个PaRAM EDMA_config(hEdma_ping,%26;amp;config); Config.src=(Uint32)0xA00191880; Config.cnt=(Uint32)0x000700B0; Config.dst=(Uint32)0x00005700; Config.rld=(Uint32)(0xB0<<16| link_tab2 %26;amp;0xffff); 链接到最后一个PaRAM EDMA_config(hEdma_ping_tab1,%26;amp;config); Config.opt=(Uint32)0x55200001; //最后一个PaRAM,LINK字段为0 config.src=(Uint32)0xA001F480; config.dst=(Uint32)0x0005C880; config.rld=(Uint32)(0xB0<<16); EDMA_config(hEdma_ping_tab2,%26;amp;config); 4 运动估计 在P帧编码中,对每个宏块进行运行估计时,需要访问存储在片外存储器的前一帧图像。考虑到当前帧的每个宏块都是在前一帧的搜索窗口内进行运行估计,所以可在片内RAM中开设一个大小为48字节%26;#215;48字节的缓冲区,这个缓冲区对应参数图像帧中以当前宏块位置为中心的一个大小为48字节%26;#215;48字节的窗口。 依据与前面一样的思想,这里同样使用乒播讲方式的搜索窗口缓冲区。在片内RAM中开辟两个48字节%26;#215;48字节的搜索窗口缓冲区,初始化时,先将搜索窗口缓冲区充满。第一次运行估计的参考搜索窗口乒缓冲区;第二次运行估计时参考乓缓冲区,此时提交一个QDMA请求,将下一宏块需要的搜索窗口数据送往搜索窗口乒缓冲区。如此反复,每次在参考某具搜索窗口缓冲区进行运动估计时,都提交一个QDMA请求,在后台将下一宏块的搜索窗口数据送入另一个搜索窗口缓冲区。图5和图6本节实际上是图像宏块编码的反过程,宏块编码时使用EDMA节省的是从片外SDRAM读取图像数据的开销,而本节使用EDMA节省的是将重建数据帧从片内L2存储器写到片外SDRAM的开销。 在片内RAM中开辟两个块组缓冲区,同样采用乒乓方式,用于保存编码过程中当胶编码宏块的重建数据。之所以开辟块组大小的缓冲区,而不是宏块大小的缓冲区,是为了防止过多的片内与片外数据传输的EDMA要求。这一点,图像宏块编码也是一样的。每当乒块组缓冲区的宏块都重建完毕,就通过提交一个QDMA请求,将该块组缓冲区内的重建宏块一次性复制到片外的重建帧缓冲区中,同时开始下一宏块的重构,并将重构宏块放在乓块组缓冲区。 本文提出的几个H.263编码环节,最自然的做法是CPU参数与数据块的搬移工作,然后再进行下一步的工序。使用EDMA的数据访问策略,可以减少CPU花费在数据搬移上的开销。在CPU和EDMA对片内存储器L2进行各自独立的访问时,可能并不是理想的同时进行,有可能产生冲突。但是CPU对存储器L2的访问优先级高于EDMA对L2的访问优先级,而且即使出现EDMA在数据搬移完毕之前,DSP已经处理完了上一步工序这样一种最恶劣的情况,DSP也只需再稍微等待片刻即可。因为已经有部分数据传输完毕,所以整个数据搬移上耗费的时间相对于不用EDMA只可能减少。如果设置合理,这个时间通常是零。

评论


相关推荐

技术专区

关闭