分类: LINUX
2013-02-21 05:04:50
原文地址:视频之五:视频数据处理与搬移 作者:leon_yu
文中我们将从处理器的角度来考察视频流,把注意力放在那些能实现高效数据处理与转移的结构和功能特色上。
视频端口的功能特色
要处理视频流,处理器就必须具有适当的接口,以保证数据能高速输入和输出该模块。有些处理器是通过一片连接到处理器的外部存储接口上的 FPGA 和/或FIFO 来实现上述接口的。这种器件一般用于协调出入处理器的、速度恒定且较慢的视频流(NTSC 视频的速度约~27 MB/s)与零星而高速的、猝发性的外部存储控制器数据流(其容量达到约 133 MWords/s 或者 266 MB/s 的水平)之间的关系。
不过,这样的安排仍然存在问题。例如,FPGA 和 FIFO 价格昂贵,往往与视频处理器本身相当。此外,使用外部存储器的接口来进行视频信号的传递,也会夺走其在这些系统中的另一项主要用途——在处理器内核与外部存储之间来回传送视频缓冲数据——所需的带宽。
因此,媒体处理系统最好采用一个专有的视频接口。例如在 Blackfin 处理器上就采用了“并行外设接口(PPI)”。PPI 是一种多功能的并行接口,它可以配置为8 和 16bit 两种带宽。它支持双向的数据流,并包含了 3 条同步线以及一个与外部时钟相连的时钟引脚。PPI 可以对 ITU‐R BT.656 数据进行无缝解码,而且还可以与 ITU‐R BT.601 视频源与显示设备,例如 TFT LCD 平板显示器接口。它可以用作高速模数转换器(ADC)和数模转换器(DAC)的连接管道。它还可以为外部处理器仿真出主控接口。
PPI 的一些内置的功能可以降低系统的成本,并改善数据的流动。例如,在BT.656 模式中,PPI 可以对输入视频流进行解码并自动忽略有效视频之外的任何信号,从而可以有效地将一路 NTSC 输入视频流的码率从 27MB/s 降低到 20MB/s,并显著减少处理视频所需的片外存储器的大小。或者,它也可以忽略有效的视频区,而只读入那些嵌入到垂直消隐间隔中的辅助数据。图 1 对这些模式进行了图示。
图 1:PPI 接口对 BT.656 各区域的有选择性的掩蔽
图中:Entire Field Sent 发送整个场,Active Video Only Sent——仅发送有效的视频,Blanking
Only Sent——仅发送消隐信号。Blanking——消隐,Field 1 Active Video——场 1 的有效视频,
Field 2 Active Video——场 2 的有效视频
类似的,在隔行扫描中 PPI 可以每隔一个场“忽略”一个场,换句话说,它不会把这些数据继续提交给DMA 控制器。虽然这种方法可以立即让输入带宽的要求降低 50%,但它也删除了 50%的视频源内容,因此有时这种折衷是无法令人接受的。不过,当输入视频的分辨率远高于所需要的输出分辨率时,这是一项有用的功能。
类似的,PPI 允许“跳过”编号为奇数或者偶数的分量,再次将所跳过的像素单元对应的 DMA 带宽节约下来。例如,在一个 4:2:2 的 YCbCr 流中,该功能将只容许亮度或者色度信号被读入,提供了在各种不同处理器之间进行算法划分的便捷方法;一个处理器可以读入亮度信号,而另一个则可以读入色度信号。它还提供了将一幅图像或者一路视频流转换为灰度级(仅有亮度信号)的简单方法。最后,在带有交织的 I/Q 数据的高速转换器应用上,这一特色使得在这些同相和正交分量之间进行划分成为可能。
重要的是,PPI并不知晓数据格式,因为它并未针对特定的视频标准来进行硬件连线。它容许用户对行长度和帧长度进行编程设定。这就给那些需要诸如CIF或者QCIF视频,而非标准的NTSC/PAL格式的应用帮了大忙。一般而言,只要输入的视频具有恰当的EAV./SAV代码(BT. 656视频)或者硬件同步信号(BT.601视频),PPI就可以对其进行处理。
封包
虽然BT.656和BT.601推荐方案可以提供10bit的像素单元,但这对于处理来说不是一个友好的字长度。这里的问题是,大多数处理器在处理按8bit、16bit或者32bit分块的数据方面效率很高,而对于处于这些值之间的那些量值都会造成数据搬移方面的效率低下问题。例如,即使一个10bit像素值只比8bit像素值宽2bit,但大多数处理器都会将其作为一个6个高位(MSB)为0的16bit数据来处理。这不仅会浪费内部数据传输总线(DMA)的带宽,而且还会浪费很多内存——这对于视频应用来说是不利的,此时,若干个整帧的缓冲数据往往要存储在外部存储器中。
数据尺寸大于8bit所带来的效率低下,还表现在数据打包无法达到最佳性能。往往一个高性能的媒体处理器将在其周边形成数据包封机制,该包封居于外部世界和处理器内部的数据传送总线之间,其目标是尽可能减少数据出入外设时总体上给这些总线的带宽造成的负担。因此,一路8bit的视频流以27MB/s的时钟频率输入外设时,可以被打包到32bit 的内部数据搬移总线上,相应的,只需该总线提供27/4或者说6.75MHz 的服务即可。请注意,总的数据传输速率仍然相同(6.75MHz * 32bit=27MB/s)。与之相反,一个以27MB/s传输的10bit的视频流将只能以2个16bit数据片的形式封装到32bit内部总线上,这就将总的传输速率降低至27/2或者说13.5MHz。在这种情况下,在每16位数据中只有10bit数据是相关的,故内部总线带宽的37.5%被浪费了。
可能的数据流
对多媒体系统中的视频端口的一些连接方式进行考察,展示系统作为一个整体与构成系统的
每种数据流动之间的相互依存关系,将是很有益的。在图 2a 中,图像源将数据发送到 PPI
中,在该处 DMA 引擎将其配属 L1 内存,在 L1 内存中,数据经过处理,转换为其最终形式,然后通过一个高速串口发送出去。该模型对于低分辨率的视频处理和 JPEG 等图像压缩算法来说是十分有效的,此类算法可以对小规模的视频数据块(对应若干行)进行处理,此后,这些数据块在随后的过程中将不再为系统所需要。上述的流程对于有些数据转换器应用来说也是十分有效的。
在图 2b 中,视频数据并没有被路由到 L1 内存,而是被引向 L3 存储器。这种配置可以支持MPEG‐2 和MPEG‐4 等算法,这些算法需要将中间视频帧存储在存储器中,以执行时间域的压缩。在这种情形中,L1和 L3 存储器之间的双向 DMA 流就可以实现像素宏块以及其他中间性数据的传送。
图中:Image Data and Syncs——图像数据和同步信号;Processor——处理器,Memory——
内存,Serial Port——串行端口,Compressed Video——经过压缩的视频;Video Data and Syncs
——视频数据和同步信号。
视频 ALU
大多数视频应用都需要对 8bit 数据进行处理,因为各像素分量(无论是 RGB或是 YCbCr)往往都是按字节计量的。因此,8bit 视频 ALU 和基于字节的地址生成可以带来像素处理方式上的巨大差异。这一点并非无足轻重,因为嵌入式处理器一般工作在 16bit 或者 32bit 的范围内。
嵌入式媒体处理器有时支持那些能高效地处理 8bit 视频和数据的语句。以表 1为例,其中总结出专门的 Blackfin 指令,综合运用这些指令,就可以实现各种不同类型的视频操作。
让我们考察几个关于这些指令的运用的示例。
4 重的 8bit 减法-绝对值-累加(SAA)指令非常适合于基于块的视频运动估算。该指令先对 4 对字节进行减法操作,并取每个差值的绝对值,然后将结果累加起来。这都是在一个周期内发生的。下面是其确切的表达式。
试考虑如图 3a 所示的宏块。16 像素×16 像素的基准帧可以进一步分为 4 组。一个非常合理的假设是相邻的视频帧是彼此相关的。也就是说,如果存在运动,则每个帧的各片区域将相对于前面诸帧的宏块发生移动。对宏块的运动进行编码所需要的信息,要少于将每个视频帧视为单独对象进行编码时所需的信息 ,MPEG 压缩使用了此技术。
这种对宏块进行的运动检测可分解为两个基本步骤。设定一个帧中的基准宏块之后,我们就能搜寻下一帧中所有在其周围的宏块(目标宏块),以决定最接近的匹配。基准宏块(在帧 n 中)的位置与可与之实现最佳匹配的目标宏块(在帧n+1 中)之间存在的偏移,就是运动矢量。
图 3b 图示出了系统中该方法的具体体现方式。
圆 = 视频帧中的某些对象
实线方框 = 基准宏块
虚线方框 = 对区域进行搜索,以发现可能的宏块。
点方框 = 最佳匹配的目标宏块(例如代表圆物体的运动矢量宏块)
一个 Blackfin 处理器的 SAA 指令执行速度很快,因为它在每个时钟周期中可利用 4 个 8bit ALU。我们可以实现如下的循环,以对图 3b 所示的 4 个对象中的每一个进行迭代处理。
/* 用于对图像组块进行迭代处理的循环中 */
SAA (R1:0,R3:2) || R1 = [I0++] || R2 = [I1++]; /*计算出绝对值并累加*/
SAA (R1:0,R3:2) (R) || R0 = [I0++] || R3 = [I1++];
SAA (R1:0,R3:2) || R1 = [I0 ++ M3] || R2 = [I1++M1]; /*取出目标组块的第 4 个字
后,指针指向下一行*/
SAA (R1:0,R3:2) (R) || R0 = [I0++] || R2 = [I1++];
现在让我们考虑另一个实例,即求 4 个相邻值平均值的运算,图 4a 示出其基本内核。通常情况下,必须进行 4 次加法和一次除法(或者乘法或者移位),才能计算出平均值。BYTEOP2P 指令可以加快该滤波器的实现。
图 4b 中心像素的量值被定义为:
x = Average(xN, xS, xE, xW)
BYTEOP2P 可以在一个周期内对两个像素执行这种求平均值处理(图 6.21 c,d)。因此,如果x1 = Average(x1N, x1S, x1E, x1W),x2 = Average(x2N, x2S, x2E, x2W),则
R3 = BYTEOP2P(R1:0, R3:2);
将在单个周期内同时计算出两个像素的平均值,前提是 x1 (N, S, E, W)信息存储在 R1 和R0,x2 (N, S, E, W)则从 R3 和 R2 取出。
关于 DMA 的考虑
具备二维 DMA(2D DMA)能力的嵌入式媒体处理器可以在系统层次上提供若干优点。对于新手而言,2D DMA 可以实现宏块对应于外部存储器的来回传递,从而使得对数据的处理成为实际传输的一部分。这消除了传输非连续数据时相应出现的开销。它还可以让系统进行有选择性的传输,即仅传输输入图像中为人们所需要的区域,而不是传输整幅图像,从而尽可能减小数据的带宽。
另一个实例是,2D DMA 可以让数据置入存储器的顺序更顺应处理的需求。例如,如图 5 所示,RGB 数据可以从一个 CCD 传感器以交织的 RGB444 格式进入处理器的 L2 存储器,但是在使用 2D DMA 的情况下,它可以以分离的 R、G 和 B平面形式传送到 L3 存储器中。对视频和图象数据颜色空间的分量进行交织/解交织化在处理前节省了额外的数据搬移。
平面化和间插式缓冲格式的对比
在“存储缓冲采用交织的结构还是平面化的结构?”这一问题上,你应该如何做出决策?交织的数据的优点是,它是图像传感器的自然输出格式,而且也是视频编码器自然而然的输入格式。不过,平面化的缓冲器(即每个像素分量存储在存储器中相互分离的区域中)对许多视频算法而言是更为有效的结构,因为它们中的许多(包括 JPEG 和 MPEG)都是依靠单独的亮度和色度信号来工作的。此 外,对 L3 中平面化缓冲器的访问,其效率要比跨越交织数据进行读取的操作更高,这是因为,当缓冲器采用平面化结构时, SDRAM页面缺失造成的延迟会随着图样尺寸的大幅增加而发散。
双重缓冲
我们在前面已经讨论了对双重缓冲的需求,这是因为它可以确保当前数据不被新的数据所覆盖,直到你已经为这种覆盖做好准备为止。对视频显示缓冲区的管理就是这一方法的绝好实例。通常,在系统中,如果各种视频源与最终显示的内容之间存在传输速率差异的话,就应该保证在老的内容和新的视频帧之间实现平滑的切换。这是利用双缓冲管理方法来实现的。一个缓冲区指向目前的视频帧,该帧被以一定的刷新速率送到显示器上。第二个缓冲区则用最新输出的帧来填充。当后一个缓冲器被填满时,DMA 发出中断信号,指示现在应该将新的帧发送到显示器上。此时,第一个缓冲区开始填充经过处理的、用于显示的视频信号,而第二个缓冲区则输出当前的显示帧。这两个缓冲区以“乒乓”方式来回切换。
我们应该注意的是,系统可以使用多个缓冲区而不仅仅是两个,以便为同步化提供更大的余地,并降低中断发生的频率及其相应造成的延迟。