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.

316 lines
14 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. ** All Rights Reserved.
  11. **
  12. ** *************************************************************************
  13. */
  14. /*****************************************************************************
  15. * exbrc.cpp
  16. *
  17. * Description:
  18. * Bit rate control routines for H.261 and H.263. The bit rate is controlled
  19. * by changing QUANT value at the GOB level (H.261) or picture and GOB level
  20. * (H.26X). InitBRC() must be called at the time encoder is instanced; it
  21. * initializes some data values in BRCState structure. CalcPQUANT() computes the new
  22. * quant. value at the picture level; it must always be called.
  23. * CalcMBQUANT computes the new quant. value at the MB level; it need not be
  24. * called if quant. adjustment is done at the picture level.
  25. *
  26. *
  27. * Routines:
  28. * InitBRC
  29. * CalcPQUANT
  30. * CalcMBQUANT
  31. * Prototypes in:
  32. * e3enc.h
  33. * Note
  34. * Encoder must update BRCState->uLastINTRAFrmSz, BRCState->uLastINTERFrmSz, and
  35. * BRCState->uTargetFrmSize.
  36. */
  37. /*
  38. * $Header: S:\h26x\src\enc\exbrc.cpv 1.15 31 Oct 1996 14:59:26 MBODART $
  39. * $Log: S:\h26x\src\enc\exbrc.cpv $
  40. //
  41. // Rev 1.15 31 Oct 1996 14:59:26 MBODART
  42. // Prevent recent changes from inadvertantly affecting H.261.
  43. //
  44. // Rev 1.14 31 Oct 1996 10:05:38 KLILLEVO
  45. // changed from DBOUT to DbgLog
  46. //
  47. //
  48. // Rev 1.13 29 Aug 1996 09:31:54 CZHU
  49. // Map intra-coded GOB to simpliar quality of inter-coded neighbours
  50. //
  51. // Rev 1.12 14 Aug 1996 16:46:22 CZHU
  52. // Adjust QP for intra frames other than the first Key frames.
  53. //
  54. // Rev 1.11 12 Mar 1996 13:26:54 KLILLEVO
  55. // new rate control with adaptive bit usage profile
  56. //
  57. // Rev 1.10 05 Feb 1996 17:15:12 TRGARDOS
  58. // Added code to do custom quantizer selection for
  59. // still frames
  60. //
  61. // Rev 1.9 01 Dec 1995 15:27:06 DBRUCKS
  62. // I removed the QP_mean affects to the global_adj value.
  63. // This resulted in removing any affect of the target frame rate on
  64. // the global adj value.
  65. //
  66. // Rev 1.8 28 Nov 1995 15:01:04 TRGARDOS
  67. // Initialized target frame rate in BRCinit.
  68. //
  69. // Rev 1.7 27 Nov 1995 19:26:00 TRGARDOS
  70. // Cleaned up bit rate control functions to be generic h26x bit rate
  71. // controller. Based off of macro blocks instead of GOBS now.
  72. //
  73. // Rev 1.6 26 Oct 1995 19:50:54 TRGARDOS
  74. // Fixed a small mistake in the global adjust calculation
  75. // and changed frame rate to a parameter.
  76. //
  77. // Rev 1.5 25 Oct 1995 23:22:36 SINGX
  78. // Changed BRC back to we just get frame rate from client
  79. // and compute global adjust ourselves.
  80. //
  81. // Rev 1.4 25 Oct 1995 20:14:40 TRGARDOS
  82. // Added code to use global adjustment passed from client.
  83. //
  84. // Rev 1.3 12 Oct 1995 12:04:42 TRGARDOS
  85. // Added QP_mean initialization in initBRC and added clipping
  86. // to all calculations of the new QP.
  87. //
  88. // Rev 1.2 11 Oct 1995 19:35:00 TRGARDOS
  89. // Modified bit rate controller.
  90. //
  91. // Rev 1.1 09 Oct 1995 11:48:10 TRGARDOS
  92. // Added float typecasting.
  93. //
  94. // Rev 1.0 06 Oct 1995 16:41:22 AGUPTA2
  95. // Initial revision.
  96. */
  97. // PhilF-: In the LAN case and QCIF mode, it looks like even with the smallest quantizer
  98. // we are way below the max allowed at 30fps. Therefore, with little motion,
  99. // the bitrate looks constant at a low bitrate value. When high motion comes in,
  100. // even with the same small quantizer we will remain below the max. So we will
  101. // use that small quantizer, and the size of those compressed frames will get bigger
  102. // because of the higher motion -> this explains why we don't have a straight
  103. // line in the LAN case when looking at StatView...
  104. #include "precomp.h"
  105. U8 clampQP(int iUnclampedQP)
  106. {
  107. return ((iUnclampedQP < 2) ? 2 : (iUnclampedQP > 31) ? 31 : iUnclampedQP);
  108. }
  109. /****************************************************************************
  110. * InitBRC
  111. * Parameter:
  112. * BRCState: T_H263EncoderCatalog ptr
  113. * Initializes some some variables in the encoder catalog.
  114. * Note
  115. * Must be called when the encoder is instanced.
  116. */
  117. void InitBRC(BRCStateStruct *BRCState, U8 DefIntraQP, U8 DefInterQP, int numMBs)
  118. {
  119. FX_ENTRY("InitBRC");
  120. BRCState->NumMBs = numMBs;
  121. BRCState->u8INTRA_QP = DefIntraQP;
  122. BRCState->u8INTER_QP = DefInterQP;
  123. BRCState->uLastINTRAFrmSz = 0;
  124. BRCState->uLastINTERFrmSz = 0;
  125. BRCState->QP_mean = DefIntraQP;
  126. BRCState->TargetFrameRate = (float) 0.0;
  127. BRCState->u8StillQnt = 0;
  128. DEBUGMSG(ZONE_BITRATE_CONTROL, ("%s: Bitrate controller initial state:\r\n numMBs = %ld macroblocks\r\n u8INTRA_QP = %ld\r\n u8INTER_QP = %ld\r\n", _fx_, BRCState->NumMBs, BRCState->u8INTRA_QP, BRCState->u8INTER_QP));
  129. DEBUGMSG(ZONE_BITRATE_CONTROL, (" uLastINTRAFrmSz = %ld bytes\r\n uLastINTERFrmSz = %ld bytes\r\n QP_mean = %ld\r\n TargetFrameRate = %ld.%ld fps\r\n", BRCState->uLastINTRAFrmSz, BRCState->uLastINTERFrmSz, BRCState->QP_mean, (DWORD)BRCState->TargetFrameRate, (DWORD)((BRCState->TargetFrameRate - (float)(DWORD)BRCState->TargetFrameRate) * 10.0f)));
  130. }
  131. /****************************************************************************
  132. * @doc INTERNAL H263FUNC
  133. *
  134. * @func U8 | CalcPQUANT | This function computes the PQUANT value to
  135. * use for the current frame. This is done by using the target frame size
  136. * and the results achieved with the previous frame.
  137. *
  138. * @parm BRCStateStruct * | BRCState | Specifies a pointer to the current
  139. * state of the bitrate controller.
  140. *
  141. * @parm EnumPicCodType | PicCodType | Specifies the type of the current
  142. * frame. If set to INTRAPIC, then the current frame is an I-frame. It
  143. * set to INTERPIC, then it is a P-frame or a PB-frame.
  144. *
  145. * @rdesc The PQUANT value.
  146. *
  147. * @comm H.261 does not have PQUANT. So, H261 encoder can call this routine
  148. * once and use the value returned as GQUANT for all GOBs. Or, it can
  149. * call CalcMBQUANT for all GOBs.
  150. *
  151. * This routine MUST be called for every frame for which QUANT adjustment
  152. * is required. CalcMBQUANT() might not be called.
  153. *
  154. * @xref <f FindNewQuant> <f CalcMBQUANT>
  155. ***************************************************************************/
  156. U8 CalcPQUANT(BRCStateStruct *BRCState, EnumPicCodType PicCodType)
  157. {
  158. FX_ENTRY("CalcPQUANT");
  159. if (PicCodType == INTERPIC)
  160. {
  161. if (BRCState->uLastINTERFrmSz != 0)
  162. {
  163. // Calculate the global adjustment parameter
  164. // Use the average QP for the last P-frame as the starting point
  165. // The quantizer increases faster than it decreases
  166. if (BRCState->uLastINTERFrmSz > BRCState->uTargetFrmSize)
  167. {
  168. BRCState->Global_Adj = ((float)((int)BRCState->uLastINTERFrmSz - (int)BRCState->uTargetFrmSize)) / (float)BRCState->uTargetFrmSize;
  169. DEBUGMSG(ZONE_BITRATE_CONTROL, ("%s: New u8INTER_QP = %ld, Global_Adj = +%ld.%ld (based on uLastINTERFrmSz = %ld bits, uTargetFrmSize = %ld bits, QP_mean = %ld)\r\n", _fx_, clampQP((int)(BRCState->QP_mean * (1 + BRCState->Global_Adj) + (float)0.5)), (DWORD)BRCState->Global_Adj, (DWORD)((BRCState->Global_Adj - (float)(DWORD)BRCState->Global_Adj) * 100.0f), (DWORD)BRCState->uLastINTERFrmSz << 3, (DWORD)BRCState->uTargetFrmSize << 3, (DWORD)BRCState->QP_mean));
  170. }
  171. else
  172. {
  173. BRCState->Global_Adj = ((float)((int)BRCState->uLastINTERFrmSz - (int)BRCState->uTargetFrmSize)) / ((float) 2.0 * BRCState->uTargetFrmSize);
  174. DEBUGMSG(ZONE_BITRATE_CONTROL, ("%s: New u8INTER_QP = %ld, Global_Adj = -%ld.%ld (based on uLastINTERFrmSz = %ld bits, uTargetFrmSize = %ld bits, QP_mean = %ld)\r\n", _fx_,clampQP((int)(BRCState->QP_mean * (1 + BRCState->Global_Adj) + (float)0.5)), (DWORD)(BRCState->Global_Adj * -1.0f), (DWORD)((BRCState->Global_Adj - (float)(DWORD)(BRCState->Global_Adj * -1.0f)) * -100.0f), (DWORD)BRCState->uLastINTERFrmSz << 3, (DWORD)BRCState->uTargetFrmSize << 3, (DWORD)BRCState->QP_mean));
  175. }
  176. BRCState->u8INTER_QP = clampQP((int)(BRCState->QP_mean * (1 + BRCState->Global_Adj) + (float)0.5));
  177. }
  178. else
  179. {
  180. // This the first P-frame - use default value
  181. BRCState->u8INTER_QP = clampQP((unsigned char) BRCState->QP_mean);
  182. BRCState->Global_Adj = (float)0.0;
  183. DEBUGMSG(ZONE_BITRATE_CONTROL, ("%s: First u8INTER_QP = %ld\r\n", _fx_, BRCState->u8INTER_QP));
  184. }
  185. return BRCState->u8INTER_QP;
  186. }
  187. else if (PicCodType == INTRAPIC)
  188. {
  189. if (BRCState->uLastINTRAFrmSz != 0)
  190. {
  191. // Calculate the global adjustment parameter
  192. // Use the average QP for the last I-frame as the starting point
  193. // Assume lighting & other conditions haven't changed too much since last I-frame
  194. // The quantizer increases faster than it decreases
  195. if (BRCState->uLastINTRAFrmSz > BRCState->uTargetFrmSize)
  196. {
  197. BRCState->Global_Adj = ((float) ((int)BRCState->uLastINTRAFrmSz - (int)BRCState->uTargetFrmSize) ) / ((float)BRCState->uTargetFrmSize);
  198. DEBUGMSG(ZONE_BITRATE_CONTROL, ("%s: New u8INTRA_QP = %ld, Global_Adj = +%ld.%ld (based on uLastINTRAFrmSz = %ld bits, uTargetFrmSize = %ld bits)\r\n", _fx_, clampQP((int)(BRCState->u8INTRA_QP * (1 + BRCState->Global_Adj) + (float)0.5)), (DWORD)BRCState->Global_Adj, (DWORD)((BRCState->Global_Adj - (float)(DWORD)BRCState->Global_Adj) * 100.0f), (DWORD)BRCState->uLastINTRAFrmSz << 3, (DWORD)BRCState->uTargetFrmSize << 3));
  199. }
  200. else
  201. {
  202. // This the first I-frame - use default value
  203. BRCState->Global_Adj = ((float) ((int)BRCState->uLastINTRAFrmSz - (int)BRCState->uTargetFrmSize) ) / ((float) 2.0 * BRCState->uTargetFrmSize);
  204. DEBUGMSG(ZONE_BITRATE_CONTROL, ("%s: New u8INTRA_QP = %ld, Global_Adj = -%ld.%ld (based on uLastINTRAFrmSz = %ld bits, uTargetFrmSize = %ld bits)\r\n", _fx_, clampQP((int)(BRCState->u8INTRA_QP * (1 + BRCState->Global_Adj) + (float)0.5)), (DWORD)(BRCState->Global_Adj * -1.0f), (DWORD)((BRCState->Global_Adj - (float)(DWORD)(BRCState->Global_Adj * -1.0f)) * -100.0f), (DWORD)BRCState->uLastINTRAFrmSz << 3, (DWORD)BRCState->uTargetFrmSize << 3));
  205. }
  206. BRCState->u8INTRA_QP = clampQP((int)(BRCState->u8INTRA_QP * (1 + BRCState->Global_Adj) + (float)0.5));
  207. }
  208. else
  209. {
  210. DEBUGMSG(ZONE_BITRATE_CONTROL, ("%s: First u8INTRA_QP = %ld\r\n", _fx_, clampQP(BRCState->u8INTRA_QP)));
  211. }
  212. return clampQP(BRCState->u8INTRA_QP);
  213. }
  214. else
  215. {
  216. DBOUT("ERROR:BRC unknown frame type");
  217. return clampQP(BRCState->u8INTRA_QP); // return any valid value
  218. }
  219. }
  220. /****************************************************************************
  221. * @doc INTERNAL H263FUNC
  222. *
  223. * @func U8 | CalcMBQUANT | This function computes the GQUANT value to
  224. * use for the current GOB. This is done by using the target frame size and
  225. * the running average of the GQUANTs computed for the previous GOBs in
  226. * the current frame.
  227. *
  228. * @parm BRCStateStruct * | BRCState | Specifies a pointer to the current
  229. * state of the bitrate controller.
  230. *
  231. * @parm U32 | uCumPrevFrmSize | Specifies the cumulated size of the previous
  232. * GOBs in the previous frame.
  233. *
  234. * @parm U32 | uPrevFrmSize | Specifies the total size of the previous
  235. * frame.
  236. *
  237. * @parm U32 | uCumFrmSize | Specifies the cumulated size of the previous
  238. * GOBs.
  239. *
  240. * @parm EnumPicCodType | PicCodType | Specifies the type of the current
  241. * frame. If set to INTRAPIC, then the current frame is an I-frame. It
  242. * set to INTERPIC, then it is a P-frame or a PB-frame.
  243. *
  244. * @rdesc The GQUANT value.
  245. *
  246. * @xref <f FindNewQuant> <f CalcPQUANT>
  247. ***************************************************************************/
  248. U8 CalcMBQUANT(BRCStateStruct *BRCState, U32 uCumPrevFrmSize, U32 uPrevFrmSize, U32 uCumFrmSize, EnumPicCodType PicCodType)
  249. {
  250. FX_ENTRY("CalcMBQUANT");
  251. float Local_Adj;
  252. int TargetCumSize;
  253. if (PicCodType == INTERPIC)
  254. {
  255. // Calculate the local adjustment parameter by looking at how well we've
  256. // been doing so far with the previous GOBs
  257. TargetCumSize = (int)uCumPrevFrmSize * BRCState->uTargetFrmSize / uPrevFrmSize;
  258. // If this is the first GOB there's no local adjustment to compute
  259. Local_Adj = TargetCumSize ? (float)((int)uCumFrmSize - TargetCumSize) / (float)TargetCumSize : 0.0f;
  260. BRCState->u8INTER_QP = clampQP((int)(BRCState->QP_mean * (1 + BRCState->Global_Adj + Local_Adj) + (float)0.5));
  261. #ifdef _DEBUG
  262. if (Local_Adj >= 0L)
  263. {
  264. DEBUGMSG(ZONE_BITRATE_CONTROL_DETAILS, (" %s: New u8INTER_QP = %ld, Local_Adj = +%ld.%ld (based on uLastINTERFrmSz = %ld bits, uTargetFrmSize = %ld bits, uCumPrevFrmSize = %ld, uPrevFrmSize = %ld, QP_mean = %ld)\r\n", _fx_, BRCState->u8INTER_QP, (DWORD)Local_Adj, (DWORD)((Local_Adj - (float)(DWORD)Local_Adj) * 100.0f), (DWORD)BRCState->uLastINTERFrmSz << 3, (DWORD)BRCState->uTargetFrmSize << 3, uCumPrevFrmSize, uPrevFrmSize, (DWORD)BRCState->QP_mean));
  265. }
  266. else
  267. {
  268. DEBUGMSG(ZONE_BITRATE_CONTROL_DETAILS, (" %s: New u8INTER_QP = %ld, Local_Adj = -%ld.%ld (based on uLastINTERFrmSz = %ld bits, uTargetFrmSize = %ld bits, uCumPrevFrmSize = %ld, uPrevFrmSize = %ld, QP_mean = %ld)\r\n", _fx_, BRCState->u8INTER_QP, (DWORD)(Local_Adj * -1.0f), (DWORD)((Local_Adj - (float)(DWORD)(Local_Adj * -1.0f)) * -100.0f), (DWORD)BRCState->uLastINTERFrmSz << 3, (DWORD)BRCState->uTargetFrmSize << 3, uCumPrevFrmSize, uPrevFrmSize, (DWORD)BRCState->QP_mean));
  269. }
  270. #endif
  271. return BRCState->u8INTER_QP;
  272. }
  273. else if (PicCodType == INTRAPIC)
  274. {
  275. // The previous I-frame is so old that there isn't much point in doing local
  276. // adjustments - so only consider the global changes
  277. DEBUGMSG(ZONE_BITRATE_CONTROL_DETAILS, (" %s: New u8INTRA_QP = %ld\r\n", _fx_, BRCState->u8INTRA_QP));
  278. return BRCState->u8INTRA_QP;
  279. }
  280. else
  281. {
  282. DBOUT("ERROR:BRC unknown frame type");
  283. return BRCState->u8INTRA_QP; // return some valid value
  284. }
  285. }