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.

1641 lines
55 KiB

  1. /* File: sv_h261_compress.c */
  2. /*****************************************************************************
  3. ** Copyright (c) Digital Equipment Corporation, 1995, 1997 **
  4. ** **
  5. ** All Rights Reserved. Unpublished rights reserved under the copyright **
  6. ** laws of the United States. **
  7. ** **
  8. ** The software contained on this media is proprietary to and embodies **
  9. ** the confidential technology of Digital Equipment Corporation. **
  10. ** Possession, use, duplication or dissemination of the software and **
  11. ** media is authorized only pursuant to a valid written license from **
  12. ** Digital Equipment Corporation. **
  13. ** **
  14. ** RESTRICTED RIGHTS LEGEND Use, duplication, or disclosure by the U.S. **
  15. ** Government is subject to restrictions as set forth in Subparagraph **
  16. ** (c)(1)(ii) of DFARS 252.227-7013, or in FAR 52.227-19, as applicable. **
  17. ******************************************************************************/
  18. /*
  19. #define VIC 1
  20. #define USE_C
  21. #define _SLIBDEBUG_
  22. */
  23. #include <math.h>
  24. #include "sv_intrn.h"
  25. #include "SC.h"
  26. #include "SC_conv.h"
  27. #include "SC_err.h"
  28. #include "sv_h261.h"
  29. #include "proto.h"
  30. #include "sv_proto.h"
  31. #ifdef WIN32
  32. #include <mmsystem.h>
  33. #endif
  34. #ifdef _SLIBDEBUG_
  35. #include <stdio.h>
  36. #include <stdlib.h>
  37. #define _DEBUG_ 0 /* detailed debuging statements */
  38. #define _VERBOSE_ 0 /* show progress */
  39. #define _VERIFY_ 1 /* verify correct operation */
  40. #define _WARN_ 0 /* warnings about strange behavior */
  41. #endif
  42. #define Limit_Alpha(x) ( (x>20.0) ? 20.0 : ((x<0.5) ? 0.5 : x) )
  43. #define Limit_Bits(x) ( (x>250.0) ? 250.0 : ((x<5.0) ? 5.0 : x) )
  44. #define Bpos_Y(h261, g, m) (h261->ImageType==IT_QCIF ? (g * 33) + (m % 33) \
  45. : (g/2)*66 + (m % 11) + (g&1)*11 + (m/11) * 22)
  46. static void ExecuteQuantization_GOB();
  47. void CopySubClip_C();
  48. void CopyRev_C();
  49. #define SKIP_THRESH 0.51
  50. #define SKIP_THRESH_INT 2
  51. #define QUANT_CHANGE_THRESH 100.0
  52. #define Intra_Start 1
  53. #define FC 6.6e-9
  54. #define TotalCodedMB_Threshold 2
  55. /* MC Threshold for coding blocks through filter*/
  56. #define D_FILTERTHRESHOLD 1
  57. /* Intra forced every so many blocks */
  58. #define SEQUENCE_INTRA_THRESHOLD 131
  59. extern int bit_set_mask[];
  60. int QuantMType[] = {0,1,0,1,0,0,1,0,0,1}; /* Quantization used */
  61. int CBPMType[] = {0,0,1,1,0,1,1,0,1,1}; /* CBP used in coding */
  62. int IntraMType[] = {1,1,0,0,0,0,0,0,0,0}; /* Intra coded macroblock */
  63. int MFMType[] = {0,0,0,0,1,1,1,1,1,1}; /* Motion forward vector used */
  64. int FilterMType[] = {0,0,0,0,0,0,0,1,1,1}; /* Filter flags */
  65. int TCoeffMType[] = {1,1,1,1,0,1,1,0,1,1}; /* Transform coeff. coded */
  66. struct CodeBook {
  67. float AcEnergy;
  68. float BitsMB;
  69. float QuantClass;
  70. } CBook[100] = {
  71. (float)3.057549, (float)13.650990, (float)16.000000,
  72. (float)2.736564, (float)15.620879, (float)10.000000,
  73. (float)3.032565, (float)13.728155, (float)14.000000,
  74. (float)2.945122, (float)14.390745, (float)17.000000,
  75. (float)4.236328, (float)25.890757, (float)17.000000,
  76. (float)2.935733, (float)14.596116, (float)18.000000,
  77. (float)2.994938, (float)14.515091, (float)19.000000,
  78. (float)3.440835, (float)15.698944, (float)21.000000,
  79. (float)3.235103, (float)13.875000, (float)22.000000,
  80. (float)3.362380, (float)11.448718, (float)23.000000,
  81. (float)4.262544, (float)17.246819, (float)23.000000,
  82. (float)3.933512, (float)15.207619, (float)25.000000,
  83. (float)3.825050, (float)14.351406, (float)26.000000,
  84. (float)3.840182, (float)14.048289, (float)27.000000,
  85. (float)3.717020, (float)14.076046, (float)28.000000,
  86. (float)3.942766, (float)14.216071, (float)29.000000,
  87. (float)3.934838, (float)13.509554, (float)30.000000,
  88. (float)3.899720, (float)14.233502, (float)31.000000,
  89. (float)2.737911, (float)16.522635, (float)5.000000,
  90. (float)2.607979, (float)15.374468, (float)6.000000,
  91. (float)2.864391, (float)15.432000, (float)7.000000,
  92. (float)2.752342, (float)15.809941, (float)8.000000,
  93. (float)2.682438, (float)16.186302, (float)9.000000,
  94. (float)3.581855, (float)34.849625, (float)10.000000,
  95. (float)2.853593, (float)14.700565, (float)11.000000,
  96. (float)2.908124, (float)14.091216, (float)12.000000,
  97. (float)3.099578, (float)15.157043, (float)15.000000,
  98. (float)3.916690, (float)23.636772, (float)16.000000,
  99. (float)5.574149, (float)251.866074, (float) 5.000000,
  100. (float)3.964282, (float)25.137724, (float)18.000000,
  101. (float)4.080521, (float)24.059999, (float)19.000000,
  102. (float)5.759516, (float)37.446808, (float)19.000000,
  103. (float)7.210877, (float)58.061539, (float)19.000000,
  104. (float)2.878292, (float)13.737089, (float)20.000000,
  105. (float)4.076149, (float)22.525490, (float)20.000000,
  106. (float)5.269855, (float)24.170732, (float)22.000000,
  107. (float)7.206488, (float)30.965218, (float)23.000000,
  108. (float)8.118586, (float)40.752293, (float)22.000000,
  109. (float)3.133760, (float)12.679641, (float)24.000000,
  110. (float)4.624318, (float)18.820961, (float)24.000000,
  111. (float)7.050338, (float)30.319149, (float)24.000000,
  112. (float)6.955218, (float)28.934525, (float)25.000000,
  113. (float)6.830490, (float)24.564627, (float)26.000000,
  114. (float)6.244225, (float)22.895706, (float)27.000000,
  115. (float)8.060182, (float)32.934959, (float)26.000000,
  116. (float)6.349021, (float)23.500000, (float)28.000000,
  117. (float)6.514215, (float)23.680555, (float)29.000000,
  118. (float)8.116955, (float)36.047619, (float)28.000000,
  119. (float)6.143418, (float)19.691589, (float)30.000000,
  120. (float)6.238575, (float)20.666666, (float)31.000000,
  121. (float)8.063477, (float)28.651785, (float)31.000000,
  122. (float)10.753970, (float)45.786884, (float)30.000000,
  123. (float)2.728013, (float)14.628572, (float)3.000000,
  124. (float)2.851330, (float)14.559524, (float)4.000000,
  125. (float)2.524028, (float)28.197674, (float)3.000000,
  126. (float)2.218242, (float)38.810001, (float)5.000000,
  127. (float)2.457342, (float)53.670456, (float)5.000000,
  128. (float)2.437406, (float)33.156628, (float)6.000000,
  129. (float)2.861240, (float)33.810810, (float)7.000000,
  130. (float)2.996593, (float)46.674419, (float)7.000000,
  131. (float)3.321854, (float)60.000000, (float)6.000000,
  132. (float)3.035449, (float)35.875000, (float)8.000000,
  133. (float)3.199618 , (float)33.715328, (float)9.000000,
  134. (float)3.625941, (float)50.168674, (float)9.000000,
  135. (float)3.577415, (float)60.454544, (float)8.000000,
  136. (float)4.022958, (float)50.719299, (float)10.000000,
  137. (float)4.749763, (float)69.863640, (float)10.000000,
  138. (float)3.209624, (float)24.840708, (float)11.000000,
  139. (float)3.293082, (float)22.490385, (float)12.000000,
  140. (float)3.845358, (float)34.169117, (float)12.000000,
  141. (float)4.811161, (float)38.609524, (float)13.000000,
  142. (float)4.716694, (float)49.273685, (float)11.000000,
  143. (float)5.540541, (float)68.905403, (float)11.000000,
  144. (float)2.989831, (float)13.654839, (float)13.000000,
  145. (float)3.670721, (float)23.812500, (float)13.000000,
  146. (float)3.589297, (float)21.033333, (float)14.000000,
  147. (float)4.645432, (float)30.153847, (float)14.000000,
  148. (float)4.498426, (float)30.930555, (float)15.000000,
  149. (float)4.926270, (float)35.812500, (float)16.000000,
  150. (float)5.255817, (float)43.228260, (float)14.000000,
  151. (float)6.547225, (float)57.948719, (float)14.000000,
  152. (float)6.379679, (float)71.934067, (float) 12.000000,
  153. (float)7.022222, (float)76.955559, (float)14.000000,
  154. (float)6.077474, (float)46.511112, (float)16.000000,
  155. (float)7.406376, (float)79.258064, (float)16.000000,
  156. (float)2.280469, (float)64.266670, (float)3.000000,
  157. (float)2.396216, (float)75.647057, (float)4.000000,
  158. (float)3.033032, (float)74.105263, (float)6.000000,
  159. (float)3.093046, (float)90.606560, (float)5.000000,
  160. (float)3.843145, (float)79.211266, (float)7.000000,
  161. (float)4.781610, (float)87.513161, (float)9.000000,
  162. (float)3.846819, (float)101.846939, (float)7.000000,
  163. (float)4.856852, (float)114.625000, (float)8.000000,
  164. (float)5.609015, (float)90.250000, (float)10.000000,
  165. (float)7.049340, (float)97.333336, (float)12.000000,
  166. (float)6.508484, (float)113.569893, (float) 10.000000,
  167. (float)7.099700, (float)136.116272, (float)10.000000,
  168. (float)8.087169, (float)100.054344, (float)13.000000,
  169. (float)9.193896, (float)135.032974, (float)12.000000,
  170. (float)11.427065, (float)162.600006, (float)14.000000
  171. };
  172. #define Abs(value) ( (value < 0) ? (-value) : value)
  173. #define BufferContents() (ScBSBitPosition(bs) + H261->BufferOffset -\
  174. (((H261->CurrentGOB*H261->NumberMDU)+H261->CurrentMDU) \
  175. *H261->bit_rate*H261->FrameSkip\
  176. /(H261->NumberGOB*H261->NumberMDU*H261->FrameRate_Fix)))
  177. #define BufferSize() (H261->bit_rate/1) /*In bits */
  178. /******** For sending RTP info. ************/
  179. static SvStatus_t sv_H261WriteExtBitstream(SvH261Info_t *H261, ScBitstream_t *bs);
  180. extern ScStatus_t ScConvert422ToYUV_char (u_char *RawImage,
  181. u_char *Y, u_char *U, u_char *V,
  182. int Width, int Height);
  183. /***** forward declarations ******/
  184. static SvStatus_t p64EncodeFrame(SvCodecInfo_t *Info, u_char *InputImage,
  185. u_char *CompData);
  186. static SvStatus_t p64EncodeGOB(SvH261Info_t *H261, ScBitstream_t *bs);
  187. static SvStatus_t p64EncodeMDU (SvH261Info_t *H261, ScBitstream_t *bs);
  188. static SvStatus_t p64CompressMDU(SvH261Info_t *H261, ScBitstream_t *bs);
  189. static void ExecuteQuantization_GOB(SvH261Info_t *H261);
  190. static int findcode(SvH261Info_t *H261, struct CodeBook *lcb);
  191. static SvStatus_t ntsc_grab (u_char *RawImage,
  192. u_char *Comp1, u_char *Comp2, u_char *Comp3,
  193. int Width, int Height);
  194. static void VertSubSampleK (unsigned char *Incomp, unsigned char *workloc,
  195. int Width, int Height);
  196. #if 0
  197. SvStatus_t SvSetFrameSkip (SvHandle_t Svh, int FrameSkip)
  198. {
  199. SvCodecInfo_t *Info = (SvCodecInfo_t *)Svh;
  200. SvH261Info_t *H261 = (SvH261Info_t *) Info->h261;
  201. H261->FrameSkip = FrameSkip;
  202. return (NoErrors);
  203. }
  204. SvStatus_t SvSetFrameCount (SvHandle_t Svh, int FrameCount)
  205. {
  206. SvCodecInfo_t *Info = (SvCodecInfo_t *)Svh;
  207. SvH261Info_t *H261 = (SvH261Info_t *) Info->h261;
  208. H261->LastFrame = FrameCount;
  209. return (NoErrors);
  210. }
  211. SvStatus_t SvSetSearchLimit (SvHandle_t Svh, int SearchLimit)
  212. {
  213. SvCodecInfo_t *Info = (SvCodecInfo_t *)Svh;
  214. SvH261Info_t *H261 = (SvH261Info_t *) Info->h261;
  215. if ((SearchLimit <= 0) || (SearchLimit > 20))
  216. return (SvErrorBadArgument);
  217. H261->search_limit = SearchLimit;
  218. return (NoErrors);
  219. }
  220. SvStatus_t SvSetMotionEstimationType (SvHandle_t Svh, int MotionEstType)
  221. {
  222. SvCodecInfo_t *Info = (SvCodecInfo_t *)Svh;
  223. SvH261Info_t *H261 = (SvH261Info_t *) Info->h261;
  224. if (MotionEstType < 0)
  225. return (SvErrorBadArgument);
  226. H261->ME_method = MotionEstType;
  227. return (NoErrors);
  228. }
  229. SvStatus_t SvSetMotionThreshold (SvHandle_t Svh, int Threshold)
  230. {
  231. SvCodecInfo_t *Info = (SvCodecInfo_t *)Svh;
  232. SvH261Info_t *H261 = (SvH261Info_t *) Info->h261;
  233. if (Threshold < 0)
  234. return (SvErrorBadArgument);
  235. H261->ME_threshold = Threshold;
  236. return (NoErrors);
  237. }
  238. SvStatus_t SvSetImageType (SvHandle_t Svh, int ImageType)
  239. {
  240. SvCodecInfo_t *Info = (SvCodecInfo_t *)Svh;
  241. SvH261Info_t *H261 = (SvH261Info_t *) Info->h261;
  242. int i;
  243. if (!Info)
  244. return (SvErrorCodecHandle);
  245. H261->ImageType = ImageType;
  246. switch(H261->ImageType)
  247. {
  248. case IT_NTSC:
  249. H261->NumberGOB = 10; /* Parameters for NTSC design */
  250. H261->NumberMDU = 33;
  251. H261->YWidth = 352;
  252. H261->YHeight = 240;
  253. H261->CWidth = H261->YWidth/2;
  254. H261->CHeight = H261->YHeight/2;
  255. break;
  256. case IT_CIF:
  257. H261->NumberGOB = 12; /* Parameters for CIF design */
  258. H261->NumberMDU = 33;
  259. H261->YWidth = 352;
  260. H261->YHeight = 288;
  261. H261->CWidth = H261->YWidth/2;
  262. H261->CHeight = H261->YHeight/2;
  263. break;
  264. case IT_QCIF:
  265. H261->NumberGOB = 3; /* Parameters for QCIF design */
  266. H261->NumberMDU = 33;
  267. H261->YWidth = 176;
  268. H261->YHeight = 144;
  269. H261->CWidth = H261->YWidth/2;
  270. H261->CHeight = H261->YHeight/2;
  271. break;
  272. default:
  273. /*WHEREAMI();*/
  274. _SlibDebug(_VERIFY_,
  275. printf("Unknown ImageType: %d\n",H261->ImageType) );
  276. return (SvErrorUnrecognizedFormat);
  277. }
  278. H261->YW4 = H261->YWidth/4;
  279. H261->CW4 = H261->CWidth/4;
  280. H261->LastIntra = (unsigned char **)
  281. ScCalloc(H261->NumberGOB*sizeof(unsigned char *));
  282. for(i=0;i<H261->NumberGOB;i++)
  283. {
  284. H261->LastIntra[i] = (unsigned char *)
  285. ScCalloc(H261->NumberMDU*sizeof(unsigned char));
  286. memset(H261->LastIntra[i],0,H261->NumberMDU);
  287. }
  288. _SlibDebug(_VERBOSE_, printf("H261->NumberGOB=%d\n",H261->NumberGOB) );
  289. switch(H261->ImageType)
  290. {
  291. case IT_NTSC:
  292. H261->PType=0x04;
  293. H261->PSpareEnable=1;
  294. H261->PSpare=0x8c;
  295. break;
  296. case IT_CIF:
  297. H261->PType=0x04;
  298. break;
  299. case IT_QCIF:
  300. H261->PType=0x00;
  301. break;
  302. default:
  303. /*WHEREAMI();*/
  304. _SlibDebug(_VERIFY_,
  305. printf("Image Type not supported: %d\n", H261->ImageType) );
  306. return (SvErrorUnrecognizedFormat);
  307. }
  308. return (NoErrors);
  309. }
  310. #endif
  311. SvStatus_t svH261CompressFree(SvHandle_t Svh)
  312. {
  313. SvCodecInfo_t *Info = (SvCodecInfo_t *)Svh;
  314. SvH261Info_t *H261 = (SvH261Info_t *) Info->h261;
  315. if (!H261->inited)
  316. return(NoErrors);
  317. if (H261->CurrentFrame > H261->LastFrame+1)
  318. H261->CurrentFrame = H261->LastFrame+1;
  319. H261->TemporalReference = H261->CurrentFrame % 32;
  320. H261->ByteOffset = 0;
  321. WritePictureHeader(H261, Info->BSOut);
  322. sv_H261HuffFree(Info->h261);
  323. if (Info->h261->LastIntra)
  324. {
  325. int i;
  326. for(i=0; i<Info->h261->NumberGOB; i++)
  327. ScFree(Info->h261->LastIntra[i]);
  328. ScFree(Info->h261->LastIntra);
  329. }
  330. if (Info->h261->Y)
  331. ScFree(Info->h261->Y);
  332. if (Info->h261->U)
  333. ScFree(Info->h261->U);
  334. if (Info->h261->V)
  335. ScFree(Info->h261->V);
  336. if (Info->h261->YREF)
  337. ScFree(Info->h261->YREF);
  338. if (Info->h261->UREF)
  339. ScFree(Info->h261->UREF);
  340. if (Info->h261->VREF)
  341. ScFree(Info->h261->VREF);
  342. if (Info->h261->YRECON)
  343. ScFree(Info->h261->YRECON);
  344. if (Info->h261->URECON)
  345. ScFree(Info->h261->URECON);
  346. if (Info->h261->VRECON)
  347. ScFree(Info->h261->VRECON);
  348. if (Info->h261->YDEC)
  349. ScFree(Info->h261->YDEC);
  350. if (Info->h261->UDEC)
  351. ScFree(Info->h261->UDEC);
  352. if (Info->h261->VDEC)
  353. ScFree(Info->h261->VDEC);
  354. if (Info->h261->workloc)
  355. ScFree(Info->h261->workloc);
  356. if (Info->h261->RTPInfo)
  357. ScFree(Info->h261->RTPInfo);
  358. H261->inited=FALSE;
  359. return (NoErrors);
  360. }
  361. SvStatus_t SvGetFrameNumber (SvHandle_t Svh, u_int *FrameNumber)
  362. {
  363. SvCodecInfo_t *Info = (SvCodecInfo_t *)Svh;
  364. *FrameNumber = Info->h261->CurrentFrame;
  365. return (NoErrors);
  366. }
  367. /*
  368. ** Purpose: Writes the RTP payload info out to the stream.
  369. */
  370. static SvStatus_t sv_H261WriteExtBitstream(SvH261Info_t *H261, ScBitstream_t *bs)
  371. {
  372. ScBSPosition_t NumberBits, i;
  373. /* use this macro to byte reverse words */
  374. #define PutBits32(BS, a) ScBSPutBits(BS, (a) & 0xff, 8); \
  375. ScBSPutBits(BS, (a>>8)&0xff, 8); \
  376. ScBSPutBits(BS, (a>>16)&0xff, 8); \
  377. ScBSPutBits(BS, (a>>24)&0xff, 8);
  378. /* Need to bitstuff here to make sure that these structures are
  379. DWORD aligned */
  380. NumberBits=ScBSBitPosition(bs);
  381. if ((NumberBits%32)!=0)
  382. ScBSPutBits(bs, 0, 32-((unsigned int)NumberBits % 32)); /* align on a DWORD boundary */
  383. for (i = 0; i < (int)H261->RTPInfo->trailer.dwNumberOfPackets; i++)
  384. {
  385. ScBSPutBits(bs,0,32) ; /* dwFlags */
  386. PutBits32(bs,H261->RTPInfo->bsinfo[i].dwBitOffset);
  387. ScBSPutBits(bs,H261->RTPInfo->bsinfo[i].MBAP,8);
  388. ScBSPutBits(bs,H261->RTPInfo->bsinfo[i].Quant,8);
  389. ScBSPutBits(bs,H261->RTPInfo->bsinfo[i].GOBN,8);
  390. ScBSPutBits(bs,H261->RTPInfo->bsinfo[i].HMV,8);
  391. ScBSPutBits(bs,H261->RTPInfo->bsinfo[i].VMV,8);
  392. ScBSPutBits(bs,0,8); /* padding0 */
  393. ScBSPutBits(bs,0,16); /* padding1 */
  394. }
  395. /* write RTP extension trailer */
  396. PutBits32(bs, H261->RTPInfo->trailer.dwVersion);
  397. PutBits32(bs, H261->RTPInfo->trailer.dwFlags);
  398. PutBits32(bs, H261->RTPInfo->trailer.dwUniqueCode);
  399. PutBits32(bs, (H261->RTPInfo->trailer.dwCompressedSize+7)/8); /*tfm - padded up to whole byte */
  400. PutBits32(bs, H261->RTPInfo->trailer.dwNumberOfPackets);
  401. ScBSPutBits(bs, H261->RTPInfo->trailer.SourceFormat, 8);
  402. ScBSPutBits(bs, H261->RTPInfo->trailer.TR, 8);
  403. ScBSPutBits(bs, H261->RTPInfo->trailer.TRB, 8);
  404. ScBSPutBits(bs, H261->RTPInfo->trailer.DBQ, 8);
  405. return (NoErrors);
  406. }
  407. /*
  408. ** Function: svH261Compress()
  409. ** Purpose: Encodes a single H261 image frame.
  410. */
  411. SvStatus_t svH261Compress(SvCodecInfo_t *Info, u_char *InputImage)
  412. {
  413. SvH261Info_t *H261=Info->h261;
  414. ScBitstream_t *bs=Info->BSOut;
  415. SvStatus_t status;
  416. int i1, i2, tBuff;
  417. int iGOB, iMDU, iMBpos, MiniFlag;
  418. unsigned char *dummy_y, *dummy_u, *dummy_v;
  419. double xValue,yValue;
  420. _SlibDebug(_DEBUG_,
  421. printf("p64EncodeFrame(Info=%p, H261=%p)\n",Info, H261) );
  422. if (H261->CurrentFrame == 0)
  423. H261->GQuant=H261->MQuant=H261->InitialQuant;
  424. H261->ByteOffset = 0;
  425. if((H261->CurrentFrame != H261->StartFrame) && H261->NoSkippedFrame)
  426. {
  427. dummy_y = H261->YRECON;
  428. dummy_u = H261->URECON;
  429. dummy_v = H261->VRECON;
  430. H261->YRECON = H261->YDEC;
  431. H261->URECON = H261->UDEC;
  432. H261->VRECON = H261->VDEC;
  433. H261->YDEC = dummy_y;
  434. H261->UDEC = dummy_u;
  435. H261->VDEC = dummy_v;
  436. /* memset(H261->YDEC, 0,( H261->PICSIZE ) );
  437. memset(H261->UDEC, 0,( H261->PICSIZEBY4) );
  438. memset(H261->VDEC, 0,( H261->PICSIZEBY4 ) );
  439. */
  440. /*
  441. dummy_y = H261->YREF;
  442. dummy_u = H261->UREF;
  443. dummy_v = H261->VREF;
  444. H261->YREF = H261->Y;
  445. H261->UREF = H261->U;
  446. H261->VREF = H261->V;
  447. H261->Y = dummy_y;
  448. H261->U = dummy_u;
  449. H261->V = dummy_v;
  450. */
  451. _SlibDebug(_DEBUG_, printf("LastBits=%d NBitsPerFrame=%d\n",
  452. H261->LastBits, H261->NBitsPerFrame) );
  453. if (H261->NBitsPerFrame)
  454. {
  455. H261->OverFlow = (int)((double) H261->LastBits/
  456. (double) H261->NBitsPerFrame + 0.5);
  457. H261->OverFlow -= 1;
  458. if(H261->OverFlow >0)
  459. {
  460. H261->alpha1 += 2.2* H261->OverFlow;
  461. H261->alpha2 -= 3.2* H261->OverFlow;
  462. H261->MIN_MQUANT += 1;
  463. H261->alpha1 = Limit_Alpha(H261->alpha1);
  464. H261->alpha2 = Limit_Alpha(H261->alpha2);
  465. }
  466. if(H261->OverFlow<0) H261->OverFlow=0;
  467. if(H261->OverFlow>2) H261->OverFlow=2;
  468. }
  469. else
  470. H261->OverFlow=0;
  471. H261->C_U_Frames += H261->OverFlow;
  472. H261->CurrentFrame += H261->OverFlow*H261->FrameSkip;
  473. }
  474. _SlibDebug(_VERBOSE_,
  475. printf("Currently Encoding Frame No. %d\n", H261->CurrentFrame) );
  476. if (IsYUV422Packed(Info->InputFormat.biCompression))
  477. {
  478. /* Input is in NTSC format, convert */
  479. if ((Info->InputFormat.biWidth == NTSC_WIDTH) &&
  480. (Info->InputFormat.biHeight == NTSC_HEIGHT))
  481. status = ntsc_grab ((unsigned char *)InputImage,
  482. (unsigned char *)(H261->Y),
  483. (unsigned char *)(H261->U),
  484. (unsigned char *)(H261->V),
  485. (int) Info->Width,(int )Info->Height);
  486. else if (((Info->InputFormat.biWidth == CIF_WIDTH) &&
  487. (Info->InputFormat.biHeight == CIF_HEIGHT)) ||
  488. ((Info->InputFormat.biWidth == QCIF_WIDTH) &&
  489. (Info->InputFormat.biHeight == QCIF_HEIGHT)))
  490. status = ScConvert422ToYUV_char(InputImage,
  491. (unsigned char *)(H261->Y),
  492. (unsigned char *)(H261->U),
  493. (unsigned char *)(H261->V),
  494. Info->Width,Info->Height);
  495. if (status != NoErrors)
  496. return (status);
  497. }
  498. else if (IsYUV411Sep(Info->InputFormat.biCompression))
  499. {
  500. /*
  501. * If YUV 12 SEP, Not converting, so just copy data to the luminance
  502. * and chrominance appropriatelyi
  503. */
  504. memcpy (H261->Y, InputImage, H261->PICSIZE );
  505. memcpy (H261->U, InputImage+( H261->PICSIZE),
  506. H261->PICSIZE/4 );
  507. memcpy (H261->V, InputImage+(H261->PICSIZE + (H261->PICSIZEBY4)),
  508. H261->PICSIZE/4);
  509. }
  510. else if (IsYUV422Sep(Info->InputFormat.biCompression))
  511. {
  512. _SlibDebug(_DEBUG_, printf("ScConvert422PlanarTo411()\n") );
  513. ScConvert422PlanarTo411(InputImage,
  514. H261->Y, H261->U, H261->V,
  515. Info->Width,Info->Height);
  516. }
  517. else
  518. {
  519. _SlibDebug(_WARN_, printf("Unsupported Video format\n") );
  520. return(SvErrorUnrecognizedFormat);
  521. }
  522. H261->Global_Avg = 0.0;
  523. if ((H261->CodedFrames >= Intra_Start) && !H261->makekey )
  524. {
  525. if (H261->ME_method==ME_BRUTE)
  526. BruteMotionEstimation(H261, H261->YREF, H261->YRECON, H261->Y);
  527. else
  528. Logsearch(H261, H261->YREF, H261->YRECON, H261->Y);
  529. /*
  530. CrawlMotionEstimation(H261, H261->YREF, H261->YRECON, H261->Y);
  531. */
  532. memset(H261->CodedMB, 1, 512);
  533. H261->TotalCodedMB_Intra = 0;
  534. H261->TotalCodedMB_Inter = 0;
  535. H261->ChChange = 0;
  536. for(iGOB=0; iGOB < H261->NumberGOB; iGOB++)
  537. {
  538. _SlibDebug(_DEBUG_, printf("ByteOffset = %d\n",H261->ByteOffset) );
  539. for (iMDU=0; iMDU<H261->NumberMDU; iMDU++)
  540. {
  541. iMBpos = Bpos_Y(H261, iGOB, iMDU);
  542. if(H261->MeOVal[iMBpos] < SKIP_THRESH_INT)
  543. {
  544. H261->CodedMB[iMBpos] = 0;
  545. MiniFlag = 0;
  546. }
  547. else if (H261->MeOVal[iMBpos] <= H261->MeVal[iMBpos])
  548. {
  549. if ((H261->PreviousMeOVal[iMBpos]-H261->ActThr2<H261->MeOVal[iMBpos])
  550. && (H261->MeOVal[iMBpos] < (H261->PreviousMeOVal[iMBpos]+
  551. H261->ActThr2)))
  552. {
  553. if (((H261->PreviousMeOVal[iMBpos]-H261->ActThr) <
  554. H261->MeOVal[iMBpos])
  555. && (H261->MeOVal[iMBpos] < (H261->PreviousMeOVal[iMBpos] +
  556. H261->ActThr)))
  557. {
  558. MiniFlag = 0;
  559. H261->CodedMB[iMBpos] = 0;
  560. }
  561. else
  562. {
  563. H261->ChChange++;
  564. MiniFlag = 1;
  565. }
  566. }
  567. else
  568. MiniFlag = 1;
  569. }
  570. else
  571. MiniFlag = 1;
  572. if (MiniFlag)
  573. {
  574. xValue = (double) H261->MeOVal[iMBpos];
  575. yValue = (double) H261->MeVal[iMBpos];
  576. xValue = xValue/256;
  577. yValue = yValue/256;
  578. H261->VARF = 3*H261->MeVAR[iMBpos]/(512.);
  579. H261->VARORF = 3*H261->MeVAROR[iMBpos]/(512.);
  580. H261->VARSQ = H261->VARF*H261->VARF;
  581. H261->VARORSQ = H261->VARORF*H261->VARORF;
  582. H261->MWOR = H261->MeMWOR[iMBpos];
  583. if ((H261->VARSQ < H261->ZBDecide) || (H261->VARORSQ > H261->VARSQ))
  584. {
  585. /* (MC+Inter)mode */
  586. if ( !H261->MeX[iMBpos] && !H261->MeY[iMBpos] &&
  587. (xValue < 0.75 || (xValue < 2.8 && yValue > (xValue*0.5)) ||
  588. yValue > (xValue/1.1)) )
  589. {
  590. H261->All_MType[iMBpos] = 2; /* Inter mode */
  591. H261->TotalCodedMB_Inter++;
  592. H261->Global_Avg += H261->VARF;
  593. }
  594. else if (H261->VARF < (double) D_FILTERTHRESHOLD) /* MC mode */
  595. {
  596. H261->All_MType[iMBpos] = 5; /* No Filter MC */
  597. H261->TotalCodedMB_Inter++;
  598. H261->Global_Avg += H261->VARF;
  599. }
  600. else
  601. {
  602. H261->All_MType[iMBpos] = 8; /* Filter MC */
  603. H261->TotalCodedMB_Inter++;
  604. H261->Global_Avg += H261->VARF;
  605. }
  606. }
  607. else
  608. {
  609. H261->All_MType[iMBpos] = 0; /*Intramode */
  610. H261->TotalCodedMB_Intra++;
  611. H261->Global_Avg += H261->VARORF;
  612. }
  613. }
  614. if (H261->LastIntra[iGOB][iMDU]>SEQUENCE_INTRA_THRESHOLD)
  615. {
  616. H261->All_MType[iMBpos]=0; /* Code intra every 132 blocks */
  617. H261->TotalCodedMB_Intra++;
  618. H261->Global_Avg += H261->VARF;
  619. }
  620. }
  621. }
  622. }
  623. else
  624. {
  625. memset(H261->CodedMB, 0, 512);
  626. H261->TotalCodedMB_Intra = 0;
  627. H261->TotalCodedMB_Inter = 0;
  628. if(H261->CodedFrames==0)
  629. i1 = 0;
  630. else
  631. i1 = (H261->NumberGOB/Intra_Start)*H261->CodedFrames;
  632. i2 = (H261->NumberGOB/Intra_Start)*(H261->CodedFrames+1);
  633. if(H261->makekey){
  634. i1 = 0;
  635. i2 = H261->NumberGOB;
  636. }
  637. for(iGOB=i1; iGOB<i2; iGOB++)
  638. {
  639. _SlibDebug(_DEBUG_, printf("ByteOffset = %d\n", H261->ByteOffset) );
  640. for(iMDU=0; iMDU<H261->NumberMDU; iMDU++)
  641. {
  642. iMBpos = Bpos_Y(H261, iGOB, iMDU);
  643. H261->All_MType[iMBpos] = 0;
  644. H261->CodedMB[iMBpos] = 1;
  645. H261->TotalCodedMB_Intra++;
  646. H261->Global_Avg += H261->VARF;
  647. }
  648. }
  649. }
  650. H261->TotalCodedMB = H261->TotalCodedMB_Intra + H261->TotalCodedMB_Inter/2;
  651. H261->TT_MB = H261->TotalCodedMB_Intra +
  652. H261->TotalCodedMB_Inter - H261->ChChange;
  653. if (H261->TT_MB) /* watch out for divide by 0 */
  654. H261->Global_Avg = H261->Global_Avg/H261->TT_MB;
  655. _SlibDebug(_DEBUG_,
  656. printf("TT_MB = %d Global_Avg=%d\n", H261->TT_MB, H261->Global_Avg) );
  657. H261->Current_CodedMB[0] = 0;
  658. H261->Current_CodedMB[1] = 0;
  659. if(H261->C_U_Frames==0) H261->BitsLeft = 0;
  660. H261->BitsLeft = H261->BitsLeft - H261->Buffer_NowPic;
  661. tBuff = H261->PBUFF - (H261->C_U_Frames%H261->PBUFF);
  662. if(tBuff >= H261->Pictures_in_Buff)
  663. {
  664. H261->Pictures_in_Buff = tBuff;
  665. if (H261->BitsLeft < - H261->Buffer_All/3)
  666. H261->BitsLeft = H261->Buffer_All;
  667. else if (H261->BitsLeft > 2*H261->Buffer_All)
  668. H261->BitsLeft = H261->Buffer_All;
  669. else
  670. H261->BitsLeft = H261->BitsLeft + H261->Buffer_All;
  671. H261->NBitsCurrentFrame = H261->BitsLeft/H261->Pictures_in_Buff;
  672. }
  673. H261->Pictures_in_Buff = tBuff;
  674. if(H261->BitsLeft > 2*H261->Buffer_All)
  675. {
  676. _SlibDebug(_DEBUG_, printf("\n Bits Left is %f times more than Buffer_All",
  677. (float)H261->BitsLeft/(float) H261->Buffer_All) );
  678. H261->BitsLeft = H261->Buffer_All;
  679. if(H261->MIN_MQUANT > 2)
  680. H261->MIN_MQUANT -= 1;
  681. }
  682. H261->NBitsCurrentFrame = H261->BitsLeft/H261->Pictures_in_Buff;
  683. H261->LowerQuant = 0;
  684. H261->FineQuant = 0;
  685. H261->ActThr = H261->ActThr5; H261->ActThr2 = H261->ActThr6;
  686. if (H261->bit_rate < 128001)
  687. if (H261->NBitsCurrentFrame > (5*H261->NBitsPerFrame/3))
  688. H261->NBitsCurrentFrame = 5*H261->NBitsPerFrame/4;
  689. else if (H261->NBitsCurrentFrame > 5*H261->NBitsPerFrame/4)
  690. {
  691. if((H261->frame_rate<=15) && (H261->bit_rate > 255000))
  692. {
  693. H261->NBitsCurrentFrame = 5*H261->NBitsPerFrame/4;
  694. H261->FineQuant = 3;
  695. H261->ActThr = H261->ActThr3;
  696. H261->ActThr2 = H261->ActThr4;
  697. }
  698. else if (H261->frame_rate==30)
  699. {
  700. H261->FineQuant = 0;
  701. H261->ActThr = H261->ActThr4;
  702. H261->ActThr2 = H261->ActThr4;
  703. H261->NBitsCurrentFrame = 5*H261->NBitsPerFrame/4;
  704. }
  705. }
  706. H261->Buffer_NowPic = 0;
  707. H261->MQuant = H261->GQuant;
  708. _SlibDebug(_DEBUG_, printf("GQuant for this picture is %d\n", H261->GQuant) );
  709. H261->TemporalReference = H261->CurrentFrame % 32;
  710. if(H261->TotalCodedMB > TotalCodedMB_Threshold)
  711. {
  712. /* TRAILER information */
  713. if (H261->extbitstream)
  714. {
  715. /* H261->RTPInfo->trailer.dwSrcVersion = 0; */
  716. H261->RTPInfo->trailer.dwVersion = 0;
  717. if(H261->CurrentFrame == H261->StartFrame)
  718. H261->RTPInfo->trailer.dwFlags = RTP_H261_INTRA_CODED;
  719. else
  720. H261->RTPInfo->trailer.dwFlags = 0;
  721. H261->RTPInfo->trailer.dwUniqueCode = BI_DECH261DIB;
  722. H261->RTPInfo->trailer.dwNumberOfPackets = 0;
  723. if(H261->ImageType == IT_QCIF)
  724. H261->RTPInfo->trailer.SourceFormat = 2;
  725. else
  726. H261->RTPInfo->trailer.SourceFormat = 3;
  727. H261->RTPInfo->trailer.TR = (unsigned char)H261->TemporalReference;
  728. H261->RTPInfo->trailer.TRB = 0;
  729. H261->RTPInfo->trailer.DBQ = 0;
  730. H261->RTPInfo->pre_MB_position=H261->RTPInfo->last_packet_position=ScBSBitPosition(bs);
  731. H261->RTPInfo->pre_MB_GOB = 0;
  732. H261->RTPInfo->pre_MBAP = 0;
  733. /* store the picture start pos in dwCompressSize,
  734. we'll subtract from this later */
  735. H261->RTPInfo->trailer.dwCompressedSize = (unsigned dword)ScBSBitPosition(bs);
  736. }
  737. H261->CodedFrames++;
  738. H261->C_U_Frames++;
  739. WritePictureHeader(H261, bs);
  740. H261->Buffer_NowPic += 32;
  741. for (H261->CurrentGOB=0; H261->CurrentGOB<H261->NumberGOB; H261->CurrentGOB++)
  742. {
  743. H261->CurrentMDU=0;
  744. _SlibDebug(_DEBUG_,
  745. printf("p64EncodeGOB() ByteOffset = %d\n", H261->ByteOffset) );
  746. status = p64EncodeGOB(H261, bs);
  747. if (status != NoErrors)
  748. return (status);
  749. }
  750. {
  751. ScBSPosition_t x = ScBSBitPosition(bs); /* mwtellb(H261); */
  752. H261->LastBits = x - H261->TotalBits;
  753. H261->TotalBits = x;
  754. if (H261->extbitstream)
  755. H261->RTPInfo->trailer.dwCompressedSize
  756. = (unsigned dword)(x-H261->RTPInfo->trailer.dwCompressedSize);
  757. }
  758. _SlibDebug(_DEBUG_, printf("after mwtellb() LastBits=%d TotalBits=%d\n",
  759. H261->LastBits, H261->TotalBits) );
  760. if (H261->bit_rate)
  761. {
  762. if (H261->CurrentFrame==H261->StartFrame)
  763. {
  764. /* Begin Buffer at 0.5 size */
  765. H261->FirstFrameBits = H261->TotalBits;
  766. H261->BufferOffset = (BufferSize()/2) - BufferContents();
  767. _SlibDebug(_DEBUG_,
  768. printf("First Frame Reset Buffer by delta bits: %d\n",
  769. H261->BufferOffset) );
  770. }
  771. /* Take off standard deduction afterwards. */
  772. H261->BufferOffset -= (H261->bit_rate*H261->FrameSkip/H261->FrameRate_Fix);
  773. }
  774. else if (H261->CurrentFrame==H261->StartFrame)
  775. H261->FirstFrameBits = H261->TotalBits;
  776. H261->CurrentGOB=0;H261->TransmittedFrames++;
  777. H261->NoSkippedFrame = 1;
  778. H261->CurrentFrame+=H261->FrameSkip;/* Change GOB & Frame at same time */
  779. /* write RTP info. */
  780. if (H261->extbitstream)
  781. {
  782. SvStatus_t status;
  783. status = sv_H261WriteExtBitstream(H261, bs);
  784. if (status!=SvErrorNone) return(status);
  785. }
  786. }
  787. else
  788. {
  789. H261->NoSkippedFrame = 0;
  790. H261->CurrentFrame+=H261->FrameSkip;
  791. H261->C_U_Frames++;
  792. H261->alpha1 -= 1.50;
  793. H261->alpha2 += 1.50;
  794. H261->MIN_MQUANT -= 1;
  795. H261->alpha1 = Limit_Alpha(H261->alpha1);
  796. H261->alpha2 = Limit_Alpha(H261->alpha2);
  797. }
  798. if(H261->makekey) H261->makekey = 0; /* disable key-frame trigger */
  799. return (NoErrors);
  800. } /**** End of Encode Frame ****/
  801. /*
  802. ** Function: p64EncodeGOB()
  803. ** Pupose: Encodes a group of blocks within a frame.
  804. */
  805. static SvStatus_t p64EncodeGOB(SvH261Info_t *H261, ScBitstream_t *bs)
  806. {
  807. const int CurrentGOB=H261->CurrentGOB;
  808. const int YWidth=H261->YWidth, CWidth=H261->CWidth;
  809. int CurrentMDU, h, VIndex, HIndex;
  810. double error, stepsize;
  811. SvStatus_t status;
  812. if (H261->extbitstream)
  813. {
  814. ScBSPosition_t cur_position;
  815. cur_position = ScBSBitPosition(bs);
  816. /* start a new packet */
  817. if (H261->RTPInfo->trailer.dwNumberOfPackets==0 ||
  818. (cur_position-H261->RTPInfo->last_packet_position)
  819. >= (unsigned)H261->packetsize-128)
  820. {
  821. SvH261BSInfo_t *bsinfo=&H261->RTPInfo->bsinfo[H261->RTPInfo->trailer.dwNumberOfPackets];
  822. /* breaking packet before GOB boundaries */
  823. H261->RTPInfo->last_packet_position = H261->RTPInfo->pre_MB_position;
  824. H261->RTPInfo->trailer.dwNumberOfPackets++;
  825. bsinfo->dwBitOffset = (unsigned dword)H261->RTPInfo->pre_MB_position;
  826. bsinfo->MBAP = (unsigned char)H261->RTPInfo->pre_MBAP;
  827. bsinfo->Quant = (unsigned char)H261->UseQuant;
  828. bsinfo->GOBN = (unsigned char)H261->RTPInfo->pre_MB_GOB;
  829. bsinfo->HMV = 0;
  830. bsinfo->VMV = 0;
  831. bsinfo->padding0 = 0;
  832. bsinfo->padding1 = 0;
  833. }
  834. H261->RTPInfo->pre_MB_position = cur_position;
  835. H261->RTPInfo->pre_MB_GOB = CurrentGOB;
  836. H261->RTPInfo->pre_MBAP=0;
  837. }
  838. if(H261->bit_rate) {
  839. if(CurrentGOB==0){
  840. H261->GQuant =8;
  841. H261->MQuant = 8;
  842. }
  843. else
  844. ExecuteQuantization_GOB(H261);
  845. }
  846. else{ /* for VBR */
  847. if (H261->CurrentFrame==H261->StartFrame)
  848. H261->GQuant = H261->MQuant = H261->QPI;
  849. else
  850. H261->GQuant = H261->MQuant = H261->QP;
  851. }
  852. switch (H261->ImageType)
  853. {
  854. case IT_NTSC:
  855. case IT_CIF:
  856. H261->GRead=CurrentGOB;
  857. break;
  858. case IT_QCIF:
  859. H261->GRead=CurrentGOB<<1;
  860. break;
  861. default:
  862. _SlibDebug(_VERIFY_,
  863. printf("Unknown Image Type: %d\n", H261->ImageType) );
  864. return (SvErrorUnrecognizedFormat);
  865. }
  866. WriteGOBHeader(H261, bs);
  867. H261->Buffer_NowPic += 26;
  868. H261->LastMBA = -1; H261->MType=0;
  869. /*
  870. * MAIN LOOP
  871. */
  872. for (CurrentMDU=0; CurrentMDU<H261->NumberMDU; CurrentMDU++)
  873. {
  874. H261->CurrentMDU=CurrentMDU;
  875. H261->MBpos = Bpos_Y(H261, CurrentGOB, CurrentMDU);
  876. H261->LastMType=H261->MType;
  877. H261->MType = H261->All_MType[H261->MBpos];
  878. if((H261->MType>1) && !H261->CodedMB[H261->MBpos])
  879. {
  880. H261->SkipMB++;
  881. if (H261->ImageType==IT_QCIF)
  882. {
  883. HIndex = (CurrentMDU % 11) * 16;
  884. VIndex = (CurrentGOB*48) + ((CurrentMDU/11) * 16);
  885. }
  886. else /* IT_CIF or NTSC */
  887. {
  888. HIndex = ((((CurrentGOB & 1)*11)+(CurrentMDU%11))*16);
  889. VIndex = ((CurrentGOB/2)*48) + ((CurrentMDU/11) * 16);
  890. }
  891. _SlibDebug(_DEBUG_,
  892. printf ("Skipping MB... MType=%d\n", H261->MType) );
  893. h = VIndex*YWidth;
  894. H261->VYWH = h + HIndex;
  895. H261->VYWH2 = (((h/2) + HIndex) /2);
  896. ScCopyMB16(&H261->YRECON[H261->VYWH], &H261->YDEC[H261->VYWH],
  897. YWidth, YWidth);
  898. ScCopyMB8 (&H261->URECON[H261->VYWH2], &H261->UDEC[H261->VYWH2],
  899. CWidth, CWidth);
  900. ScCopyMB8 (&H261->VRECON[H261->VYWH2], &H261->VDEC[H261->VYWH2],
  901. CWidth, CWidth);
  902. }
  903. else
  904. {
  905. /*
  906. * Encode a MDU - was a call to p64EncodeMDU()
  907. */
  908. H261->Current_MBBits=0;
  909. status = p64CompressMDU(H261, bs);
  910. if (status != NoErrors)
  911. return (status);
  912. if (H261->extbitstream)
  913. {
  914. ScBSPosition_t cur_position;
  915. cur_position = ScBSBitPosition(bs);
  916. /* start a new packet */
  917. if ((cur_position-H261->RTPInfo->last_packet_position) >= (unsigned)H261->packetsize-128)
  918. {
  919. SvH261BSInfo_t *bsinfo=&H261->RTPInfo->bsinfo[H261->RTPInfo->trailer.dwNumberOfPackets];
  920. H261->RTPInfo->last_packet_position = H261->RTPInfo->pre_MB_position;
  921. H261->RTPInfo->trailer.dwNumberOfPackets++;
  922. bsinfo->dwBitOffset = (unsigned dword)H261->RTPInfo->pre_MB_position;
  923. bsinfo->MBAP = (unsigned char)H261->RTPInfo->pre_MBAP;
  924. bsinfo->Quant = (unsigned char)H261->UseQuant;
  925. bsinfo->GOBN = (unsigned char)H261->RTPInfo->pre_MB_GOB;
  926. bsinfo->HMV = 0;
  927. bsinfo->VMV = 0;
  928. bsinfo->padding0 = 0;
  929. bsinfo->padding1 = 0;
  930. }
  931. H261->RTPInfo->pre_MB_position = cur_position;
  932. H261->RTPInfo->pre_MB_GOB = H261->CurrentGOB;
  933. H261->RTPInfo->pre_MBAP = H261->LastMBA;
  934. }
  935. H261->QUse++; /* Accumulate statistics */
  936. H261->QSum+=H261->UseQuant;
  937. if (H261->MType < 10)
  938. H261->MacroTypeFrequency[H261->MType]++;
  939. else
  940. {
  941. _SlibDebug(_VERIFY_, printf("Illegal MType: %d\n",H261->MType) );
  942. return (SvErrorIllegalMType);
  943. }
  944. H261->Buffer_NowPic += H261->Current_MBBits;
  945. /*
  946. H261->MyCB[H261->CurrentCBNo].BitsMB += 0.02*(H261->Current_MBBits -
  947. H261->MyCB[H261->CurrentCBNo].BitsMB);
  948. */
  949. if (H261->MType > 1 && H261->bit_rate > 0)
  950. {
  951. error = (H261->Current_MBBits - CBook[H261->CurrentCBNo].BitsMB);
  952. if (fabs(error) > (0.2*H261->Current_MBBits))
  953. error = CBook[H261->CurrentCBNo].BitsMB * 0.2*error/fabs(error);
  954. if (error > 0)
  955. stepsize = 0.005/(H261->Current_MBBits*H261->bit_rate/112000.0);
  956. if (error <= 0)
  957. stepsize = 0.07/(H261->Current_MBBits*H261->bit_rate/112000.0);
  958. CBook[H261->CurrentCBNo].BitsMB += (float)(stepsize*error);
  959. }
  960. }
  961. }
  962. return (NoErrors);
  963. } /**** End of p64EncodeGOB ****/
  964. #if 0
  965. /* Now done inline */
  966. /*
  967. ** Function: p64EncodeMDU()
  968. ** Purpose: Encodes the MDU by read/compressing the MDU, then
  969. ** writing it, then decoding it and accumulating statistics.
  970. */
  971. static SvStatus_t p64EncodeMDU (SvH261Info_t *H261, ScBitstream_t *bs)
  972. {
  973. SvStatus_t status;
  974. H261->Current_MBBits=0;
  975. status = p64CompressMDU(H261, bs);
  976. if (status != NoErrors)
  977. return (status);
  978. H261->QUse++; /* Accumulate statistics */
  979. H261->QSum+=H261->UseQuant;
  980. if (H261->MType < 10)
  981. H261->MacroTypeFrequency[H261->MType]++;
  982. else
  983. {
  984. _SlibDebug(_VERIFY_, printf("Illegal MType: %d\n",H261->MType) );
  985. return (SvErrorIllegalMType);
  986. }
  987. return (NoErrors);
  988. }
  989. #endif
  990. /* these temporary buffers are used by p64CompressMDU and
  991. should be allocated elsewhere */
  992. static float Idct[6][64];
  993. static int Odct[6][64];
  994. static float TempDct[64];
  995. static int Dct[64];
  996. /*
  997. ** Function: p64CompressMDU()
  998. ** Pupose: Reads in the MDU, and attempts to compress it.
  999. ** If the chosen MType is invalid, it finds the closest match.
  1000. */
  1001. static SvStatus_t p64CompressMDU(SvH261Info_t *H261, ScBitstream_t *bs)
  1002. {
  1003. const int CurrentGOB=H261->CurrentGOB, CurrentMDU=H261->CurrentMDU;
  1004. const int YWidth=H261->YWidth, CWidth=H261->CWidth;
  1005. const int YW4=H261->YW4, CW4 = H261->CW4;
  1006. int j, x, tQuant, indQ, VIndex, HIndex, MType;
  1007. int accum, pmask, CBPFlag, *input;
  1008. SvStatus_t status;
  1009. int inputbuf[10][64];
  1010. unsigned int *y0ptr, *y1ptr, *y2ptr, *y3ptr;
  1011. unsigned int *uptr, *vptr;
  1012. unsigned int *y0ptr_dec, *y1ptr_dec, *y2ptr_dec,*y3ptr_dec;
  1013. unsigned int *uptr_dec, *vptr_dec;
  1014. if (H261->ImageType==IT_QCIF)
  1015. {
  1016. HIndex = (CurrentMDU % 11) * 16;
  1017. VIndex = (CurrentGOB*48) + ((CurrentMDU/11) * 16);
  1018. }
  1019. else /* IT_CIF or NTSC */
  1020. {
  1021. HIndex = ((((CurrentGOB & 1)*11)+(CurrentMDU%11))*16);
  1022. VIndex = ((CurrentGOB/2)*48) + ((CurrentMDU/11) * 16);
  1023. }
  1024. H261->MQFlag = 0;
  1025. if(H261->MType < 2)
  1026. H261->Avg_AC = H261->MeVAROR[H261->MBpos]/256.0;
  1027. else
  1028. H261->Avg_AC = H261->MeVAR[H261->MBpos]/256.0;
  1029. H261->MVDH = H261->MeX[H261->MBpos];
  1030. H261->MVDV = H261->MeY[H261->MBpos];
  1031. H261->VYWH = (VIndex*YWidth) + HIndex;
  1032. H261->VYWH2 = ((((VIndex*YWidth)/2) + HIndex) /2);
  1033. H261->VYWHMV = H261->VYWH + H261->MVDH + (H261->MVDV*YWidth);
  1034. H261->VYWHMV2 = H261->VYWH2 +
  1035. ((H261->MVDV/2)*CWidth) + (H261->MVDH/2);
  1036. y0ptr = (unsigned int *) (H261->Y + H261->VYWH);
  1037. y1ptr = y0ptr + 2;
  1038. y2ptr = y0ptr + (YWidth<<1);
  1039. y3ptr = y2ptr + 2;
  1040. uptr = (unsigned int *) (H261->U + H261->VYWH2);
  1041. vptr = (unsigned int *) (H261->V + H261->VYWH2);
  1042. y0ptr_dec = (unsigned int *) (H261->YDEC + H261->VYWH);
  1043. y1ptr_dec = y0ptr_dec + 2;
  1044. y2ptr_dec = y0ptr_dec + (YWidth<<1);
  1045. y3ptr_dec = y2ptr_dec + 2;
  1046. uptr_dec = (unsigned int *) (H261->UDEC + H261->VYWH2);
  1047. vptr_dec = (unsigned int *) (H261->VDEC + H261->VYWH2);
  1048. tQuant = H261->MQuant;
  1049. if (CurrentMDU==0 || H261->LastMBA==-1)
  1050. H261->MQuant = H261->GQuant;
  1051. else
  1052. {
  1053. if(H261->bit_rate)
  1054. ExecuteQuantization_GOB(H261);
  1055. indQ = H261->GQuant-tQuant;
  1056. if (indQ < 0)
  1057. indQ = indQ*2;
  1058. if (Abs(indQ) < H261->MSmooth)
  1059. H261->MQuant = tQuant;
  1060. else
  1061. {
  1062. H261->MQuant = H261->GQuant;
  1063. H261->MQFlag = 1;
  1064. }
  1065. }
  1066. if (H261->MQFlag && H261->MType!=4 && H261->MType!=7)
  1067. {
  1068. H261->MType++;
  1069. _SlibDebug(_DEBUG_, printf("H261->MType++ == %d\n", H261->MType) );
  1070. }
  1071. else
  1072. _SlibDebug(_DEBUG_, printf("H261->MType == %d\n", H261->MType) );
  1073. MType=H261->MType;
  1074. H261->Current_MBBits = 0;
  1075. if (QuantMType[MType])
  1076. {
  1077. if(H261->bit_rate){ /* CBR */
  1078. H261->UseQuant = H261->MQuant;
  1079. H261->GQuant = H261->MQuant; /* Future MB Quant is now MQuant */
  1080. }
  1081. else { /* VBR */
  1082. if (H261->CurrentFrame==H261->StartFrame || IntraMType[MType])
  1083. H261->UseQuant = H261->GQuant = H261->MQuant = H261->QPI;
  1084. else
  1085. H261->UseQuant = H261->GQuant = H261->MQuant = H261->QP;
  1086. }
  1087. }
  1088. else
  1089. H261->UseQuant = H261->GQuant;
  1090. /*
  1091. * WRITE
  1092. */
  1093. H261->MBA = CurrentMDU - H261->LastMBA;
  1094. if (TCoeffMType[MType])
  1095. {
  1096. if (!IntraMType[MType])
  1097. {
  1098. if (FilterMType[MType])
  1099. {
  1100. ScCopyMB16(&H261->YRECON[H261->VYWHMV], &H261->mbRecY[0], YWidth, 16);
  1101. ScCopyMB8 (&H261->URECON[H261->VYWHMV2],&H261->mbRecU[0], CWidth, 8);
  1102. ScCopyMB8 (&H261->VRECON[H261->VYWHMV2],&H261->mbRecV[0], CWidth, 8);
  1103. ScLoopFilter(&H261->mbRecY[0], H261->workloc, 16);
  1104. ScLoopFilter(&H261->mbRecY[8], H261->workloc, 16);
  1105. ScLoopFilter(&H261->mbRecY[128], H261->workloc, 16);
  1106. ScLoopFilter(&H261->mbRecY[136], H261->workloc, 16);
  1107. ScLoopFilter(&H261->mbRecU[0], H261->workloc, 8);
  1108. ScLoopFilter(&H261->mbRecV[0], H261->workloc, 8);
  1109. }
  1110. else if (MFMType[MType])
  1111. {
  1112. ScCopyMB16(&H261->YRECON[H261->VYWHMV], &H261->mbRecY[0], YWidth, 16);
  1113. ScCopyMB8 (&H261->URECON[H261->VYWHMV2],&H261->mbRecU[0], CWidth, 8);
  1114. ScCopyMB8 (&H261->VRECON[H261->VYWHMV2],&H261->mbRecV[0], CWidth, 8);
  1115. }
  1116. else
  1117. {
  1118. ScCopyMB16(&H261->YRECON[H261->VYWH], &H261->mbRecY[0], YWidth, 16);
  1119. ScCopyMB8 (&H261->URECON[H261->VYWH2],&H261->mbRecU[0], CWidth, 8);
  1120. ScCopyMB8 (&H261->VRECON[H261->VYWH2],&H261->mbRecV[0], CWidth, 8);
  1121. }
  1122. _SlibDebug(_DEBUG_, printf("Doing CopySub \n") );
  1123. ScCopySubClip(&H261->mbRecY[0], &Idct[0][0], y0ptr, 4, YW4);
  1124. ScCopySubClip(&H261->mbRecY[8], &Idct[1][0], y1ptr, 4, YW4);
  1125. ScCopySubClip(&H261->mbRecY[128], &Idct[2][0], y2ptr, 4, YW4);
  1126. ScCopySubClip(&H261->mbRecY[136], &Idct[3][0], y3ptr, 4, YW4);
  1127. ScCopySubClip(&H261->mbRecU[0], &Idct[4][0], uptr, 2, CW4);
  1128. ScCopySubClip(&H261->mbRecV[0], &Idct[5][0], vptr, 2, CW4);
  1129. }
  1130. else
  1131. {
  1132. _SlibDebug(_DEBUG_, printf("Doing CopyRev \n") );
  1133. ScCopyRev(y0ptr, &Idct[0][0], YW4 );
  1134. ScCopyRev(y1ptr, &Idct[1][0], YW4);
  1135. ScCopyRev(y2ptr, &Idct[2][0], YW4);
  1136. ScCopyRev(y3ptr, &Idct[3][0], YW4);
  1137. ScCopyRev(uptr, &Idct[4][0], CW4);
  1138. ScCopyRev(vptr, &Idct[5][0], CW4);
  1139. }
  1140. }
  1141. /*
  1142. * DCT, Quantize, and Zigzag.
  1143. * Dequantize and IDCT
  1144. */
  1145. if (IntraMType[MType])
  1146. {
  1147. _SlibDebug(_DEBUG_, printf("Doing IntraQuant\n") );
  1148. for(j=0; j<6; j++)
  1149. {
  1150. /* ScaleDct(&Idct[j][0],TempDct);*/
  1151. ScFDCT8x8(&Idct[j][0],TempDct);
  1152. IntraQuant(TempDct, Dct, H261->UseQuant);
  1153. ZigzagMatrix(Dct, &inputbuf[j][0]);
  1154. Inv_Quant(Dct, H261->UseQuant, IntraMType[MType], TempDct);
  1155. ScScaleIDCT8x8(TempDct, &Odct[j][0]);
  1156. }
  1157. }
  1158. else
  1159. {
  1160. _SlibDebug(_DEBUG_, printf("Doing InterQuant\n") );
  1161. for(j=0; j<6; j++)
  1162. {
  1163. /* ScaleDct(&Idct[j][0],TempDct);*/
  1164. ScFDCT8x8(&Idct[j][0],TempDct);
  1165. InterQuant(TempDct, Dct, H261->UseQuant);
  1166. ZigzagMatrix(Dct, &inputbuf[j][0]);
  1167. Inv_Quant(Dct, H261->UseQuant, IntraMType[MType], TempDct);
  1168. ScScaleIDCT8x8(TempDct, &Odct[j][0]);
  1169. }
  1170. }
  1171. if (!CBPMType[MType])
  1172. {
  1173. CBPFlag=0;
  1174. H261->CBP = 0x3f;
  1175. }
  1176. else
  1177. {
  1178. for(pmask=0, H261->CBP=0, j=0; j<6; j++)
  1179. {
  1180. input = &inputbuf[j][0];
  1181. for(accum=0, x=0; x<64; x++)
  1182. accum += (int)Abs(input[x]);
  1183. if (accum && (pmask==0))
  1184. pmask|=bit_set_mask[5-j];
  1185. if (accum>H261->CBPThreshold)
  1186. H261->CBP |= bit_set_mask[5-j];
  1187. }
  1188. if (!H261->CBP)
  1189. {
  1190. if (pmask)
  1191. H261->CBP=pmask;
  1192. else if (!FilterMType[MType])
  1193. {
  1194. H261->MType=4;
  1195. MType=4;
  1196. }
  1197. else
  1198. {
  1199. H261->MType=7;
  1200. MType=7;
  1201. }
  1202. }
  1203. }
  1204. _SlibDebug(_DEBUG_,printf("CurrentGOB=%d CurrentMDU=%d LastIntra[%d]=%p\n",
  1205. CurrentGOB, CurrentMDU,CurrentGOB,
  1206. H261->LastIntra[CurrentGOB]) );
  1207. if (IntraMType[MType])
  1208. H261->LastIntra[CurrentGOB][CurrentMDU]=0;
  1209. else
  1210. H261->LastIntra[CurrentGOB][CurrentMDU]++;
  1211. /*
  1212. * Write out the MB
  1213. */
  1214. status = WriteMBHeader(H261, bs);
  1215. if (status != NoErrors)
  1216. return (status);
  1217. H261->LastMBA = CurrentMDU;
  1218. H261->TotalMB[IntraMType[MType]]++;
  1219. H261->Current_CodedMB[IntraMType[MType]]++;
  1220. if (TCoeffMType[MType])
  1221. for(j=0; j<6; j++)
  1222. {
  1223. if (H261->CBP & bit_set_mask[5-j])
  1224. {
  1225. input = &inputbuf[j][0];
  1226. if (j>3)
  1227. H261->UVTypeFrequency[MType]++;
  1228. else
  1229. H261->YTypeFrequency[MType]++;
  1230. H261->CodedBlockBits=0;
  1231. if (CBPMType[MType])
  1232. status = CBPEncodeAC(H261, bs, 0, input);
  1233. else
  1234. {
  1235. EncodeDC(H261, bs, *input);
  1236. H261->Current_MBBits += 8;
  1237. status = EncodeAC(H261, bs, 1, input);
  1238. }
  1239. if (status != NoErrors)
  1240. return (status);
  1241. H261->Current_MBBits += H261->CurrentBlockBits;
  1242. H261->MBBits[IntraMType[MType]] += H261->CodedBlockBits;
  1243. if (j<4)
  1244. H261->YCoefBits+=H261->CodedBlockBits;
  1245. else if (j==5)
  1246. H261->UCoefBits+=H261->CodedBlockBits;
  1247. else
  1248. H261->VCoefBits+=H261->CodedBlockBits;
  1249. }
  1250. }
  1251. /*
  1252. * Now write it to Frame _dec !!
  1253. */
  1254. if(!IntraMType[MType])
  1255. {
  1256. const unsigned char CBP = (unsigned char)H261->CBP;
  1257. if (CBP & 0x20)
  1258. {
  1259. ScCopyAddClip(&H261->mbRecY[0], &Odct[0][0], y0ptr_dec, 16, YW4);
  1260. H261->CBPFreq[0]++;
  1261. }
  1262. else
  1263. ScCopyMV8(&H261->mbRecY[0], y0ptr_dec, 16, YW4);
  1264. if (CBP & 0x10)
  1265. {
  1266. ScCopyAddClip(&H261->mbRecY[8], &Odct[1][0],y1ptr_dec, 16, YW4);
  1267. H261->CBPFreq[1]++;
  1268. }
  1269. else
  1270. ScCopyMV8(&H261->mbRecY[8], y1ptr_dec, 16, YW4);
  1271. if (CBP & 0x08)
  1272. {
  1273. ScCopyAddClip(&H261->mbRecY[128], &Odct[2][0], y2ptr_dec, 16, YW4);
  1274. H261->CBPFreq[2]++;
  1275. }
  1276. else
  1277. ScCopyMV8(&H261->mbRecY[128], y2ptr_dec, 16, YW4);
  1278. if (CBP & 0x04)
  1279. {
  1280. ScCopyAddClip(&H261->mbRecY[136], &Odct[3][0], y3ptr_dec, 16, YW4);
  1281. H261->CBPFreq[3]++;
  1282. }
  1283. else
  1284. ScCopyMV8(&H261->mbRecY[136], y3ptr_dec, 16, YW4);
  1285. if (CBP & 0x02)
  1286. {
  1287. ScCopyAddClip(&H261->mbRecU[0], &Odct[4][0], uptr_dec, 8, CW4);
  1288. H261->CBPFreq[4]++;
  1289. }
  1290. else
  1291. ScCopyMV8(&H261->mbRecU[0], uptr_dec, 8, CW4);
  1292. if (CBP & 0x01)
  1293. {
  1294. ScCopyAddClip(&H261->mbRecV[0], &Odct[5][0], vptr_dec, 8, CW4);
  1295. H261->CBPFreq[5]++;
  1296. }
  1297. else
  1298. ScCopyMV8(&H261->mbRecV[0], vptr_dec, 8, CW4);
  1299. }
  1300. else
  1301. {
  1302. ScCopyClip(&Odct[0][0], y0ptr_dec, YW4);
  1303. ScCopyClip(&Odct[1][0], y1ptr_dec, YW4);
  1304. ScCopyClip(&Odct[2][0], y2ptr_dec, YW4);
  1305. ScCopyClip(&Odct[3][0], y3ptr_dec, YW4);
  1306. ScCopyClip(&Odct[4][0], uptr_dec, CW4);
  1307. ScCopyClip(&Odct[5][0], vptr_dec, CW4);
  1308. }
  1309. return (NoErrors);
  1310. }
  1311. #ifndef Bpos_Y
  1312. /* Now a macro */
  1313. /*
  1314. ** Function: Bpos_Y()
  1315. ** Purpose: Returns the designated MDU number inside of the frame of the
  1316. ** installed Iob given by the input gob, mdu, horizontal and
  1317. ** vertical offset. It returns 0 on error.
  1318. */
  1319. static int Bpos_Y(SvH261Info_t *H261, int g, int m)
  1320. {
  1321. int tg;
  1322. BEGIN("Bpos");
  1323. switch (H261->ImageType)
  1324. {
  1325. case IT_QCIF:
  1326. tg = (g * 33) + (m % 33);
  1327. /*
  1328. tg = (g/2) * 33 + (m%11) + (m/11)*11;
  1329. */
  1330. return(tg);
  1331. break;
  1332. case IT_CIF:
  1333. case IT_NTSC:
  1334. tg = (g/2)*66 + (m % 11) + (g&1)*11 + (m/11) * 22;
  1335. return(tg);
  1336. break;
  1337. default:
  1338. /* WHEREAMI();*/
  1339. _SlibDebug(_VERIFY_,
  1340. printf("Unknown image type: %d.\n",H261->ImageType) );
  1341. /* return (SvErrorUnrecognizedFormat);*/
  1342. break;
  1343. }
  1344. return(0);
  1345. }
  1346. #endif
  1347. static void ExecuteQuantization_GOB(SvH261Info_t *H261)
  1348. {
  1349. double si1, si2;
  1350. if(H261->TotalCodedMB)
  1351. {
  1352. if(H261->bit_rate) { /* CBR */
  1353. si1 = (double) H261->CurrentGOB / (double) H261->NumberGOB;
  1354. si2 =(double) exp(-4.0*(si1-0.5)*(si1-0.5)) + 0.45;
  1355. if (H261->Avg_AC >= H261->Global_Avg)
  1356. H261->BitsAvailableMB =(float)(si2 *
  1357. H261->NBitsCurrentFrame/(1.0 *(float) H261->TT_MB) -
  1358. (H261->Global_Avg - H261->Avg_AC)*2.5) ;
  1359. else if (H261->Avg_AC < H261->Global_Avg)
  1360. H261->BitsAvailableMB = (float)( si2* H261->NBitsCurrentFrame/
  1361. (1.0*(float) H261->TT_MB) -
  1362. (H261->Global_Avg - H261->Avg_AC)*2.5 ) ;
  1363. if(H261->MType > 0)
  1364. H261->LowerQuant = H261->LowerQuant_FIX;
  1365. else
  1366. H261->LowerQuant = 0;
  1367. H261->BitsAvailableMB += H261->LowerQuant;
  1368. H261->BitsAvailableMB =(float)Limit_Bits(H261->BitsAvailableMB);
  1369. H261->ACE = (float) H261->Avg_AC;
  1370. H261->GQuant = findcode(H261, CBook);
  1371. if(H261->FineQuant) H261->GQuant -= H261->FineQuant;
  1372. if(H261->CurrentFrame == H261->StartFrame) H261->GQuant = 8;
  1373. if (H261->GQuant < 1) H261->GQuant = 1;
  1374. if(H261->GQuant > 28) H261->GQuant = 28;
  1375. }
  1376. else /* VBR */
  1377. H261->GQuant = H261->QP;
  1378. }
  1379. }
  1380. static int findcode(SvH261Info_t *H261, struct CodeBook *cb)
  1381. {
  1382. const codelength=H261->CodeLength;
  1383. const float ace=H261->ACE, bmb=H261->BitsAvailableMB;
  1384. int i, mincb=-1;
  1385. float distance, mindist, val1, val2;
  1386. struct CodeBook *lcb=cb;
  1387. H261->CurrentCBNo = 15;
  1388. if((ace <=0.0) || (bmb <=0.0))
  1389. return(25);
  1390. mindist = (float)1000000.0;
  1391. for(i=0; i<codelength; i++)
  1392. {
  1393. val1=lcb->AcEnergy - ace;
  1394. val2=lcb->BitsMB - bmb;
  1395. distance = (val1*val1) + (val2*val2);
  1396. if (distance < mindist)
  1397. {
  1398. mindist = distance;
  1399. mincb = i;
  1400. }
  1401. lcb++;
  1402. }
  1403. if (mincb>=0)
  1404. {
  1405. H261->CurrentCBNo = mincb;
  1406. return((int)cb[mincb].QuantClass);
  1407. }
  1408. else
  1409. return(25);
  1410. }
  1411. /*
  1412. ** Function: ntsc_grab()
  1413. ** Purpose: Grab a Q/CIF frame from a 4:2:2 NTSC input. We dup every 10th
  1414. ** pixel horizontally and every 4th line vertically. We also
  1415. ** discard the chroma on every other line, since CIF wants 4:1:1.
  1416. */
  1417. static SvStatus_t ntsc_grab (u_char *RawImage,
  1418. u_char *Comp1, u_char *Comp2, u_char *Comp3,
  1419. int Width, int Height)
  1420. {
  1421. int h, w;
  1422. u_char *yp = Comp1, *up = Comp2, *vp = Comp3;
  1423. int NTSC_Height = 240;
  1424. int NTSC_Width = 320;
  1425. int stride = Width;
  1426. int vdup = 5;
  1427. for (h = 0; h < NTSC_Height; ++h)
  1428. {
  1429. int hdup = 10/2;
  1430. for (w = NTSC_Width; w > 0; w -= 2)
  1431. {
  1432. yp[0] = RawImage[0];
  1433. yp[1] = RawImage[2];
  1434. yp += 2;
  1435. if ((h & 1) == 0)
  1436. {
  1437. *up++ = RawImage[1];
  1438. *vp++ = RawImage[3];
  1439. }
  1440. RawImage += 4;
  1441. if (--hdup <= 0)
  1442. {
  1443. hdup = 10/2;
  1444. yp[0] = yp[-1];
  1445. yp += 1;
  1446. if ((h & 1) == 0)
  1447. {
  1448. if ((w & 2) == 0)
  1449. {
  1450. up[0] = up[-1];
  1451. ++up;
  1452. vp[0] = vp[-1];
  1453. ++vp;
  1454. }
  1455. }
  1456. }
  1457. }
  1458. if (--vdup <= 0)
  1459. {
  1460. vdup = 5;
  1461. /* copy previous line */
  1462. memcpy((char*)yp, (char*)yp - stride, stride);
  1463. yp += stride;
  1464. if ((h & 1) == 0)
  1465. {
  1466. int s = stride >> 1;
  1467. memcpy((char*)up, (char*)up - s, s);
  1468. memcpy((char*)vp, (char*)vp - s, s);
  1469. up += s;
  1470. vp += s;
  1471. }
  1472. }
  1473. }
  1474. return (NoErrors);
  1475. }
  1476. #ifdef USE_C
  1477. static void VertSubSampleK (unsigned char *Incomp, unsigned char *workloc,
  1478. int Width, int Height)
  1479. {
  1480. int j, i, temp;
  1481. int ByteWidth = Width * 4;
  1482. for(j=0; j<(Width ); j++) {
  1483. temp = Incomp[(j * 4)]*3;
  1484. temp += Incomp[(j * 4)+ByteWidth]*3;
  1485. temp += Incomp[(j * 4)+ByteWidth*2];
  1486. temp = temp/7;
  1487. workloc[j] = (unsigned char) temp;
  1488. }
  1489. for(i=2; i<(Height-2); i += 2) {
  1490. for(j=0; j<(Width ); j++) {
  1491. temp = Incomp[(i-1)*ByteWidth + (j * 4)];
  1492. temp += Incomp[i*ByteWidth + (j * 4)]*3;
  1493. temp += Incomp[(i+1)*ByteWidth + (j * 4)]*3;
  1494. temp += Incomp[(i+2)*ByteWidth + (j * 4)];
  1495. workloc[(i/2)*Width + j] = (unsigned char) (temp >> 3);
  1496. }
  1497. }
  1498. i = Width*(Height/2-1);
  1499. for(j=0; j<Width; j++) {
  1500. temp = Incomp[(j * 4) + (Height-3)*ByteWidth];
  1501. temp += Incomp[j + (Height-2)*ByteWidth]*3;
  1502. temp += Incomp[j + (Height-1)*ByteWidth]*3;
  1503. temp = temp/7;
  1504. workloc[i+j] = (unsigned char) temp;
  1505. }
  1506. }
  1507. #endif
  1508.