ortp移植到hi3518eh.264封包rtp发送

合集下载

H.264视频流RTP打包的传输与实现

H.264视频流RTP打包的传输与实现

H.264视频流RTP打包的传输与实现
近年来,随着宽带Internet网络的广泛普及以及多媒体技术的迅速发展,人们对Internet视频信息越来越倾向于以形象直观的方式获取。

基于网络的视频流实时传输技术的研究正逐渐被应用在生活及科研领域中。

但由于实时网络视频流需要传输庞大的数据量,因此不但对视频压缩技术提出了更高的要求,而且对网络传输协议的选择也显得极其重要。

本文详细分析了H.264视频标准的编码特性和实时传输协议RTP(Real-time Transport Protocol)。

由ITU-T和MPEG共同制定的新一代视频编码标准H.264把编解码分为NAL 和VCL两层,而且应用了几种新的错误恢复技术,使其拥有更出色的压缩性能和更好的网络适应性。

现有Internet网络的尽力而为特性对视频数据的网络传输提出了更大的要求,RTP/RTCP协议是IETF制订的实时流媒体传输标准,不但引入时间戳和递增序号而且利用RTCP来反馈QoS信息,广泛应用于多媒体通信。

基于以上的理论,在设计中深入研究了适合于网络传输的H.264NALU结构和RTP载荷结构,然后提出了一种适合于网络传输的单一打包和分组打包相结合的RTP打包方式,最后利用VC++6.0实现了对H.264视频流的RTP打包传输机制,并在接收端利用抓包工具wireshark进行验证,完成了预计设计目标。

RTP协议全解(H264码流和PS流)-2015-4-22

RTP协议全解(H264码流和PS流)-2015-4-22

RTP协议全解(H264码流和PS流)写在前面:RTP的解析,网上找了很多资料,但是都不全,所以我力图整理出一个比较全面的解析,其中借鉴了很多文章,我都列在了文章最后,在此表示感谢。

互联网的发展离不开大家的无私奉献,我决定从我做起,希望大家支持。

原创不易,转载请附上链接,谢谢/chen495810242/article/details/392073051、RTP Header解析图11) V:RTP协议的版本号,占2位,当前协议版本号为22) P:填充标志,占1位,如果P=1,则在该报文的尾部填充一个或多个额外的八位组,它们不是有效载荷的一部分。

3) X:扩展标志,占1位,如果X=1,则在RTP报头后跟有一个扩展报头4) CC:CSRC计数器,占4位,指示CSRC 标识符的个数5) M: 标记,占1位,不同的有效载荷有不同的含义,对于视频,标记一帧的结束;对于音频,标记会话的开始。

6) PT: 有效荷载类型,占7位,用于说明RTP报文中有效载荷的类型,如GSM音频、JPEM图像等,在流媒体中大部分是用来区分音频流和视频流的,这样便于客户端进行解析。

7) 序列号:占16位,用于标识发送者所发送的RTP报文的序列号,每发送一个报文,序列号增1。

这个字段当下层的承载协议用UDP的时候,网络状况不好的时候可以用来检查丢包。

同时出现网络抖动的情况可以用来对数据进行重新排序,序列号的初始值是随机的,同时音频包和视频包的sequence是分别记数的。

8) 时戳(Timestamp):占32位,必须使用90 kHz 时钟频率。

时戳反映了该RTP报文的第一个八位组的采样时刻。

接收者使用时戳来计算延迟和延迟抖动,并进行同步控制。

9) 同步信源(SSRC)标识符:占32位,用于标识同步信源。

该标识符是随机选择的,参加同一视频会议的两个同步信源不能有相同的SSRC。

10) 特约信源(CSRC)标识符:每个CSRC标识符占32位,可以有0~15个。

java、android可用的rtp封包解包h264案例

java、android可用的rtp封包解包h264案例

java、android可⽤的rtp封包解包h264案例做直播,⾳视频通讯。

经常需要通过rtp协议封装⾳视频数据来发送。

⽹上找到的基本都是c或c++版本的,没有JAVA版本的。

就算千⾟万苦找到⼀篇java版本的,要么不能⽤,要么就是⼀些⽚段,要么有封包没解包。

很是蛋疼,本⼈也是这样,刚开始不太熟悉rtp协议,不太明⽩怎么封包组包,痛苦了⼏天,终于搞出来了,分享给有需要的朋友,希望对你们有所帮助。

直接看代码吧。

不多说了。

⾸先看看关键类:package com.imsdk.socket.udp.codec;import android.os.SystemClock;import android.util.Log;import java.io.ByteArrayInputStream;import java.io.IOException;import java.io.InputStream;import java.math.BigDecimal;import java.util.Random;import java.util.concurrent.Semaphore;public class RtspPacketEncode {private static final String TAG = "RtspPacketEncode";//------------视频转换数据监听-----------public interface H264ToRtpLinsener {void h264ToRtpResponse(byte[] out, int len);}private H264ToRtpLinsener h264ToRtpLinsener;//执⾏回调private void exceuteH264ToRtpLinsener(byte[] out, int len) {if (this.h264ToRtpLinsener != null) {h264ToRtpLinsener.h264ToRtpResponse(out, len);}}// -------视频--------private int framerate = 10;private byte[] sendbuf = new byte[1500];private int packageSize = 1400;private int seq_num = 0;private int timestamp_increse = (int) (90000.0 / framerate);//framerate是帧率private int ts_current = 0;private int bytes = 0;// -------视频END--------public RtspPacketEncode(H264ToRtpLinsener h264ToRtpLinsener) {this.h264ToRtpLinsener = h264ToRtpLinsener;}/*** ⼀帧⼀帧的RTP封包** @param r* @return*/public void h264ToRtp(byte[] r, int h264len) throws Exception {CalculateUtil.memset(sendbuf, 0, 1500);sendbuf[1] = (byte) (sendbuf[1] | 96); // 负载类型号96,其值为:01100000sendbuf[0] = (byte) (sendbuf[0] | 0x80); // 版本号,此版本固定为2sendbuf[1] = (byte) (sendbuf[1] & 254); //标志位,由具体协议规定其值,其值为:01100000sendbuf[11] = 10;//随机指定10,并在本RTP回话中全局唯⼀,java默认采⽤⽹络字节序号不⽤转换(同源标识符的最后⼀个字节)if (h264len <= packageSize) {sendbuf[1] = (byte) (sendbuf[1] | 0x80); // 设置rtp M位为1,其值为:11100000,分包的最后⼀⽚,M位(第⼀位)为0,后7位是⼗进制的96,表⽰负载类型 sendbuf[3] = (byte) seq_num++;System.arraycopy(CalculateUtil.intToByte(seq_num++), 0, sendbuf, 2, 2);//send[2]和send[3]为序列号,共两位{// java默认的⽹络字节序是⼤端字节序(⽆论在什么平台上),因为windows为⼩字节序,所以必须倒序/**参考:* /u011068702/article/details/51857557* /blog/1591261*/byte temp = 0;temp = sendbuf[3];sendbuf[3] = sendbuf[2];sendbuf[2] = temp;}// FU-A HEADER, 并将这个HEADER填⼊sendbuf[12]sendbuf[12] = (byte) (sendbuf[12] | ((byte) (r[0] & 0x80)) << 7);sendbuf[12] = (byte) (sendbuf[12] | ((byte) ((r[0] & 0x60) >> 5)) << 5);sendbuf[12] = (byte) (sendbuf[12] | ((byte) (r[0] & 0x1f)));// 同理将sendbuf[13]赋给nalu_payload//NALU头已经写到sendbuf[12]中,接下来则存放的是NAL的第⼀个字节之后的数据。

最新 基于Hi3510 和无线发送模块的视频传输设计-精品

最新 基于Hi3510 和无线发送模块的视频传输设计-精品

基于Hi3510 和无线发送模块的视频传输设计1.引言近几年,国内在嵌入式无线联网领域发送数据大都基于802.x 或WI-FI 技术,带以表现的是无限网卡或无线路由器。

目前也出现了基于手机无线发送数据的嵌入式相关设计,但大都是基于2.5G 技术的短信方式的监控的设计。

本文在此基础上设计了一个嵌入式linux 系统下利用3G 无线发送模块在移动网络上发送视频图像的系统。

本文涉及海思公司推出的一款SOC 高性能视频编解码芯片Hi3510,其具备强大的视频处理功能,可实现D1 画质的实时编码及传输。

随着中国3G 时代的到来,高宽带及多媒体技术获得高速发展,手机上语音视频数据的传输成为了人们了解外界事物的一条重要渠道,本文正是基于该芯片的优越性,从软件和硬件上设计实现了一个在3G 网络上传输视频的系统。

2.系统总体设计本文选用海思公司Hi3510 作为对视频数据的编码处理,选用联芯科技科技DTM6211无线模块作为对视频数据的发送处理。

其整体工作原理是:摄像头采集的数据通过PAL 制的CVBS 信号输入工作在主模式TW2834 芯片中,经A/D 转换后,由BT.656 接口接收转换后为CIF 格式的信号,并通过AHB 总线把接收到得图像数据存入到外存中(SDROM);Hi3510读取外存中视频数据,进行H.264 编码,包括帧内预测、帧间预测、DCT 变换、量化、熵编码等,得到编码后裸码流存储到外设中;将外设中视频数据通过USB 端口经测试版发送到无线模块中,其中关于无线模块的UDP 数据传输设置控制工作是通过Hi3510 的RS232中国科技论文在线接口经测试版发送AT 指令控制,然后无线模块将数据封装成符合UDP 格式的IP 数据包,最后利用PS 业务发送到网络。

3.系统硬件设计3.1 视频处理模块视频处理模块采用Hi3510,是海思公司推出的一款基于H.264 BP 算法的视频压缩芯片,该芯片采用ARM+DSP+硬件加速引擎的多核高集成度的SoC 构架,具备强大的视频处理功能。

海思方案 HI3518E平台ISP调试环境搭建

海思方案 HI3518E平台ISP调试环境搭建

3518E平台的搭建海思的SDK提供了ISP调试的相关工具,降低了IPC开发ISP调试的难度。

初次搭建ISP调试环境,记录一下。

SDK版本:Hi3518_MPP_V1.0.A.0硬件平台:HI3518E_OV9732工具包:PQ_TOOL (Hi3518E_V100R001C01SPC0A0\01.software\pc\PQ_TOOL)文件说明:Hi3518_ITTB_MPP2_V1.0.A.0_B030.tgz 设备端工具; PQTools_V3.7.5.zip PC端工具环境搭建步骤:(1)将Hi3518_ITTB_MPP2_V1.0.A.0_B030.tgz拷贝至nfs共享目录名,解压后运行HiIspTool.sh脚本倘若用海思自带的工具出图像并调节ISP运行:#./HiIspTool.sh -a -p ov9732_720p_line.inips一下可以看到两个进程696 adminlvj 58488 S ./ittb_stream -p ov9732_720p_line.ini699 adminlvj 19676 S ./ittb_control倘若运行自己的工程出图像了,这时只需要运行一下命令即可。

ps一下可以看到一个进程699 adminlvj 19676 S ./ittb_control(2)PC端直接解压PQTools_V3.7.5.zip,运行HiPQTools.exe,输入选择sdk版本Hi3518_MPP_V1.0.A.0 ,输入设备IP,就可以连接上摄像头倘若运行了ittb_stream,可以PC端软件上打开视频图像窗口连接成功,至此,最简单的ISP调试环境搭建就完成了。

复杂的就是后面的ISP调节过程了。

备注:运行脚本的时候可能会报错,查看相关打印信息,将错误消除。

当前产品我们用的是HI3518E+OV9732,SDK中并没有提供相关的sensor库和相关的config文件,所以运行报错了!解决:将OV9732sensor库拷贝至Hi3518_ITTB_MPP2_V1.0.A.0/libs/下,将ov9732_720p_line.ini拷贝至Hi3518_ITTB_MPP2_V1.0.A.0/configs/下附录:ov9732_720p_line.ini[plain]view plaincopyprint?1.[sensor]2.Sensor_type =ov9732 ;the type of sensor3.Mode =0 ;LINE mode,mode = 0 ,WDR mode,mode =14.DllFile =libs/libsns_ov9732.so ;LineDllFile path5.6.[vi_dev]7.Input_mod =2 ;VI_INPUT_MODE_BT656 = 08. ;VI_INPUT_MODE_BT601,9. ;VI_INPUT_MODE_DIGITAL_CAMERA10.11.Work_mod =0 ;VI_WORK_MODE_1Multiplex = 012.13. ;VI_WORK_MODE_2Multiplex,14.15. ;VI_WORK_MODE_4Multiplexbine_mode =0 ;Y/C composite or separation mode18.19. ;VI_COMBINE_COMPOSITE = 0 /*Composite mode */20.21. ;VI_COMBINE_SEPARATE, /*Separate mode */22.p_mode =0 ;Component mode (single-component or dual-component)24.25. ;VI_COMP_MODE_SINGLE = 0, /*single component mode */26.27. ;VI_COMP_MODE_DOUBLE = 1, /*double component mode */28.29.Clock_edge =1 ;Clock edge mode (sampling on the rising or falling edge)30.31. ;VI_CLK_EDGE_SINGLE_UP=0, /*rising edge */32.33. ;VI_CLK_EDGE_SINGLE_DOWN, /*falling edge */34.35.Mask_num =2 ;Component mask37.Mask_0 =0xFFC0000038.39.Mask_1 =0x040.41.Scan_mode = 1;VI_SCAN_INTERLACED = 042.43. ;VI_SCAN_PROGRESSIVE,44.45.Data_seq =2 ;data sequence (ONLY for YUV format)46.47. ;----2th component U/V sequence in bt112048.49. ; VI_INPUT_DATA_VUVU = 0,50.51. ; VI_INPUT_DATA_UVUV,52.53. ;----input sequence for yuv54.55. ; VI_INPUT_DATA_UYVY = 0,56.59. ; VI_INPUT_DATA_YUYV,60.61. ; VI_INPUT_DATA_YVYU62.63.64.65.Vsync =1 ; vertical synchronization signal66.67. ;VI_VSYNC_FIELD = 0,68.69. ;VI_VSYNC_PULSE,70.71.VsyncNeg=0 ;Polarity of the vertical synchronization signal72.73. ;VI_VSYNC_NEG_HIGH = 0,74.75. ;VI_VSYNC_NEG_LOW /*if VIU_VSYNC_E76.77.Hsync =0 ;Attribute of the horizontal synchronization signal78.81. ;VI_HSYNC_PULSE,82.83.HsyncNeg =0 ;Polarity of the horizontal synchronization signal84.85. ;VI_HSYNC_NEG_HIGH = 0,86.87. ;VI_HSYNC_NEG_LOW88.89.VsyncValid =0 ;Attribute of the valid vertical synchronization signal90.91. ;VI_VSYNC_NORM_PULSE = 0,92.93. ;VI_VSYNC_VALID_SINGAL,94.95.VsyncValidNeg =0;Polarity of the valid vertical synchronization signal96.97. ;VI_VSYNC_VALID_NEG_HIGH = 0,98.99. ;VI_VSYNC_VALID_NEG_LOW101.Timingblank_HsyncHfb =0 ;Horizontal front blanking width102.103.Timingblank_HsyncAct =1280 ;Horizontal effetive width104.105.Timingblank_HsyncHbb =0 ;Horizontal back blanking width106.107.Timingblank_VsyncVfb =0 ;Vertical front blanking height108.109.Timingblank_VsyncVact =720 ;Vertical effetive width110.111.Timingblank_VsyncVbb=0 ;Vertical back blanking height112.113.Timingblank_VsyncVbfb =0 ;Even-field vertical front blanking height(inter lace, invalid progressive)114.115.Timingblank_VsyncVbact=0 ;Even-field vertical effetive width(interlace, i nvalid progressive)116.117.Timingblank_VsyncVbbb =0 ;Even-field vertical back blanking height(inte rlace, invalid progressive)118.121.;----- only for bt656 ----------122.FixCode =0 ;BT656_FIXCODE_1 = 0,123.124. ;BT656_FIXCODE_0125.126.FieldPolar=0 ;BT656_FIELD_POLAR_STD = 0127.128. ;BT656_FIELD_POLAR_NSTD129.130.DataPath =1 ;ISP enable or bypass131.132. ;VI_PATH_BYPASS = 0,/* ISP bypass */133.134. ;VI_PATH_ISP = 1,/* ISP enable */135.136. ;VI_PATH_RAW = 2,/* Capture raw data, for debug */ 137.138.InputDataType=1 ;VI_DATA_TYPE_YUV = 0,VI_DATA_TYPE_RGB = 1, 139.142.143.[vi_chn]144.145.CapRect_X =0146.147.CapRect_Y =0148.149.CapRect_Width=1280150.151.CapRect_Height=720152.153.DestSize_Width=1280154.155.DestSize_Height=720156.157.CapSel =2 ;Frame/field select. ONLY used in interlaced mode158. ;VI_CAPSEL_TOP = 0, /* top field */159. ;VI_CAPSEL_BOTTOM, /* bottom field */160. ;VI_CAPSEL_BOTH, /* top and bottom field */162.PixFormat =19 ;163.164.165.166.SrcFrameRate=-1 ;Source frame rate. -1: not controll 167.168.FrameRate =-1 ;Target frame rate. -1: not controll169.170.171.[vpss_group]172.Vpss_DrEn =FALSE173.174.Vpss_DbEn =FALSE175.176.Vpss_IeEn =TRUE177.178.Vpss_NrEn =TRUE179.180.Vpss_HistEn =TRUE181.182.Vpss_DieMode=0 ;Define de-interlace mode183.184. ;VPSS_DIE_MODE_AUTO = 0,185.186. ;VPSS_DIE_MODE_NODIE = 1,187.188. ;VPSS_DIE_MODE_DIE = 2,189.190.[vpss_chn]191.Vpss_W =1280192.Vpss_H =720193.194.[isp_image]195.196.Isp_W =1280197.198.Isp_H =720199.200.I sp_FrameRate=30201.202.Isp_Bayer =3 ;BAYER_RGGB=0, BAYER_GRBG=1, BAYER_GBRG=2, BAYER_ BGGR=3203.205.[isp_timing]206.207.Isp_WndMode=0 ;WIND_NONE= 0,WIND_HOR= 1,WIND_VER= 2,WIND_A LL= 3,208.209.I sp_HorWndStart=0210.211.Isp_HorWndLength=1280212.213.Isp_VerWndStart=0214.215.Isp_VerWndLength=720216.217.[vb_conf]218.219.VbCnt=8220.221.222.[venc]223.224.RcMode =VENC_RC_MODE_H264CBR226.Gop =30227.228.StatTime =1229.230.ViFrmRate =30231.232.TargetFrmRate=25233.;----- only for VENC_RC_MODE_H264CBR ----------234.BitRate=4096235.FluctuateLevel=1236.;----- only for VENC_RC_MODE_H264VBR ----------237.MaxBitRate =10000238.239.MaxQp=32240.241.MinQp=24242.;----- only for VENC_RC_MODE_H264FIXQP ----------243.IQp=20244.245.PQp=23 246.247.[bind]248.249.V iDev =0 250.251.ViChn =0 252.253.VpssGrp =0 254.255.VpssChn = 0 256.257.VencGrp =0 258.259.VencChn =0 260.261.VoDev =0 262.263.VoChn =0 264.265.V iSnapChn =0266.267.VpssSnapGrp=0 268.269.V pssSnapChn=1 270.271.VencSnapGrp=1 272.273.VencSnapChn=1。

Hi3518EV20X/Hi3516CV200 SDK 安装以及升级使用说明

Hi3518EV20X/Hi3516CV200 SDK 安装以及升级使用说明
3) 执行source /பைடு நூலகம்tc/profile, 安装交叉编译器的脚本配置的环境变量就可以生效了,或者请重新登陆也可。
5、编译osdrv
参见osdrv目录下readme
6、SDK目录介绍
Hi3518E_SDK_Vx.x.x.x 目录结构如下:
|-- sdk.cleanup # SDK清理脚本
| |-- rootfs_*.tgz # rootfs压缩包
| `-- image_* # 可供FLASH烧写的映像文件,如内核、根文件系统
|-- scripts # 存放shell脚本的目录
在"Hi3518EV200R001***/01.software/board"目录下,您可以看到一个 Hi3518E_SDK_Vx.x.x.x.tgz 的文件,该文件就是Hi3518EV20X/Hi3516CV200 的软件开发包。
2、解压缩SDK包
在linux服务器上(或者一台装有linux的PC上,主流的linux发行版本均可以),使用命令:tar -zxf Hi3518E_SDK_Vx.x.x.x.tgz,解压缩该文件,可以得到一个Hi3518E_SDK_Vx.x.x.x目录。
4、在linux服务器上安装交叉编译器
1)安装uclibc交叉编译器(注意,需要有sudo权限或者root权限):
进入Hi3518E_SDK_Vx.x.x.x/osdrv/opensource/toolchain/arm-hisiv300-linux目录,运行chmod +x cross.install,然后运行./cross.install即可。
# Demo单板默认为从SPI Flash启动。

Hi3510工作原理,Hi3510 -H.264 BP算法的

Hi3510工作原理,Hi3510 -H.264 BP算法的

Hi3510 工作原理,Hi3510 -H.264 BP 算法的Hi3510 工作原理Hi3510 -H.264 BP 算法的视频压缩芯片Hi3510 是海思公司推出的一款基于H.264 BP 算法的视频压缩芯片,该芯片采用ARM+DSP+硬件加速引擎的多核高集成度的SoC 构架,具备强大的视频处理功能。

可实现DVD 画质的实时编码性能,能自适应各种网络环境,确保画面的清晰度和实时性,低码率的H.264 编码技术极大减少网络存储空间,并通过集成DES/3DES 加解密硬件引擎确保网络安全。

Hi3510 采用0.13μm工艺、LFBGA400 封装,大小为19×19mm,引脚间距为0.8mm,片内集成了包括数字视频接口、USB、ETH、I2S、I2C、GPIO、SPI、UART、SDRAM、DDR 等接口,满足各种应用场景的设备开发的同时能大大降低了设备的BOM 成本。

Hi3510 的工作原理:视频输入单元通过ITU-R BT.601/656 接口接收由VADC 输出的数字视频信息,并通过AHB 总线把接收到的原始图像写入到外存(SDR SDRAM 或DDR SDRAM)中;视频编解码器从外存中读取图像,进行运动估计(帧间预测)、帧内预测、DCT 变换、量化、熵编码(CAVLC+Exp-Golomb)、IDCT 变换、反量化、运动补偿等操作,最后将符合H.264 协议的裸码流和编码重构帧(作为下一帧的参考帧)写入到外存中;视频输出单元从外存中读取图像并通过ITU-R BT.601/656 接口送给VDAC 进行显示,应用的需求不同,视频输出单元从外存中读取的图像内容也不同,当需要对输入图像进行预览时,视频输出单元从外存中读取原始图像,当需要观察视频编码器的编码效果时,视频输出单元从外存中读取编码重构帧;ARM 对视频编码器输出的码流进行协议栈的封装,然后送网口发送,以实现视频点播业务。

如图1 所示,该芯片由ARM+DSP+视频编解码加速器+图形引擎缩放器的核心构成,集成了丰富的外围接口,并内部集成包括如数字水印、DES/3DES 算法,使得单芯片能适应基乎所有的工。

Etherent帧的封装和发送过程

Etherent帧的封装和发送过程

计算机网络课程设计实验一帧封装实验目的:•编写程序,根据给出的原始数据,组装一个IEEE 格式的帧(题目)默认的输入文件为二进制原始数据(文件名分别为input1和input2))。

•要求程序为命令行程序。

比如,可执行文件名为,则命令行形式如下:EncapFramer inputfile outputfile,其中,inputfile为原始数据文件,outputfile 为输出结果。

•输出:对应input1和input2得结果分别为output1和output2。

试验要求:•编写程序,根据给出的原始数据,组装一个IEEE 格式的帧(题目)默认的输入文件为二进制原始数据(文件名分别为input1和input2))。

•要求程序为命令行程序。

比如,可执行文件名为,则命令行形式如下:EncapFramer inputfile outputfile,其中,inputfile为原始数据文件,outputfile 为输出结果。

输出:对应input1和input2得结果分别为output1和output2实验设计相关知识:帧:来源于串行线路上的通信。

其中,发送者在发送数据的前后各添加特殊的字符,使它们成为一个帧。

Ethernet从某种程度上可以被看作是机器之间的数据链路层连接。

按标准的帧结构如下表所示(标准的Ethernet帧结构由7部分组成)其中,帧数据字段的最小长度为46B。

如果帧的LLC数据少于46B,则应将数据字段填充至46B。

填充字符是任意的,不计入长度字段值中。

在校验字段中,使用的是CRC校验。

校验的范围包括目的地址字段、源地址字段、长度字段、LLC数据字段。

循环冗余编码(CRC)是一种重要的线性分组码、编码和解码方法,具有简单、检错和纠错能力强等特点,在通信领域广泛地用于实现差错控制。

CRC校验码的检错能力很强,不仅能检查出离散错误,还能检查出突发错误。

利用CRC 进行检错的过程可简单描述如下:在发送端根据要传送的k 位二进制码序列,以一定的规则产生一个校验用的r 位监督码(CRC 码),附在原始信息的后边,构成一个新的二进制码序列(共k+r 位),然后发送出去。

H.264基础及RTP封包详解

H.264基础及RTP封包详解

H.264基础及RTP封包详解一. h264基础概念1、NAL、Slice与frame意思及相互关系1 frame的数据可以分为多个slice.每个slice中的数据,在帧内预测只用到自己slice的数据,与其他slice 数据没有依赖关系。

NAL 是用来将编码的数据进行大包的。

比如,每一个slice 数据可以放在NAL 包中。

I frame 是自己独立编码,不依赖于其他frame 数据。

P frame 依赖 I frame 数据。

B frame 依赖 I frame, P frame 或其他 B frame 数据。

一个frame是可以分割成多个Slice来编码的,而一个Slice编码之后被打包进一个NAL单元,不过NAL单元除了容纳Slice编码的码流外,还可以容纳其他数据,比如序列参数集SPS。

NAL指网络提取层,里面放一些与网络相关的信息Slice是片的意思,264中把图像分成一帧(frame)或两场(field),而帧又可以分成一个或几个片(Slilce);片由宏块(MB)组成。

宏块是编码处理的基本单元。

2、NAL nal_unit_type中的1(非IDR图像的编码条带)、2(编码条带数据分割块A)、3(编码条带数据分割块B)、4(编码条带数据分割块C)、5(IDR图像的编码条带)种类型与 Slice种的三种编码模式:I_slice、P_slice、B_sliceNAL nal_unit_type 里的五种类型,代表接下来数据是表示啥信息的和具体如何分块。

I_slice、P_slice、B_slice 表示I类型的片、P类型的片,B类型的片.其中I_slice为帧内预测模式编码;P_slice为单向预测编码或帧内模式;B_slice 中为双向预测或帧内模式。

3、还有frame的3种类型:I frame、P frame、 B frame之间有什么映射关系么?I frame、P frame、 B frame关系同 I_slice、P_slice、B_slice,slice和frame区别在问题1中已经讲明白。

具体H264字节流拆包和RTP封包方法如下

具体H264字节流拆包和RTP封包方法如下

可以通过生成SDP文件给播放器在指定端口接收数据播放,如果你不用动态调整编码器什么的就不用考虑另外发送RTCP.而且RTCP必须自己实现RTSP服务结合起来用,没有实现RTSP服务,就谈不上实现RTCP.具体H264字节流拆包和RTP封包方法如下:UINT MediaStreamH264::TransportData(PBYTE pData, UINT dataSize, int pts){PBYTE p_buffer = pData;int i_buffer = dataSize;UINT writeSize = 0;while( i_buffer > 4 && ( p_buffer[0] != 0 || p_buffer[1] != 0 || p_buffer[2] !=1 ) ){i_buffer--;p_buffer++;}/* Split nal units */while( i_buffer > 4 ){int i_offset;int i_size = i_buffer;int i_skip = i_buffer;/* search nal end */for( i_offset = 4; i_offset+2 < i_buffer ; i_offset++){if( p_buffer[i_offset] == 0 && p_buffer[i_offset+1] == 0 && p_buffer[i_offset+2] == 1 ){/* we found another startcode */i_size = i_offset - ( p_buffer[i_offset-1] == 0 ? 1 :0);i_skip = i_offset;break;}}/* TODO add STAP-A to remove a lot of overhead with small slice/sei/... */UINT iWrite = TransportH264Nal(p_buffer, i_size, pts, (i_size >= i_buffer) );if (iWrite > 0 )writeSize += iWrite;i_buffer -= i_skip;p_buffer += i_skip;}return writeSize;}UINTMediaStreamH264::TransportH264Nal(constPBYTEpNal,UINTnalSize,INT32pts,BOOL isLast){ATLock atlock(&m_tlockRun);if (m_bRun == FALSE)return 0;if( nalSize < 5 )return 0;UINT mtu = m_nMTU;const int i_max = mtu - RTP_HEADER_SIZE; /* payload max in one packet */int i_nal_hdr;int i_nal_type;i_nal_hdr = pNal[3];i_nal_type = i_nal_hdr&0x1f;string sps;string pps;if( i_nal_type == 7 || i_nal_type == 8 ){/* XXX Why do you want to remove them ? It will break streaming with* SPS/PPS change (broadcast) ? */return 0;}/* Skip start code */PBYTE p_data = pNal;int i_data = nalSize;p_data += 3;i_data -= 3;int writeSize = 0;if( i_data <= i_max ){/* Single NAL unit packet *///writeSize = m_pRtpTransport->SetRtpData(p_data, i_data, pts, isLast);writeSize = m_pRtpTransport->Write(p_data, i_data, m_nRtpPayloadType, pts, 0, isLast);if (writeSize <= 0)return 0;return writeSize;}else{/* FU-A Fragmentation Unit without interleaving */const int i_count = ( i_data-1 + i_max-2 - 1 ) / (i_max-2);int i;p_data++;i_data--;for( i = 0; i < i_count; i++ ){const int i_payload = (i_data < (i_max-2)) ? i_data :(i_max-2);const int nalSize = 2 + i_payload;m_Packet.ExtendBuffer(nalSize);/* FU indicator */m_Packet.m_pData[0] = 0x00 | (i_nal_hdr & 0x60) | 28;/* FU header */m_Packet.m_pData[1] = ( i == 0 ? 0x80 :0x00 ) | ( (i == i_count-1) ? 0x40 :0x00 ) | i_nal_type;/* FU payload */memcpy( &m_Packet.m_pData[2], p_data, i_payload );m_Packet.m_DataSize = nalSize;//intiWrite=m_pRtpTransport->SetRtpData(m_Packet.m_pData,m_Packet.m_Da taSize,pts,isLast && (i == i_count-1));intiWrite=m_pRtpTransport->Write(m_Packet.m_pData,m_Packet.m_DataSize, m_nRtpPayloadType, pts, 0, isLast && (i == i_count-1));if (iWrite > 0)writeSize += iWrite;i_data -= i_payload;p_data += i_payload;}}return writeSize;}楼主这个问题给的分太少老~~起码给500分才够~~可以通过生成SDP文件给播放器在指定端口接收数据播放,如果你不用动态调整编码器什么的就不用考虑另外发送RTCP.而且RTCP必须自己实现RTSP服务结合起来用,没有实现RTSP服务,就谈不上实现RTCP.具体H264字节流拆包和RTP封包方法如下:UINT MediaStreamH264::TransportData(PBYTE pData, UINT dataSize, int pts){PBYTE p_buffer = pData;int i_buffer = dataSize;UINT writeSize = 0;while( i_buffer > 4 && ( p_buffer[0] != 0 || p_buffer[1] != 0 || p_buffer[2] !=1 ) ){i_buffer--;p_buffer++;}/* Split nal units */while( i_buffer > 4 ){int i_offset;int i_size = i_buffer;int i_skip = i_buffer;/* search nal end */for( i_offset = 4; i_offset+2 < i_buffer ; i_offset++){if( p_buffer[i_offset] == 0 && p_buffer[i_offset+1] == 0 && p_buffer[i_offset+2] == 1 ){/* we found another startcode */i_size = i_offset - ( p_buffer[i_offset-1] == 0 ? 1 :0);i_skip = i_offset;break;}}/* TODO add STAP-A to remove a lot of overhead with small slice/sei/... */UINT iWrite = TransportH264Nal(p_buffer, i_size, pts, (i_size >= i_buffer) );if (iWrite > 0 )writeSize += iWrite;i_buffer -= i_skip;p_buffer += i_skip;}return writeSize;}UINTMediaStreamH264::TransportH264Nal(constPBYTEpNal,UINTnalSize,INT32pts,BOOL isLast){ATLock atlock(&m_tlockRun);if (m_bRun == FALSE)return 0;if( nalSize < 5 )return 0;UINT mtu = m_nMTU;const int i_max = mtu - RTP_HEADER_SIZE; /* payload max in one packet */int i_nal_hdr;int i_nal_type;i_nal_hdr = pNal[3];i_nal_type = i_nal_hdr&0x1f;string sps;string pps;if( i_nal_type == 7 || i_nal_type == 8 ){/* XXX Why do you want to remove them ? It will break streaming with* SPS/PPS change (broadcast) ? */return 0;}/* Skip start code */PBYTE p_data = pNal;int i_data = nalSize;p_data += 3;i_data -= 3;int writeSize = 0;if( i_data <= i_max ){/* Single NAL unit packet *///writeSize = m_pRtpTransport->SetRtpData(p_data, i_data, pts, isLast);writeSize = m_pRtpTransport->Write(p_data, i_data, m_nRtpPayloadType, pts, 0, isLast);if (writeSize <= 0)return 0;return writeSize;}else{/* FU-A Fragmentation Unit without interleaving */const int i_count = ( i_data-1 + i_max-2 - 1 ) / (i_max-2);int i;p_data++;i_data--;for( i = 0; i < i_count; i++ ){const int i_payload = (i_data < (i_max-2)) ? i_data :(i_max-2);const int nalSize = 2 + i_payload;m_Packet.ExtendBuffer(nalSize);/* FU indicator */m_Packet.m_pData[0] = 0x00 | (i_nal_hdr & 0x60) | 28;/* FU header */m_Packet.m_pData[1] = ( i == 0 ? 0x80 :0x00 ) | ( (i == i_count-1) ? 0x40 :0x00 ) | i_nal_type;/* FU payload */memcpy( &m_Packet.m_pData[2], p_data, i_payload );m_Packet.m_DataSize = nalSize;//intiWrite=m_pRtpTransport->SetRtpData(m_Packet.m_pData,m_Packet.m_Da taSize,pts,isLast && (i == i_count-1));intiWrite=m_pRtpTransport->Write(m_Packet.m_pData,m_nRtpPayloadType, pts, 0, isLast && (i == i_count-1));if (iWrite > 0)writeSize += iWrite;i_data -= i_payload;p_data += i_payload;}}return writeSize;}m_Packet.m_DataSize,。

DirectShow的RTP发包(H264)Filter转

DirectShow的RTP发包(H264)Filter转

DirectShow的RTP发包(H264)Filter转基于DirectShow的框架H.264 RTP Sender Filter开发框架与环境:1.VS2017——⼯具集为V120-VS20132.jrtplib-3.11.1 jthread-1.3.3 编译为32位版3.程序为32位程序4.DirectShow链路图如下(控制台为RTP发送地址与本机端⼝)5.RTP拆包⽅式为FU-A6.x264编码filter为ffdshow codec(本filter⽀持输⼊为H264的sample)7.本程序开源(部分实现借鉴了许多CSDN博客与⼤⽜的程序),请遵守开源协议实现部分有空的话应该会整理个更详细的版本,这⾥主要就说⼀下遇到的问题好了。

实现DirectShow+jrtplib的H264收发包程序,总共⽤时约两周,主要的精⼒和时间花在了RTP协议、RTP拆包与H.264字节流处理、H.264格式的解析上。

1.H.264的NAL单元(NALU)H.264编码实现了⽹络层也就是NAL,其中每⼀个单元(NALU)适⽤于⽹络传输,详细的这⾥不阐述了,捡重点的⽅便⼤家快速理解。

编码器对原始采集视频(图像)进⾏处理后,输出的每⼀帧即是⼀个NALU。

这⾥的每⼀帧包括编码器初始化输出的PPS和SPS。

实际上,我们需要⽤RTP实现的传输,就是从输⼊pin中的数据,提取每⼀帧(NALU),对NALU进⾏打包发送。

H.264编解码,怎样完成?需要怎样保持数据的发送?⾸先,H.264的编码,除了初始化编码器后,输出PPS和SPS外,之后的所有NALU单元,都为I-P-B帧的组合。

其中,I帧为关键帧,解码器遇到这⼀帧后,会清除重置解码器的预测基准(具体请参考H.264编码与运动预测模型),⽽P 帧和B帧则是前向预测帧和双向预测帧。

H.264由于进⾏了运动预测,因此除了I帧外,P帧和B帧仅需要较少的bit进⾏编码,从⽽减少传输的数据量。

webrtc rtp包解析流程

webrtc rtp包解析流程

webrtc rtp包解析流程WebRTC(Web Real-Time Communication)是一种支持浏览器之间进行实时音视频通信的开放标准。

RTP(Real-time Transport Protocol)是WebRTC中用于传输音视频数据的协议。

在WebRTC中,RTP包的解析流程涉及到多个步骤和组件,我会从多个角度来解释这个流程。

首先,RTP包解析流程涉及到发送端和接收端两个主要组件。

发送端首先将音视频数据封装成RTP包,然后通过网络传输给接收端。

接收端接收到RTP包后,需要对RTP包进行解析,提取音视频数据并进行播放。

在发送端,RTP包的生成通常涉及到以下几个步骤,首先,将音视频数据进行采样和编码,然后将编码后的数据封装成RTP包。

在封装RTP包的过程中,需要添加RTP头部信息,包括版本号、序列号、时间戳等信息。

此外,还需要添加RTP扩展头部信息,用于传输一些额外的信息,比如帧间距福等。

最后,将封装好的RTP包通过网络传输给接收端。

在接收端,RTP包的解析流程通常包括以下几个步骤,首先,接收端需要从网络中接收RTP包,并进行解包,提取RTP头部信息和音视频数据。

然后,根据RTP头部信息进行序列重排和时钟同步,以确保音视频数据的顺序和同步性。

接着,对音视频数据进行解码和渲染,最终呈现给用户。

除了以上描述的基本流程,RTP包的解析还涉及到一些复杂的技术细节,比如网络传输中的拥塞控制、丢包恢复、抖动缓冲等。

此外,WebRTC中还使用了一些其他的协议和技术,比如SRTP (Secure Real-time Transport Protocol)用于加密RTP包,RTCP (RTP Control Protocol)用于传输控制信息等。

总的来说,RTP包的解析流程涉及到多个步骤和技术,包括RTP包的生成、传输和接收端的解析处理。

这个流程需要综合考虑音视频数据的采样、编码、传输和解码等多个环节,以确保实时音视频通信的顺畅和稳定。

海思Hi3556V200通过FTP与PC互传文件[更直观]

海思Hi3556V200通过FTP与PC互传文件[更直观]
5.这个时候后视镜和pc都有自己的ip,打开网络连接列表,选中设备和主机的两个连接,右键选择“添加到桥”,使其建立连接,这时在各自的环境ping对方,是通的。(设备有时候显示不出来,请重启电脑后,再重置板子这边的FTP软件,我们找到了一个叫stupid-ftpd的东西,我们把它下下来,源码包为stupid-ftpd-1.5beta.tar.gz
【1】把Makefile里面的CC=gcc改成CC=arm-himix100-linux-gcc
【2】把stupid-ftpd.conf 里面的port=2121改成 port=21
然后make一下,把两个文件 拷贝到板子的根目录下面:
stupid-ftpd.Linux6和stupid-ftpd.conf
ifconfig usb0 192.168.1.250 netmask 255.255.255.0
route add default gw 192.168.1.1
ifconfig -a
ifconfig lo up
这时候ifconfig查看后视镜的ip如下:
4.在windows命令提示行下,ipconfig,找到本地网卡的ip地址如下:
这个命令会启动usb转网口的功能,这时用usb线连接pc,pc端则需要加载
Hi3559V200_MobileCam_V1.0.13/SoftWare/pc/usb_tools/linux.inf
这个驱动文件
2.驱动成功加载,在设备管理器->网络适配器中,会出现如图所示图标
3.这时要人工给这个网口分配ip地址,且跟你的电脑是要在同一个ip段范围内
这一次我们要讲一个比tftp更好用的功能,FTP,配上windows端的FlashFXP可视化界面,传输起文件来,那是更加直观明了!

Hi3520 U-Boot 移植应用指南

Hi3520 U-Boot 移植应用指南

本文档提及的其他所有商标或注册商标,由各自的所有人拥有。
注意
您购买的产品、服务或特性等应受海思公司商业合同和条款的约束,本文档中描述的全部或部分产品、服 务或特性可能不在您的购买或使用范围之内。除非合同另有约定,海思公司对本文档内容不做任何明示或 默示的声明或保证。
由于产品版本升级或其他原因,本文档内容会不定期进行更新。除非另有约定,本文档仅作为使用指导, 本文档中的所有陈述、信息和建议不构成任何明..................................................................................................................3-1
3.1 概述............................................................................................................................................................3-1 3.2 初始化程序及U-boot.................................................................................................................................3-1 3.3 通过RealView Debugger烧写U-boot ........................................................................................................3-1

海思Hi35xx平台调试笔记

海思Hi35xx平台调试笔记

海思Hi35xx平台调试笔记1、进⼊板⼦debug环境 (根据⾃⼰情况)1) mount /dev/sda3 /root/disk2) minicom3) nfspc:sudo vi /etc/exports/root/disk/hi3516 *(rw,sync,no_root_squash,no_subtree_check)sudo /etc/init.d/nfs-kernel-server restartsudo /etc/init.d/rpcbind restartsudo ifconfig eth1 172.16.23.157board:ifconfig wlan1 172.16.23.158mount -t nfs -o nolock 172.16.23.157:/root/disk/hi3516 /root/hi3516注意海思sdk⾥的mpp⽬录名不要改动,改了会导致sample编译出错。

2、⾳视频数据循环采集a. 在sample_venc.c⽂件中,海思官⽅是把采集到的数据都保存到⽂件中,我们需要更改到缓存⾥,以便后⾯推送到rtsp/rtmp/hls服务端。

for (i = 0; i < s32ChnTotal; i++){if (FD_ISSET(VencFd[i], &read_fds)){/*******************************************************step 2.1 : query how many packs in one-frame stream.*******************************************************/memset(&stStream, 0, sizeof(stStream));s32Ret = HI_MPI_VENC_Query(i, &stStat);if (HI_SUCCESS != s32Ret){SAMPLE_PRT("HI_MPI_VENC_Query chn[%d] failed with %#x!\n", i, s32Ret);break;}/*******************************************************step 2.2 : malloc corresponding number of pack nodes.*******************************************************/stStream.pstPack = (VENC_PACK_S*)malloc(sizeof(VENC_PACK_S) * stStat.u32CurPacks);if (NULL == stStream.pstPack){SAMPLE_PRT("malloc stream pack failed!\n");break;}/*******************************************************step 2.3 : call mpi to get one-frame stream*******************************************************/stStream.u32PackCount = stStat.u32CurPacks;s32Ret = HI_MPI_VENC_GetStream(i, &stStream, HI_TRUE);if (HI_SUCCESS != s32Ret){free(stStream.pstPack);stStream.pstPack = NULL;SAMPLE_PRT("HI_MPI_VENC_GetStream failed with %#x!\n", \s32Ret);break;}/*******************************************************step 2.4 : save frame to file*******************************************************/HisiPutH264DataToBuffer(&stStream);/*s32Ret = SAMPLE_COMM_VENC_SaveStream(enPayLoadType[i], pFile[i], &stStream);if (HI_SUCCESS != s32Ret){free(stStream.pstPack);stStream.pstPack = NULL;SAMPLE_PRT("save stream failed!\n");break;}*//*******************************************************step 2.5 : release stream*******************************************************/s32Ret = HI_MPI_VENC_ReleaseStream(i, &stStream);if (HI_SUCCESS != s32Ret){free(stStream.pstPack);stStream.pstPack = NULL;break;}/*******************************************************step 2.6 : free pack nodes*******************************************************/free(stStream.pstPack);stStream.pstPack = NULL;}}b. HI_S32 HisiPutH264DataToBuffer(VENC_STREAM_S *pstStream)函数⽐较重要HI_S32 HisiPutH264DataToBuffer(VENC_STREAM_S *pstStream){HI_S32 i,j,x;HI_S32 len=0,off=0,len2=2,uplen=0;unsigned char *pstr;int iframe=0;for (i = 0; i < pstStream->u32PackCount; i++){len+=pstStream->pstPack[i].u32Len;}if(n<NMAX){for (i = 0; i < pstStream->u32PackCount; i++){memcpy(ringfifo[iput].buffer+off,pstStream->pstPack[i].pu8Addr,pstStream->pstPack[i].u32Len); off+=pstStream->pstPack[i].u32Len;pstr=pstStream->pstPack[i].pu8Addr;if(pstr[4]==0x67){UpdateSps(pstr+4,pstStream->pstPack[i].u32Len-4);iframe=1;}if(pstr[4]==0x68){UpdatePps(pstr+4,pstStream->pstPack[i].u32Len-4);}}ringfifo[iput].size= len;if(iframe){// printf("I");ringfifo[iput].frame_type = FRAME_TYPE_I;}else{ringfifo[iput].frame_type = FRAME_TYPE_P;// printf("P");}iput = addring(iput);// printf("(%d)",iput);// fflush(stdout);n++;}return HI_SUCCESS;}c. VENC_STREAM_S相关结构体//定义帧码流类型结构体:typedef structhiVENC_STREAM_S{VENC_PACK_S *pstPack; //帧码流包结构。

基于H.265编解码高清视频传输系统

基于H.265编解码高清视频传输系统

基于H.265编解码高清视频传输系统胡博;赵旦峰;王中刊【期刊名称】《应用科技》【年(卷),期】2017(044)001【摘要】为解决高清视频的实时传输将带来带宽压力的增加和时延的增长等,基于H.265编解码提出一种新的高清视频传输系统设计方法来改善上述情况。

系统首先采用Hi3516A处理器对高清视频进行H.265硬编码,然后运用Boost:asio库进行专用流媒体服务器设计,最后基于 DirectX进行渲染显示方案设计。

经系统实验验证,文中系统通过对高清1080P视频在25 fps帧率以及2 M码流传输情况下经H.265编解码后,系统传输时延约为120 ms。

同时在普通高清720P和标清480i视频采集条件下,H.265相对于H.264在传输码率减半时解码后图像的PSNR值与经H.264编解码解码后图像的PSNR值基本相同。

但在高清1080P视频采集条件下,H.265编解码在1 M码率传输时解码后图像的PSNR值明显优于H.264编解码在2 M码率传输时解码后图像的PSNR值。

【总页数】6页(P27-32)【作者】胡博;赵旦峰;王中刊【作者单位】哈尔滨工程大学信息与通信工程学院,黑龙江哈尔滨150001;哈尔滨工程大学信息与通信工程学院,黑龙江哈尔滨150001;哈尔滨工程大学信息与通信工程学院,黑龙江哈尔滨150001【正文语种】中文【中图分类】TP277【相关文献】1.基于H.265编解码的高清视频传输系统研究 [J], 刘韶辉;王星2.基于H.265的无线数字音视频传输系统设计 [J], 余波;徐文磊;熊强强3.基于H.265编解码的高清视频传输系统 [J], 何江; 杨丞(通讯作者); 谈澳利; 魏倩; 戴博颖4.基于Cortex-A9和H.265的无线视频传输系统设计 [J], 苏宁; 龙月梅; 欧月娥; 罗秋萍; 李雅箐5.数码视讯为用户提供更好的视频业务——数码视讯推出新一代H.265高清编解码器 [J], 赵法彬因版权原因,仅展示原文概要,查看原文内容请购买。

Linux系统中H.264编解码器的移植与应用

Linux系统中H.264编解码器的移植与应用

Linux系统中H.264编解码器的移植与应用作者:马敬奇来源:《科技资讯》 2015年第10期马敬奇(广东工业大学广东广州 510006)摘要:Linux系统因开源而被更多的企业所采用,H.264编解码因具有高压缩比、良好的网络适应性成为视频编解码技术的研究热点。

怎样将H.264编解码器移植到Linux系统上,以完成效率更高、压缩比更高视频编解码技术,是突破编解码技术的关键。

该文经过分析H.264编解码算法,将H.264编解码器移植到Linux系统中,实现了H.264对视频文件的编解码,为嵌入式系统的移植奠定了基础。

关键词:Linux H.264编解码嵌入式中图分类号:TP368文献标识码:A文章编号:1672-3791(2015)04(a)-0030-011 Linux系统介绍Linux极大的继承了UNIX操作系统,Minix系统、GNU计划、POSIX标准和Internet网络的发展也极大的推动其发展。

Linux系统内核由进程调度,文件管理,内存管理,网络接口,进程间通信组成。

在Linux系统采取的一种树结构实现文件的管理,所有文件都是从“根”(用“/”代表)开始的,这种树结构具有比磁盘分区更大的灵活性。

2 H.264标准2.1 H.264编码器H.264编码器[1]以帧为单位进行,编码从开始。

为当前帧的前一帧,即为当前帧,与编码预测值P相减得到带编码的帧差。

其中的预测值P有两种方法获得。

(1)帧间预测[2]模式下通过运动补偿得到;(2)在帧内模式下由当中已完成编码并且重建的宏块[3]预测得到。

帧差经由T(DCT变换)变换器得到的数据再经由Q(量化器)变化得到量化系数X。

最后量化系数X经由重排序、熵编码得到完整的.264编码流[4]。

是通过量化系数X经过一系列变换得到的,目的是编码后面的宏块并且重建编码帧,首先量化系数X经过Q-1和T-1,得到反变换恢复值;与P相加得到原始帧,经过滤波获得重建帧。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

ortp移植到hi3518eh.264封包rtp发送看到ORTP是纯C实现的rtp库,于是移植到3518e试用一下.1.下载源码链接地址里面有个tar res跳转链接跳转入链接地址下载最新的ortp-0.23.0.tar.gz,并解压2.编译./configure --prefix=/work/hi3518/ortp--host=arm-hisiv100nptl-linuxmakemake install配置只需指定安装目录prefix,编译平台host即可,这里host 直接赋值arm-hisiv100nptl-linux-gcc前缀即可,注意不是arm-hisiv100nptl-linux-而是arm-hisiv100nptl-linux。

3.部署到开发板将编译生成的库/work/hi3518/ortp/lib/libortp.so.9复制到开发板/usr/lib中4.添加ortp库到mpp2中在海思SDK mpp2目录下新建rtp目录,将/work/hi3518/ortp/下全部内容复制到该目录下,修改mpp2/sample/Makefile.param,添加:INC_FLAGS += -I$(MPP_PATH)/rtp/include-L$(MPP_PATH)/rtp/lib/ -lortp5.修改代码示例程序venc中有将视频进行264编码并保存为文件(nfs挂载),这里一步步分析sample_venc.c即可找到最终的保存是通过sample_comm_venc.c中的SAMPLE_COMM_VENC_SaveH264函数完成的,这里只要修改该函数为封包发送即可。

下面是sample_comm_venc.c中需要添加的部分:#include &lt;ortp/ortp.h&gt;#include &lt;signal.h&gt;#include &lt;stdlib.h&gt;#include &lt;sys/types.h&gt;#include &lt;sys/time.h&gt;#include &lt;stdio.h&gt;#define Y_PLOAD_TYPE 96 //H.264#define MAX_RTP_PKT_LENGTH 1400#define DefaultTimestampIncrement 3600 //(90000/25)uint32_t g_userts=0;RtpSession *pRtpSession = NULL;/** 初始化** 主要用于对ortp以及其它参数进行初始化* @param: char * ipStr 目的端IP地址描述串* @param: iint port 目的端RTP监听端口* @return: RtpSession * 返回指向RtpSession对象的指针,如果为NULL,则初始化失败* @note:*/RtpSession * rtpInit( char * ipStr, int port){RtpSession *session;char *ssrc;printf("********oRTP for H.264 Init********\n");ortp_init();ortp_scheduler_init();ortp_set_log_level_mask(ORTP_MESSAGE|ORTP_WARNIN G|ORTP_ERROR);session=rtp_session_new(RTP_SESSION_SENDONLY);rtp_session_set_scheduling_mode(session,1);rtp_session_set_blocking_mode(session,0);//rtp_session_set_connected_mode(session,TRUE);rtp_session_set_remote_addr(session,ipStr,port);rtp_session_set_payload_type(session,Y_PLOAD_TYPE);ssrc=getenv("SSRC");if (ssrc!=NULL) {printf("using SSRC=%i.\n",atoi(ssrc));// 设置输出流的SSRC。

不做此步的话将会给个随机值rtp_session_set_ssrc(session,atoi(ssrc));}return session;}/** 结束ortp的发送,释放资源** @param: RtpSession *session RTP会话对象的指针* @return: 0表示成功* @note:int rtpExit(RtpSession *session){printf("********oRTP for H.264 Exit********\n");g_userts = 0;rtp_session_destroy(session);ortp_exit();ortp_global_stats_display();return 0;}/** 发送rtp数据包** 主要用于发送rtp数据包* @param: RtpSession *session RTP会话对象的指针* @param: const char *buffer 要发送的数据的缓冲区地址* @param: int len 要发送的数据长度* @return: int 实际发送的数据包数目* @note: 如果要发送的数据包长度大于BYTES_PER_COUNT,本函数内部会进行分包处理int rtpSend(RtpSession *session, char *buffer, int len) {int sendBytes = 0;int status;uint32_t valid_len=len-4;unsigned char NALU=buffer[4];//printf("send len=%d\n",len);//如果数据小于MAX_RTP_PKT_LENGTH字节,直接发送:单一NAL单元模式if(valid_len &lt;= MAX_RTP_PKT_LENGTH){sendBytes = rtp_session_send_with_ts(session,&amp;buffer[4],valid_len,g_userts);return sendBytes;else if (valid_len &gt; MAX_RTP_PKT_LENGTH){//切分为很多个包发送,每个包前要对头进行处理,如第一个包valid_len -= 1;int k=0,l=0;k=valid_len/MAX_RTP_PKT_LENGTH;l=valid_len%MAX_RTP_PKT_LENGTH;int t=0;int pos=5;if(l!=0){k=k+1;}while(t&lt;k)//||(t==k&amp;&amp;l&gt;0)){if(t&lt;(k-1))//(t&lt;k&amp;&amp;l!=0)||(t&lt;(k-1))&amp;&am p;(l==0))//(0==t)||(t&lt;k&amp;&amp;0!=l)){buffer[pos-2]=(NALU &amp; 0x60)|28;buffer[pos-1]=(NALU &amp; 0x1f);if(0==t){buffer[pos-1]|=0x80;}sendBytes =rtp_session_send_with_ts(session,&amp;buffer[pos-2],MAX_RTP_PKT_LENGTH+2,g_userts);t++;pos+=MAX_RTP_PKT_LENGTH;}else//if((k==t&amp;&amp;l&gt;0)||((t==k-1)&amp;&amp;l==0)) {int iSendLen;if(l&gt;0){iSendLen=valid_len-t*MAX_RTP_PKT_LENGTH;}elseiSendLen=MAX_RTP_PKT_LENGTH;buffer[pos-2]=(NALU &amp; 0x60)|28;buffer[pos-1]=(NALU &amp; 0x1f);buffer[pos-1]|=0x40;sendBytes =rtp_session_send_with_ts(session,&amp;buffer[pos-2],iSendLen+2,g_userts);t++;}}}g_userts += DefaultTimestampIncrement;//timestamp increasereturn len;}在实现调用前需要进行ortp加载初始化,我们在该文件中的函数SAMPLE_COMM_VENC_GetVencStreamProc中添加初始化即可:/***rtp init****/pRtpSession = rtpInit( "129.1.4.196" ,8080);if (pRtpSession==NULL){printf( "error rtpInit" );exit(-1);return 0;}/******************************************step 2: Start to get streams of each channel.******************************************/注:这里为了简便在程序中写死了发送目标为129.1.4.196:8080,这要与下面的cfg.sdp对应. 然后修改SAMPLE_COMM_VENC_SaveH264函数调用rtp发送:/*************************************************** *************************** funciton : save H264 stream*************************************************** ***************************/HI_S32 SAMPLE_COMM_VENC_SaveH264(FILE*fpH264File, VENC_STREAM_S *pstStream){HI_S32 i;for (i = 0; i &lt; pstStream-&gt;u32PackCount; i++){#if 0fwrite(pstStream-&gt;pstPack[i].pu8Addr[0],pstStream-&gt;pstPack[i].u32Len[0], 1,fpH264File);fflush(fpH264File);if (pstStream-&gt;pstPack[i].u32Len[1] &gt; 0){fwrite(pstStream-&gt;pstPack[i].pu8Addr[1],pstStream-&gt;pstPack[i].u32Len[1], 1, fpH264File);fflush(fpH264File);}#elsertpSend(pRtpSession,pstStream-&gt;pstPack[i].pu8Addr[0],pstStream-&gt;pstPack[i].u32Len[0]);if (pstStream-&gt;pstPack[i].u32Len[1] &gt; 0){rtpSend(pRtpSession,pstStream-&gt;pstPack[i].pu8Addr[1],pstStream-&gt;pstPack[i].u32Len[1]);}#endif}return HI_SUCCESS;}这样编译获得sample_venc.6.运行将sample_venc加载到开发板并运行,#./sample_venc 0please press twice ENTER to exit this sample********oRTP for H.264 Init********Av profile add H.264ortp-message-Setting random local addresses.ortp-message-rtp session [0x1c95758] set to rtp[129.1.4.196:8080] rtcp [129.1.4.196:8081]ortp-message-Using permissive algorithmortp-message-Sending RTCP SR compound message on session [0x1c95758].ortp-message-Sending RTCP SR compound message on session [0x1c95758].......7.VLC播放PC端使用VLC来播放,编写cfg.sdp如下:m=video 8080 RTP/A VP 96a=rtpmap:96 H264/90000;a=decode_buf=300;a=framerate:25c=IN IP4 129.1.4.196这里129.1.4.196即为PC的IP,Port8080为监控rtp使用端口,payloadtype为96,即h.264.VLC能够正常播放,但有延时。

相关文档
最新文档