C#实现RTP数据报传输参照RFC3550.docx_第1页
C#实现RTP数据报传输参照RFC3550.docx_第2页
C#实现RTP数据报传输参照RFC3550.docx_第3页
C#实现RTP数据报传输参照RFC3550.docx_第4页
C#实现RTP数据报传输参照RFC3550.docx_第5页
已阅读5页,还剩6页未读 继续免费阅读

下载本文档

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

文档简介

C#实现RTP数据报传输参照RFC3550闲暇时折腾IP网络视频监控系统,需要支持视频帧数据报在网络内的传输。未采用H.264或MPEG4等编码压缩方式,直接使用Bitmap图片。由于对帧的准确到达要求不好,所以采用UDP传输。如果发生网络丢包现象则直接将帧丢弃。为了记录数据报的传输顺序和帧的时间戳,所以研究了下RFC3550协议,采用RTP包封装视频帧。并未全面深究,所以未使用SSRC和CSRC,因为不确切了解其用意。不过目前的实现情况已经足够了。1. / 2. /RTP(RFC3550)协定数据报 3. / 4. / 5. /TheRTPheaderhasthefollowingformat: 6. /0123 7. /01234567890123456789012345678901 8. /+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 9. /|V=2|P|X|CC|M|PT|sequencenumber| 10. /+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 11. /|timestamp| 12. /+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 13. /|synchronizationsource(SSRC)identifier| 14. /+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ 15. /|contributingsource(CSRC)identifiers| 16. /|.| 17. /+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 18. / 19. publicclassRtpPacket 20. 21. / 22. /version(V):2bits 23. /RTP版本标识,当前规范定义值为2. 24. /ThisfieldidentifiestheversionofRTP.Theversiondefinedbythisspecificationistwo(2). 25. /(Thevalue1isusedbythefirstdraftversionofRTPandthevalue0isusedbytheprotocol 26. /initiallyimplementedinthevataudiotool.) 27. / 28. publicintVersiongetreturn2; 29. 30. / 31. /padding(P):1bit 32. /如果设定padding,在报文的末端就会包含一个或者多个padding字节,这不属于payload。 33. /最后一个字节的padding有一个计数器,标识需要忽略多少个padding位元组(包括自己)。 34. /一些加密算法可能需要固定块长度的padding,或者是为了在更低层数据单元中携带一些RTP报文。 35. /Ifthepaddingbitisset,thepacketcontainsoneormoreadditionalpaddingoctetsatthe 36. /endwhicharenotpartofthepayload.Thelastoctetofthepaddingcontainsacountof 37. /howmanypaddingoctetsshouldbeignored,includingitself.Paddingmaybeneededby 38. /someencryptionalgorithmswithfixedblocksizesorforcarryingseveralRTPpacketsina 39. /lower-layerprotocoldataunit. 40. / 41. publicintPaddinggetreturn0; 42. 43. / 44. /extension(X):1bit 45. /如果设定了extension位,定长头字段后面会有一个头扩展。 46. /Iftheextensionbitisset,thefixedheadermustbefollowedbyexactlyoneheaderextensio. 47. / 48. publicintExtensiongetreturn0; 49. 50. / 51. /CSRCcount(CC):4bits 52. /CSRCcount标识了定长头字段中包含的CSRCidentifier的数量。 53. /TheCSRCcountcontainsthenumberofCSRCidentifiersthatfollowthefixedheader. 54. / 55. publicintCCgetreturn0; 56. 57. / 58. /marker(M):1bit 59. /marker是由一个profile定义的。用来允许标识在像报文流中界定帧界等的事件。 60. /一个profile可能定义了附加的标识位或者通过修改payloadtype域中的位数量来指定没有标识位. 61. /Theinterpretationofthemarkerisdefinedbyaprofile.Itisintendedtoallowsignificant 62. /eventssuchasframeboundariestobemarkedinthepacketstream.Aprofilemaydefine 63. /additionalmarkerbitsorspecifythatthereisnomarkerbitbychangingthenumberofbits 64. /inthepayloadtypefield. 65. / 66. publicintMarkergetreturn0; 67. 68. / 69. /payloadtype(PT):7bits 70. /这个字段定一个RTPpayload的格式和在应用中定义解释。 71. /profile可能指定一个从payloadtype码字到payloadformat的默认静态映像。 72. /也可以通过non-RTP方法来定义附加的payloadtype码字(见第3章)。 73. /在RFC35511中定义了一系列的默认音视频映射。 74. /一个RTP源有可能在会话中改变payloadtype,但是这个域在复用独立的媒体时是不同的。(见5.2节)。 75. /接收者必须忽略它不识别的payloadtype。 76. /ThisfieldidentifiestheformatoftheRTPpayloadanddeterminesitsinterpretationbythe 77. /application.Aprofilemayspecifyadefaultstaticmappingofpayloadtypecodestopayload 78. /formats.Additionalpayloadtypecodesmaybedefineddynamicallythroughnon-RTPmeans 79. /(seeSection3).Asetofdefaultmappingsforaudioandvideoisspecifiedinthecompanion 80. /RFC35511.AnRTPsourcemaychangethepayloadtypeduringasession,butthisfield 81. /shouldnotbeusedformultiplexingseparatemediastreams(seeSection5.2). 82. /Areceivermustignorepacketswithpayloadtypesthatitdoesnotunderstand. 83. / 84. publicRtpPayloadTypePayloadTypeget;privateset; 85. 86. / 87. /sequencenumber:16bits 88. /每发送一个RTP数据报文序号值加一,接收者也可用来检测丢失的包或者重建报文序列。 89. /初始的值是随机的,这样就使得known-plaintext攻击更加困难,即使源并没有加密(见9。1), 90. /因为要通过的translator会做这些事情。关于选择随机数方面的技术见17。 91. /ThesequencenumberincrementsbyoneforeachRTPdatapacketsent,andmaybeused 92. /bythereceivertodetectpacketlossandtorestorepacketsequence.Theinitialvalueofthe 93. /sequencenumbershouldberandom(unpredictable)tomakeknown-plaintextattackson 94. /encryptionmoredificult,evenifthesourceitselfdoesnotencryptaccordingtothemethod 95. /inSection9.1,becausethepacketsmayflowthroughatranslatorthatdoes.Techniquesfor 96. /choosingunpredictablenumbersarediscussedin17. 97. / 98. publicintSequenceNumberget;privateset; 99. 100. / 101. /timestamp:32bits 102. /timestamp反映的是RTP数据报文中的第一个字段的采样时刻的时间瞬时值。 103. /采样时间值必须是从恒定的和线性的时间中得到以便于同步和jitter计算(见第6.4.1节)。 104. /必须保证同步和测量保温jitter到来所需要的时间精度(一帧一个tick一般情况下是不够的)。 105. /时钟频率是与payload所携带的数据格式有关的,在profile中静态的定义或是在定义格式的payloadformat中, 106. /或通过non-RTP方法所定义的payloadformat中动态的定义。如果RTP报文周期的生成,就采用虚拟的(nominal) 107. /采样时钟而不是从系统时钟读数。例如,在固定位元速率的音频中,timestamp时钟会在每个采样周期时加一。 108. /如果音讯应用中从输入设备中读入160个采样周期的块,thetimestamp就会每一块增加160, 109. /而不管块是否传输了或是丢弃了。 110. /对于序号来说,timestamp初始值是随机的。只要它们是同时(逻辑上)同时生成的, 111. /这些连续的的RTP报文就会有相同的timestamp, 112. /例如,同属一个视频帧。正像在MPEG中内插视频帧一样, 113. /连续的但不是按顺序发送的RTP报文可能含有相同的timestamp。 114. /ThetimestampreflectsthesamplinginstantofthefirstoctetintheRTPdatapacket.The 115. /samplinginstantmustbederivedfromaclockthatincrementsmonotonicallyandlinearly 116. /intimetoallowsynchronizationandjittercalculations(seeSection6.4.1).Theresolution 117. /oftheclockmustbesuficientforthedesiredsynchronizationaccuracyandformeasuring 118. /packetarrivaljitter(onetickpervideoframeistypicallynotsuficient).Theclockfrequency 119. /isdependentontheformatofdatacarriedaspayloadandisspecifiedstaticallyintheprofile 120. /orpayloadformatspecificationthatdefinestheformat,ormaybespecifieddynamicallyfor 121. /payloadformatsdefinedthroughnon-RTPmeans.IfRTPpacketsaregeneratedperiodically, 122. /thenominalsamplinginstantasdeterminedfromthesamplingclockistobeused,nota 123. /readingofthesystemclock.Asanexample,forfixed-rateaudiothetimestampclockwould 124. /likelyincrementbyoneforeachsamplingperiod.Ifanaudioapplicationreadsblockscovering 125. /160samplingperiodsfromtheinputdevice,thetimestampwouldbeincreasedby160for 126. /eachsuchblock,regardlessofwhethertheblockistransmittedinapacketordroppedassilent. 127. / 128. publiclongTimestampget;privateset; 129. 130. / 131. /SSRC:32bits 132. /SSRC域识别同步源。为了防止在一个会话中有相同的同步源有相同的SSRCidentifier, 133. /这个identifier必须随机选取。 134. /生成随机identifier的算法见目录A.6。虽然选择相同的identifier概率很小, 135. /但是所有的RTPimplementation必须检测和解决冲突。 136. /第8章描述了冲突的概率和解决机制和RTP级的检测机制,根据唯一的SSRCidentifier前向循环。 137. /如果有源改变了它的源传输地址, 138. /就必须为它选择一个新的SSRCidentifier来避免被识别为循环过的源(见第8.2节)。 139. /TheSSRCfieldidentifiesthesynchronizationsource.Thisidentifiershouldbechosen 140. /randomly,withtheintentthatnotwosynchronizationsourceswithinthesameRTPsession 141. /willhavethesameSSRCidentifier.Anexamplealgorithmforgeneratingarandomidentifier 142. /ispresentedinAppendixA.6.Althoughtheprobabilityofmultiplesourceschoosingthesame 143. /identifierislow,allRTPimplementationsmustbepreparedtodetectandresolvecollisions. 144. /Section8describestheprobabilityofcollisionalongwithamechanismforresolvingcollisions 145. /anddetectingRTP-levelforwardingloopsbasedontheuniquenessoftheSSRCidentifier.If 146. /asourcechangesitssourcetransportaddress,itmustalsochooseanewSSRCidentifierto 147. /avoidbeinginterpretedasaloopedsource(seeSection8.2). 148. / 149. publicintSSRCgetreturn0; 150. 151. / 152. /每一个RTP包中都有前12个字节定长的头字段 153. /ThefirsttwelveoctetsarepresentineveryRTPpacket 154. / 155. publicconstintHeaderSize=12; 156. / 157. /RTP消息头 158. / 159. privatebyte_header; 160. / 161. /RTP消息头 162. / 163. publicbyteHeadergetreturn_header; 164. 165. / 166. /RTP有效载荷长度 167. / 168. privateint_payloadSize; 169. / 170. /RTP有效载荷长度 171. / 172. publicintPayloadSizegetreturn_payloadSize; 173. 174. / 175. /RTP有效载荷 176. / 177. privatebyte_payload; 178. / 179. /RTP有效载荷 180. / 181. publicbytePayloadgetreturn_payload; 182. 183. / 184. /RTP消息总长度,包括Header和Payload 185. / 186. publicintLengthgetreturnHeaderSize+PayloadSize; 187. 188. / 189. /RTP(RFC3550)协定数据报 190. / 191. /数据报文有效载荷类型 192. /数据报文序号值 193. /数据报文采样时刻 194. /数据 195. /数据长度 196. publicRtpPacket( 197. RtpPayloadTypeplayloadType, 198. intsequenceNumber, 199. longtimestamp, 200. bytedata, 201. intdataSize) 202. 203. /fillchangingheaderfields 204. SequenceNumber=sequenceNumber; 205. Timestamp=timestamp; 206. PayloadType=playloadType; 207. 208. /buildtheheaderbistream 209. _header=newbyteHeaderSize; 210. 211. /filltheheaderarrayofbytewithRTPheaderfields 212. _header0=(byte)(Version6)|(Padding5)|(Extension4)|CC); 213. _header1=(byte)(Marker8); 215. _header3=(byte)(SequenceNumber); 216. for(inti=0;i(8*i); 219. 220. for(inti=0;i(8*i); 223. 224. 225. /fillthepayloadbitstream 226. _payload=newbytedataSize; 227. _payloadSize=dataSize; 228. 229. /fillpayloadarrayofbytefromdata(giveninparameteroftheconstructor) 230. Array.Copy(data,0,_payload,0,dataSize); 231. 232. 233. / 234. /RTP(RFC3550)协定数据报 235. / 236. /数据报文有效载荷类型 237. /数据报文序号值 238. /数据报文采样时刻 239. /图片 240. publicRtpPacket( 241. RtpPayloadTypeplayloadType, 242. intsequenceNumber, 243. longtimestamp, 244. Imageframe) 245. 246. /fillchangingheaderfields 247. SequenceNumber=sequenceNumber; 248. Timestamp=timestamp; 249. PayloadType=playloadType; 250. 251. /buildtheheaderbistream 252. _header=newbyteHeaderSize; 253. 254. /filltheheaderarrayofbytewithRTPheaderfields 255. _header0=(byte)(Version6)|(Padding5)|(Extension4)|CC); 256. _header1=(byte)(Marker8); 258. _header3=(byte)(SequenceNumber); 259. for(inti=0;i(8*i); 262. 263. for(inti=0;i(8*i); 266. 267. 268. /fillthepayloadbitstream 269. using(MemoryStreamms=newMemoryStream() 270. 271. frame.Save(ms,ImageFormat.Jpeg); 272. _payload=ms.ToArray(); 273. _payloadSize=_payload.Length; 274. 275. 276. 277. / 278. /RTP(RFC3550)协定数据报 279. / 280. /数据包 281. /数据包长度 282. publicRtpPacket(bytepacket,intpacketSize) 283. 284. /checkiftotalpacketsizeislowerthantheheadersize 285. if(packetSize=HeaderSize) 286. 287. /gettheheaderbitsream 288. _header=newbyteHeaderSize; 289. for(inti=0;iHeaderSize;i+) 290. 291. _headeri=packeti; 292. 293. 294. /getthepayloadbitstream 295. _payloadSize=packetSize-HeaderSize; 296. _payload=newbyte_payloadSize; 297. for(inti=HeaderSize;ipacketSize;i+) 298. 299. _payloadi-HeaderSize=packeti; 300. 301. 302. /interpretthechangingfieldsoftheheader 303. PayloadType=(RtpPayloadType)(_header1&127); 304. SequenceNumber=UnsignedInt(_header3)+256*UnsignedInt(_header2); 305. Timestamp=UnsignedInt(_header7) 306. +256*UnsignedInt(

温馨提示

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

评论

0/150

提交评论