Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

444 lines
11 KiB

  1. /* *************************************************************************
  2. ** INTEL Corporation Proprietary Information
  3. **
  4. ** This listing is supplied under the terms of a license
  5. ** agreement with INTEL Corporation and may not be copied
  6. ** nor disclosed except in accordance with the terms of
  7. ** that agreement.
  8. **
  9. ** Copyright (c) 1995 Intel Corporation.
  10. ** Copyright (c) 1996 Intel Corporation.
  11. ** All Rights Reserved.
  12. **
  13. ** *************************************************************************
  14. // $Author: AGUPTA2 $
  15. // $Date: 14 Apr 1997 16:58:54 $
  16. // $Archive: S:\h26x\src\enc\e1rtp.cpv $
  17. // $Header: S:\h26x\src\enc\e1rtp.cpv 1.10 14 Apr 1997 16:58:54 AGUPTA2 $
  18. // $Log: S:\h26x\src\enc\e1rtp.cpv $
  19. //
  20. // Rev 1.10 14 Apr 1997 16:58:54 AGUPTA2
  21. // Added a new function to return size of just the extended bit-stream (RTP pa
  22. //
  23. // Rev 1.9 21 Nov 1996 10:51:46 RHAZRA
  24. // Changed the packet threshold to 80%
  25. //
  26. // Rev 1.8 18 Nov 1996 17:11:34 MBODART
  27. // Replaced all debug message invocations with Active Movie's DbgLog.
  28. //
  29. // Rev 1.7 07 Nov 1996 14:43:46 RHAZRA
  30. // Changed declaration of packet size threshold function.
  31. //
  32. // Rev 1.6 30 Sep 1996 08:50:06 RHAZRA
  33. // Look for zero GOB number entry in Rewind operation.
  34. //
  35. // Rev 1.5 24 Sep 1996 13:48:46 RHAZRA
  36. // Changed MBAP to be in the range 0-31 as demanded by the RTP spec.
  37. //
  38. // Rev 1.4 17 Sep 1996 21:59:44 RHAZRA
  39. // Assigned GOB number to zero at GOB-level packet fragmentation to
  40. // be consistent with the RTP spec.
  41. //
  42. // Rev 1.3 16 Sep 1996 09:31:14 RHAZRA
  43. //
  44. // Now return motion vectors in interger pel units as opposed to
  45. // half pel units for interoperability.
  46. //
  47. // Rev 1.2 26 Aug 1996 10:11:44 RHAZRA
  48. // Fixed a bug in RewindBSinfoStream function.
  49. //
  50. // Rev 1.1 23 Aug 1996 13:04:52 RHAZRA
  51. // Added #ifdef RING0 ... #endif to avoid wsprintf and GlobaclAlloc
  52. // problems in RING0
  53. //
  54. // Rev 1.0 21 Aug 1996 18:31:20 RHAZRA
  55. // Initial revision.
  56. //
  57. // Rev 1.1 28 Apr 1996 20:09:04 BECHOLS
  58. //
  59. // Removed RTP_HEADER IFDEFs.
  60. //
  61. // Rev 1.0 22 Apr 1996 17:46:10 BECHOLS
  62. // Initial revision.
  63. //
  64. // Rev 1.7 10 Apr 1996 13:33:04 CZHU
  65. // Moved packet loss sim to c3rtp.cpp
  66. //
  67. // Rev 1.6 29 Mar 1996 13:37:42 CZHU
  68. //
  69. //
  70. // Rev 1.5 01 Mar 1996 16:37:08 DBRUCKS
  71. //
  72. // change to use 3/4ths of packet size as the threshold
  73. // change to make packet size a parameter
  74. //
  75. // Rev 1.4 23 Feb 1996 17:36:48 CZHU
  76. //
  77. //
  78. // Rev 1.3 23 Feb 1996 16:18:28 CZHU
  79. // integrate with build 29
  80. //
  81. // Rev 1.2 15 Feb 1996 12:00:42 CZHU
  82. // ean up
  83. // Clean up
  84. //
  85. // Rev 1.1 14 Feb 1996 14:59:36 CZHU
  86. // Support both mode A and mode B payload modes.
  87. //
  88. // Rev 1.0 12 Feb 1996 17:04:44 CZHU
  89. // Initial revision.
  90. //
  91. // Rev 1.5 25 Jan 1996 16:14:34 CZHU
  92. //
  93. // name changes
  94. //
  95. // Rev 1.4 15 Dec 1995 13:06:46 CZHU
  96. //
  97. //
  98. //
  99. //
  100. //
  101. //
  102. // Rev 1.3 11 Dec 1995 14:52:42 CZHU
  103. // Added support for per MB packetization
  104. //
  105. // Rev 1.2 04 Dec 1995 16:50:26 CZHU
  106. //
  107. // Rev 1.1 01 Dec 1995 15:53:52 CZHU
  108. // Included Init() and Term() functions.
  109. //
  110. // Rev 1.0 01 Dec 1995 15:31:02 CZHU
  111. // Initial revision.
  112. */
  113. /*
  114. * This file is for RTP payload generation. See EPS for details
  115. *
  116. *
  117. */
  118. #include "precomp.h"
  119. /*
  120. * Helper function to calculate the threshold of packet size
  121. * for given maximum packet size and data rate
  122. */
  123. U32 getRTPPacketSizeThreshold(U32 uRequested)
  124. { U32 uSize;
  125. uSize = (uRequested * 85) / 100;
  126. ASSERT(uSize);
  127. return uSize;
  128. }
  129. I32 H261RTP_InitBsInfoStream(
  130. T_H263EncoderCatalog * EC,
  131. UINT unPacketSize)
  132. {
  133. U32 uBsInfoSize;
  134. uBsInfoSize = EC->FrameHeight * EC->FrameWidth * 3 / 4 ;
  135. uBsInfoSize = uBsInfoSize*sizeof(T_RTP_H261_BSINFO)/ DEFAULT_PACKET_SIZE;
  136. EC->hBsInfoStream= GlobalAlloc(GHND, uBsInfoSize);
  137. if ( EC->hBsInfoStream)
  138. {
  139. EC->pBaseBsInfoStream = (void *)GlobalLock(EC->hBsInfoStream);
  140. EC->pBsInfoStream = EC->pBaseBsInfoStream;
  141. EC->uBase = 0;
  142. EC->uNumOfPackets=0;
  143. EC->uPacketSizeThreshold = getRTPPacketSizeThreshold(unPacketSize);
  144. }
  145. else return FALSE;
  146. #ifndef RING0
  147. #ifdef _DEBUG
  148. DBOUT("BsInfoStream initialized....\n");
  149. #endif
  150. #endif
  151. return TRUE;
  152. }
  153. /*
  154. * H263RTPFindMVs
  155. * Find motion vector predictors for current MB and return in arraryMVs[]
  156. *
  157. */
  158. U32 H261RTPFindMVs (
  159. T_H263EncoderCatalog * EC,
  160. T_MBlockActionStream * pMBlockAction,
  161. //U32 uMBA,
  162. //U32 uGOBN,
  163. I8 arrayMVs[2],
  164. UN unCurrentMB,
  165. UN unLastCodedMB
  166. )
  167. {
  168. if ( ((unCurrentMB - unLastCodedMB) != 1) || ((unCurrentMB % 11) == 0) )
  169. {
  170. arrayMVs[0]=0;
  171. arrayMVs[1]=0;
  172. }
  173. else
  174. {
  175. arrayMVs[0]= pMBlockAction[-1].BlkY1.PHMV;
  176. arrayMVs[1]= pMBlockAction[-1].BlkY1.PVMV;
  177. }
  178. return TRUE;
  179. }
  180. /*
  181. * This routine is called at the beginning of each MB
  182. * to update the BitstreamInfoStream;
  183. *
  184. */
  185. I32 H261RTP_MBUpdateBsInfo (
  186. T_H263EncoderCatalog * EC,
  187. T_MBlockActionStream * pMBlockAction,
  188. U32 uQuant,
  189. U32 uMBAP,
  190. U32 uGOBN,
  191. U8 *pBitStream,
  192. U32 uBitOffset,
  193. UN unCurrentMB,
  194. UN unLastCodedMB
  195. )
  196. {
  197. U32 uNewBytes;
  198. T_RTP_H261_BSINFO *pBsInfoStream ;
  199. //compute the difference
  200. uNewBytes = (U32)pBitStream - (U32)EC->pU8_BitStream - EC->uBase;
  201. if ((uNewBytes < EC->uPacketSizeThreshold) ||
  202. (unCurrentMB == 0) )
  203. {
  204. return TRUE;
  205. }
  206. else
  207. {
  208. I8 arrayMVs[2];
  209. ASSERT(unCurrentMB); //it should not happen on the first MB in a GOB
  210. pBsInfoStream = (T_RTP_H261_BSINFO *)EC->pBsInfoStream;
  211. EC->uBase += uNewBytes;
  212. pBsInfoStream->uFlags = 0;
  213. pBsInfoStream->uBitOffset = uBitOffset + EC->uBase*8; //next bit
  214. //pBsInfoStream->u8MBA = (U8)(unLastCodedMB + 1);
  215. pBsInfoStream->u8MBA = (U8)(unLastCodedMB);
  216. if (!unCurrentMB)
  217. pBsInfoStream->u8Quant = (U8)0; // this case should never be true
  218. else
  219. pBsInfoStream->u8Quant = (U8)uQuant;
  220. pBsInfoStream->u8GOBN = (U8)uGOBN;
  221. H261RTPFindMVs(EC, pMBlockAction,/* uMBAP, uGOBN,*/ arrayMVs, unCurrentMB,
  222. unLastCodedMB);
  223. pBsInfoStream->i8HMV = (arrayMVs[0]>>1);
  224. pBsInfoStream->i8VMV = (arrayMVs[1]>>1);
  225. }//end of if (size <packetSize)
  226. #ifndef RING0
  227. #ifdef _DEBUG
  228. { char msg[200];
  229. wsprintf(msg, "uFlag =%d,BitOffset=%d, MBA=%d, uQuant=%d,GOBN=%d,pBitStream=%lx,PacketSize= %d B",
  230. pBsInfoStream->uFlags,
  231. pBsInfoStream->uBitOffset,
  232. pBsInfoStream->u8MBA,
  233. pBsInfoStream->u8Quant,
  234. pBsInfoStream->u8GOBN,
  235. (U32)pBitStream,
  236. uNewBytes);
  237. DBOUT(msg);
  238. }
  239. #endif
  240. #endif
  241. EC->pBsInfoStream = (void *) ++pBsInfoStream; //create a new packet
  242. EC->uNumOfPackets++;
  243. return TRUE;
  244. }
  245. /*
  246. * This Routine is called every GOB except GOB 1 to build a
  247. * packet
  248. *
  249. */
  250. I32 H261RTP_GOBUpdateBsInfo (
  251. T_H263EncoderCatalog * EC,
  252. U32 uGOBN,
  253. U8 *pBitStream,
  254. U32 uBitOffset
  255. )
  256. {
  257. U32 uNewBytes;
  258. T_RTP_H261_BSINFO *pBsInfoStream ;
  259. //compute the difference
  260. uNewBytes = (U32)pBitStream - (U32)EC->pU8_BitStream - EC->uBase;
  261. {
  262. pBsInfoStream = (T_RTP_H261_BSINFO *)EC->pBsInfoStream;
  263. if (uGOBN > 1) //avoid break between uMBA=0 and GOB header.
  264. {
  265. if (uNewBytes)
  266. {
  267. EC->uBase += uNewBytes;
  268. pBsInfoStream->uBitOffset = uBitOffset + EC->uBase*8; //next bit
  269. }
  270. else
  271. {
  272. goto nobreak;
  273. }
  274. }
  275. else
  276. pBsInfoStream->uBitOffset = 0;
  277. pBsInfoStream->uFlags = 0;
  278. pBsInfoStream->u8MBA = 0;
  279. pBsInfoStream->u8Quant = 0; // invalid Quant to signal packet starts a GOB
  280. //pBsInfoStream->u8GOBN =(U8)uGOBN;
  281. pBsInfoStream->u8GOBN = 0;
  282. pBsInfoStream->i8HMV = 0;
  283. pBsInfoStream->i8VMV = 0;
  284. EC->uNumOfPackets++;
  285. #ifndef RING0
  286. #ifdef _DEBUG
  287. { char msg[120];
  288. wsprintf(msg, "uFlag =%d,BitOffset=%d, MBA=%d, uQuant=%d,GOBN=%d,pBitStream=%lx,PacketSize= %d B",
  289. pBsInfoStream->uFlags,
  290. pBsInfoStream->uBitOffset,
  291. pBsInfoStream->u8MBA,
  292. pBsInfoStream->u8Quant,
  293. pBsInfoStream->u8GOBN,
  294. (U32)pBitStream,
  295. uNewBytes);
  296. DBOUT(msg);
  297. }
  298. #endif
  299. #endif
  300. EC->pBsInfoStream= (void *) ++pBsInfoStream; //create a new packet
  301. }
  302. nobreak:
  303. return TRUE;
  304. }
  305. void H261RTP_TermBsInfoStream(T_H263EncoderCatalog * EC)
  306. {
  307. #ifndef RING0
  308. #ifdef _DEBUG
  309. DBOUT("BsInfoStream freed....");
  310. #endif
  311. #endif
  312. if ( EC->hBsInfoStream)
  313. {
  314. GlobalUnlock(EC->hBsInfoStream);
  315. GlobalFree(EC->hBsInfoStream);
  316. }
  317. EC->hBsInfoStream= NULL;
  318. return;
  319. }
  320. #define DONTCARE 0
  321. /*************************************************
  322. * Return the maximum size of EBS (i.e. RTP part)
  323. * including maximum of 3 bytes required for aligning
  324. * start of EBS
  325. ************************************************/
  326. U32 H261RTP_GetMaxBsInfoStreamSize(
  327. T_H263EncoderCatalog * EC
  328. )
  329. {
  330. return (3 + (EC->uNumOfPackets *sizeof(T_RTP_H261_BSINFO)) + sizeof(T_H26X_RTP_BSINFO_TRAILER));
  331. }
  332. U32 H261RTP_AttachBsInfoStream(
  333. T_H263EncoderCatalog * EC,
  334. U8 *lpOutput,
  335. U32 uSize
  336. )
  337. { U32 uIncreasedSize;
  338. T_H26X_RTP_BSINFO_TRAILER BsInfoTrailer;
  339. T_RTP_H261_BSINFO *pBsInfoStream ;
  340. U8 * lpAligned;
  341. //build bsinfo for the last packets
  342. BsInfoTrailer.uVersion = H26X_RTP_PAYLOAD_VERSION;
  343. BsInfoTrailer.uFlags = 0;
  344. if (EC->PictureHeader.PicCodType == INTRAPIC)
  345. BsInfoTrailer.uFlags |= RTP_H26X_INTRA_CODED;
  346. BsInfoTrailer.uUniqueCode = H261_RTP_BS_START_CODE;
  347. BsInfoTrailer.uCompressedSize = uSize;
  348. BsInfoTrailer.uNumOfPackets = EC->uNumOfPackets;
  349. BsInfoTrailer.u8Src = 0;
  350. BsInfoTrailer.u8TR = EC->PictureHeader.TR;
  351. BsInfoTrailer.u8TRB = DONTCARE;
  352. BsInfoTrailer.u8DBQ = DONTCARE;
  353. //update size feild for the last BsInfoTrailer
  354. pBsInfoStream = (T_RTP_H261_BSINFO *)EC->pBsInfoStream;
  355. uIncreasedSize = EC->uNumOfPackets *sizeof(T_RTP_H261_BSINFO);
  356. lpAligned =(U8 *)( (U32)(lpOutput + uSize + 3 ) & 0xfffffffc);
  357. memcpy( lpAligned,
  358. EC->pBaseBsInfoStream,
  359. uIncreasedSize);
  360. memcpy(lpAligned + uIncreasedSize,
  361. &BsInfoTrailer,
  362. sizeof(T_H26X_RTP_BSINFO_TRAILER));
  363. EC->pBsInfoStream = EC->pBaseBsInfoStream;
  364. EC->uBase =0;
  365. EC->uNumOfPackets=0;
  366. uIncreasedSize += sizeof(T_H26X_RTP_BSINFO_TRAILER)+ (U32)(lpAligned- lpOutput-uSize);
  367. return uIncreasedSize;
  368. }
  369. I32 H261RTP_RewindBsInfoStream(T_H263EncoderCatalog *EC, U32 uGOBN)
  370. {
  371. T_RTP_H261_BSINFO *pBsInfoStream;
  372. pBsInfoStream = (T_RTP_H261_BSINFO *) EC->pBsInfoStream;
  373. pBsInfoStream--;
  374. while ( ! ((pBsInfoStream->u8GOBN == 0) &&
  375. (pBsInfoStream->u8Quant == 0)
  376. )
  377. )
  378. {
  379. EC->uNumOfPackets--;
  380. pBsInfoStream--;
  381. }
  382. EC->pBsInfoStream = (void *) ++pBsInfoStream;
  383. return TRUE;
  384. }