基于Linu的视频传输系统(方案)_第1页
基于Linu的视频传输系统(方案)_第2页
基于Linu的视频传输系统(方案)_第3页
基于Linu的视频传输系统(方案)_第4页
基于Linu的视频传输系统(方案)_第5页
已阅读5页,还剩18页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

名目原创性声明 3\l“_TOC_250009“摘要 4\l“_TOC_250008“系统方案 4功能与指标 4\l“_TOC_250007“方案选择与论证 4\l“_TOC_250006“系统组成框图 4硬件平台介 4视频采集方案的选择 4视频编码方案的选择 5视频传输方案的选择 6\l“_TOC_250005“显示方案选择 6系统软件实现 6效劳器 6\l“_TOC_250004“视频采集模块 6\l“_TOC_250003“视频压缩模块 10\l“_TOC_250002“网络传输发送模块 13客户端 19\l“_TOC_250001“网络传输接收模块 19\l“_TOC_250000“视频解码模块 19视频显示模块 22四系统测试 25附录:源代码参考书目12023年英特尔杯大学生电子设计竞赛嵌入式系统专题邀请赛参赛作品原创性声明果由本人担当。参赛队员签名:日期:年月日2摘要VIDEO4LINUXXVIDRTPABSTRACTOnthebasisofLinuxplatform,thissystemrealizesthevideodata”scollection,compressionandnetworktransmission.Thevideodata”scollectionisrealizedthroughUSBcameraandnetworktransmissionisrealizedbyRtpprotocalwhichisdesignedforstreammedia.Allofthesemakehignreal-timeperformance.关键词:视频RTPXVIDSDL系统方案实现功能与指标MPEG4JRTPYUV100KB图像大小平均为5KB,在局域网环境下延迟小于0.5秒,视频清楚无失真。鉴于效劳器的主频限制,组5,5方案选择与论证系统组成框图:USB摄像头10网络远程登录主机硬件平台介绍:硬件平台介绍:GENE-8310AAEON3理与传输的效劳器。视频采集方案的选择:LINUX有自带的摄像头驱动模块Video4Linux.Video4Linux为针对视频设备的应用程序编程供给一系列USBI/Oopenclose视频应用程序Video4Linux2视频编解码方案的选择Xvid作为其次代MPEG-4编码具有多方面的优点,XVID是DIVX开发小组因不满DIVX被封闭而在其根底上开发的源码开放的视频编码解码平台。对于其次代的MPEG4视频编码内核来说。XVID的各种特点都有代表性和先进意义。1.它支持多种编码模式:除了最原始的单重估定码流压缩〔1-pass CBR之外部掌握和内部掌握的两种双重(2-pass)动态码流压缩模式。2.在量化方式上Xvid不仅供给了标准的MPEG量化方式,还特地供给了更适合低码流压缩的.h263量化方式。3.除了量化方式迭择,Xvid还供给了强大的对压缩过程中的量化幅度的范围掌握。用户可以选定压缩时允许使用的量化幅度范围。例如设定一个量化的上限,就可以避开可能消灭的画质大幅下降的状况4.在运动侦测(MotionSearch)和曲平衡安排(Curve)方面,XVID对画面帧进展运动侦测以及对全片段的运动侦测结果进展分析后,重以曲线平衡安排每一帧的量化幅度以做到:需要高码流的运动画面可以安排更多空间更高的码流更低的量化幅度来保持画面的细节;而对于不包含太多运动信息的静态画面则消减安排预算这种把好钢用在刀刃上的做法,是Xvid作为其次代MPEG-4编码的核心内容。5.Xvid供给了多极运动侦测精度,包括半像素插值的技术以16x16像素的微区块为单元标示上运动矢量:以及4分运动矢量(inter4vmotionvectors)的方式,以8x8的像素区块为单元更细致的纪录运动向量以供二重分析。6.动态关键帧距是另一个Xvid所具有的在空间和画面之间获得最大平衡的技术我们知道在视频压缩中不是每一帧都记录着全部的画面信息事实上只有关键帧记录着完整的画面信息而后续的P帧(P-Frame)仅仅是纪录下与之前一帧的差值假设关键帧之间的画面变化很大则会铺张贵重的空间在P-Frame上;而参加把后续的帧不再有更大的变化就可以节约P帧所需的空间。因此,依据画面镜头切换和运动幅度来变换关键帧的位置,对于视频压缩下的画面质量提高,就有着事半功倍的效果。4视频传输方案的选择TCPUDP,TCP实时性较高。TransportProtocol,RTP〕Internet〔Unicast,单播〕或者一对多〔Multicast,多播〕的网络环境中实现传流媒体数据的实时传输。RTPUDPUDPTCPRTP显示方案选择SDL〔SimpleDirectMediaLayer〕是一个跨平台的多媒体玩耍支持库。其中包含了对图形、声音、线程等等的支持,目前可以运行在很多平台上,其中包括XWindow、XWindowwithDGA、LinuxFrameBuffer掌握台等等。SDL比方Alpha混和、透亮处理、YUV掩盖、Gamma校正等等。而且在SDL环境中能够格外便利地加载支持OpenGL的MesaSDLYUVSDL视频信息接收接压后的显示。系统软件实现效劳器效劳器实现了采集数据然后压缩后进展实时传输,用了三个线程分别实现了视频的采集压缩〔线程2〕,压缩后视频流的传输〔3〕。效劳器应用程序运行后,效劳器即创立线程122获得客IPIP3,3JRTP缩模块,和网络传输发送模块。〔1〕视频采集模块Linux内核公开支持的OV511等摄像头芯片,但由于较陈旧在市面不简洁找到。我们选用LOGITECH5的QUICKCAMCOOL摄像头并从网上下载摄像头驱动程序qc-usb-0.6.3.tar.gz然后进展解压、编译、安装。LinuxUSB摄像头的安装与驱动。USBVideo4LinuxAPI函数集来编写视频采集程序。Linux下,全部外设都被看成是一种特别的文件,称为设备文件。系统调用是内核和应用程序之间的操作。LinuxVideo4LinuxAPI,视频应用程序通过标准的系统调用即可操作各种不同的视频捕获设备。Video4Linux向虚拟文件系统注册视频设备文件,应用程序通过操作视频设备文件实现对视频设备的访问。Linux1所示开启视频设备〔〕猎取设备信息及图像信息〔〕〔〕帧数据〔〕关闭视频设备〔〕送压缩模块是否中止采集终止开头NY62LINUX下视频采集流程图Video4Linux视频设备数据构造的定义structvdInintfd;//文件描述符char*videodevice;//视频捕获接口文件structvideo_mmapvmmap;structvideo_capabilityvideocap;//包含设备的根本信息〔设备名称、支持的最大最小区分率、信号源信息等〕intmmapsize;structvideo_mbufvideombuf;映射的帧信息,实际是映射到摄像头存储缓冲区的帧信息,包括帧的大小〔size〕,最多支持的帧数〔frames〕每帧相对基址的偏移〔offset〕structvideo_picturevideopict;//采集图像的各种属性structvideo_windowvideowin;structvideo_channelvideochan;intcameratype;//是否能capture,彩色还是黑白,是否VID_TYPE_CAPTURE等

能裁剪等等。//设备名称charbridge[9];intpalette;//availablepaletteintchannel//信号源个数intgrabMethod;unsignedchar*pFramebuffer;//指向内存映射的指针unsignedchar*ptframe[4];//指向压缩后的帧的指针数组intframelock[4];//pthread_mutex_tgrabmutex;//视频采集线程和传输线程的互斥信号intframesizeIn;//视频帧的大小volatileintframe_cour;//指向压缩后的帧的指针数组下标intbppIn;//采集的视频帧的BPPinthdrwidth;//采集的视频帧的宽度inthdrheight;//采集的视频帧的高度intformatIn;//采集的视频帧的格式intsignalquit;//停顿视频采集的信号};在视频采集之前,先要对Video4Linux进展初始化7ioctl(intfd,indcmd,…)函数和设备进展“对话”。Fd是设备的文件描述符,cmd是用户程序对设备的掌握命令,省略号一般是一个表示类型长度的参数,也可以没有。初始化步骤如下:翻开视频:open(vd->videodevice,O_RDWR))读video_capabilityioctl(vd->fd,VIDIOCGCAP,&(vd->videocap))vd->capability各重量video_picture中信息调用函数ioctl(vd->fd,VIDIOCGPICT,&(vd->picture))video_picturevd->videopictioctl(vd->fd,VIDIOCSPICT,&vd->videopict)即可实现对图象截取有两种方式:第一种是用read直接读取数据,其次种是用mmap是把设备文件映射到内存,用内存映射法一个显而易见的好处是效率高,由于进程可以直接读写内存,而不需要任何数据的拷贝,所以我们选择这种方法。具体做法是1ioctl(vd->fd,VIDIOCGMBUF,&(vd->videombuf))把摄象头对应的设备文件映射到内存区。调用函数vd->pFramebuffer= (unsignedchar*)0),成功调用后设备文件内容映射到内存区,返回的映象内存区指针给vd->pFramebuffer,失败时返回-1。vd->vmmapvd->vmmap.height=vd->hdrheight;vd->vmmap.width=vd->hdrwidth;vd->vmmap.format=vd->formatIn;图象采集可分为单帧采集和连续帧采集,在本系统中承受连续帧采集的方法采集。将vd->videombuf.framese2&(vd->vmmap)函数,假设调用成功,则激活设备真正开头一帧图像的截ioctl(vd->fd,VIDIOCSYNC,&vd->vmmap.frame)函数推断该帧图像是否截取完毕,成功返回表示截取完毕,之后就可将采集到的帧进展压缩,然后将压缩后的文件vd->vmmap.frame,vd->frame_cour〔2〕视频压缩模块对图像帧的编码是通过调用xvidcore-1.1.0XVID之前要对XVID进展初始xvid_enc_createXVID_ENC_CREATE,&xvid_enc_create,NULL)建立编码器,初始化函数如下:Intenc_init(intuse_assembler){intxerr;xvid_plugin_single_tsingle;//运算参数xvid_plugin_2pass1_trc2pass1;8xvid_plugin_2pass2_trc2pass2;xvid_enc_plugin_tplugins[7];xvid_gbl_init_txvid_gbl_init;//xvidxvid_enc_create_txvid_enc_create;//xvid/*Setversion--versioncheckingwilldonebyxvidcore*//*------------------------------------------------------------------------*XviD初始化参数*----------------------------------------------------------------------*/memset(&xvid_gbl_init,0,sizeof(xvid_gbl_init));xvid_gbl_init.version=XVID_VERSION;xvid_gbl_init.debug=0;//设置版本号/*DowehavetoenableASMoptimizations?*/if(use_assembler){xvid_gbl_init.cpu_flags=0;}xvid_global(NULL,XVID_GBL_INIT,&xvid_gbl_init,NULL);//初始化/*------------------------------------------------------------------------*XviD编码器参数*----------------------------------------------------------------------*/memset(&xvid_enc_create,0,sizeof(xvid_enc_create));xvid_enc_create.version=XVID_VERSION;//设置版本号xvid_enc_create.width=XDIM;//编码器输入宽度xvid_enc_create.height=YDIM;//编码器输入高度xvid_enc_fileXVID_PROFILE_S_L3;//编码的框架级别/*initplugins*/xvid_enc_create.zones=NULL;xvid_enc_create.num_zones=0;xvid_enc_create.plugins=NULL;xvid_enc_create.num_plugins=0;9/*Nofancythreadtests*/xvid_enc_create.num_threads=0;/*Framerate-Dosomequickfloatfps=fincr/fbasehack*/if((ARG_FRAMERATE-(int)ARG_FRAMERATE)<SMALL_EPS){xvid_enc_create.fincr=1;xvid_enc_create.fbase=(int)ARG_FRAMERATE;}else{xvid_enc_create.fincr=FRAMERATE_INCR;xvid_enc_create.fbase=(int)(FRAMERATE_INCR*ARG_FRAMERATE);}if(ARG_MAXKEYINTERVAL>0){xvid_enc_create.max_key_interval=ARG_MAXKEYINTERVAL;}else{xvid_enc_create.max_key_interval=(int)ARG_FRAMERATE*10;}//关键帧之间的间距xvid_enc_create.max_bframes=0;//Bxvid_enc_create.bquant_ratio=150;xvid_enc_create.bquant_offset=100;xvid_enc_create.frame_drop_ratio=0;//0100/*Globalencoderoptions*/xvid_enc_create.global=0;/*Iuseasmallvaluehere,sincewillnotencodewholemovies,butshortclips*/xerrxvid_encore(NULL,XVID_ENC_CREATE,&xvid_enc_create,NULL);/*创立编码器,但创立enc_mainret=xvid_encore(enc_handle,XVID_ENC_ENCODE,&xvid_enc_frame,&xvid_enc_stats)时*/enc_handle=xvid_enc_create.handle;10return(xerr);}I设置成-1IPI以更快更好地修正、掩盖错误。XVIDIntenc_main(unsignedchar*image,unsignedchar*bitstream,int*key,int*stats_type,int*stats_quant,int*stats_length,intsse[3]){intret;xvid_enc_frame_txvid_enc_frame;xvid_enc_stats_txvid_enc_stats;memset(&xvid_enc_frame,0,sizeof(xvid_enc_frame));xvid_enc_frame.version=XVID_VERSION;//帧版本号memset(&xvid_enc_stats,0,sizeof(xvid_enc_stats));xvid_enc_stats.versionXVID_VERSION;//编码状态版本号/*Bindoutputbuffer*/xvid_enc_frame.bitstream=bitstream;xvid_enc_frame.length=-1;/*Initializeinputimagefields*/if(image){11xvid_enc_frame.input.plane[0]=image;xvid_enc_frame.input.cspXVID_CSP_I420;//视频输入格式xvid_enc_frame.input.stride[0]=XDIM;}else{xvid_enc_frame.input.csp=XVID_CSP_NULL;}xvid_enc_frame.vol_flags=0;xvid_enc_frame.vop_flags=vop_presets[ARG_QUALITY];/*Frametype--letcoredecideforus*/xvid_enc_frame.typeXVID_TYPE_AUTO;//自动打算帧格式/*Forcetherightquantizer--ItisinternallymanagedbyRCplugins*/xvid_enc_frame.quant=3;xvid_enc_frame.motion=motion_presets[ARG_QUALITY];/*Wedon”tusespecialmatrices*/xvid_enc_frame.quant_intra_matrix=NULL;xvid_enc_frame.quant_inter_matrix=NULL;ret=xvid_encore(enc_handle,XVID_ENC_ENCODE,&xvid_enc_frame,xvid_enc_stats*key=(xvid_enc_frame.out_flags&XVID_KEYFRAME);*stats_type=xvid_enc_stats.type;*stats_quant=xvid_enc_stats.quant;*stats_length=xvid_enc_stats.length;sse[0]=xvid_enc_stats.sse_y;sse[1]=xvid_enc_stats.sse_u;sse[2]=xvid_enc_stats.sse_v;return(ret);}网络传输发送模块12流媒体协议分析:TransportProtocol,RTP〕Internet协议,利用它能够在一对一〔Unicast,单播〕或者一对多〔Multicast,多播〕的网络环境中实现传流媒体数据的实时传输。RTPUDPRTPLinux平RTPJRTPLIB3.5.2。JRTPLIB是一个面对对RFC3550RTP库,而且目前仍在维护API〔RTCP〕jrtplib内部实现。RTPRTP〔Header〕〔Payload〕12频数据。RTP3.1V=2 PX CC MPT时间戳(SSRC)(CSRC)

序列号3.1RTP其中几个域及其意义如下:其中几个域及其意义如下:版本号(V):标明RTP补充位(P):假设该位被设置,则在该packet末尾包含了额外的附加信息。扩展位(X):假设该位被设置,则在固定的头部后存在一个扩展头部。标记位(M)::M=1时,表示一帧的完毕,下一个发送或接收的RTP数据包为的一帧。〔CC〕:CSRCCSRCRTPRTP来源。负载类型〔PT〕:标明RTP负载的格式,包括所承受的编码算法、采样频率等。常用的PT值如图3.213所示:所示:PT编码标准采样速率〔HZ〕26JPEG9000031H.2619000034h.26390000图3.2 常用的负载类型及PT值RTP本身并不负责数据的重传。抖动的影响,但具体如何来补偿延迟抖动则由应用程序本身负责。RTP的流媒体传输供给了相应的根底。RTP和分段〔Segmentation〕就足够了;RTP序本身来保证。RTP3.3具体的应用程序RTP/RTCPUDP TCPIPv4/IPv6局域网/广域网3.3RTPRTCPRTCPRTPRTCP14不同的RTCP数据报来实现的,主要有如下几种类型:(RRRTP〔SDES〕:主要功能是作为会话成员有关标识信息的载体,如用户名、邮件地址等,此外还具有向会话成员传达会话掌握信息的功能。话。RTCP的掌握信息,来了解其他参与者的当前状况。SR,RTCP流间的同步信息,以及已经发送的数据报和字节的计数,接收端依据这些信息可以估量出实际的数据传RR,RTCP报的最大序列号、丧失的数据报数目、延时抖动和时间戳等重要信息,发送端应用依据这些信息可以估量或者依据网络状况平滑地调整应用程序的效劳质量。环境搭建:JRTPLIBC++RTP库。为Linux系统安装JRTPLIB,从JRTPLIB“://lumumba.luc.ac.be/jori/jrtplib/jrtplib.html“://lumumba.luc.ac.be/jori/jrtplib/jrtplib.html下载最的源码包jrtplib-3.5.2.tar.bz2。同时为了参加对线程的支持,需要单独下载jthread1.2.0.tar.bz2.。将下载后的源码包保存在/usr/local/srcbzip2-dcjrtplib-3.5.2b.tar.bz2|tarxvf–进展配置和编译:cdjrtplib-3.5.2makeJRTPLIB的安装:makeinstall。流媒体编程RTPSessionRTP会话;RTPSessionsession;UDPIpv415Ipv4。在真正创立会话之前还需设置两个参数:第一个参数为设置恰当的时戳单元RTPSessionParamssessionparams;1.0/90000.0RTP90000Hz90000.0,所以时戳单元应当被设1/90000.01.0/8000.0。IPv4RTPUDPv4TransmissionParams,其中要设置的参数为数据传输所用的端口号。RTPUDPv4TransmissionParamstransparams;transparams.SetPortbase(localportbase);create函数真正创立会话:假设RTP会话创立过程失败,Create方法将返回一个负数,通过它虽然可以很简洁地推断出函数调用到底是成功的还是失败,却很难明白出错的缘由到底什么。JRTPLIB的全部函数假设返回负数就说明消灭了某种形式的错误,而具体的出错信息则可以通过调用息。RTPIPv4ADDRESSaddr(desIP,desportbase);session.AddDestination(addr);session.SetDefaultPayloadType;session.SetDefaultMark;session.SetDefaultTimestampIncrement;函数实现的。intSendPacket(constvoid*data,size_tlen,uint8_tpt,boolmark,uint32_ttimestampinc);len,ptmark为标志位,01,可以使用此标志位推断一帧的开头或完毕。用于表示是否是同一帧数据,对于同一帧数据设置同一时间戳。接收端也可以依据时间戳来推断一帧数据的开头或完毕。intSendPacket(constvoid*data,size_tlen,uint8_tpt,boolmark,uint32_ttimestampinc,uint16_thdrextID,constvoid*hdrextdata,size_tnumhdrextwords);此函数用于发送带附加报头的数据帧。hdrextID用于对不同的报头进展编号,numhdrextwords。16程序流程框图:程序流程框图:开头发送1400字节?通过RTP发送数据将该帧拆成几个不大于1400字节的数据包组帧并发送给解码线程接收到RTP包时间戳与上一个一样?网络循环接收直到不同时间戳的RTP包RTP接收数据NN17YY图3 网络发送接收程序流程图对程序流程图的说明:发送端拆帧的算法如下:If1400直接用RTPSessio::SendPacket发送出去;}else{端对数据的接收。}接收端组帧算法如下:while(RTPRTP{把接收到的数据保存在缓存中。}率更低,且实时性更强,传输质量明显提高。客户端网络传输接收模块JrtpJthread的支持,使得具体的数据接收在后台运行,只需改写类RTPSessionOnPollThreadStep和ProcessRTPPacket(constRTPSourceDataRTPPacket&rtppackRTP会话中允许有多个参与者,通过调用RTPSession类的GotoFirstSourceWithData和GotoNextSourceWithData方法来遍历那些携带有数据的源。在函数OnPollThreadStep中,为了正确接收同一数据源的数据据,必需先对数EndDataAccess实现对数据源表的解锁。(constRTPSourceData&srcdat,constRTPPacket&rtppack);中对接收到的数据包进展处理。18首先调用char*payloadpointer=(char*)rtppack.GetPayloadData得到源数据包的指针,并通过rtppack.HasMarker到的包临时保存到内存缓冲区中,等到有足够的帧数据后再调用解码线程进展解码。memcpy(receivepointer,payloadpointer,rtppack.GetPayloadLength)将数据临时保存在receivepointerJRTPLIBRTP数据报定义了三种接收模式,其中每种接收模式都具体规定了哪些到达的RTP数据报RTPSessionSetReceiveMode方法可以设置以下这些接收模式:RECEIVEMODE_ALL:为缺省的接收模式,全部到达的RTP数据报都将被接收;RECEIVEMODE_IGNORESOME:除了某些特定的发送者之外,全部到达的RTP数据报都将被接收,AddToIgnoreListDeleteFromIgnoreListClearIgnoreList方法来进展设置;RECEIVEMODE_ACCEPTSOMERTP数据AddToAcceptList、DeleteFromAcceptList和ClearAcceptList方法来进展设置。视频解码模块客户端解码的流程图如下所示:设置解码帧缓冲区停顿显示解码一帧VOL头YNYNSDL显示终止19开头Dec_init解码初始化YUV在调用解码模块之前要正确的初始化解码器。初始化解码器的程序如下所示:staticintdec_init(intuse_assembler,intdebug_level){intret;xvid_gbl_init_txvid_gbl_init;xvid_dec_create_txvid_dec_create;memset(&xvid_gbl_init,0,sizeof(xvid_gbl_init_t));memset(&xvid_dec_create,0,sizeof(xvid_dec_create_t));/*------------------------------------------------------------------------*XviD核心初始化*----------------------------------------------------------------------*//*Version*/xvid_gbl_init.version=XVID_VERSION;//版本号/*Assemblysetting*/if(use_assembler)xvid_gbl_init.cpu_flags=0;elsexvid_gbl_init.cpu_flags=XVID_CPU_FORCE;xvid_gbl_init.debug=debug_level;xvid_global(NULL,0,&xvid_gbl_init,NULL);/*------------------------------------------------------------------------20*XviD解码器初始化*----------------------------------------------------------------------*/xvid_dec_create.version=XVID_VERSION;//解码器版本号xvid_dec_create.width=0;//帧的宽自动适应xvid_dec_create.height=0;//帧的高自动适应ret=xvid_decore(NULL,XVID_DEC_CREATE,&xvid_dec_create,NULL);//创立解码实例dec_handle=(int*)xvid_dec_create.handle;//传递句柄return(ret);}xvid_decore(dec_handle,XVID_DEC_DECODE,&xvid_dec_frame,xvid_dec_stats)将得xvid_dec_stats如下:staticintdec_main(unsignedchar*istream,unsignedchar*ostream,intistream_size,xvid_dec_stats_t*xvid_dec_stats){intret;xvid_dec_frame_txvid_dec_frame;/*Resetallstructures*/memset(&xvid_dec_frame,0,sizeof(xvid_dec_frame_t));memset(xvid_dec_stats,0,sizeof(x

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论