最近考虑使用RTP替换原有的高清视频传输协议,遂上网查找有关H264视频RTP打包、解包的文档和代码。功夫不负有心人,找到不少有价值的文档和代码。参考这些资料,写了H264 RTP打包类、解包类,实现了单个NAL单元包和FU_A分片单元包。对于丢包处理,采用简单的策略:丢弃随后的所有数据包,直到收到关键帧。测试效果还不错,代码贴上来,若能为同道中人借鉴一二,足矣。两个类的使用说明如下(省略了错误处理过程):

DWORD H264SSRC ;

 CH264_RTP_PACK pack ( H264SSRC ) ;

 BYTE *pVideoData ;

 DWORD Size, ts ;

 bool IsEndOfFrame ;

 WORD wLen ;

 pack.Set ( pVideoData, Size, ts, IsEndOfFrame ) ;

 BYTE *pPacket ;

 while ( pPacket = pack.Get ( &wLen ) )

 {

  // rtp packet process

  // ...

 }

HRESULT hr ;

 CH264_RTP_UNPACK unpack ( hr ) ;

 BYTE *pRtpData ;

 WORD inSize;

 int outSize ;

 BYTE *pFrame = unpack.Parse_RTP_Packet ( pRtpData, inSize, &outSize ) ;

 if ( pFrame != NULL )

 {

  // frame process

  // ...

 }

[cpp] view
plain
 copy

  1. //////////////////////////////////////////////////////////////////////////////////////////
  2. // class CH264_RTP_PACK start
  3. class CH264_RTP_PACK
  4. {
  5. #define RTP_VERSION 2
  6. typedef struct NAL_msg_s
  7. {
  8. bool eoFrame ;
  9. unsigned char type;     // NAL type
  10. unsigned char *start;   // pointer to first location in the send buffer
  11. unsigned char *end; // pointer to last location in send buffer
  12. unsigned long size ;
  13. } NAL_MSG_t;
  14. typedef struct
  15. {
  16. //LITTLE_ENDIAN
  17. unsigned short   cc:4;      /* CSRC count                 */
  18. unsigned short   x:1;       /* header extension flag      */
  19. unsigned short   p:1;       /* padding flag               */
  20. unsigned short   v:2;       /* packet type                */
  21. unsigned short   pt:7;      /* payload type               */
  22. unsigned short   m:1;       /* marker bit                 */
  23. unsigned short    seq;      /* sequence number            */
  24. unsigned long     ts;       /* timestamp                  */
  25. unsigned long     ssrc;     /* synchronization source     */
  26. } rtp_hdr_t;
  27. typedef struct tagRTP_INFO
  28. {
  29. NAL_MSG_t   nal;        // NAL information
  30. rtp_hdr_t   rtp_hdr;    // RTP header is assembled here
  31. int hdr_len;            // length of RTP header
  32. unsigned char *pRTP;    // pointer to where RTP packet has beem assembled
  33. unsigned char *start;   // pointer to start of payload
  34. unsigned char *end;     // pointer to end of payload
  35. unsigned int s_bit;     // bit in the FU header
  36. unsigned int e_bit;     // bit in the FU header
  37. bool FU_flag;       // fragmented NAL Unit flag
  38. } RTP_INFO;
  39. public:
  40. CH264_RTP_PACK(unsigned long H264SSRC, unsigned char H264PAYLOADTYPE=96, unsigned short MAXRTPPACKSIZE=1472 )
  41. {
  42. m_MAXRTPPACKSIZE = MAXRTPPACKSIZE ;
  43. if ( m_MAXRTPPACKSIZE > 10000 )
  44. {
  45. m_MAXRTPPACKSIZE = 10000 ;
  46. }
  47. if ( m_MAXRTPPACKSIZE < 50 )
  48. {
  49. m_MAXRTPPACKSIZE = 50 ;
  50. }
  51. memset ( &m_RTP_Info, 0, sizeof(m_RTP_Info) ) ;
  52. m_RTP_Info.rtp_hdr.pt = H264PAYLOADTYPE ;
  53. m_RTP_Info.rtp_hdr.ssrc = H264SSRC ;
  54. m_RTP_Info.rtp_hdr.v = RTP_VERSION ;
  55. m_RTP_Info.rtp_hdr.seq = 0 ;
  56. }
  57. ~CH264_RTP_PACK(void)
  58. {
  59. }
  60. //传入Set的数据必须是一个完整的NAL,起始码为0x00000001。
  61. //起始码之前至少预留10个字节,以避免内存COPY操作。
  62. //打包完成后,原缓冲区内的数据被破坏。
  63. bool Set ( unsigned char *NAL_Buf, unsigned long NAL_Size, unsigned long Time_Stamp, bool End_Of_Frame )
  64. {
  65. unsigned long startcode = StartCode(NAL_Buf) ;
  66. if ( startcode != 0x01000000 )
  67. {
  68. return false ;
  69. }
  70. int type = NAL_Buf[4] & 0x1f ;
  71. if ( type < 1 || type > 12 )
  72. {
  73. return false ;
  74. }
  75. m_RTP_Info.nal.start = NAL_Buf ;
  76. m_RTP_Info.nal.size = NAL_Size ;
  77. m_RTP_Info.nal.eoFrame = End_Of_Frame ;
  78. m_RTP_Info.nal.type = m_RTP_Info.nal.start[4] ;
  79. m_RTP_Info.nal.end = m_RTP_Info.nal.start + m_RTP_Info.nal.size ;
  80. m_RTP_Info.rtp_hdr.ts = Time_Stamp ;
  81. m_RTP_Info.nal.start += 4 ; // skip the syncword
  82. if ( (m_RTP_Info.nal.size + 7) > m_MAXRTPPACKSIZE )
  83. {
  84. m_RTP_Info.FU_flag = true ;
  85. m_RTP_Info.s_bit = 1 ;
  86. m_RTP_Info.e_bit = 0 ;
  87. m_RTP_Info.nal.start += 1 ; // skip NAL header
  88. }
  89. else
  90. {
  91. m_RTP_Info.FU_flag = false ;
  92. m_RTP_Info.s_bit = m_RTP_Info.e_bit = 0 ;
  93. }
  94. m_RTP_Info.start = m_RTP_Info.end = m_RTP_Info.nal.start ;
  95. m_bBeginNAL = true ;
  96. return true ;
  97. }
  98. //循环调用Get获取RTP包,直到返回值为NULL
  99. unsigned char* Get ( unsigned short *pPacketSize )
  100. {
  101. if ( m_RTP_Info.end == m_RTP_Info.nal.end )
  102. {
  103. *pPacketSize = 0 ;
  104. return NULL ;
  105. }
  106. if ( m_bBeginNAL )
  107. {
  108. m_bBeginNAL = false ;
  109. }
  110. else
  111. {
  112. m_RTP_Info.start = m_RTP_Info.end;  // continue with the next RTP-FU packet
  113. }
  114. int bytesLeft = m_RTP_Info.nal.end - m_RTP_Info.start ;
  115. int maxSize = m_MAXRTPPACKSIZE - 12 ;   // sizeof(basic rtp header) == 12 bytes
  116. if ( m_RTP_Info.FU_flag )
  117. maxSize -= 2 ;
  118. if ( bytesLeft > maxSize )
  119. {
  120. m_RTP_Info.end = m_RTP_Info.start + maxSize ;   // limit RTP packetsize to 1472 bytes
  121. }
  122. else
  123. {
  124. m_RTP_Info.end = m_RTP_Info.start + bytesLeft ;
  125. }
  126. if ( m_RTP_Info.FU_flag )
  127. {   // multiple packet NAL slice
  128. if ( m_RTP_Info.end == m_RTP_Info.nal.end )
  129. {
  130. m_RTP_Info.e_bit = 1 ;
  131. }
  132. }
  133. m_RTP_Info.rtp_hdr.m =  m_RTP_Info.nal.eoFrame ? 1 : 0 ; // should be set at EofFrame
  134. if ( m_RTP_Info.FU_flag && !m_RTP_Info.e_bit )
  135. {
  136. m_RTP_Info.rtp_hdr.m = 0 ;
  137. }
  138. m_RTP_Info.rtp_hdr.seq++ ;
  139. unsigned char *cp = m_RTP_Info.start ;
  140. cp -= ( m_RTP_Info.FU_flag ? 14 : 12 ) ;
  141. m_RTP_Info.pRTP = cp ;
  142. unsigned char *cp2 = (unsigned char *)&m_RTP_Info.rtp_hdr ;
  143. cp[0] = cp2[0] ;
  144. cp[1] = cp2[1] ;
  145. cp[2] = ( m_RTP_Info.rtp_hdr.seq >> 8 ) & 0xff ;
  146. cp[3] = m_RTP_Info.rtp_hdr.seq & 0xff ;
  147. cp[4] = ( m_RTP_Info.rtp_hdr.ts >> 24 ) & 0xff ;
  148. cp[5] = ( m_RTP_Info.rtp_hdr.ts >> 16 ) & 0xff ;
  149. cp[6] = ( m_RTP_Info.rtp_hdr.ts >>  8 ) & 0xff ;
  150. cp[7] = m_RTP_Info.rtp_hdr.ts & 0xff ;
  151. cp[8] =  ( m_RTP_Info.rtp_hdr.ssrc >> 24 ) & 0xff ;
  152. cp[9] =  ( m_RTP_Info.rtp_hdr.ssrc >> 16 ) & 0xff ;
  153. cp[10] = ( m_RTP_Info.rtp_hdr.ssrc >>  8 ) & 0xff ;
  154. cp[11] = m_RTP_Info.rtp_hdr.ssrc & 0xff ;
  155. m_RTP_Info.hdr_len = 12 ;
  156. /*!
  157. * /n The FU indicator octet has the following format:
  158. * /n
  159. * /n      +---------------+
  160. * /n MSB  |0|1|2|3|4|5|6|7|  LSB
  161. * /n      +-+-+-+-+-+-+-+-+
  162. * /n      |F|NRI|  Type   |
  163. * /n      +---------------+
  164. * /n
  165. * /n The FU header has the following format:
  166. * /n
  167. * /n      +---------------+
  168. * /n      |0|1|2|3|4|5|6|7|
  169. * /n      +-+-+-+-+-+-+-+-+
  170. * /n      |S|E|R|  Type   |
  171. * /n      +---------------+
  172. */
  173. if ( m_RTP_Info.FU_flag )
  174. {
  175. // FU indicator  F|NRI|Type
  176. cp[12] = ( m_RTP_Info.nal.type & 0xe0 ) | 28 ;  //Type is 28 for FU_A
  177. //FU header     S|E|R|Type
  178. cp[13] = ( m_RTP_Info.s_bit << 7 ) | ( m_RTP_Info.e_bit << 6 ) | ( m_RTP_Info.nal.type & 0x1f ) ; //R = 0, must be ignored by receiver
  179. m_RTP_Info.s_bit = m_RTP_Info.e_bit= 0 ;
  180. m_RTP_Info.hdr_len = 14 ;
  181. }
  182. m_RTP_Info.start = &cp[m_RTP_Info.hdr_len] ;    // new start of payload
  183. *pPacketSize = m_RTP_Info.hdr_len + ( m_RTP_Info.end - m_RTP_Info.start ) ;
  184. return m_RTP_Info.pRTP ;
  185. }
  186. private:
  187. unsigned int StartCode( unsigned char *cp )
  188. {
  189. unsigned int d32 ;
  190. d32 = cp[3] ;
  191. d32 <<= 8 ;
  192. d32 |= cp[2] ;
  193. d32 <<= 8 ;
  194. d32 |= cp[1] ;
  195. d32 <<= 8 ;
  196. d32 |= cp[0] ;
  197. return d32 ;
  198. }
  199. private:
  200. RTP_INFO m_RTP_Info ;
  201. bool m_bBeginNAL ;
  202. unsigned short m_MAXRTPPACKSIZE ;
  203. };
  204. // class CH264_RTP_PACK end
  205. //////////////////////////////////////////////////////////////////////////////////////////
  206. //////////////////////////////////////////////////////////////////////////////////////////
  207. // class CH264_RTP_UNPACK start
  208. class CH264_RTP_UNPACK
  209. {
  210. #define RTP_VERSION 2
  211. #define BUF_SIZE (1024 * 500)
  212. typedef struct
  213. {
  214. //LITTLE_ENDIAN
  215. unsigned short   cc:4;      /* CSRC count                 */
  216. unsigned short   x:1;       /* header extension flag      */
  217. unsigned short   p:1;       /* padding flag               */
  218. unsigned short   v:2;       /* packet type                */
  219. unsigned short   pt:7;      /* payload type               */
  220. unsigned short   m:1;       /* marker bit                 */
  221. unsigned short    seq;      /* sequence number            */
  222. unsigned long     ts;       /* timestamp                  */
  223. unsigned long     ssrc;     /* synchronization source     */
  224. } rtp_hdr_t;
  225. public:
  226. CH264_RTP_UNPACK ( HRESULT &hr, unsigned char H264PAYLOADTYPE = 96 )
  227. : m_bSPSFound(false)
  228. , m_bWaitKeyFrame(true)
  229. , m_bPrevFrameEnd(false)
  230. , m_bAssemblingFrame(false)
  231. , m_wSeq(1234)
  232. , m_ssrc(0)
  233. {
  234. m_pBuf = new BYTE[BUF_SIZE] ;
  235. if ( m_pBuf == NULL )
  236. {
  237. hr = E_OUTOFMEMORY ;
  238. return ;
  239. }
  240. m_H264PAYLOADTYPE = H264PAYLOADTYPE ;
  241. m_pEnd = m_pBuf + BUF_SIZE ;
  242. m_pStart = m_pBuf ;
  243. m_dwSize = 0 ;
  244. hr = S_OK ;
  245. }
  246. ~CH264_RTP_UNPACK(void)
  247. {
  248. delete [] m_pBuf ;
  249. }
  250. //pBuf为H264 RTP视频数据包,nSize为RTP视频数据包字节长度,outSize为输出视频数据帧字节长度。
  251. //返回值为指向视频数据帧的指针。输入数据可能被破坏。
  252. BYTE* Parse_RTP_Packet ( BYTE *pBuf, unsigned short nSize, int *outSize )
  253. {
  254. if ( nSize <= 12 )
  255. {
  256. return NULL ;
  257. }
  258. BYTE *cp = (BYTE*)&m_RTP_Header ;
  259. cp[0] = pBuf[0] ;
  260. cp[1] = pBuf[1] ;
  261. m_RTP_Header.seq = pBuf[2] ;
  262. m_RTP_Header.seq <<= 8 ;
  263. m_RTP_Header.seq |= pBuf[3] ;
  264. m_RTP_Header.ts = pBuf[4] ;
  265. m_RTP_Header.ts <<= 8 ;
  266. m_RTP_Header.ts |= pBuf[5] ;
  267. m_RTP_Header.ts <<= 8 ;
  268. m_RTP_Header.ts |= pBuf[6] ;
  269. m_RTP_Header.ts <<= 8 ;
  270. m_RTP_Header.ts |= pBuf[7] ;
  271. m_RTP_Header.ssrc = pBuf[8] ;
  272. m_RTP_Header.ssrc <<= 8 ;
  273. m_RTP_Header.ssrc |= pBuf[9] ;
  274. m_RTP_Header.ssrc <<= 8 ;
  275. m_RTP_Header.ssrc |= pBuf[10] ;
  276. m_RTP_Header.ssrc <<= 8 ;
  277. m_RTP_Header.ssrc |= pBuf[11] ;
  278. BYTE *pPayload = pBuf + 12 ;
  279. DWORD PayloadSize = nSize - 12 ;
  280. // Check the RTP version number (it should be 2):
  281. if ( m_RTP_Header.v != RTP_VERSION )
  282. {
  283. return NULL ;
  284. }
  285. /*
  286. // Skip over any CSRC identifiers in the header:
  287. if ( m_RTP_Header.cc )
  288. {
  289. long cc = m_RTP_Header.cc * 4 ;
  290. if ( Size < cc )
  291. {
  292. return NULL ;
  293. }
  294. Size -= cc ;
  295. p += cc ;
  296. }
  297. // Check for (& ignore) any RTP header extension
  298. if ( m_RTP_Header.x )
  299. {
  300. if ( Size < 4 )
  301. {
  302. return NULL ;
  303. }
  304. Size -= 4 ;
  305. p += 2 ;
  306. long l = p[0] ;
  307. l <<= 8 ;
  308. l |= p[1] ;
  309. p += 2 ;
  310. l *= 4 ;
  311. if ( Size < l ) ;
  312. {
  313. return NULL ;
  314. }
  315. Size -= l ;
  316. p += l ;
  317. }
  318. // Discard any padding bytes:
  319. if ( m_RTP_Header.p )
  320. {
  321. if ( Size == 0 )
  322. {
  323. return NULL ;
  324. }
  325. long Padding = p[Size-1] ;
  326. if ( Size < Padding )
  327. {
  328. return NULL ;
  329. }
  330. Size -= Padding ;
  331. }*/
  332. // Check the Payload Type.
  333. if ( m_RTP_Header.pt != m_H264PAYLOADTYPE )
  334. {
  335. return NULL ;
  336. }
  337. int PayloadType = pPayload[0] & 0x1f ;
  338. int NALType = PayloadType ;
  339. if ( NALType == 28 ) // FU_A
  340. {
  341. if ( PayloadSize < 2 )
  342. {
  343. return NULL ;
  344. }
  345. NALType = pPayload[1] & 0x1f ;
  346. }
  347. if ( m_ssrc != m_RTP_Header.ssrc )
  348. {
  349. m_ssrc = m_RTP_Header.ssrc ;
  350. SetLostPacket () ;
  351. }
  352. if ( NALType == 0x07 ) // SPS
  353. {
  354. m_bSPSFound = true ;
  355. }
  356. if ( !m_bSPSFound )
  357. {
  358. return NULL ;
  359. }
  360. if ( NALType == 0x07 || NALType == 0x08 ) // SPS PPS
  361. {
  362. m_wSeq = m_RTP_Header.seq ;
  363. m_bPrevFrameEnd = true ;
  364. pPayload -= 4 ;
  365. *((DWORD*)(pPayload)) = 0x01000000 ;
  366. *outSize = PayloadSize + 4 ;
  367. return pPayload ;
  368. }
  369. if ( m_bWaitKeyFrame )
  370. {
  371. if ( m_RTP_Header.m ) // frame end
  372. {
  373. m_bPrevFrameEnd = true ;
  374. if ( !m_bAssemblingFrame )
  375. {
  376. m_wSeq = m_RTP_Header.seq ;
  377. return NULL ;
  378. }
  379. }
  380. if ( !m_bPrevFrameEnd )
  381. {
  382. m_wSeq = m_RTP_Header.seq ;
  383. return NULL ;
  384. }
  385. else
  386. {
  387. if ( NALType != 0x05 ) // KEY FRAME
  388. {
  389. m_wSeq = m_RTP_Header.seq ;
  390. m_bPrevFrameEnd = false ;
  391. return NULL ;
  392. }
  393. }
  394. }
  395. ///////////////////////////////////////////////////////////////
  396. if ( m_RTP_Header.seq != (WORD)( m_wSeq + 1 ) ) // lost packet
  397. {
  398. m_wSeq = m_RTP_Header.seq ;
  399. SetLostPacket () ;
  400. return NULL ;
  401. }
  402. else
  403. {
  404. // 码流正常
  405. m_wSeq = m_RTP_Header.seq ;
  406. m_bAssemblingFrame = true ;
  407. if ( PayloadType != 28 ) // whole NAL
  408. {
  409. *((DWORD*)(m_pStart)) = 0x01000000 ;
  410. m_pStart += 4 ;
  411. m_dwSize += 4 ;
  412. }
  413. else // FU_A
  414. {
  415. if ( pPayload[1] & 0x80 ) // FU_A start
  416. {
  417. *((DWORD*)(m_pStart)) = 0x01000000 ;
  418. m_pStart += 4 ;
  419. m_dwSize += 4 ;
  420. pPayload[1] = ( pPayload[0] & 0xE0 ) | NALType ;
  421. pPayload += 1 ;
  422. PayloadSize -= 1 ;
  423. }
  424. else
  425. {
  426. pPayload += 2 ;
  427. PayloadSize -= 2 ;
  428. }
  429. }
  430. if ( m_pStart + PayloadSize < m_pEnd )
  431. {
  432. CopyMemory ( m_pStart, pPayload, PayloadSize ) ;
  433. m_dwSize += PayloadSize ;
  434. m_pStart += PayloadSize ;
  435. }
  436. else // memory overflow
  437. {
  438. SetLostPacket () ;
  439. return NULL ;
  440. }
  441. if ( m_RTP_Header.m ) // frame end
  442. {
  443. *outSize = m_dwSize ;
  444. m_pStart = m_pBuf ;
  445. m_dwSize = 0 ;
  446. if ( NALType == 0x05 ) // KEY FRAME
  447. {
  448. m_bWaitKeyFrame = false ;
  449. }
  450. return m_pBuf ;
  451. }
  452. else
  453. {
  454. return NULL ;
  455. }
  456. }
  457. }
  458. void SetLostPacket()
  459. {
  460. m_bSPSFound = false ;
  461. m_bWaitKeyFrame = true ;
  462. m_bPrevFrameEnd = false ;
  463. m_bAssemblingFrame = false ;
  464. m_pStart = m_pBuf ;
  465. m_dwSize = 0 ;
  466. }
  467. private:
  468. rtp_hdr_t m_RTP_Header ;
  469. BYTE *m_pBuf ;
  470. bool m_bSPSFound ;
  471. bool m_bWaitKeyFrame ;
  472. bool m_bAssemblingFrame ;
  473. bool m_bPrevFrameEnd ;
  474. BYTE *m_pStart ;
  475. BYTE *m_pEnd ;
  476. DWORD m_dwSize ;
  477. WORD m_wSeq ;
  478. BYTE m_H264PAYLOADTYPE ;
  479. DWORD m_ssrc ;
  480. };
  481. // class CH264_RTP_UNPACK end
  482. //////////////////////////////////////////////////////////////////////////////////////////

【FFMPEG】基于RTP的H264视频数据打包解包类的更多相关文章

  1. (转)基于RTP的H264视频数据打包解包类

    最近考虑使用RTP替换原有的高清视频传输协议,遂上网查找有关H264视频RTP打包.解包的文档和代码.功夫不负有心人,找到不少有价值的文档和代码.参考这些资料,写了H264 RTP打包类.解包类,实现 ...

  2. 基于RTP的H264视频数据打包解包类

    from:http://blog.csdn.net/dengzikun/article/details/5807694 最近考虑使用RTP替换原有的高清视频传输协议,遂上网查找有关H264视频RTP打 ...

  3. h264_rtp打包解包类及实现demo

    打包头文件: class CH2642Rtp { public: CH2642Rtp(uint32_t ssrc, uint8_t payloadType = 96, uint8_t fps = 25 ...

  4. indows下PHP通过ffmpeg给上传的视频截图详解

    windows下PHP通过ffmpeg给上传的视频截图详解,php_ffmpeg.dll安装下载,找了很久php_ffmpeg.dll的下载地址和应用,发现有用的资源很少,现在问题解决了,贴出来跟大家 ...

  5. Java之集合初探(二)Iterator(迭代器),collections,打包/解包(装箱拆箱),泛型(Generic),comparable接口

    Iterator(迭代器) 所有实现了Collection接口的容器都有一个iterator方法, 用来返回一个实现了Iterator接口的对象 Iterator对象称作迭代器, 用来方便的实现对容器 ...

  6. 07.进程管理+作业控制+文件查找与压缩+文件压缩与打包+tar打包解包+NFS

    进程管理 程序放在磁盘上叫文件,把它复制到内存,并在cpu运行,就叫进程, 进程多少也反映当前运行程序的多少 进程在系统中会为每个进程生成一个进程号,在所有的进程中有一个特殊进程即init进程, 它是 ...

  7. Mtk Android 打包解包*.img

    打包/解包 boot.img, system.img, userdata.img, or recovery.img [DESCRIPTION] MTK codebase编译出来的image必须使用MT ...

  8. 【Unity】AssetBundle的使用——打包/解包

    最近参考了各位大神的资源,初步学习了Unity的资源管理模式,包括在编辑器管理(使用AssetDatabase)和在运行时管理(使用Resources和AssetBundle).在此简单总结运行时用A ...

  9. xpack文件打包解包代码库

    Github ###概述 xpack是一个文件资源打包工具及类库,可以对多文件进行打包解包. 其使用文件名的hash作为索引,建立hash索引表以加速文件查找. ###特性 支持hashid自动解冲突 ...

随机推荐

  1. ACM-ICPC 2018 焦作赛区网络预赛 K. Transport Ship(DP)

    题目链接:https://nanti.jisuanke.com/t/31720 题意:有n种飞船,每种飞船有(1 << c)- 1  艘,容量为 k[i] ,q 次询问,每次询问选若干艘飞 ...

  2. [ML] The Basics: Training Your First Model

    The problem we will solve is to convert from Celsius to Fahrenheit, where the approximate formula is ...

  3. Win2008 R2 IIS FTP防火墙的配置

    注意以下两个选项要在防火墙下开启,否则将会访问失败.

  4. const 与指针 的用法

    请找出下面程序中有哪些错误: 1 2 3 4 5 6 7 8 9 10 11 12 13 int main() {    int i=10;    int j=1;    const int *p1; ...

  5. C#字符串和值转换 以及万能转换

    2.使用万能转换器进行不同类型转换 Convert.ToXxx(object value) int  iRet = Convert.ToInt32("201"); float fR ...

  6. POJ 1741 Tree ——(树分治)

    思路参考于:http://blog.csdn.net/yang_7_46/article/details/9966455,不再赘述. 复杂度:找树的重心然后分治复杂度为logn,每次对距离数组dep排 ...

  7. 2016 Multi-University Training Contest 3 部分题解

    1001,只要枚举区间即可.签到题,要注意的是输入0的话也是“TAT”.不过今天补题的时候却WA了好几次,觉得奇怪.原来出现在判断条件那里,x是一个int64类型的变量,在进行(x<65536* ...

  8. cookies ,session,localstorage讲解

    一 .cookie (1)简介 因为HTTP协议是无状态的,服务器不知道用户上一次做了什么,这严重阻碍了交互式Web应用程序的实现.在典型的网上购物场景中,用户浏览了几个页面,买了一盒饼干和两饮料.最 ...

  9. IntelliJ IDEA 2017.3 多模块右边栏 maven projects,maven项目命名问题

    我新建了一个maven web 模块,命名为cloud-access,可是install的时候,名字突然变为cloud-access Maven Webapp了,我就纳闷了,怎么回事.找了很久没发现原 ...

  10. No Desktop License Servers available to provide a license

    远程桌面连接失败,提示:“no Remote Desktop License Servers available to provide a license” 原因:没有remote desktop l ...