关 闭

新闻中心

EEPW首页 > 安全与国防 > 设计应用 > 并行处理的H.264到AVS转码器设计

并行处理的H.264到AVS转码器设计

作者:时间:2016-12-23来源:网络收藏

  1 引言

  转码应用涉及视频服务器、通用多媒体访问设备、监控系统、机顶盒、DVD等多媒体设备和系统。其基本原则是在环境和处理能力受限的情况下,在码流转换的质量和复杂性之间取得最佳折衷。实现的关键是对压缩视频码流中的压缩数据进行复用,避免重新编码中的复杂运算。研究中的转码技术主要包括:码率转换、分辨率转换、帧率转换、语法转换等。

  MediaCoder是目前比较优秀的一款转码软件,它将众多来自开源社区优秀的音视频软件整合于一个友好的图形界面。它可以直接、批量地在众多音频视频压缩格式和容器格式之间转换,支持的格式包括H.264,Xvid,MPEG-1/2/4等,但是没有将AVS视频编码标准融合进来。本文介绍的软件解码器实现了H.264到AVS两个视频编码标准的转码。针对这两个标准的硬件转码器还在研发之中,上海龙晶微电子有限公司基于AVS标准提出了国内第一款具有完全自主知识产权的高清电视解码芯片DS10000。双核技术的广泛应用可用并行处理办法加快速度。视频转码可分为同类视频转码技术和不同类视频转码技术。

  2 像素域和变换域转码结构

  图1是空域转码器结构框图,将H.264码流进行熵解码和反量化,然后逆DCT变换,得到像素域的像素值;根据解码的运动矢量和频域残差数据进行运动估计(Motion Estimation,ME),根据得到的运动矢量进行运动补偿(Motion Compensation,MC);再将得到的残差数据进行变换和量化、熵编码形成AVS码流。



  图2是变换域转码器结构框图,转码中不需要解得像素域的像素值,H.264码流经过熵解码和反量化,在频域中进行补偿,得到频域中重构的HT系数值,然后由H.264中的4×4HT系数变换成AVS中的8×8HT系数,根据H.264中解码得到的运动矢量和HT系数值来进行运动估计ME,由得到的8×8HT系数值在频域进行误差补偿;进行量化和熵编码形成AVS码流。

  3 多线程转码器设计

  应用程序加载到内存中,给出一个执行点称为线程。线程是系统需要分配CPU时间的基本执行单元。单个进程在任何时刻可包含多个线程,它们可同时执行进程地址空间内的代码。

  1) 子线程的创建与终止

  VC++应用程序的主线程在创建应用程序时生成,创建子线程可通过调用CreateThread函数创建,其格式:

HANDLE = CreateThread (LPSECURITY ATTRIBUTES Ipsa,DWORD cbstack,LPTHREAD START ROUTINE lpStartAd2dr,LPVOIDlpvThreadParm,DWORD fdwCreate,LPDWORD lpIDThread);

  在本转码器中,子线程创建方法如下:

slot=0; hThrds[slot]=CreateThread(NULL,0,ThreadFunc,(LPVOID)slot,0,&threadID).

  2) 转码器的多线程实现结构

  由图1和图2可以看出,转码器的解码和编码部分是相对独立的。虽然在编码端要用到解码得到的运动矢量、分块模式还有频域中的系数等信息,如果是单线程程序的话,在编码到这一帧时,解码程序就要停止,只有当编码这一帧的程序执行完后,才能开始执行下一帧的解码程序。所以,在解码时编码程序停止,在编码时解码程序停止,这将花费大量的时间来等待。

  如果是在双核或者多核计算机上,可采用并行处理的方法,可启动两个或多个线程,一个解码线程和一个编码线程,在编码第n帧时,同时解码第n+1帧,达到解码和编码同时执行的效果。考虑到对系统内存的要求,这里设置缓存区的大小为2,多线程转码器实现框架如图3所示。

  多线程转码器执行顺序如下:当解码第n帧完成,判断第n-1帧是否已经编码完成,如果没有完成,则等待编码第n-1帧直到它完成,如果第n-1帧已完成,则开始解码第n+1帧,并同时开始编码第n帧;当第n+1帧解码完成时,再判断第n帧编码是否完成,若没完成,则等待它完成,若完成,则开始编码第n+1帧,然后令n=n+2,进行循环。所以,实现了编码和解码并行处理,解码当前帧和编码前一帧是同时进行的。

  3) 多线程转码器的具体实现方法

  缓存区大小设置为2,奇数帧共用一组变量,偶数帧共用一组变量。H.264中解码的当前帧序号用img->number表示,AVS编码端编码的当前帧序号用img_avs->number表示。在解码第n+2帧时,decode_slice()解码一帧的函数前面加上判断是否编码完第n帧:

if (img->number=(img_aVs->number+2))WaitForSingleObject(hThrds[0],INFINITE);

  解码第n+2帧完成时,等待编码线程结束,Wait-ForSingleObjeet(hThrds[0],INFINITE),然后开始一个新的进程:

slot=0;hThrds[0]=CreateThread(NULL,0,ThreadFunc,(LPVOID)slot,0,&threadID)

  在整个程序执行完之前,等待线程执行完以后,再结束整个转码程序。

  4 仿真结果

  测试序列:foreman,格式为CIF(352×288),编码成IPPPPIPPP…,264量化系数为28,AVS端编码的量化系数为36,编码帧数为100帧。

  计算机配置:Intel奔腾1.6 GHz,内存1 Gbyte,Win-dows XP sp2操作系统。

  对于串行单线程的方式,平均转码一帧的时间为113.57 ms;并行多线程的方式,平均转码一帧的时间为80.19 ms。所以使用多线程编码的方式,由于编码和解码同时执行,时间可节约41.63%,转码速度是单线程编码方式的1.42倍。这是因为进程调度也要花费一定时间,所以双线程编码的速度没有达到单线程编码的2倍。本文中,考虑到对存储的要求,缓存区仅设置为2,使用的是一种乒乓式的访问策略,解码端和编码端在每一时刻都分别只访问一组存储空间,不会同时访问一组存储空间。如果把缓存区设置得更大一点,速度将还会有大幅度的提高。



评论


技术专区

关闭