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.

531 lines
17 KiB

  1. /* File: sv_h261_decompress.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. This file handle the decompression of an H.261 compressed data source.
  20. *************************************************************/
  21. #include <stdio.h>
  22. #include <stdlib.h>
  23. #ifdef __osf__
  24. #include <sys/time.h>
  25. #else
  26. #include <time.h>
  27. #endif
  28. #include "sv_intrn.h"
  29. #include "sv_h261.h"
  30. #include "proto.h"
  31. #include "sv_proto.h"
  32. #include "SC_err.h"
  33. /*PUBLIC*/
  34. extern int QuantMType[];
  35. extern int CBPMType[];
  36. extern int IntraMType[];
  37. extern int MFMType[];
  38. extern int FilterMType[];
  39. extern int TCoeffMType[];
  40. extern int bit_set_mask[];
  41. static SvStatus_t p64DecodeGOB (SvH261Info_t *H261, ScBitstream_t *bs);
  42. static SvStatus_t SetCCITT(SvH261Info_t *H261);
  43. extern void ReadPictureHeader(SvH261Info_t *H261, ScBitstream_t *bs);
  44. /*
  45. ** Read up to the Sequence header and get the image size
  46. */
  47. SvStatus_t sv_GetH261ImageInfo(int fd, SvImageInfo_t *iminfo)
  48. {
  49. ScBitstream_t *bs;
  50. SvStatus_t stat;
  51. int input;
  52. int GRead;
  53. int PType;
  54. int PSpareEnable;
  55. int TemporalReference;
  56. int PSpare;
  57. int ImageType;
  58. stat=ScBSCreateFromFile(&bs, fd, NULL, 2048);
  59. /* ReadHeaderHeader */
  60. input = (int) ScBSGetBits(bs, 16);
  61. if ((input != 1) || (bs->EOI ))
  62. {
  63. /* not implemented
  64. if (seof()==0)
  65. {*/
  66. /* printf("Illegal GOB Start Code. Read: %d\n",input);
  67. }*/
  68. return(-1);
  69. }
  70. /* ReadHeaderTrailer */
  71. GRead = (int)ScBSGetBits(bs,4)-1;
  72. if (GRead < 0) /* End Of Frame */
  73. {
  74. /* ReadPictureHeader */
  75. TemporalReference = (int) ScBSGetBits(bs,5);
  76. PType = (int) ScBSGetBits(bs,6);
  77. for(PSpareEnable = 0;ScBSGetBit(bs);)
  78. {
  79. PSpareEnable=1;
  80. PSpare = (int)ScBSGetBits(bs,8);
  81. }
  82. }
  83. /* printf ("PType : %d \n",PType);*/
  84. if (PType&0x04)
  85. {
  86. if (PSpareEnable&&PSpare==0x8c)
  87. ImageType=IT_NTSC;
  88. else
  89. ImageType=IT_CIF;
  90. }
  91. else
  92. ImageType=IT_QCIF;
  93. /* printf ("ImageType %d \n", ImageType);*/
  94. /* iminfo->width = (ScBSGetBits(bs,SV_HORIZONTAL_SIZE_LEN)+15) & (~15);
  95. iminfo->height = (ScBSGetBits(bs,SV_VERTICAL_SIZE_LEN)+15) & (~15);
  96. */
  97. switch(ImageType)
  98. {
  99. case IT_NTSC:
  100. iminfo->width = 352;
  101. iminfo->height = 240;
  102. break;
  103. case IT_CIF:
  104. iminfo->width = 352;
  105. iminfo->height = 288;
  106. break;
  107. case IT_QCIF:
  108. iminfo->width = 176;
  109. iminfo->height = 144;
  110. break;
  111. default:
  112. sc_dprintf("Unknown ImageType: %d\n",ImageType);
  113. return (SvErrorUnrecognizedFormat);
  114. }
  115. ScBSReset(bs); /* insure the file position is at the beginning */
  116. if (bs->EOI)
  117. stat=SvErrorEndBitstream;
  118. ScBSDestroy(bs);
  119. return(stat);
  120. }
  121. /*
  122. ** Function: svH261Decompress()
  123. ** Purpose: Decodes a single H261 Frame.
  124. */
  125. SvStatus_t svH261Decompress(SvCodecInfo_t *Info,
  126. u_char *MultiBuf, u_char **ImagePtr)
  127. {
  128. SvStatus_t status;
  129. SvH261Info_t *H261=Info->h261;
  130. ScBitstream_t *bs=Info->BSIn;
  131. ScCallbackInfo_t CB;
  132. unsigned char *dummy_y, *dummy_u, *dummy_v;
  133. if (MultiBuf)
  134. H261->DecompData = MultiBuf;
  135. if (Info->BSIn->EOI)
  136. status = SvErrorEndBitstream;
  137. /* Initialize the read buffer position and general info */
  138. status = ReadHeaderHeader(H261,bs); /* nonzero on error or eof */
  139. if (status != NoErrors)
  140. return (status);
  141. if (H261->CurrentFrame == 0)
  142. {
  143. DGenScaleMat(); /* Generate the scaling matrix - should be done in 'begin' */
  144. if (H261->PICSIZE==0) /* something not initialized correctly */
  145. return(SvErrorBadImageSize);
  146. /* set up current frame pointers */
  147. H261->Y = H261->DecompData;
  148. H261->U = H261->DecompData + H261->PICSIZE;
  149. H261->V = H261->DecompData + H261->PICSIZE + (H261->PICSIZE/4);
  150. /* initialize image buffer with black */
  151. memset(H261->Y, 16, H261->PICSIZE);
  152. memset(H261->U, 128, H261->PICSIZE/4);
  153. memset(H261->V, 128, H261->PICSIZE/4);
  154. /* set up reference frame pointers */
  155. H261->YREF = H261->V + H261->PICSIZE/4;
  156. H261->UREF = H261->YREF + H261->PICSIZE;
  157. H261->VREF = H261->UREF + H261->PICSIZE/4;
  158. /* initialize image buffer with black */
  159. memset(H261->YREF, 16, H261->PICSIZE);
  160. memset(H261->UREF, 128, H261->PICSIZE/4);
  161. memset(H261->VREF, 128, H261->PICSIZE/4);
  162. if (H261->CallbackFunction)
  163. {
  164. CB.Message = CB_SEQ_HEADER;
  165. CB.Data = NULL;
  166. CB.DataSize = 0;
  167. CB.DataUsed = 0;
  168. CB.DataType = CB_DATA_NONE;
  169. CB.Action = CB_ACTION_CONTINUE;
  170. (*H261->CallbackFunction)(Info, &CB, NULL);
  171. sc_dprintf("Callback: CB_SEQ_HEADER. Data=0x%X, Action = %d\n",
  172. CB.Data, CB.Action);
  173. if (CB.Action == CB_ACTION_END)
  174. return (ScErrorClientEnd);
  175. }
  176. }
  177. else
  178. {
  179. /* Switch Y,U,V with YREF, UREF, VREF */
  180. dummy_y = H261->Y;
  181. dummy_u = H261->U;
  182. dummy_v = H261->V;
  183. H261->Y = H261->YREF;
  184. H261->U = H261->UREF;
  185. H261->V = H261->VREF;
  186. H261->YREF = dummy_y;
  187. H261->UREF = dummy_u;
  188. H261->VREF = dummy_v;
  189. memcpy(H261->Y, H261->YREF, H261->PICSIZE);
  190. memcpy(H261->U, H261->UREF, H261->PICSIZEBY4);
  191. memcpy(H261->V, H261->VREF, H261->PICSIZEBY4);
  192. }
  193. while(1)
  194. {
  195. ReadHeaderTrailer(H261,bs); /* Reads the trailer of the PSC or GBSC code...
  196. Determines if GOB or new picture */
  197. if (bs->EOI)
  198. return (SvErrorEndBitstream);
  199. if ((H261->GRead < 0)) /* End Of Frame - Reading new picture */
  200. {
  201. ReadPictureHeader(H261,bs);
  202. if (H261->CallbackFunction)
  203. {
  204. CB.Message = CB_FRAME_FOUND;
  205. CB.Data = NULL;
  206. CB.DataSize = 0;
  207. CB.DataUsed = 0;
  208. CB.DataType = CB_DATA_NONE;
  209. CB.Action = CB_ACTION_CONTINUE;
  210. (*H261->CallbackFunction)(Info, &CB, NULL);
  211. sc_dprintf("Callback: CB_FRAME_FOUND. Data=0x%X, Action=%d\n",
  212. CB.Data, CB.Action);
  213. if (CB.Action == CB_ACTION_END)
  214. return (ScErrorClientEnd);
  215. }
  216. /* This should already be done by begin */
  217. if (H261->CurrentFrame == 0)
  218. {
  219. /* This should already be done by begin */
  220. if (H261->PType&0x04)
  221. {
  222. if (H261->PSpareEnable&&H261->PSpare==0x8c)
  223. H261->ImageType=IT_NTSC;
  224. else
  225. H261->ImageType=IT_CIF;
  226. }
  227. else
  228. H261->ImageType=IT_QCIF;
  229. /* set here */
  230. status = SetCCITT(H261);
  231. if (status != NoErrors)
  232. return (status);
  233. H261->TemporalOffset=(H261->TemporalReference-H261->CurrentFrame)%32;
  234. /* ywidth = H261->YWidth; */
  235. H261->CWidth = (H261->YWidth/2);
  236. H261->YW4 = (H261->YWidth/4);
  237. H261->CW4 = (H261->CWidth/4);
  238. /* yheight = H261->YHeight; */
  239. /* printf("\n Init.. ImageType is %d", H261->ImageType);*/
  240. }/* End of first frame */
  241. else /* already initialized */
  242. {
  243. while (((H261->CurrentFrame+H261->TemporalOffset)%32) !=
  244. H261->TemporalReference)
  245. H261->CurrentFrame++;
  246. }
  247. #if 0 /* def WIN32 */
  248. if (H261->CurrentGOB == 11)
  249. {
  250. H261->CurrentGOB = 0;
  251. memcpy(H261->YREF, H261->Y, H261->PICSIZE);
  252. memcpy(H261->UREF, H261->U, H261->PICSIZEBY4);
  253. memcpy(H261->VREF, H261->V, H261->PICSIZEBY4);
  254. *ImagePtr = H261->Y;
  255. return (NoErrors);
  256. }
  257. #endif
  258. /* Reads the header off of the stream.
  259. This is a precursor to PSC or GOB read.
  260. nonzero on error or eof */
  261. status = ReadHeaderHeader(H261,bs);
  262. /* if true, indicates that this could be EOF */
  263. if (status != NoErrors)
  264. return (status);
  265. continue;
  266. } /* End of Read New Picture Header */
  267. /* printf ("Now doing the DecodeGOB \n");*/
  268. status = p64DecodeGOB(H261,bs); /* Else decode the GOB */
  269. if (H261->CurrentGOB == (H261->NumberGOB-1))
  270. {
  271. H261->CurrentFrame++;
  272. *ImagePtr = H261->Y;
  273. H261->CurrentGOB = 0;
  274. return (NoErrors);
  275. }
  276. if (status != NoErrors)
  277. return (status);
  278. } /* End of while loop */
  279. }
  280. /*
  281. ** Function: p64DecodeGOB
  282. ** Purpose: Decodes the GOB block of the current frame.
  283. */
  284. static SvStatus_t p64DecodeGOB (SvH261Info_t *H261, ScBitstream_t *bs)
  285. {
  286. int i, i8, tempmbh;
  287. SvStatus_t status;
  288. unsigned int *y0ptr, *y1ptr, *y2ptr, *y3ptr;
  289. unsigned int *uptr, *vptr;
  290. int Odct[6][64];
  291. int VIndex;
  292. int HIndex;
  293. float ipfloat[64];
  294. /* printf ("bs->EOI %d \n " , bs->EOI);
  295. */
  296. ReadGOBHeader(H261,bs); /* Read the group of blocks header */
  297. if (bs->EOI)
  298. return (SvErrorEndBitstream);
  299. switch(H261->ImageType)
  300. {
  301. case IT_NTSC:
  302. case IT_CIF:
  303. H261->CurrentGOB = H261->GRead;
  304. break;
  305. case IT_QCIF:
  306. H261->CurrentGOB = (H261->GRead>>1);
  307. break;
  308. default:
  309. return (SvErrorUnrecognizedFormat);
  310. /* printf("Unknown Image Type: %d.\n",H261->ImageType);*/
  311. break;
  312. }
  313. if (H261->CurrentGOB > H261->NumberGOB)
  314. {
  315. return (SvErrorCompBufOverflow);
  316. /*
  317. printf("Buffer Overflow: Current:%d Number:%d\n",
  318. H261->CurrentGOB, H261->NumberGOB);
  319. return;
  320. */
  321. }
  322. H261->LastMBA = -1; /* Reset the MBA and the other predictors */
  323. H261->LastMVDH = 0;
  324. H261->LastMVDV = 0;
  325. tempmbh = ReadMBHeader(H261, bs);
  326. if (bs->EOI)
  327. return(SvErrorEndBitstream);
  328. while (tempmbh==0)
  329. {
  330. H261->LastMBA = H261->LastMBA + H261->MBA;
  331. H261->CurrentMDU = H261->LastMBA;
  332. if (H261->CurrentMDU > 32)
  333. return (NoErrors);
  334. if (!CBPMType[H261->MType])
  335. H261->CBP = 0x3f;
  336. if (QuantMType[H261->MType])
  337. {
  338. H261->UseQuant=H261->MQuant;
  339. H261->GQuant=H261->MQuant;
  340. }
  341. else
  342. H261->UseQuant=H261->GQuant;
  343. switch (H261->ImageType)
  344. {
  345. case IT_QCIF:
  346. HIndex = ((H261->CurrentMDU % 11) * 16);
  347. VIndex = (H261->CurrentGOB*48) + ((H261->CurrentMDU/11) * 16);
  348. break;
  349. case IT_NTSC:
  350. case IT_CIF:
  351. HIndex = ((((H261->CurrentGOB & 1)*11) + (H261->CurrentMDU%11)) * 16);
  352. VIndex = ((H261->CurrentGOB/2)*48) + ((H261->CurrentMDU/11) * 16);
  353. break;
  354. default:
  355. /* printf("\n Unknown Image Type \n");*/
  356. return (SvErrorUnrecognizedFormat);
  357. }
  358. i = VIndex*H261->YWidth;
  359. H261->VYWH = i + HIndex;
  360. H261->VYWH2 = (((i/2) + HIndex) /2);
  361. i8 = H261->MVDV*H261->YWidth + H261->MVDH;
  362. H261->VYWHMV = H261->VYWH + i8;
  363. H261->VYWHMV2 = H261->VYWH2 + ((H261->MVDV /2)*H261->CWidth) + (H261->MVDH /2);
  364. for(i8=0; i8<6; i8++)
  365. {
  366. if ((H261->CBP & bit_set_mask[5-i8])&&(TCoeffMType[H261->MType]))
  367. {
  368. if (CBPMType[H261->MType])
  369. status = CBPDecodeAC_Scale(H261, bs, 0, H261->UseQuant, IntraMType[H261->MType], ipfloat);
  370. else
  371. {
  372. *ipfloat = DecodeDC_Scale(H261,bs,IntraMType[H261->MType],H261->UseQuant);
  373. status = DecodeAC_Scale(H261,bs,1,H261->UseQuant, ipfloat);
  374. }
  375. ScScaleIDCT8x8(ipfloat, &Odct[i8][0]);
  376. }
  377. else
  378. memset(&Odct[i8][0], 0, 256);
  379. }
  380. y0ptr = (unsigned int *) (H261->Y+H261->VYWH);
  381. y1ptr = y0ptr + 2;
  382. y2ptr = y0ptr + ((H261->YWidth)<<1);
  383. y3ptr = y2ptr + 2;
  384. uptr = (unsigned int *) (H261->U+H261->VYWH2);
  385. vptr = (unsigned int *) (H261->V+H261->VYWH2);
  386. /* printf ("IntraMType[H261->MType] : %d \n",IntraMType[H261->MType]);*/
  387. if (!IntraMType[H261->MType])
  388. {
  389. if (FilterMType[H261->MType])
  390. {
  391. ScCopyMB16(&H261->YREF[H261->VYWHMV], &H261->mbRecY[0], H261->YWidth, 16);
  392. ScCopyMB8(&H261->UREF[H261->VYWHMV2], &H261->mbRecU[0], H261->CWidth, 8);
  393. ScCopyMB8(&H261->VREF[H261->VYWHMV2], &H261->mbRecV[0], H261->CWidth, 8);
  394. ScLoopFilter(&H261->mbRecY[0], H261->workloc, 16);
  395. ScLoopFilter(&H261->mbRecY[8], H261->workloc, 16);
  396. ScLoopFilter(&H261->mbRecY[128], H261->workloc, 16);
  397. ScLoopFilter(&H261->mbRecY[136], H261->workloc, 16);
  398. ScLoopFilter(&H261->mbRecU[0], H261->workloc, 8);
  399. ScLoopFilter(&H261->mbRecV[0], H261->workloc, 8);
  400. }
  401. else if (MFMType[H261->MType])
  402. {
  403. ScCopyMB16(&H261->YREF[H261->VYWHMV], &H261->mbRecY[0], H261->YWidth, 16);
  404. ScCopyMB8(&H261->UREF[H261->VYWHMV2], &H261->mbRecU[0], H261->CWidth, 8);
  405. ScCopyMB8(&H261->VREF[H261->VYWHMV2], &H261->mbRecV[0], H261->CWidth, 8);
  406. }
  407. else
  408. {
  409. ScCopyMB16(&H261->YREF[H261->VYWH], &H261->mbRecY[0], H261->YWidth, 16);
  410. ScCopyMB8(&H261->UREF[H261->VYWH2], &H261->mbRecU[0], H261->CWidth, 8);
  411. ScCopyMB8(&H261->VREF[H261->VYWH2], &H261->mbRecV[0], H261->CWidth, 8);
  412. }
  413. if (H261->CBP & 0x20)
  414. ScCopyAddClip(&H261->mbRecY[0], &Odct[0][0], y0ptr, 16, H261->YW4);
  415. else
  416. ScCopyMV8(&H261->mbRecY[0], y0ptr, 16, H261->YW4);
  417. if (H261->CBP & 0x10)
  418. ScCopyAddClip(&H261->mbRecY[8], &Odct[1][0], y1ptr, 16, H261->YW4);
  419. else
  420. ScCopyMV8(&H261->mbRecY[8], y1ptr, 16, H261->YW4);
  421. if (H261->CBP & 0x08)
  422. ScCopyAddClip(&H261->mbRecY[128], &Odct[2][0], y2ptr, 16, H261->YW4);
  423. else
  424. ScCopyMV8(&H261->mbRecY[128], y2ptr, 16, H261->YW4);
  425. if (H261->CBP & 0x04)
  426. ScCopyAddClip(&H261->mbRecY[136], &Odct[3][0], y3ptr, 16, H261->YW4);
  427. else
  428. ScCopyMV8(&H261->mbRecY[136], y3ptr, 16, H261->YW4);
  429. if (H261->CBP & 0x02)
  430. ScCopyAddClip(&H261->mbRecU[0], &Odct[4][0], uptr, 8, H261->CW4);
  431. else
  432. ScCopyMV8(&H261->mbRecU[0], uptr, 8, H261->CW4);
  433. if (H261->CBP & 0x01)
  434. ScCopyAddClip(&H261->mbRecV[0], &Odct[5][0], vptr, 8, H261->CW4);
  435. else
  436. ScCopyMV8(&H261->mbRecV[0], vptr, 8, H261->CW4);
  437. }
  438. else
  439. {
  440. ScCopyClip(&Odct[0][0], y0ptr, H261->YW4);
  441. ScCopyClip(&Odct[1][0], y1ptr, H261->YW4);
  442. ScCopyClip(&Odct[2][0], y2ptr, H261->YW4);
  443. ScCopyClip(&Odct[3][0], y3ptr, H261->YW4);
  444. ScCopyClip(&Odct[4][0], uptr, H261->CW4);
  445. ScCopyClip(&Odct[5][0], vptr, H261->CW4);
  446. }
  447. if (H261->CurrentMDU >= 32)
  448. {
  449. if (H261->CurrentGOB < (H261->NumberGOB-1))
  450. tempmbh = ReadMBHeader(H261, bs);
  451. return (NoErrors);
  452. }
  453. tempmbh = ReadMBHeader(H261, bs);
  454. if (bs->EOI)
  455. return (SvErrorEndBitstream);
  456. }
  457. return(NoErrors);
  458. }
  459. /*
  460. ** Function: SetCCITT()
  461. ** Purpose: Sets the CImage and CFrame parameters for CCITT coding.
  462. */
  463. static SvStatus_t SetCCITT(SvH261Info_t *H261)
  464. {
  465. BEGIN("SetCCITT");
  466. switch(H261->ImageType)
  467. {
  468. case IT_NTSC:
  469. H261->NumberGOB = 10; /* Parameters for NTSC design */
  470. H261->NumberMDU = 33;
  471. H261->YWidth = 352;
  472. H261->YHeight = 240;
  473. break;
  474. case IT_CIF:
  475. H261->NumberGOB = 12; /* Parameters for NTSC design */
  476. H261->NumberMDU = 33;
  477. H261->YWidth = 352;
  478. H261->YHeight = 288;
  479. break;
  480. case IT_QCIF:
  481. H261->NumberGOB = 3; /* Parameters for NTSC design */
  482. H261->NumberMDU = 33;
  483. H261->YWidth = 176;
  484. H261->YHeight = 144;
  485. break;
  486. default:
  487. return (SvErrorUnrecognizedFormat);
  488. /* printf("Unknown ImageType: %d\n",H261->ImageType);*/
  489. /* exit(ERROR_BOUNDS);*/
  490. /* break;*/
  491. }
  492. return (NoErrors);
  493. }
  494. SvStatus_t svH261DecompressFree(SvHandle_t Svh)
  495. {
  496. SvCodecInfo_t *Info = (SvCodecInfo_t *)Svh;
  497. SvH261Info_t *H261 = (SvH261Info_t *) Info->h261;
  498. if (!H261->inited)
  499. return(NoErrors);
  500. sv_H261HuffFree(Info->h261);
  501. if (Info->h261->workloc)
  502. ScFree(Info->h261->workloc);
  503. H261->inited=FALSE;
  504. return (NoErrors);
  505. }