Source code of Windows XP (NT5)
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.

3626 lines
116 KiB

  1. //
  2. // MODULE : STi3520A.C
  3. // PURPOSE : STi3520A specific code
  4. // AUTHOR : JBS Yadawa
  5. // CREATED : 7/20/96
  6. //
  7. //
  8. // Copyright (C) 1996 SGS-THOMSON Microelectronics
  9. //
  10. //
  11. // REVISION HISTORY :
  12. //
  13. // DATE :
  14. //
  15. // COMMENTS :
  16. //
  17. #include "common.h"
  18. #include "strmini.h"
  19. #include "stdefs.h"
  20. #include "common.h"
  21. #include "debug.h"
  22. #include "board.h"
  23. #include "error.h"
  24. #include "sti3520A.h"
  25. static BYTE DefIntQuant[QUANT_TAB_SIZE] = {
  26. 0x08, 0x10, 0x10, 0x13, 0x10, 0x13, 0x16, 0x16,
  27. 0x16, 0x16, 0x16, 0x16, 0x1A, 0x18, 0x1A, 0x1B,
  28. 0x1B, 0x1B, 0x1A, 0x1A, 0x1A, 0x1A, 0x1B, 0x1B,
  29. 0x1B, 0x1D, 0x1D, 0x1D, 0x22, 0x22, 0x22, 0x1D,
  30. 0x1D, 0x1D, 0x1B, 0x1B, 0x1D, 0x1D, 0x20, 0x20,
  31. 0x22, 0x22, 0x25, 0x26, 0x25, 0x23, 0x23, 0x22,
  32. 0x23, 0x26, 0x26, 0x28, 0x28, 0x28, 0x30, 0x30,
  33. 0x2E, 0x2E, 0x38, 0x38, 0x3A, 0x45, 0x45, 0x53
  34. };
  35. // Default Non Intra Table
  36. static BYTE DefNonIntQuant[QUANT_TAB_SIZE];
  37. // Non Default Table
  38. static BYTE QuantTab[QUANT_TAB_SIZE];
  39. BYTE Sequence = 1;
  40. extern WORD synchronizing;
  41. char seq_occured;
  42. PVIDEO pVideo;
  43. extern PCARD pCard;
  44. static void NEARAPI ReadHeaderDataFifo (void);
  45. static void NEARAPI VideoAssociatePTS (void);
  46. static void NEARAPI VideoNextStartCode (WORD i);
  47. static void NEARAPI VideoSequenceHeader(void);
  48. static void NEARAPI VideoExtensionHeader(void);
  49. static void NEARAPI VideoGopHeader(void);
  50. static void NEARAPI VideoPictureHeader(void);
  51. static void NEARAPI VideoPictExtensionHeader(void);
  52. static void NEARAPI VideoUser(void);
  53. static void NEARAPI VideoSetRecons(void);
  54. static void NEARAPI VideoStoreRFBBuf (WORD rfp, WORD ffp, WORD bfp );
  55. static void NEARAPI VideoVsyncRout(void);
  56. static void NEARAPI VideoChooseField(void);
  57. static BOOL NEARAPI IsChipSTi3520(void);
  58. static void NEARAPI VideoSetABStart(WORD abg);
  59. static void NEARAPI VideoSetABStop(WORD abs);
  60. static void NEARAPI VideoSetABThresh(WORD abt) ;
  61. static void NEARAPI VideoSetBBStart(WORD bbg);
  62. static WORD NEARAPI VideoGetBBL(void);
  63. static void NEARAPI VideoSetBBStop(WORD bbs);
  64. static void NEARAPI VideoSetBBThresh(WORD bbt);
  65. static WORD NEARAPI VideoBlockMove(DWORD SrcAddress, DWORD DestAddress, WORD Size);
  66. static void NEARAPI VideoStartBlockMove(DWORD SrcAddress, DWORD DestAddress, DWORD Size);
  67. static void NEARAPI VideoCommandSkip(WORD Nbpicture);
  68. static void NEARAPI VideoSetSRC(WORD SrceSize, WORD DestSize);
  69. static void NEARAPI VideoLoadQuantTables(BOOL Intra,BYTE * Table );
  70. static void NEARAPI VideoComputeInst(void);
  71. static void NEARAPI VideoWaitDec (void);
  72. static void NEARAPI VideoStoreINS (void);
  73. static DWORD NEARAPI ReadCDCount (void);
  74. static DWORD NEARAPI ReadSCDCount (void);
  75. static void NEARAPI VideoSetMWP(DWORD mwp);
  76. static void NEARAPI VideoSetMRP(DWORD mrp);
  77. static BOOL NEARAPI VideoMemWriteFifoEmpty( void );
  78. static BOOL NEARAPI VideoMemReadFifoFull( void );
  79. static BOOL NEARAPI VideoHeaderFifoEmpty( void );
  80. static BOOL NEARAPI VideoBlockMoveIdle( void );
  81. static void NEARAPI VideoEnableDecoding(BOOL OnOff);
  82. static void NEARAPI VideoEnableErrConc(BOOL OnOff);
  83. static void NEARAPI VideoPipeReset (void);
  84. static void NEARAPI VideoSoftReset (void);
  85. static void NEARAPI VideoEnableInterfaces (BOOL OnOff );
  86. static void NEARAPI VideoPreventOvf(BOOL OnOff );
  87. static void NEARAPI VideoSetFullRes(void);
  88. static void NEARAPI VideoSetHalfRes(void);
  89. static void NEARAPI VideoSelect8M(BOOL OnOff);
  90. static void NEARAPI VideoSetDramRefresh(WORD Refresh);
  91. static void NEARAPI VideoSelect20M(BOOL OnOff);
  92. static void NEARAPI VideoSetDFA(WORD dfa);
  93. static void NEARAPI VideoDisableDisplay(void);
  94. static void NEARAPI VideoEnableDisplay(void);
  95. static void NEARAPI VideoInitVar(STREAMTYPE StreamType);
  96. static void NEARAPI VideoReset35XX(STREAMTYPE StreamType);
  97. static void NEARAPI VideoInitPLL(void);
  98. static void NEARAPI VideoOsdOn(void);
  99. static void NEARAPI VideoOsdOff (void);
  100. static void NEARAPI VideoInitOEP (DWORD point_oep);
  101. static void NEARAPI VideoDisplayCtrl(void);
  102. static void NEARAPI VideoSetPSV(void);
  103. static void NEARAPI VideoSRCOn(void);
  104. static void NEARAPI VideoSRCOff (void);
  105. static void NEARAPI VideoFullOSD (WORD col);
  106. static void NEARAPI VideoSeek(STREAMTYPE StreamType);
  107. BOOL FARAPI VideoOpen(void)
  108. {
  109. pVideo = pCard->pVideo;
  110. pVideo->errCode = NO_ERROR;
  111. pVideo->VideoState = StatePowerup;
  112. pVideo->ActiveState = StatePowerup;
  113. return (pVideo->errCode);
  114. }
  115. void FARAPI VideoClose(void)
  116. {
  117. }
  118. void FARAPI VideoInitDecoder(STREAMTYPE StreamType)
  119. {
  120. VideoInitVar(StreamType);
  121. VideoReset35XX(StreamType);
  122. pVideo->VideoState = StateInit;
  123. pVideo->ActiveState = StateInit;
  124. }
  125. void FARAPI VideoSeekDecoder(STREAMTYPE StreamType)
  126. {
  127. VideoInitVar(StreamType);
  128. VideoSeek(StreamType);
  129. pVideo->VideoState = StateInit;
  130. pVideo->ActiveState = StateInit;
  131. }
  132. void FARAPI VideoSetMode(WORD Mode, WORD param)
  133. {
  134. pVideo->DecodeMode = Mode;
  135. switch(pVideo->DecodeMode) {
  136. case PlayModeNormal:
  137. pVideo->fastForward = 0;
  138. pVideo->decSlowDown = 0;
  139. break;
  140. case PlayModeFast:
  141. pVideo->fastForward = 1;
  142. pVideo->decSlowDown = 0;
  143. break;
  144. case PlayModeSlow:
  145. pVideo->fastForward = 0;
  146. pVideo->decSlowDown = param;
  147. break;
  148. }
  149. }
  150. void FARAPI VideoDecode(void)
  151. {
  152. switch (pVideo->VideoState) {
  153. case StatePowerup:
  154. break; /* Video chip is not intialized */
  155. case StateInit: /* Starts first Sequence search. */
  156. HostDisableIT();
  157. BoardWriteVideo(ITM, 0);
  158. pVideo->intMask = PSD | HIT | TOP | BOT;
  159. BoardWriteVideo ( ITM + 1, (BYTE)(pVideo->intMask));
  160. BoardWriteVideo(ITM1, 0);
  161. HostEnableIT();
  162. pVideo->VideoState = StateStartup;
  163. pVideo->ActiveState = StateStartup;
  164. break;
  165. case StateStartup:
  166. case StateWaitForDTS:
  167. case StateDecode:
  168. break;
  169. case StatePause:
  170. case StateStep:
  171. HostDisableIT();
  172. pVideo->VideoState = pVideo->ActiveState;
  173. HostEnableIT();
  174. break;
  175. }
  176. }
  177. void FARAPI VideoStep(void)
  178. {
  179. switch(pVideo->VideoState) {
  180. case StatePowerup:
  181. case StateInit:
  182. break;
  183. case StateStartup:
  184. case StateWaitForDTS:
  185. case StateDecode:
  186. VideoPause();
  187. VideoStep(); // Recurse call !
  188. break;
  189. case StateStep:
  190. break;
  191. case StatePause:
  192. if ((!pVideo->displaySecondField) && (!(BoardReadVideo(CTL) & 0x4)))
  193. pVideo->displaySecondField = 1;
  194. else
  195. pVideo->VideoState = StateStep; /* One single picture will be decoded */
  196. pVideo->perFrame = TRUE;
  197. }
  198. }
  199. void FARAPI VideoBack(void)
  200. {
  201. switch (pVideo->VideoState) {
  202. case StatePowerup:
  203. case StateInit:
  204. case StateStep:
  205. break;
  206. case StateWaitForDTS:
  207. case StateStartup:
  208. case StateDecode:
  209. VideoPause();
  210. case StatePause:
  211. pVideo->displaySecondField = 0;
  212. break;
  213. }
  214. }
  215. void FARAPI VideoStop(void)
  216. {
  217. switch (pVideo->VideoState) {
  218. case StatePowerup:
  219. break;
  220. case StateInit:
  221. break;
  222. case StateStartup:
  223. case StateWaitForDTS:
  224. case StateDecode:
  225. case StateStep:
  226. case StatePause:
  227. pVideo->VideoState = StatePowerup;
  228. VideoInitDecoder(DUAL_PES);
  229. VideoMaskInt();
  230. break;
  231. }
  232. }
  233. void FARAPI VideoPause(void)
  234. {
  235. switch (pVideo->VideoState) {
  236. case StatePowerup: // Not yet decoding
  237. case StateInit: // Not yet decoding
  238. case StatePause: // already in Pause mode
  239. break;
  240. case StateWaitForDTS:
  241. case StateStartup:
  242. case StateDecode:
  243. case StateStep:
  244. pVideo->VideoState = StatePause;
  245. break;
  246. }
  247. /* When the video controller is in PAUSE state, the program will not store
  248. any new instruction into the video decoder */
  249. }
  250. BOOL FARAPI AudioIsEnoughPlace(WORD size)
  251. {
  252. if (VideoGetABL() >= (pVideo->AudioBufferSize - (size >> 8)) - 1)
  253. return FALSE;
  254. else
  255. return TRUE;
  256. }
  257. BOOL FARAPI VideoIsEnoughPlace(WORD size)
  258. {
  259. if (VideoGetBBL() >= (pVideo->VideoBufferSize - (size >> 8)) - 1)
  260. return FALSE;
  261. else
  262. return TRUE;
  263. }
  264. DWORD FARAPI VideoGetFirstDTS(void)
  265. {
  266. DWORD Ditiesse;
  267. WORD lattency = 1500; /* field duration for 60 Hz video */
  268. if (pVideo->StreamInfo.displayMode == 0)
  269. lattency = 1800; /* field duration for 50 Hz video */
  270. /* a B picture is displayed 1 field after its decoding starts
  271. an I or a P picture is displayed 3 fields after decoding starts */
  272. if (pVideo->pDecodedPict->pict_type != 2) // I or P picture
  273. lattency = lattency * 3;
  274. Ditiesse = pVideo->pDecodedPict->dwPTS;
  275. Ditiesse = Ditiesse - lattency;
  276. return Ditiesse;
  277. }
  278. WORD FARAPI VideoGetErrorMsg(void)
  279. {
  280. return pVideo->errCode;
  281. }
  282. void FARAPI VideoSkip(void)
  283. {
  284. pVideo->fastForward = 1;
  285. /* the variable will come back to zero when skip instruction is computed */
  286. /* only if pVideo->DecodeMode != VIDEO_FAST */
  287. }
  288. void FARAPI VideoRepeat(void)
  289. {
  290. pVideo->decSlowDown = 1;
  291. /* The variable will come back to zero when repeat done */
  292. /* only if pVideo->DecodeMode != VIDEO_SLOW */
  293. }
  294. WORD FARAPI VideoGetState(void)
  295. {
  296. return pVideo->VideoState;
  297. }
  298. DWORD FARAPI VideoGetPTS(void)
  299. {
  300. return pVideo->pCurrDisplay->dwPTS;
  301. }
  302. BOOL FARAPI VideoIsFirstDTS(void)
  303. {
  304. return pVideo->FirstDTS;
  305. }
  306. BOOL FARAPI VideoIsFirstField(void)
  307. {
  308. if ((pVideo->VsyncNumber == 1) && (pVideo->VsyncInterrupt == TRUE))
  309. return TRUE;
  310. else
  311. return FALSE;
  312. }
  313. BOOL FARAPI VideoForceBKC(BOOL bEnable)
  314. {
  315. if(bEnable)
  316. pVideo->currDCF = pVideo->currDCF & 0xDF; // FBC
  317. else
  318. pVideo->currDCF = pVideo->currDCF | 0x20; // Don't FBC
  319. return TRUE;
  320. }
  321. void FARAPI VideoMaskInt (void)
  322. {
  323. BoardWriteVideo( ITM, 0 ); // mask chip interrupts before reading the status
  324. BoardWriteVideo( ITM + 1, 0 ); // avoids possible gliches on the IRQ line
  325. BoardWriteVideo( VID_ITM1, 0 ); // mask chip interrupts before
  326. }
  327. void FARAPI VideoRestoreInt (void)
  328. {
  329. BoardWriteVideo( ITM, (BYTE)( pVideo->intMask >> 8 ) );
  330. BoardWriteVideo( ITM + 1,(BYTE) ( pVideo->intMask & 0xFF ) );
  331. }
  332. BOOL FARAPI VideoVideoInt(void)
  333. {
  334. BOOL VideoITOccured = FALSE;
  335. WORD compute;
  336. pVideo->VsyncInterrupt = FALSE;
  337. pVideo->FirstDTS = FALSE;
  338. BoardReadVideo ( ITS1 );
  339. /* All interrupts except the first one are computed in this area */
  340. pVideo->intStatus = (WORD)BoardReadVideo ( ITS ) << 8;
  341. // Reading the interrupt status register
  342. pVideo->intStatus = BoardReadVideo ( ITS + 1 ) | pVideo->intStatus;
  343. // All the STI3500 interrupts are cleared */
  344. pVideo->intStatus = pVideo->intStatus & pVideo->intMask;
  345. // To mask the IT not used */
  346. while ( pVideo->intStatus )
  347. {
  348. VideoITOccured = TRUE;
  349. /******************************************************/
  350. /** BOTTOM VSYNC INTERRUPT **/
  351. /******************************************************/
  352. if ( ( pVideo->intStatus & BOT ) != 0x0 )
  353. {
  354. pVideo->intStatus = pVideo->intStatus & ~BOT;
  355. // clear BOT bit
  356. VideoChooseField ();
  357. pVideo->currField = BOT;
  358. if(pVideo->InvertedField)
  359. pVideo->currField = TOP;
  360. VideoVsyncRout ();
  361. }
  362. /******************************************************/
  363. /** TOP VSYNC INTERRUPT **/
  364. /******************************************************/
  365. if ( ( pVideo->intStatus & TOP ) != 0x0 )
  366. {
  367. pVideo->intStatus = pVideo->intStatus & ~TOP;
  368. // clear TOP bit
  369. VideoChooseField ();
  370. pVideo->currField = TOP;
  371. if(pVideo->InvertedField)
  372. pVideo->currField = BOT;
  373. VideoVsyncRout ();
  374. }
  375. /******************************************************/
  376. /** DSYNC INTERRUPT **/
  377. /******************************************************/
  378. /***************************************************************/
  379. /* The DSYNC interrupt is generated on each VSYNC (RPT = 0) */
  380. /* if the next INStrucztion has the EXE bit set. */
  381. /* On each DSYNC a new Header Search is automatically started. */
  382. /***************************************************************/
  383. if ( ( pVideo->intStatus & PSD ) != 0x0 )
  384. {
  385. pVideo->intStatus = pVideo->intStatus & ~PSD;
  386. // clear PSD bit
  387. pVideo->VsyncNumber = 0; /* clear software watch-dog */
  388. /* check if we have reached the first picture with a PTS */
  389. if ( pVideo->NextInstr.Seq ) // first interrupt enabled (Searching Sequence)
  390. {
  391. VideoWaitDec (); // put decoder in Wait mode
  392. pVideo->intMask = 0x1; /* enable header hit interrupt */
  393. pVideo->NextInstr.Seq = 0;
  394. pVideo->NextInstr.Exe = 0;
  395. }
  396. else
  397. {
  398. Sequence = 0;
  399. if ( VideoGetState () == StateWaitForDTS )
  400. {
  401. if ( pVideo->pDecodedPict->validPTS == TRUE )
  402. {
  403. pVideo->FirstDTS = TRUE;
  404. pVideo->VideoState = StateDecode;
  405. }
  406. }
  407. /* Check bit buffer level consistency with pVideo->vbveDelay */
  408. /* of the picture that the STi3500 starts to decode */
  409. if ( ( pVideo->fieldMode == 0 ) || ( pVideo->fieldMode == 2 ) )
  410. // frame picture or first field of a field picture
  411. {
  412. compute = VideoGetBBL();
  413. if ( compute < ( 4 * pVideo->vbvDelay / 5) ) // 0.8 is 4/5 !
  414. // bit buffer level is not high enough for the next
  415. // picture: wait !!!
  416. { // we stop the current decoding
  417. // process for two fields
  418. VideoEnableDecoding(OFF);
  419. pVideo->needDataInBuff = pVideo->currField;
  420. }
  421. }
  422. /********************************************************************/
  423. /*
  424. * We put the decoder in wait mode on DSYNC: EXE bit reset
  425. * into INS.
  426. */
  427. /*
  428. * In normal case the DSYNC interrupt is quickly followed
  429. * by a
  430. */
  431. /*
  432. * Header Hit int. during which the next INS is written
  433. * with EXE=1.
  434. */
  435. /*
  436. * If for any reason the header hit is delayed, the STi3500
  437. * will
  438. */
  439. /* see the notEXE and stay in WAIT mode without crashing... */
  440. /* this can typically appear if the bit buffer gets empty. */
  441. /********************************************************************/
  442. if ( !pVideo->needDataInBuff )
  443. {
  444. VideoWaitDec (); // put decoder in Wait mode
  445. pVideo->NextInstr.Exe = 0;
  446. // reset EXE bit.
  447. }
  448. /* update the display frame pointer for the next VSYNC */
  449. if ( ( pVideo->fieldMode == 0 ) || ( pVideo->fieldMode == 2 ) )
  450. // frame picture or first field of a field picture
  451. {
  452. pVideo->pCurrDisplay = pVideo->pNextDisplay;
  453. // preset the VSYNC counter
  454. pVideo->pictDispIndex = 0 - ( 2 * pVideo->decSlowDown );
  455. if ( pVideo->DecodeMode != PlayModeSlow)
  456. pVideo->decSlowDown = 0; /* allows to do the repeat
  457. * function */
  458. BoardWriteVideo( DFP, (BYTE)( pVideo->pCurrDisplay->buffer >> 8 ) );
  459. BoardWriteVideo( DFP + 1, (BYTE)( pVideo->pCurrDisplay->buffer & 0xFF ) );
  460. pVideo->displaySecondField = 0;
  461. VideoChooseField ();
  462. }
  463. VideoSetPSV (); // update the next pan vector
  464. // frame picture or second field of field picture */
  465. // if ( ( pVideo->VideoState == StatePause ) && ( pVideo->fieldMode != 2 ) )
  466. // pVideo->pictureDecoded = 1;
  467. // to know that in step by step, the picture is decoded
  468. }
  469. }
  470. /******************************************************/
  471. /** HEADER HIT INTERRUPT **/
  472. /******************************************************/
  473. if ( ( pVideo->intStatus & HIT ) != 0 )
  474. // Test Header hit interrupt
  475. {
  476. WORD temp = 0;
  477. pVideo->intStatus = pVideo->intStatus & ~HIT;
  478. // clear HIT bit
  479. while ( VideoHeaderFifoEmpty())
  480. /* Header fifo not available */
  481. {
  482. temp++;
  483. if ( temp == 0xFFFF )
  484. {
  485. if ( !pVideo->errCode )
  486. pVideo->errCode = BUF_EMPTY;
  487. SetErrorCode(ERR_HEADER_FIFO_EMPTY);
  488. break;
  489. }
  490. }
  491. /* Waiting... */
  492. compute = BoardReadVideo(HDF);
  493. //compute = BoardReadVideo ( HDF );
  494. /* load MSB */
  495. pVideo->hdrPos = 0; /* start code is MSB */
  496. if ( compute == 0x01 )
  497. {
  498. pVideo->hdrPos = 8; /* start code value is in LSB */
  499. pVideo->hdrNextWord = (WORD)BoardReadVideo(HDF)<<8;//BoardReadVideo ( HDF ) << 8;
  500. ReadHeaderDataFifo ();
  501. /* Result in pVideo->hdrFirstWord */
  502. }
  503. else
  504. {
  505. pVideo->hdrNextWord = 0;
  506. pVideo->hdrFirstWord = BoardReadVideo(HDF);
  507. pVideo->hdrFirstWord = pVideo->hdrFirstWord | ( compute << 8 );
  508. }
  509. /*
  510. * on that point the start code value is always the MSByte of
  511. * pVideo->hdrFirstWord
  512. */
  513. switch ( pVideo->hdrFirstWord & 0xFF00 )
  514. {
  515. DWORD buf_control;
  516. DWORD size_of_pict;
  517. case SEQ:
  518. VideoSequenceHeader ();
  519. /* Restart Header Search */
  520. BoardWriteVideo ( VID_HDS, HDS );
  521. break;
  522. case EXT:
  523. VideoExtensionHeader ();
  524. BoardWriteVideo ( VID_HDS, HDS );
  525. /* Restart Header Search */
  526. break;
  527. case GOP:
  528. VideoGopHeader ();
  529. BoardWriteVideo ( VID_HDS, HDS );
  530. /* Restart Header Search */
  531. break;
  532. case PICT:
  533. VideoPictureHeader ();
  534. // This part of the code
  535. // Computes the size of last picture
  536. // and substracts it to lastbuffer level
  537. // This allows to track if pipe/scd are misalined
  538. buf_control = ReadSCDCount ();
  539. if ( pVideo->LastScdCount > buf_control )
  540. size_of_pict = ( 0x1000000L - pVideo->LastScdCount ) + buf_control;
  541. else
  542. size_of_pict = buf_control - pVideo->LastScdCount;
  543. pVideo->LastScdCount = buf_control;
  544. if ( pVideo->fastForward )
  545. pVideo->LastPipeReset = 3;
  546. pVideo->LastBufferLevel -= ( WORD ) ( size_of_pict >> 7 );
  547. //End of misalined pb tracking
  548. /* don't restart header search !!! */
  549. if ( pVideo->skipMode ) // restart search only if we
  550. // skip this picture
  551. {
  552. BoardWriteVideo ( VID_HDS, HDS );
  553. /* Restart Header Search */
  554. }
  555. break;
  556. case USER: // We don't care about user
  557. // fields
  558. BoardWriteVideo ( VID_HDS, HDS );
  559. /* Restart Header Search */
  560. break;
  561. case SEQ_END: // end of sequence code
  562. compute = (WORD)BoardReadVideo ( ITS ) << 8;
  563. // this start code can be back to back with next one
  564. compute = ( compute | BoardReadVideo ( ITS + 1 ) );
  565. // in such case the HDS bit can be set
  566. pVideo->intStatus = ( pVideo->intStatus | compute ) & pVideo->intMask;
  567. if ( !( pVideo->intStatus & HIT ) )
  568. {
  569. BoardWriteVideo ( VID_HDS, HDS );
  570. /* Restart Header Search */
  571. }
  572. break;
  573. case SEQ_ERR: // the chip will enter the
  574. // automatic error concealment
  575. // mode
  576. compute = (WORD)BoardReadVideo ( ITS ) << 8;
  577. // this start code can be back to back with next one
  578. compute = ( compute | BoardReadVideo ( ITS + 1 ) );
  579. // in such case the HDS bit can be set
  580. pVideo->intStatus = ( pVideo->intStatus | compute ) & pVideo->intMask;
  581. if ( !( pVideo->intStatus & HIT ) )
  582. {
  583. BoardWriteVideo ( VID_HDS, HDS );
  584. /* Restart Header Search */
  585. }
  586. break;
  587. default:
  588. if ( !pVideo->errCode )
  589. pVideo->errCode = S_C_ERR;
  590. SetErrorCode(ERR_UNKNOWN_SC);
  591. // non video start code
  592. break;
  593. }
  594. } // end of header hit interrupt
  595. /******************************************************/
  596. /** BIT BUFFER FULL INTERRUPT **/
  597. /******************************************************/
  598. if ( ( pVideo->intStatus & BBF ) != 0x0 )
  599. /* Bit buffer full */
  600. {
  601. pVideo->intStatus = pVideo->intStatus & ~BBF;
  602. // clear BBF bit
  603. if ( pVideo->vbvReached == 1 ) /* bit buffer level too high */
  604. {
  605. if ( !pVideo->errCode )
  606. pVideo->errCode = FULL_BUF; /* mention of the error */
  607. SetErrorCode(ERR_BIT_BUFFER_FULL);
  608. VideoWaitDec (); // put decoder in Wait mode
  609. pVideo->NextInstr = pVideo->ZeroInstr;
  610. }
  611. else
  612. {
  613. WORD BitBufferLevel;
  614. BitBufferLevel = pVideo->VideoBufferSize - 2;
  615. VideoSetBBThresh(BitBufferLevel);
  616. pVideo->intMask = PID | SER | PER | PSD | BOT | TOP | BBE | HIT;
  617. /* enable all interrupts that may be used */
  618. BoardReadVideo ( ITS );
  619. BoardReadVideo ( ITS + 1);
  620. // to clear previous TOP VSYNC flag
  621. pVideo->NextInstr.Exe = 1;; // decoding will start on
  622. // next "good" Vsync */
  623. pVideo->VsyncNumber = 0;
  624. pVideo->pictDispIndex = 1;
  625. pVideo->pCurrDisplay->nb_display_field = 1;
  626. pVideo->vbvReached = 1;
  627. pVideo->FistVsyncAfterVbv = NOT_YET_VST;
  628. }
  629. }
  630. //*****************************************************/
  631. //* pipeline ERROR **/
  632. //*****************************************************/
  633. // The pipeline reset is made here by software */
  634. // It is also possible to enable the automatic */
  635. // Pipeline reset by setting bit EPR of CTL reg. */
  636. // This could be done in the Reset3500 routine */
  637. // In this case the pipeline error interrupt is */
  638. // only used as a flag for the external micro. */
  639. //*****************************************************/
  640. if ( ( pVideo->intStatus & PER ) != 0x0 )
  641. {
  642. pVideo->intStatus = pVideo->intStatus & ~PER;
  643. // clear PER bit
  644. // VideoPipeReset ( pVideo );
  645. }
  646. /******************************************************/
  647. /** serious ERROR **/
  648. /******************************************************/
  649. if ( ( pVideo->intStatus & SER ) != 0x0 )
  650. {
  651. pVideo->intStatus = pVideo->intStatus & ~SER;
  652. // clear SER bit
  653. VideoPipeReset ();
  654. }
  655. /********************************/
  656. /* bit buffer empty interrupt */
  657. /********************************/
  658. if ( ( pVideo->intStatus & BBE ) != 0x0 )
  659. // bit buffer empty
  660. {
  661. pVideo->intStatus = pVideo->intStatus & ~BBE;
  662. // clear BBE bit
  663. }
  664. /********************************/
  665. /* pipeline idle interrupt */
  666. /********************************/
  667. if ( ( pVideo->intStatus & PID ) != 0x0 )
  668. // pipeline idle
  669. {
  670. //***************************************
  671. // Check If pipe is misalined with scd
  672. // and restart header search if it is
  673. // the case
  674. //***************************************
  675. DWORD NewCd;
  676. DWORD EnterBitBuffer;
  677. WORD NewBbl;
  678. WORD ExpectedBbl;
  679. // clear PID bit
  680. pVideo->intStatus = pVideo->intStatus & ~PID;
  681. /* read BBL level */
  682. NewBbl = VideoGetBBL();
  683. /* Read number of compressed data loaded into the chip */
  684. NewCd = ReadCDCount ();
  685. if ( NewCd < pVideo->LastCdCount )
  686. EnterBitBuffer = ( 0x1000000L - pVideo->LastCdCount ) + NewCd;
  687. else
  688. EnterBitBuffer = ( NewCd - pVideo->LastCdCount );
  689. //Expected Bitbuffer level is Old bbl + what enterred - what left
  690. //pVideo->LastBufferLevel holds Old bbl + what enterred and has been
  691. // updated in picture hit interrupt.
  692. ExpectedBbl = (WORD)(pVideo->LastBufferLevel + ( EnterBitBuffer >> 8 ) - 2);
  693. if ( pVideo->LastPipeReset == 0 )
  694. {
  695. /* BBL is lower than it should be !!! */
  696. if ( NewBbl < ExpectedBbl )
  697. {
  698. /* here we force manually a new header search because */
  699. /* the pipeline is supposed to have skipped a picture */
  700. /* i.e. the start code detector and the pipeline are */
  701. /* not synchronised on the same picture */
  702. BoardWriteVideo ( VID_HDS, HDS );
  703. pVideo->LastPipeReset = 1;
  704. }
  705. }
  706. else
  707. {
  708. pVideo->LastPipeReset--;
  709. }
  710. pVideo->LastCdCount = NewCd;
  711. pVideo->LastBufferLevel = NewBbl;
  712. }
  713. /******************************************************/
  714. /** END OF INTERRUPT ROUTINE **/
  715. /******************************************************/
  716. /* common to all interrupts */
  717. /* set interrupt mask to the correct value */
  718. } // end of while
  719. return VideoITOccured;
  720. }
  721. /****************************************************************************/
  722. /* notations of the bits position in pVideo->hdrFirstWord registers are */
  723. /* X for a nibble that must be read */
  724. /* x for a bit that must be read */
  725. /* 0 for a nibble not read */
  726. /* o for a bit not read */
  727. /* example : 0 X xxoo 0 means: bits 15 to 12 not read, */
  728. /* bits 11 to 6 extracted, bits 5 to 0 not read */
  729. /****************************************************************************/
  730. //----------------------------------------------------------------------------
  731. // Read of the header data fifo
  732. //----------------------------------------------------------------------------
  733. /*
  734. returns the next word(16 bits) of the
  735. Header data Fifo into pVideo->hdrFirstWord variable
  736. */
  737. static void NEARAPI ReadHeaderDataFifo (void)
  738. {
  739. WORD i = 0;
  740. while ( VideoHeaderFifoEmpty()) /* Header fifo not available */
  741. {
  742. i++;
  743. if (i == 0xFFFF) {
  744. if ( !pVideo->errCode )
  745. pVideo->errCode = BUF_EMPTY;
  746. SetErrorCode(ERR_BIT_BUFFER_EMPTY);
  747. break;
  748. }
  749. } /* Waiting... */
  750. pVideo->hdrFirstWord = BoardReadVideo(HDF);
  751. if (pVideo->hdrPos == 8) {
  752. pVideo->hdrFirstWord = pVideo->hdrNextWord | pVideo->hdrFirstWord;
  753. pVideo->hdrNextWord = BoardReadVideo(HDF) << 8;
  754. }
  755. else
  756. {
  757. pVideo->hdrFirstWord = pVideo->hdrFirstWord << 8;
  758. pVideo->hdrFirstWord = BoardReadVideo(HDF) | pVideo->hdrFirstWord;
  759. }
  760. }
  761. //----------------------------------------------------------------------------
  762. // Routine associating the PTS values with each picture
  763. //----------------------------------------------------------------------------
  764. static void NEARAPI VideoAssociatePTS (void)
  765. {
  766. pVideo->pDecodedPict->validPTS = VideoIsValidPTS( );
  767. if(pVideo->pDecodedPict->validPTS) {
  768. pVideo->pDecodedPict->dwPTS = BoardReadVideoPTS( );
  769. }
  770. }
  771. //----------------------------------------------------------------------------
  772. // Read of the next start code in the bit stream
  773. //----------------------------------------------------------------------------
  774. /*
  775. This routine is used at the end of the picture header
  776. when the Start Code Detection mechanism is not used
  777. */
  778. static void NEARAPI VideoNextStartCode (WORD i)
  779. {
  780. long temp = 0;
  781. if ( i )
  782. temp = pVideo->hdrFirstWord & 0xFF; // use LSB of pVideo->hdrFirstWord
  783. while ( temp == 0 )
  784. {
  785. ReadHeaderDataFifo (); // read next 16 bits
  786. if ( pVideo->errCode )
  787. {
  788. i = 3;
  789. break;
  790. }
  791. temp = ( temp << 16 ) | pVideo->hdrFirstWord;
  792. i = i + 2;
  793. }
  794. if ( i < 3 ) { // A start code is not found: bit stream error !!
  795. pVideo->errCode = PICT_HEAD;
  796. SetErrorCode(ERR_PICTURE_HEADER);
  797. }
  798. else
  799. {
  800. if ( ( temp & 0xFFFFFF00L ) == 0x00000100L ) // this is a start code
  801. {
  802. if ( !pVideo->hdrPos ) // there is nothing into
  803. // pVideo->hdrNextWord
  804. {
  805. pVideo->hdrPos = 8;
  806. pVideo->hdrNextWord = ( pVideo->hdrFirstWord & 0xFF ) << 8;
  807. ReadHeaderDataFifo ();
  808. }
  809. else
  810. { // pVideo->hdrPos = 8: the next
  811. // byte is into pVideo->hdrNextWord
  812. pVideo->hdrFirstWord = ( pVideo->hdrFirstWord << 8 ) | ( pVideo->hdrNextWord >> 8 );
  813. pVideo->hdrPos = 0;
  814. }
  815. }
  816. else if ( ( temp & 0xFFFFFFFFL ) == 0x00000001L ) // this is a start code
  817. {
  818. ReadHeaderDataFifo ();
  819. }
  820. else { // temp does not contain a start code : bit stream error !
  821. if ( !pVideo->errCode )
  822. pVideo->errCode = PICT_HEAD;
  823. SetErrorCode(ERR_PICTURE_HEADER);
  824. }
  825. }
  826. i = BoardReadVideo ( ITS ) << 8; // allows to clear the Header hit bit
  827. i = ( i | BoardReadVideo ( ITS + 1 ) ) & 0xFFFE; // allows to clear the
  828. // Header hit bit
  829. pVideo->intStatus = ( pVideo->intStatus | i ) & pVideo->intMask;
  830. /* if no bit stream error, we leave the routine with the start code into pVideo->hdrFirstWord as XX00 */
  831. }
  832. //----------------------------------------------------------------------------
  833. // SEQUENCE START CODE
  834. //----------------------------------------------------------------------------
  835. static void NEARAPI VideoSequenceHeader(void)
  836. {
  837. DWORD compute, i;
  838. /* default intra quantization matrix */
  839. // default Non intra quantization matrix, All coefs = 16
  840. for (i = 0 ; i < QUANT_TAB_SIZE ; i++)
  841. DefNonIntQuant[i] = 16;
  842. seq_occured = 1; // mention to the picture header that a sequence has occured
  843. // in order to reset the next pan offsets.
  844. /* Horizontal picture size is 12 bits: 00XX + X000 */
  845. pVideo->StreamInfo.horSize = ( pVideo->hdrFirstWord << 4 ) & 0xFFF; // extract 8 MSB
  846. ReadHeaderDataFifo ();
  847. pVideo->StreamInfo.horSize = pVideo->StreamInfo.horSize | ( pVideo->hdrFirstWord >> 12 ); // 4 LSB of horizontal
  848. // size
  849. /* Vertical picture size is 12 bits: 0XXX */
  850. pVideo->StreamInfo.verSize = pVideo->hdrFirstWord & 0xFFF; // 12 LSB of Vertical picture
  851. // size
  852. /* pixel aspect ratio is 4 bits: X000 */
  853. ReadHeaderDataFifo ();
  854. pVideo->StreamInfo.pixelRatio = ( pVideo->hdrFirstWord >> 12 ) & 0xF;
  855. /* frame rate is 4 bits: 0X00 */
  856. pVideo->StreamInfo.frameRate = ( pVideo->hdrFirstWord >> 8 ) & 0xF;
  857. pVideo->StreamInfo.displayMode = 1; // 60 Hz interlaced display
  858. pVideo->BufferA = BUFF_A_NTSC;
  859. pVideo->BufferB = BUFF_B_NTSC;
  860. pVideo->BufferC = BUFF_C_NTSC;
  861. switch ( pVideo->StreamInfo.frameRate )
  862. {
  863. case 1: // picture rate is 23.976 Hz:
  864. break; // display in 3:2 pull-down at
  865. // 59.94 Hz interlaced if MPEG1
  866. case 2: // picture rate is 24 Hz:
  867. break; // display in 3:2 pull-down at
  868. // 60 Hz interlaced if MPEG1
  869. case 3: // picture rate is 25 Hz:
  870. // display 50 Hz interlaced
  871. pVideo->StreamInfo.displayMode = 0;
  872. pVideo->BufferA = BUFF_A_PAL;
  873. pVideo->BufferB = BUFF_B_PAL;
  874. pVideo->BufferC = BUFF_C_PAL;
  875. break;
  876. case 4: // picture rate is 29.97 Hz
  877. break;
  878. case 5: // picture rate is 30 Hz
  879. break;
  880. default:
  881. SetErrorCode(ERR_FRAME_RATE_NOT_SUPPORTED);
  882. if ( !pVideo->errCode )
  883. pVideo->errCode = FRAME_RATE; /* frame rate not supported by the board */
  884. break;
  885. }
  886. /* bit rate is 18 bits: 00XX + XX xxoo 0 */
  887. pVideo->StreamInfo.bitRate = (long) pVideo->hdrFirstWord;
  888. pVideo->StreamInfo.bitRate = ( pVideo->StreamInfo.bitRate << 10 ) & 0x3FC00L;
  889. ReadHeaderDataFifo();
  890. pVideo->StreamInfo.bitRate = pVideo->StreamInfo.bitRate | ( pVideo->hdrFirstWord >> 6 );
  891. /* bit rate is 18 bits only for MPEG1 bit streams */
  892. if ( !pVideo->StreamInfo.modeMPEG2 )
  893. {
  894. long tota = 400L;
  895. pVideo->StreamInfo.bitRate = pVideo->StreamInfo.bitRate * tota; /* bit rate is a multiple of 400
  896. * bits/s */
  897. }
  898. /*
  899. * for MPEG2 bit streams bit rate is 30 bits: 12 more bits in
  900. * sequence extension
  901. */
  902. /* marker bit: 00 ooxo 0 : just skipped ... */
  903. /* pVideo->vbvBufferSize is 10 bits : 00 ooox X + X xooo 00 */
  904. pVideo->vbvBufferSize = ( pVideo->hdrFirstWord << 5 ) & 0x3E0;
  905. ReadHeaderDataFifo ();
  906. pVideo->vbvBufferSize = pVideo->vbvBufferSize | ( pVideo->hdrFirstWord >> 11 );
  907. // if( (!pVideo->StreamInfo.modeMPEG2) && ((pVideo->vbvBufferSize*8) > BUF_FULL) )
  908. // if (!pVideo->errCode) pVideo->errCode = SMALL_BUF; /* Buffer size too small to decode the bit stream */
  909. // for MPEG2 bit streams pVideo->vbvBufferSize is 15 bits: 5 more bits in
  910. // sequence extension */
  911. // constrained flag is 1 bit: 0 oxoo 00 : just skipped... */
  912. // load intra quant table bit : 0 ooxo 00 */
  913. if ( ( pVideo->hdrFirstWord & 0x200 ) != 0 ) // Test load intra quantizer
  914. // matrix */
  915. {
  916. // Read Non Default Intra Quant Table
  917. for ( i = 0; i < (QUANT_TAB_SIZE/2) ; i++)
  918. {
  919. compute = pVideo->hdrFirstWord << 7;
  920. ReadHeaderDataFifo ();
  921. compute = compute | ( pVideo->hdrFirstWord >> 9 );
  922. QuantTab[2*i] = (BYTE)( compute >> 8 );
  923. QuantTab[2*i+1] = (BYTE)( compute & 0xFF );
  924. }
  925. // Load Intra Quant Tables
  926. VideoLoadQuantTables(TRUE , QuantTab );
  927. pVideo->defaultTbl = pVideo->defaultTbl & 0xE; // bit 0 = 0 : no default table
  928. // in the chip */
  929. }
  930. else if ( !( pVideo->defaultTbl & 0x1 ) ) // Load default intra matrix */
  931. {
  932. VideoLoadQuantTables(TRUE , DefIntQuant );
  933. pVideo->defaultTbl++; // bit 0 = 1 default intra table
  934. // is in the chip */
  935. }
  936. // load non intra quant table bit : 0 ooox 00 */
  937. if ( ( pVideo->hdrFirstWord & 0x100 ) != 0 ) // Test load non intra quantizer
  938. // matrix */
  939. { // Load non intra quantizer
  940. // matrix */
  941. for ( i = 0; i < (QUANT_TAB_SIZE/2) ; i++)
  942. {
  943. compute = pVideo->hdrFirstWord & 0xFF;
  944. QuantTab[2*i] = (BYTE)( compute );
  945. ReadHeaderDataFifo ();
  946. compute = ( pVideo->hdrFirstWord >> 8 ) & 0xFF;
  947. QuantTab[2*i+1] = (BYTE)( compute );
  948. }
  949. VideoLoadQuantTables(FALSE , QuantTab );
  950. pVideo->defaultTbl = pVideo->defaultTbl & 0xD; // bit 1 = 0 : no default
  951. // non-intra matrix */
  952. }
  953. else if ( !( pVideo->defaultTbl & 0x2 ) ) // default non intra table not
  954. // in the chip */
  955. {
  956. VideoLoadQuantTables(FALSE , DefNonIntQuant );
  957. pVideo->defaultTbl = pVideo->defaultTbl | 0x2; // bit 1 = 1: default non intra
  958. // table into the chip */
  959. }
  960. if ( ( !pVideo->StreamInfo.modeMPEG2 ) && ( pVideo->notInitDone ) ) // initialisation of the
  961. // frame size is only done
  962. // once
  963. {
  964. VideoSetPictureSize ();
  965. // BoardVideoSetDisplayMode ( (BYTE)(pVideo->StreamInfo.displayMode));
  966. VideoInitXY ();
  967. pVideo->notInitDone = 0;
  968. }
  969. // in case of MPEG2 bit streams the initialisation can only be done
  970. // after sequence extension */
  971. // end of sequence header analysis */
  972. }
  973. //----------------------------------------------------------------------------
  974. // EXTENSION START CODE
  975. //----------------------------------------------------------------------------
  976. // interrupt only enabled after sequence or GOP start code */
  977. static void NEARAPI VideoExtensionHeader(void)
  978. {
  979. WORD comput1;
  980. DWORD temp;
  981. // extension field is 4 bits: 00X0 */
  982. switch ( pVideo->hdrFirstWord & 0xF0 )
  983. {
  984. //**********************************************************/
  985. // SEQUENCE EXTENSION */
  986. //**********************************************************/
  987. case SEQ_EXT: // sequence extension field
  988. // always present in MPEG2
  989. if ( !pVideo->StreamInfo.modeMPEG2 ) // automatic detection of the
  990. // standard
  991. {
  992. DWORD tota = 400L;
  993. pVideo->StreamInfo.bitRate = pVideo->StreamInfo.bitRate / tota; // bit rate was mult. by
  994. // 400 in sequence header
  995. // if pVideo->StreamInfo.modeMPEG2 = 0
  996. pVideo->StreamInfo.modeMPEG2 = 1;
  997. pVideo->NextInstr.Mp2 = 1;
  998. pVideo->notInitDone = 1;
  999. }
  1000. /* one bit reserved for future use : 000xooo */
  1001. /* Profile indication: 000oxxx */
  1002. comput1 = pVideo->hdrFirstWord & 0x7;
  1003. if ( ( comput1 != 4 ) && ( comput1 != 5 ) ) { // main profile Id =
  1004. // 100, simple profile =
  1005. // 101
  1006. SetErrorCode(ERR_PROFILE_NOT_SUPPORTED);
  1007. if ( !pVideo->errCode )
  1008. pVideo->errCode = MAIN_PROF;// not simple or main profile bitstream
  1009. }
  1010. /* Level indication: X000 */
  1011. ReadHeaderDataFifo ();
  1012. comput1 = pVideo->hdrFirstWord & 0xF000;
  1013. if ( ( comput1 != 0x8000 ) && ( comput1 != 0xA000 ) ) {// main level Id = 1000,
  1014. // low level = 1010
  1015. if ( !pVideo->errCode )
  1016. pVideo->errCode = MAIN_PROF;// not low or main level bitstream
  1017. SetErrorCode(ERR_LEVEL_NOT_SUPPORTED);
  1018. }
  1019. /* non interlaced sequence bit : 0 xooo 00 */
  1020. pVideo->StreamInfo.progSeq = 0;
  1021. if ( ( pVideo->hdrFirstWord & 0x0800 ) ) // non-interlaced frames
  1022. pVideo->StreamInfo.progSeq = 1;
  1023. /* chroma format is 2 bits: 0 oxxo 00 */
  1024. // test if 4.1.1 chroma format
  1025. if ( ( pVideo->hdrFirstWord & 0x600 ) != 0x200 ) {
  1026. if ( !pVideo->errCode )
  1027. pVideo->errCode = CHROMA; // chroma format not supported
  1028. SetErrorCode(ERR_CHROMA_FORMAT_NOT_SUPPORTED);
  1029. }
  1030. /* horizontal size extension is 2 bits : 0 ooox xooo 0 */
  1031. comput1 = ( pVideo->hdrFirstWord & 0x180 ); // extract 2 MSb of
  1032. // horizontal picture size
  1033. pVideo->StreamInfo.horSize = pVideo->StreamInfo.horSize | ( comput1 << 3 );
  1034. /* vertical size extension is 2 bits: 00 oxxo 0 */
  1035. comput1 = ( pVideo->hdrFirstWord & 0x60 ); // extract 2 MSb of
  1036. // vertical picture size
  1037. pVideo->StreamInfo.verSize = pVideo->StreamInfo.verSize | ( comput1 << 5 );
  1038. /* bit rate extension is 12 bits: 00 ooox X + X xxxo 00 */
  1039. temp = ( pVideo->hdrFirstWord & 0x1F ) << 25;
  1040. ReadHeaderDataFifo ();
  1041. temp = ( ( pVideo->hdrFirstWord & 0xFE00 ) << 9 ) | temp;
  1042. pVideo->StreamInfo.bitRate = temp | pVideo->StreamInfo.bitRate;
  1043. if ( pVideo->StreamInfo.bitRate > 37500L ) // more than 15 Mbits/s
  1044. {
  1045. if ( !pVideo->errCode )
  1046. pVideo->errCode = HIGH_BIT_RATE; // put a warning only for the eval board
  1047. SetErrorCode(ERR_BITRATE_TO_HIGH);
  1048. }
  1049. else
  1050. {
  1051. long tota = 400L;
  1052. pVideo->StreamInfo.bitRate = pVideo->StreamInfo.bitRate * tota; /* bit rate is a multiple of 400 bits/s */
  1053. }
  1054. /* marker bit: 0 ooox 00 : just skipped */
  1055. /* pVideo->vbvBufferSize_extension is 8 bits : 00 XX */
  1056. pVideo->vbvBufferSize = pVideo->vbvBufferSize | ( ( pVideo->hdrFirstWord & 0xFF ) << 10 );
  1057. // frame rate extension not tested here */
  1058. if ( pVideo->notInitDone )
  1059. {
  1060. VideoSetPictureSize ();
  1061. // BoardVideoSetDisplayMode ( (BYTE)(pVideo->StreamInfo.displayMode) );
  1062. VideoInitXY ();
  1063. pVideo->notInitDone = 0;
  1064. }
  1065. break;
  1066. // end of sequence extension field */
  1067. //**********************************************************/
  1068. // SEQUENCE DISPLAY EXTENSION */
  1069. //**********************************************************/
  1070. case SEQ_DISP: // sequence display extension
  1071. // field
  1072. pVideo->seqDispExt = 1;
  1073. /* video format is 3 bits: 00 0 xxxo : not used... */
  1074. /* colour description is 1 bit : 00 0 ooox */
  1075. if ( pVideo->hdrFirstWord & 0x1 )
  1076. {
  1077. ReadHeaderDataFifo ();
  1078. /* colour primaries is 8 bits: XX 00 : not used... */
  1079. /*
  1080. * transfer characteristics is 8 bits: 00 XX : not
  1081. * used...
  1082. */
  1083. ReadHeaderDataFifo ();
  1084. /* matrix coefficients is 8 bits: XX 00: not used... */
  1085. /*
  1086. * pan_horizontal_dimension is 14 bits: 00 XX + X xxoo
  1087. * 00
  1088. */
  1089. pVideo->StreamInfo.horDimension = ( pVideo->hdrFirstWord & 0xFF ) << 6;
  1090. ReadHeaderDataFifo ();
  1091. pVideo->StreamInfo.horDimension = pVideo->StreamInfo.horDimension | ( ( pVideo->hdrFirstWord & 0xFC00 ) >> 10 );
  1092. /* skip marker bit : 0ooxo 00 */
  1093. /*
  1094. * pan_vertical_dimension is 14 bits: 0 ooox XX + X
  1095. * xooo 00
  1096. */
  1097. pVideo->StreamInfo.verDimension = ( pVideo->hdrFirstWord & 0x1FF ) << 5;
  1098. ReadHeaderDataFifo ();
  1099. pVideo->StreamInfo.verDimension = pVideo->StreamInfo.verDimension | ( ( pVideo->hdrFirstWord & 0xF800 ) >> 11 );
  1100. }
  1101. else
  1102. {
  1103. /* pan_horizontal_dimension is 14 bits: XX X xxoo */
  1104. ReadHeaderDataFifo ();
  1105. pVideo->StreamInfo.horDimension = ( pVideo->hdrFirstWord & 0xFFFC ) >> 2;
  1106. /* skip marker bit : 00 0 ooxo */
  1107. /*
  1108. * pan_vertical_dimension is 14 bits: 00 0 ooox + XX X
  1109. * xooo
  1110. */
  1111. pVideo->StreamInfo.verDimension = ( pVideo->hdrFirstWord & 0x1 ) << 13;
  1112. ReadHeaderDataFifo ();
  1113. pVideo->StreamInfo.verDimension = pVideo->StreamInfo.verDimension | ( ( pVideo->hdrFirstWord & 0xFFF8 ) >> 3 );
  1114. }
  1115. /* pVideo->StreamInfo.horDimension and pVideo->StreamInfo.verDimension represent the area of the decoded */
  1116. /* picture that will be displayed on the full screen */
  1117. /*
  1118. * this area should be interpolated to the size of the
  1119. * display
  1120. */
  1121. /*
  1122. * this is not possible vertically. Horizontally the SRC is
  1123. * used
  1124. */
  1125. /* to deliver 720 pixels */
  1126. if ( pVideo->StreamInfo.horDimension < pVideo->StreamInfo.horSize )
  1127. {
  1128. DWORD lsr;
  1129. BYTE i;
  1130. // lsr = 256 * (pVideo->StreamInfo.horSize-4) / (display size - 1)
  1131. lsr = ( 256 * ( long ) ( pVideo->StreamInfo.horDimension - 4 ) ) / 719;
  1132. if ( lsr < 32 )
  1133. lsr = 32;
  1134. i = BoardReadVideo ( LSO );
  1135. BoardWriteVideo ( LSO, i ); // programmation of the
  1136. // SRC
  1137. BoardWriteVideo ( LSR, (BYTE)lsr );
  1138. i = BoardReadVideo ( CSO );
  1139. BoardWriteVideo ( CSO,i);
  1140. if ( !pVideo->useSRC ) // flag enabling or not the use of SRC
  1141. {
  1142. VideoSRCOn ();
  1143. }
  1144. }
  1145. break;
  1146. default: /* other extension fields are
  1147. * not tested here */
  1148. break; /* extensions related to the
  1149. * picture are tested at the end
  1150. * of the picture header */
  1151. }
  1152. }
  1153. //----------------------------------------------------------------------------
  1154. // G.O.P. START CODE
  1155. //----------------------------------------------------------------------------
  1156. /* GOP informations are extracted but not used ! */
  1157. static void NEARAPI VideoGopHeader(void)
  1158. {
  1159. WORD compute;
  1160. pVideo->hdrHours = (BYTE) ( pVideo->hdrFirstWord >> 2 ) & 0x1F; /* Skip drop frame flag */
  1161. compute = ( pVideo->hdrFirstWord << 4 ) & 0x3F;
  1162. ReadHeaderDataFifo ();
  1163. pVideo->hdrMinutes = (BYTE)(( pVideo->hdrFirstWord >> 12 ) | compute);
  1164. pVideo->hdrSeconds = (BYTE)( pVideo->hdrFirstWord >> 5 ) & 0x3F;
  1165. compute = ( pVideo->hdrFirstWord << 1 ) & 0x3F;
  1166. ReadHeaderDataFifo ();
  1167. pVideo->pictTimeCode = (BYTE)(( pVideo->hdrFirstWord >> 15 ) | compute);
  1168. if ( pVideo->StreamInfo.countGOP != 0 )
  1169. pVideo->StreamInfo.countGOP = pVideo->StreamInfo.countGOP | 0x100; /* Second Gop */
  1170. // to avoid any confusion between gops when testing the pVideo->decSlowDownral
  1171. // ref. for display
  1172. pVideo->GOPindex = pVideo->GOPindex + 0x4000;
  1173. }
  1174. //----------------------------------------------------------------------------
  1175. // PICTURE START CODE
  1176. //----------------------------------------------------------------------------
  1177. static void NEARAPI VideoPictureHeader(void)
  1178. {
  1179. WORD comput1;
  1180. DWORD temp;
  1181. // Determine which picture variable can be used to store the next
  1182. // decoding parameters.
  1183. // We use the next variable in pVideo->pictArray table, because the
  1184. // corresponding frame
  1185. // has been already displayed.
  1186. // The decoded picture buffer is not incremented if we are on a
  1187. // second field picture
  1188. // or if we have decided to skip the previous picture.
  1189. // The first_field attribute is not changed on the second field of
  1190. // 2 field pictures.
  1191. if ( ( !pVideo->skipMode ) && ( pVideo->fieldMode < 2 ) )
  1192. {
  1193. WORD i; // increment picture buffer
  1194. for ( i = 0; i < 4; i++ )
  1195. if ( pVideo->pictArray[i].tempRef == 1025 )
  1196. {
  1197. pVideo->pDecodedPict = &pVideo->pictArray[i];
  1198. break;
  1199. }
  1200. // We always initialise first_field to TOP (default for MPEG1).
  1201. // It could be changed in case of 3:2 pull-down in MPEG1
  1202. // or into the picture coding extension for MPEG2 bit stream.
  1203. pVideo->pDecodedPict->first_field = TOP;
  1204. }
  1205. pVideo->currPictCount++;
  1206. if ( pVideo->currPictCount == 6 )
  1207. {
  1208. // Unforce the border color and start displaying
  1209. pVideo->currDCF = pVideo->currDCF | 0x20;
  1210. BoardWriteVideo ( DCF, 0 );
  1211. BoardWriteVideo ( DCF + 1, (BYTE)(pVideo->currDCF));
  1212. }
  1213. // write the latest transmitted pan offsets into the new pVideo->pictArray
  1214. // variable
  1215. // those offsets may be changed in the picture pan and scan
  1216. // extension...
  1217. // for MPEG1 bit stream they remain to zero.
  1218. // if a sequence had occured since the last decoded picture the pan
  1219. // offsets are all reset to 0
  1220. if ( seq_occured )
  1221. {
  1222. pVideo->latestPanHor = 0;
  1223. pVideo->latestPanVer = 0;
  1224. }
  1225. for ( comput1 = 0; comput1 < 3; comput1++ )
  1226. {
  1227. pVideo->pDecodedPict->pan_hor_offset[comput1] = pVideo->latestPanHor;
  1228. pVideo->pDecodedPict->pan_vert_offset[comput1] = pVideo->latestPanVer;
  1229. }
  1230. seq_occured = 0;
  1231. /* start analysis of the picture header */
  1232. comput1 = pVideo->hdrFirstWord << 2;
  1233. ReadHeaderDataFifo (); /* read next 16 bits */
  1234. /* picture pVideo->decSlowDownral reference is 10 bits: 00XX + xxoo 000 */
  1235. pVideo->pDecodedPict->tempRef = comput1 | ( pVideo->hdrFirstWord >> 14 ) | pVideo->GOPindex;
  1236. /* picture type is 3 bits : ooxx xooo 00 */
  1237. pVideo->pDecodedPict->pict_type = (BYTE)( pVideo->hdrFirstWord >> 11 ) & 0x7; // set picture type of
  1238. // decoded picture
  1239. pVideo->NextInstr.Pct =(BYTE) (pVideo->pDecodedPict->pict_type)&0x3; /* Picture type in instruction register */
  1240. // Only 2 bits are stored
  1241. if ( pVideo->skipMode ) // We are on the second picture:
  1242. // the previous one will be
  1243. // skipped
  1244. pVideo->skipMode++;
  1245. else // !pVideo->skipMode. We skip a picture if
  1246. // pVideo->fastForward = 1 and on B pictures
  1247. // only
  1248. if ( pVideo->fastForward && ( pVideo->fieldMode < 2 ) )
  1249. {
  1250. pVideo->NotSkipped++;
  1251. if ( ( pVideo->pDecodedPict->pict_type == 3 ) // we are on a B picture
  1252. || ( ( pVideo->NotSkipped > 5 ) && ( pVideo->pDecodedPict->pict_type == 2 ) ) ) // we are on a P picture
  1253. // we are on a B
  1254. // picture
  1255. {
  1256. pVideo->NotSkipped = 0;
  1257. pVideo->skipMode = 1; // this picture will be skipped
  1258. }
  1259. }
  1260. /* pVideo->vbvDelay is 16 bits: O oxxx XX + X xooo OO */
  1261. comput1 = pVideo->hdrFirstWord << 5; /* VBV delay is 16 bits */
  1262. ReadHeaderDataFifo (); /* read next 16 bits */
  1263. comput1 = comput1 | ( pVideo->hdrFirstWord >> 11 );
  1264. if (( comput1 == 0 )||( comput1 >= 0x3000 ))
  1265. // 0x0 means that the pVideo->vbvDelay is not compliant with MPEG !
  1266. // 0xFFFF variable bitrate
  1267. comput1 = 0x3000; // we force it to an average
  1268. // pVideo->vbvDelay ...
  1269. temp = ( ( long ) comput1 * ( pVideo->StreamInfo.bitRate / ( 2048 ) ) ) / 90000L; /* 2048 = 8*256 ! */
  1270. if ( temp < 0x20 )
  1271. temp = 0x20;
  1272. if ( temp > 0x330 )
  1273. temp = 0x330;
  1274. pVideo->vbvDelay = (WORD)temp;
  1275. if ( !pVideo->vbvReached ) /* BBT set to vbv value for the
  1276. * first picture */
  1277. {
  1278. VideoSetBBThresh((WORD)temp);
  1279. pVideo->intMask = 0x8; /* Enable buffer full interrupts */
  1280. }
  1281. temp = 10; /* number of bits - 1 not
  1282. * analysed in pVideo->hdrFirstWord */
  1283. if ( pVideo->StreamInfo.countGOP < 0x100 ) /* To init the GOP structure */
  1284. { /* this is only done for display
  1285. * of the GOP structure */
  1286. if ( pVideo->StreamInfo.countGOP < 28 )
  1287. {
  1288. if ( pVideo->pDecodedPict->pict_type == 1 ) /* I picture */
  1289. pVideo->StreamInfo.firstGOP[pVideo->StreamInfo.countGOP] = 'I';
  1290. else if ( pVideo->pDecodedPict->pict_type == 2 ) /* P picture */
  1291. pVideo->StreamInfo.firstGOP[pVideo->StreamInfo.countGOP] = 'P';
  1292. else if ( pVideo->pDecodedPict->pict_type == 3 ) /* B picture *//* B
  1293. * picture */
  1294. pVideo->StreamInfo.firstGOP[pVideo->StreamInfo.countGOP] = 'B';
  1295. else
  1296. pVideo->StreamInfo.firstGOP[pVideo->StreamInfo.countGOP] = 'D'; /* D picture */
  1297. pVideo->StreamInfo.firstGOP[pVideo->StreamInfo.countGOP + 1] = 0;
  1298. }
  1299. pVideo->StreamInfo.countGOP++;
  1300. }
  1301. /* P or B picture forward vectors extraction */
  1302. if ( ( pVideo->pDecodedPict->pict_type == 2 ) ||
  1303. ( pVideo->pDecodedPict->pict_type == 3 ) ) /* P or B picture */
  1304. {
  1305. /* full_pixel_forward_vector is one bit: 0 oxoo 00 */
  1306. if ( ( pVideo->hdrFirstWord & 0x400 ) != 0 )
  1307. pVideo->NextInstr.Ffh = 0x8; //Msb of FFH is 1
  1308. else
  1309. pVideo->NextInstr.Ffh = 0;
  1310. /* forward_f_code is 3 bits: 0 ooxx xooo 0 */
  1311. comput1 = ( pVideo->hdrFirstWord >> 7 ) & 0x7;
  1312. pVideo->NextInstr.Ffh = (BYTE)(pVideo->NextInstr.Ffh | comput1);
  1313. temp = 6; /* number of bits - 1 not
  1314. * analysed in pVideo->hdrFirstWord */
  1315. }
  1316. /* B picture backward vector extraction */
  1317. if ( pVideo->pDecodedPict->pict_type == 3 ) /* B picture */
  1318. {
  1319. /* full_pixel_backward_vector is one bit: 00 oxoo 0 */
  1320. if ( ( pVideo->hdrFirstWord & 0x40 ) != 0 )
  1321. pVideo->NextInstr.Bfh = 0x8;// Msb of Bfh is 1
  1322. else
  1323. pVideo->NextInstr.Bfh = 0x0;// Msb of Bfh is 0
  1324. /* backward_f_code is 3 bits: 00 ooxx xooo */
  1325. comput1 = ( pVideo->hdrFirstWord >> 3 ) & 0x0007;
  1326. pVideo->NextInstr.Bfh = (BYTE)(pVideo->NextInstr.Bfh | comput1);
  1327. temp = 2; /* number of bits - 1 not analysed in pVideo->hdrFirstWord */
  1328. }
  1329. /*
  1330. * If extra informations picture follow they must be extracted from
  1331. * the header FIFO
  1332. */
  1333. /*
  1334. * it is not possible to restart the header search as the next
  1335. * header may be a picture one
  1336. */
  1337. /*
  1338. * the research of the first Slice is made by polling of the header
  1339. * fifo
  1340. */
  1341. while ( !pVideo->errCode && ( ( pVideo->hdrFirstWord & ( 1 << temp ) ) != 0 ) ) /* extra bit picture = 1 */
  1342. { /* if extra bit picture = 1 , 8 bits follow */
  1343. if ( temp <= 8 )
  1344. {
  1345. ReadHeaderDataFifo ();
  1346. temp = temp + 16;
  1347. }
  1348. temp = temp - 9; /* skip 8 bit of extra
  1349. * information picture */
  1350. } /* and next extra bit picture
  1351. * bit */
  1352. /*
  1353. * if extension or user data follow they must be extracted from the
  1354. * header
  1355. */
  1356. pVideo->hdrFirstWord = pVideo->hdrFirstWord & ( ( 1 << temp ) - 1 );
  1357. if ( pVideo->hdrFirstWord != 0 ) {/* all remaining bits should be zero */
  1358. if ( !pVideo->errCode ) {
  1359. pVideo->errCode = PICT_HEAD; /* picture header should be followed by a start code (at least slice) */
  1360. }
  1361. SetErrorCode(ERR_PICTURE_HEADER);
  1362. }
  1363. if ( temp > 7 ) /* LSbyte of pVideo->hdrFirstWord is part of the next start code */
  1364. VideoNextStartCode (1 ); // already one byte into
  1365. // pVideo->hdrFirstWord
  1366. else
  1367. VideoNextStartCode (0 );
  1368. /*
  1369. * at this point pVideo->hdrFirstWord contains the next start code value in the
  1370. * MSByte
  1371. */
  1372. while (!pVideo->errCode) {
  1373. if ( ( pVideo->hdrFirstWord & 0xFF00 ) == 0x0100 )
  1374. break; // we have reached the slice start code
  1375. else if ( ( pVideo->hdrFirstWord & 0xFF00 ) == USER )
  1376. VideoUser ();
  1377. else if ( ( pVideo->hdrFirstWord & 0xFF00 ) == EXT ) // there can be several
  1378. // extension fields
  1379. VideoPictExtensionHeader ();
  1380. else
  1381. break;
  1382. }
  1383. /*
  1384. * We have reached the first Slice start code: all parameters are
  1385. * ready for next decoding
  1386. */
  1387. /* end of picture header + picture extensions decoding */
  1388. VideoAssociatePTS ();
  1389. if ( ( !pVideo->fieldMode && ( pVideo->skipMode != 1 ) ) || ( pVideo->fieldMode && ( !pVideo->skipMode || ( pVideo->skipMode == 3 ) ) ) )
  1390. {
  1391. VideoSetRecons (); // initialise RFP, FFP and BFP
  1392. if ( ( pVideo->fieldMode == 0 ) || ( pVideo->fieldMode == 2 ) ) // we are on a frame
  1393. // picture or the first
  1394. // field of a field
  1395. // picture
  1396. VideoDisplayCtrl (); // computes the next frame to
  1397. // display
  1398. }
  1399. // implementation of 3:2 pull-down functionality on MPEG1 bit
  1400. // streams
  1401. // encoded at 23.97Hz or 24 Hz and displayed at 60 Hz.
  1402. // 3:2 pull-down on MPEG2 bit streams must be controlled with
  1403. // "repeat_first_field" bit
  1404. if ( ( !pVideo->StreamInfo.modeMPEG2 ) && ( ( pVideo->StreamInfo.frameRate == 1 ) || ( pVideo->StreamInfo.frameRate == 2 ) ) )
  1405. {
  1406. if ( pVideo->pCurrDisplay->nb_display_field == 2 )
  1407. { /* same field polarity for the
  1408. * next frame */
  1409. pVideo->pNextDisplay->nb_display_field = 3;
  1410. if ( pVideo->pCurrDisplay->first_field == TOP )
  1411. pVideo->pNextDisplay->first_field = TOP;
  1412. else
  1413. pVideo->pNextDisplay->first_field = BOT;
  1414. }
  1415. else
  1416. { // previous picture was
  1417. // displayed 3 times //
  1418. // the first field polarity is
  1419. // changing
  1420. pVideo->pNextDisplay->nb_display_field = 2;
  1421. if ( pVideo->pCurrDisplay->first_field == TOP )
  1422. pVideo->pNextDisplay->first_field = BOT;
  1423. else
  1424. pVideo->pNextDisplay->first_field = TOP;
  1425. }
  1426. }
  1427. if ( pVideo->vbvReached ) // enable next instruction if
  1428. // not skipping a picture
  1429. {
  1430. if ( !pVideo->skipMode ) // no skipped picture
  1431. {
  1432. pVideo->NextInstr.Exe = 1; // enable EXE bit
  1433. pVideo->NextInstr.Skip = 0;
  1434. pVideo->currCommand = 0; // reset skip bits
  1435. }
  1436. else if ( ( pVideo->skipMode == 2 ) && !pVideo->fieldMode )
  1437. // skip == 2: We are on the picture following a skipped one
  1438. // the instruction can be stored with associated skip bits
  1439. // in CMD
  1440. {
  1441. // HostDirectPutChar('1', BLACK, LIGHTGREEN);
  1442. pVideo->currCommand = 0x10; // pVideo->skipMode 1 picture
  1443. pVideo->NextInstr.Exe = 1; // enable EXE bit
  1444. pVideo->NextInstr.Skip = 1; // skip 1 picture
  1445. pVideo->skipMode = 0;
  1446. if ( pVideo->DecodeMode != PlayModeFast )
  1447. pVideo->fastForward = 0; /* allows to skip only one
  1448. * picture */
  1449. }
  1450. else if ( pVideo->skipMode == 3 )
  1451. {
  1452. // HostDirectPutChar('2', BLACK, LIGHTGREEN);
  1453. // we are on the picture following two skipped fields
  1454. pVideo->currCommand = 0x20; // pVideo->skipMode 2 fields
  1455. pVideo->NextInstr.Exe = 1; // enable EXE bit
  1456. pVideo->NextInstr.Skip = 2; // Skip 2 fields
  1457. pVideo->skipMode = 0;
  1458. if ( pVideo->DecodeMode != PlayModeFast)
  1459. pVideo->fastForward = 0; /* allows to skip only one
  1460. * picture */
  1461. }
  1462. /*
  1463. * store the next instruction if we are on the good field to do
  1464. * it
  1465. */
  1466. if ( ( ( pVideo->pictDispIndex >= pVideo->pCurrDisplay->nb_display_field - 1 ) && !pVideo->fieldMode )
  1467. || ( ( pVideo->fieldMode == 2 ) && ( pVideo->pictDispIndex >= pVideo->pCurrDisplay->nb_display_field - 2 ) ) )
  1468. {
  1469. if ( pVideo->pNextDisplay->first_field != pVideo->currField )
  1470. VideoWaitDec (); // this is the opposite phase:
  1471. // put decoder in wait mode
  1472. else
  1473. // store the next instruction that will be taken into
  1474. // account on the next VSYNC
  1475. VideoStoreINS (); // store next INS in case where
  1476. // enough VSYNC already occured
  1477. }
  1478. else if ( pVideo->fieldMode == 1 )
  1479. VideoStoreINS ();
  1480. }
  1481. // clear Header hit flag due to polling of extension or user bits
  1482. // after the picture start code
  1483. // but keep track of possible other interrupt
  1484. comput1 = (WORD)BoardReadVideo ( ITS ) << 8;
  1485. comput1 = ( comput1 | BoardReadVideo ( ITS + 1 ) ) & 0xFFFE; // allows to clear the
  1486. // Header hit bit
  1487. pVideo->intStatus = ( pVideo->intStatus | comput1 ) & pVideo->intMask;
  1488. }
  1489. //----------------------------------------------------------------------------
  1490. //
  1491. //----------------------------------------------------------------------------
  1492. /***************************************************************/
  1493. /* This is an extension start code following a picture */
  1494. /* In MPEG2 bit stream, this start code can be: */
  1495. /* Picture Coding (always) */
  1496. /* Quant matrix (optional) */
  1497. /* Picture Pan & Scan (optional) */
  1498. /* Picture Scalable (optional) : not tested yet */
  1499. /***************************************************************/
  1500. static void NEARAPI VideoPictExtensionHeader(void)
  1501. {
  1502. WORD comput1, i;
  1503. WORD compute; // need to be int!!
  1504. BYTE QuantTab[QUANT_TAB_SIZE];
  1505. /* extension Id is 4 bits: 00 X0 */
  1506. comput1 = pVideo->hdrFirstWord & 0xF0;
  1507. switch ( comput1 )
  1508. {
  1509. /******* picture coding extension *******/
  1510. case PICT_COD:
  1511. if ( pVideo->StreamInfo.modeMPEG2 )
  1512. {
  1513. // clear top field first,forward and backward f_code,
  1514. // motion vectors flag
  1515. pVideo->NextInstr.Tff = 0; //pVideo->nextInstr1 & 0x403E;
  1516. pVideo->NextInstr.Bfh = 0;
  1517. pVideo->NextInstr.Ffh = 0;
  1518. pVideo->NextInstr.Cmv = 0;
  1519. pVideo->NextInstr.Pst = 0;
  1520. pVideo->NextInstr.Bfv = 0;
  1521. pVideo->NextInstr.Ffv = 0;
  1522. pVideo->NextInstr.Dcp = 0;
  1523. pVideo->NextInstr.Frm = 0;
  1524. pVideo->NextInstr.Qst = 0;
  1525. pVideo->NextInstr.Azz = 0;
  1526. pVideo->NextInstr.Ivf = 0;
  1527. // forward_horizontal_f_code is 4 bits: 00 0X
  1528. comput1 = pVideo->hdrFirstWord & 0xF;
  1529. pVideo->NextInstr.Ffh = (BYTE)comput1;
  1530. // forward_vertical_f_code is 4 bits: X0 00
  1531. ReadHeaderDataFifo ();
  1532. comput1 = pVideo->hdrFirstWord & 0xF000;
  1533. comput1 = comput1 >> 12;
  1534. pVideo->NextInstr.Ffv = (BYTE)comput1;
  1535. // backward_horizontal_f_code is 4 bits: 0X 00
  1536. comput1 = pVideo->hdrFirstWord & 0xF00;
  1537. comput1 = comput1 >>8;
  1538. pVideo->NextInstr.Bfh = (BYTE)comput1;
  1539. // backward_vertical_f_code is 4bits: 00 X0
  1540. comput1 = pVideo->hdrFirstWord & 0xF0;
  1541. comput1 = comput1 >> 4;
  1542. pVideo->NextInstr.Bfv = (BYTE)comput1;
  1543. // intra DC precision is 2 bits: 00 0 xx00
  1544. comput1 = pVideo->hdrFirstWord & 0x0C;
  1545. if ( comput1 == 0xC ) {
  1546. if ( !pVideo->errCode ) {
  1547. pVideo->errCode = DC_PREC; // 11 bit DC precision
  1548. }
  1549. SetErrorCode(ERR_INTRA_DC_PRECISION);
  1550. }
  1551. pVideo->NextInstr.Dcp = (BYTE)( comput1 >> 2 );
  1552. // picture structure is 2 bits: 00 0 ooxx
  1553. pVideo->pDecodedPict->pict_struc = (BYTE)(pVideo->hdrFirstWord & 0x3);
  1554. pVideo->NextInstr.Pst = pVideo->pDecodedPict->pict_struc ;
  1555. if ( pVideo->pDecodedPict->pict_struc == 3 ) // frame picture
  1556. pVideo->fieldMode = 0;
  1557. else // field picture
  1558. if ( pVideo->fieldMode == 2 )
  1559. pVideo->fieldMode = 1; // second field
  1560. else
  1561. {
  1562. pVideo->fieldMode = 2; // first field
  1563. if ( pVideo->pDecodedPict->pict_struc == 2 ) // bottom field is the
  1564. // first field
  1565. pVideo->pDecodedPict->first_field = BOT;
  1566. }
  1567. ReadHeaderDataFifo ();
  1568. // top_field_first bit is one bit: xooo 0 00
  1569. // first_field is already initialised to TOP (beginning
  1570. // of picture header)
  1571. if ( ( !pVideo->StreamInfo.progSeq ) && ( pVideo->pDecodedPict->pict_struc == 3 ) )
  1572. { // this is an interlaced frame
  1573. // picture
  1574. if ( ( ( pVideo->hdrFirstWord & 0x8000 ) != 0 ) ) // top field first
  1575. pVideo->NextInstr.Tff = 1; // set top_field_first
  1576. else // top_field_first already reset
  1577. // into pVideo->NextInstr
  1578. pVideo->pDecodedPict->first_field = BOT; // bottom field is BOT
  1579. // field
  1580. }
  1581. if ( pVideo->vbvReached == 0 ) // pre-initialise for start of
  1582. // the first decoding task
  1583. { // on the good field polarity
  1584. pVideo->pictArray[0].first_field = pVideo->pDecodedPict->first_field;
  1585. pVideo->pictArray[1].first_field = pVideo->pDecodedPict->first_field;
  1586. pVideo->pictArray[2].first_field = pVideo->pDecodedPict->first_field;
  1587. pVideo->pictArray[3].first_field = pVideo->pDecodedPict->first_field;
  1588. }
  1589. // frame_pred_frame_DCT is one bit: oxoo 0 00
  1590. if ( ( pVideo->hdrFirstWord & 0x4000 ) != 0 )
  1591. pVideo->NextInstr.Frm = 1 ; // frame DCT and 16x16
  1592. // prediction
  1593. // concealment_motion_vectors flag is one bit: ooxo 0
  1594. // 00
  1595. if ( pVideo->hdrFirstWord & 0x2000 )
  1596. pVideo->NextInstr.Cmv = 1;
  1597. // qscale_type is one bit: ooox 0 00
  1598. if ( ( pVideo->hdrFirstWord & 0x1000 ) != 0 )
  1599. pVideo->NextInstr.Qst = 1; // non linear quantizer
  1600. // scale
  1601. // intra_vlc_format is one bit: 0 xooo 00
  1602. if ( ( pVideo->hdrFirstWord & 0x800 ) != 0 )
  1603. pVideo->NextInstr.Ivf = 1; // alternative intra VLC
  1604. // table
  1605. // alternate scan bit: 0 oxoo 00
  1606. if ( ( pVideo->hdrFirstWord & 0x400 ) != 0 )
  1607. pVideo->NextInstr.Azz = 1; // alternative scan
  1608. // repeat_first_field is one bit: 0 ooxo 00
  1609. // A 2 field picture is considered as one picture
  1610. // displayed twice
  1611. pVideo->pDecodedPict->nb_display_field = 2; // display picture
  1612. // during 2 fields
  1613. // period
  1614. if ( pVideo->pDecodedPict->pict_struc == 3 ) // frame picture
  1615. {
  1616. if ( pVideo->hdrFirstWord & 0x200 ) // repeat first field
  1617. pVideo->pDecodedPict->nb_display_field = 3; // display picture
  1618. // during 3 fields
  1619. // period
  1620. }
  1621. // chroma_postprocessing_type is one bit: 0 ooox 00
  1622. if ( ( pVideo->hdrFirstWord & 0x100 ) )
  1623. {
  1624. // use the field repeat mode for chroma vertical
  1625. // filter (if enabled)
  1626. pVideo->fullVerFilter = pVideo->fullVerFilter | 0x2;
  1627. pVideo->currDCF = pVideo->currDCF | 0x2;
  1628. }
  1629. else
  1630. {
  1631. // use the line repeat mode for chroma vertical
  1632. // filter (if enabled)
  1633. pVideo->fullVerFilter = pVideo->fullVerFilter & 0xFFFD;
  1634. pVideo->currDCF = pVideo->currDCF & 0xFFFD;
  1635. }
  1636. BoardWriteVideo ( DCF, 0 );
  1637. BoardWriteVideo ( DCF + 1, (BYTE)(pVideo->currDCF));
  1638. // progressive_frame is one bit: 00 xooo 0
  1639. // composite_display_flag is one bit: 00 oxoo 0
  1640. if ( pVideo->hdrFirstWord & 0x40 )
  1641. {
  1642. // v_axis is one bit: 00 ooxo 0
  1643. // field_sequence is 3 bits: 00 ooox xxoo
  1644. // sub_carrier is one bit: 00 0 ooxo
  1645. ReadHeaderDataFifo ();
  1646. // burst_amplitude is 7 bit: 00 0 ooox + X xooo 00
  1647. // sub_carrier_phase is 8 bits: 0 oxxx X xooo
  1648. // check the 3 lsb of pVideo->hdrFirstWord: next info must be a
  1649. // start code
  1650. if ( pVideo->hdrFirstWord & 0x7 ) {
  1651. if ( !pVideo->errCode ) {
  1652. pVideo->errCode = PICT_HEAD;
  1653. }
  1654. SetErrorCode(ERR_PICTURE_HEADER);
  1655. }
  1656. VideoNextStartCode (0 );
  1657. }
  1658. else
  1659. {
  1660. if ( pVideo->hdrFirstWord & 0x3F ) {
  1661. if ( !pVideo->errCode )
  1662. pVideo->errCode = PICT_HEAD;
  1663. SetErrorCode(ERR_PICTURE_HEADER);
  1664. }
  1665. VideoNextStartCode (0 );
  1666. }
  1667. } // end of if pVideo->StreamInfo.modeMPEG2
  1668. break;
  1669. /******* Quantization table extension *******/
  1670. case QUANT_EXT:
  1671. /* load_intra_quantizer_matrix is one bit: 00 0 xooo */
  1672. if ( ( pVideo->hdrFirstWord & 0x8 ) != 0 )
  1673. { /* Load intra quantizer matrix */
  1674. /* two quant values are 16 bits: 00 0 oxxx + XX X xooo */
  1675. // Read Non Default Intra Quant Table
  1676. for ( i = 0; i < (QUANT_TAB_SIZE/2) ; i++)
  1677. {
  1678. compute = pVideo->hdrFirstWord << 13;
  1679. ReadHeaderDataFifo ();
  1680. compute = compute | ( pVideo->hdrFirstWord >> 3 );
  1681. QuantTab[2*i] = (BYTE)( compute >> 8 );
  1682. QuantTab[2*i+1] = (BYTE)( compute & 0xFF );
  1683. }
  1684. // Load Intra Quant Tables
  1685. VideoLoadQuantTables(TRUE , QuantTab );
  1686. pVideo->defaultTbl = pVideo->defaultTbl & 0xE; // bit 0 = 0 : no default table
  1687. // in the chip */
  1688. }
  1689. /* load_non_intra_quantizer_matrix is one bit: 00 0 oxoo */
  1690. if ( ( pVideo->hdrFirstWord & 0x4 ) != 0 )
  1691. { /* Load non intra quantizer matrix */
  1692. // Read Non Default Non Intra Quant Table
  1693. for ( i = 0; i < (QUANT_TAB_SIZE/2) ; i++)
  1694. {
  1695. compute = pVideo->hdrFirstWord << 14;
  1696. ReadHeaderDataFifo ();
  1697. compute = compute | ( pVideo->hdrFirstWord >> 2 );
  1698. QuantTab[2*i] = (BYTE)( compute >> 8 );
  1699. QuantTab[2*i+1] = (BYTE)( compute & 0xFF );
  1700. }
  1701. // Load Non Intra Quant Tables
  1702. VideoLoadQuantTables(FALSE , QuantTab );
  1703. pVideo->defaultTbl = pVideo->defaultTbl & 0xD; /* bit 1 = 0 : no default
  1704. * non-intra matrix */
  1705. }
  1706. // check the 2 lsb of pVideo->hdrFirstWord: next info must be a start
  1707. // code
  1708. if ( pVideo->hdrFirstWord & 0x3 ) {
  1709. if ( !pVideo->errCode )
  1710. pVideo->errCode = PICT_HEAD;
  1711. SetErrorCode(ERR_PICTURE_HEADER);
  1712. }
  1713. VideoNextStartCode (0 );
  1714. break;
  1715. /******* picture pan and scan extension *******/
  1716. case PICT_PSV:
  1717. /**************************************************************/
  1718. /* The programmation of the STi3500 offsets is given by: */
  1719. /* PSV = integer part of (pVideo->StreamInfo.horSize/2 - pVideo->StreamInfo.horDimension/2 + offset) */
  1720. /*
  1721. * LSO = fractional part of (pVideo->StreamInfo.horSize/2 - pVideo->StreamInfo.horDimension/2 +
  1722. * offset)
  1723. */
  1724. /**************************************************************/
  1725. /* pan_horizontal_offset_integer is 12 bits: 00 0X + XX 00 */
  1726. pVideo->latestPanHor = ( pVideo->hdrFirstWord & 0xF ) << 12;
  1727. ReadHeaderDataFifo();
  1728. pVideo->latestPanHor = pVideo->latestPanHor | ( ( pVideo->hdrFirstWord & 0xFF00 ) >> 4 );
  1729. // pan_horizontal_offset has been multiplied by 16
  1730. /* pan_horizontal_offset_sub_pixel is 4 bits: 00 X0 */
  1731. /* that are concatenated with the integer part */
  1732. pVideo->latestPanHor = pVideo->latestPanHor | ( ( pVideo->hdrFirstWord & 0xF0 ) >> 4 );
  1733. // to simplify, the 2 last instructions can be concatenated
  1734. // in:
  1735. // pVideo->latestPanHor = pVideo->latestPanHor | ((pVideo->hdrFirstWord & 0xFFF0)
  1736. // >> 4);
  1737. // note that pVideo->latestPanHor is a signed int
  1738. // marker bit 00 0 xooo: just skipped
  1739. /*
  1740. * pan_vertical_offset_integer is 12 bits: 00 0oxxx + XX
  1741. * xooo0
  1742. */
  1743. pVideo->latestPanVer = ( pVideo->hdrFirstWord & 0x7 ) << 13;
  1744. ReadHeaderDataFifo ();
  1745. /* pan_vertical_offset_sub_pixel is 4 bits: 00 oxxx xooo */
  1746. // they are linked with the integer part
  1747. pVideo->latestPanVer = pVideo->latestPanVer | ( ( pVideo->hdrFirstWord & 0xFFF8 ) >> 3 );
  1748. // write pan vectors into the decoded picture structure
  1749. if ( ( pVideo->fieldMode == 0 ) || ( pVideo->fieldMode == 2 ) ) // frame picture or
  1750. // first field
  1751. {
  1752. pVideo->pDecodedPict->pan_hor_offset[0] = pVideo->latestPanHor;
  1753. pVideo->pDecodedPict->pan_vert_offset[0] = pVideo->latestPanVer;
  1754. }
  1755. else
  1756. { // the offset of second field of
  1757. // a field picture is stored
  1758. // // on the second offset
  1759. // position of the same variable
  1760. pVideo->pDecodedPict->pan_hor_offset[1] = pVideo->latestPanHor;
  1761. pVideo->pDecodedPict->pan_vert_offset[1] = pVideo->latestPanVer;
  1762. }
  1763. // marker bit 00 0 oxoo
  1764. if ( pVideo->StreamInfo.progSeq ) // a progressive sequence is
  1765. // always displayed with the
  1766. // same pan and scan offset
  1767. {
  1768. pVideo->pDecodedPict->pan_hor_offset[1] = pVideo->latestPanHor;
  1769. pVideo->pDecodedPict->pan_vert_offset[1] = pVideo->latestPanVer;
  1770. pVideo->pDecodedPict->pan_hor_offset[2] = pVideo->latestPanHor;
  1771. pVideo->pDecodedPict->pan_vert_offset[2] = pVideo->latestPanVer;
  1772. if ( pVideo->hdrFirstWord & 0x3 ) {
  1773. if ( !pVideo->errCode )
  1774. pVideo->errCode = PICT_HEAD;
  1775. SetErrorCode(ERR_PICTURE_HEADER);
  1776. }
  1777. VideoNextStartCode (0);
  1778. }
  1779. else if ( !pVideo->StreamInfo.progSeq && ( pVideo->pDecodedPict->pict_struc == 3 ) )
  1780. // Frame picture, not progressive sequence: 2 or 3 pan
  1781. // offsets
  1782. {
  1783. // extract second pan and scan offset
  1784. /*
  1785. * pan_horizontal_offset_integer is 12 bits: 00 0ooxx +
  1786. * XX xxoo0
  1787. */
  1788. pVideo->latestPanHor = ( pVideo->hdrFirstWord & 0x3 ) << 14;
  1789. ReadHeaderDataFifo ();
  1790. pVideo->latestPanHor = pVideo->latestPanHor | ( ( pVideo->hdrFirstWord & 0xFFC0 ) >> 2 );
  1791. // pan_horizontal_offset has been multiplied by 16
  1792. /*
  1793. * pan_horizontal_offset_sub_pixel is 4 bits: 00 ooxx
  1794. * xxoo
  1795. */
  1796. /* that are concatenated with the integer part */
  1797. pVideo->latestPanHor = pVideo->latestPanHor | ( ( pVideo->hdrFirstWord & 0x3C ) >> 2 );
  1798. pVideo->pDecodedPict->pan_hor_offset[1] = pVideo->latestPanHor;
  1799. // marker bit 00 0 ooxo
  1800. /*
  1801. * pan_vertical_offset_integer is 12 bits: 00 0ooox +
  1802. * XX xxxo0
  1803. */
  1804. pVideo->latestPanVer = ( pVideo->hdrFirstWord & 0x1 ) << 15;
  1805. ReadHeaderDataFifo ();
  1806. /*
  1807. * pan_vertical_offset_sub_pixel is 4 bits: 00 ooox
  1808. * xxxo
  1809. */
  1810. // concatenated with the integer part
  1811. pVideo->latestPanVer = pVideo->latestPanVer | ( ( pVideo->hdrFirstWord & 0xFFFE ) >> 1 );
  1812. pVideo->pDecodedPict->pan_vert_offset[1] = pVideo->latestPanVer;
  1813. // marker bit 00 0 ooox
  1814. if ( pVideo->pDecodedPict->nb_display_field != 3 )
  1815. VideoNextStartCode (0);
  1816. else
  1817. { // 3 pan & scan offsets
  1818. /* pan_horizontal_offset_integer is 12 bits: XX X0 */
  1819. /* pan_horizontal_offset_sub_pixel is 4 bits: 00 0X */
  1820. /* they are concatenated in a single word */
  1821. ReadHeaderDataFifo ();
  1822. pVideo->latestPanHor = pVideo->hdrFirstWord;
  1823. pVideo->pDecodedPict->pan_hor_offset[2] = pVideo->latestPanHor;
  1824. ReadHeaderDataFifo ();
  1825. // marker bit xooo0 00
  1826. /*
  1827. * pan_vertical_offset_integer is 12 bits: oxxx X X
  1828. * xooo
  1829. */
  1830. /*
  1831. * pan_vertical_offset_sub_pixel is 4 bits: 00 0
  1832. * oxxx + xooo 0 00
  1833. */
  1834. pVideo->latestPanVer = ( pVideo->hdrFirstWord & 0x7FFF ) << 1;
  1835. ReadHeaderDataFifo ();
  1836. pVideo->latestPanVer = ( pVideo->hdrFirstWord & 0x8000 ) >> 15;
  1837. pVideo->pDecodedPict->pan_vert_offset[2] = pVideo->latestPanVer;
  1838. // marker bit oxoo 0 00
  1839. if ( pVideo->hdrFirstWord & 0x3FFF ) {
  1840. if ( !pVideo->errCode )
  1841. pVideo->errCode = PICT_HEAD;
  1842. SetErrorCode(ERR_PICTURE_HEADER);
  1843. }
  1844. VideoNextStartCode (1);
  1845. }
  1846. }
  1847. break;
  1848. /******* picture scalable extension *******/
  1849. case PICT_SCAL:
  1850. pVideo->hdrFirstWord = 0x0100; // not supported: just leave the
  1851. // test
  1852. break;
  1853. /******* other extension start codes *******/
  1854. default:
  1855. if ( !pVideo->errCode )
  1856. pVideo->errCode = BAD_EXT; // extension start code not at the good location !!
  1857. SetErrorCode(ERR_BAD_EXTENSION_SC);
  1858. break;
  1859. } // end of switch
  1860. }
  1861. //----------------------------------------------------------------------------
  1862. // USER HEADER routine
  1863. //----------------------------------------------------------------------------
  1864. /* this routine just bypasses all the bytes of the user header */
  1865. /* and is exit with the next start code value into pVideo->hdrFirstWord XX00 */
  1866. static void NEARAPI VideoUser(void)
  1867. {
  1868. DWORD toto;
  1869. WORD i;
  1870. toto = pVideo->hdrFirstWord << 16;
  1871. ReadHeaderDataFifo ();
  1872. toto = toto | pVideo->hdrFirstWord;
  1873. while ( ( ( toto & 0x00FFFFFFL ) != 0x00000001L ) &&
  1874. ( ( toto & 0xFFFFFF00L ) != 0x00000100L ) )
  1875. {
  1876. toto = toto << 16;
  1877. ReadHeaderDataFifo ();
  1878. toto = toto | pVideo->hdrFirstWord;
  1879. }
  1880. if ( ( toto & 0x00FFFFFFL ) == 0x00000001L )
  1881. ReadHeaderDataFifo ();
  1882. else
  1883. { // pVideo->hdrFirstWord == 01XX
  1884. if ( !pVideo->hdrPos ) // there is nothing into pVideo->hdrNextWord
  1885. {
  1886. pVideo->hdrPos = 8;
  1887. pVideo->hdrNextWord = ( pVideo->hdrFirstWord & 0xFF ) << 8;
  1888. ReadHeaderDataFifo ();
  1889. }
  1890. else
  1891. { // pVideo->hdrPos = 8: the next
  1892. // byte is into pVideo->hdrNextWord
  1893. pVideo->hdrFirstWord = ( pVideo->hdrFirstWord << 8 ) | ( pVideo->hdrNextWord >> 8 );
  1894. pVideo->hdrPos = 0;
  1895. }
  1896. }
  1897. i = BoardReadVideo ( ITS ) << 8; // allows to clear the Header
  1898. // hit bit
  1899. i = ( i | BoardReadVideo ( ITS + 1 ) ) & 0xFFFE; // allows to clear the
  1900. // Header hit bit
  1901. pVideo->intStatus = ( pVideo->intStatus | i ) & pVideo->intMask;
  1902. }
  1903. //----------------------------------------------------------------------------
  1904. // Set next reconstructed,forward and backward frame pointer
  1905. //----------------------------------------------------------------------------
  1906. static void NEARAPI VideoSetRecons(void)
  1907. {
  1908. /************************ I or P pictures ****************************/
  1909. if ( pVideo->pDecodedPict->pict_type != 0x3 )
  1910. {
  1911. if ( pVideo->frameStoreAttr == FORWARD_PRED ) /* pVideo->frameStoreAttr is the prediction
  1912. * attribute of BUFF_A */
  1913. {
  1914. if ( pVideo->fieldMode < 2 )
  1915. pVideo->frameStoreAttr = BACKWARD_PRED;
  1916. /* Change the prediction attribute */
  1917. if ( ( pVideo->fieldMode == 0 ) || ( pVideo->fieldMode == 2 ) )
  1918. // frame picture or first field of 2 field pictures
  1919. VideoStoreRFBBuf (pVideo->BufferA, pVideo->BufferB, pVideo->BufferB );
  1920. // rfp = A, ffp = bfp = B
  1921. else // second field of 2 field
  1922. // pictures
  1923. VideoStoreRFBBuf (pVideo->BufferA, pVideo->BufferB, pVideo->BufferA );
  1924. // rfp = A, ffp = B, bfp = A
  1925. }
  1926. else
  1927. {
  1928. if ( pVideo->fieldMode < 2 ) // frame picture or 2 field
  1929. pVideo->frameStoreAttr = FORWARD_PRED;/* Change the prediction */
  1930. if ( ( pVideo->fieldMode == 0 ) || ( pVideo->fieldMode == 2 ) )
  1931. // frame picture or first field of 2 field pictures
  1932. VideoStoreRFBBuf (pVideo->BufferB, pVideo->BufferA, pVideo->BufferA );
  1933. // rfp = B, ffp = bfp = A
  1934. else // seond field of 2 field
  1935. // pictures
  1936. VideoStoreRFBBuf (pVideo->BufferB, pVideo->BufferA, pVideo->BufferB );
  1937. // rfp = B, ffp = A, bfp = B
  1938. }
  1939. }
  1940. /************************ B pictures ****************************/
  1941. else
  1942. { /* B picture */
  1943. if ( pVideo->frameStoreAttr == FORWARD_PRED )
  1944. VideoStoreRFBBuf (pVideo->BufferC, pVideo->BufferA, pVideo->BufferB );
  1945. else
  1946. VideoStoreRFBBuf ( pVideo->BufferC, pVideo->BufferB, pVideo->BufferA );
  1947. }
  1948. /*********** common for all kind of pictures *********************/
  1949. /* test if displayed frame = reconstructed frame */
  1950. if ( ( pVideo->pCurrDisplay->buffer == pVideo->pDecodedPict->buffer ) && ( pVideo->currPictCount >= 4 ) && !pVideo->fieldMode )
  1951. pVideo->NextInstr.Ovw = 1;/* overwrite mode */
  1952. else
  1953. pVideo->NextInstr.Ovw = 0;/* not overwite mode */
  1954. }
  1955. //----------------------------------------------------------------------------
  1956. // Store reconstructed,forward and backward frame pointers */
  1957. //----------------------------------------------------------------------------
  1958. static void NEARAPI VideoStoreRFBBuf (WORD rfp, WORD ffp, WORD bfp )
  1959. {
  1960. BoardWriteVideo ( RFP, (BYTE)((rfp >> 8 )));
  1961. /* Address where to decode the next frame */
  1962. BoardWriteVideo ( RFP + 1, (BYTE)((rfp & 0xFF )));
  1963. pVideo->pDecodedPict->buffer = rfp;
  1964. BoardWriteVideo ( FFP,(BYTE)(( ffp >> 8 )));
  1965. /* Used by P picture */
  1966. BoardWriteVideo ( FFP + 1, (BYTE)((ffp & 0xFF )));
  1967. BoardWriteVideo ( BFP, (BYTE)((bfp >> 8 )));
  1968. /* Used by P picture in case of dual prime */
  1969. BoardWriteVideo ( BFP + 1, (BYTE)(bfp&0xFF));
  1970. }
  1971. //----------------------------------------------------------------------------
  1972. // Routine called on each VSYNC occurence
  1973. //----------------------------------------------------------------------------
  1974. static void NEARAPI VideoVsyncRout(void)
  1975. {
  1976. WORD i;
  1977. pVideo->VsyncInterrupt = TRUE;
  1978. if ( pVideo->VideoState == StateStartup )
  1979. {
  1980. if ((VideoGetBBL()) > 2)
  1981. {
  1982. pVideo->NextInstr.Exe = 1;
  1983. pVideo->NextInstr.Seq = 1;
  1984. VideoStoreINS(); // Stores Instruction content
  1985. pVideo->VideoState = StateWaitForDTS;
  1986. pVideo->ActiveState = StateWaitForDTS;
  1987. }
  1988. return;
  1989. }
  1990. if ( pVideo->VideoState == StatePause )
  1991. return;
  1992. if ( ( !pVideo->needDataInBuff ) && ( pVideo->vbvReached == 1 ) )
  1993. {
  1994. pVideo->VsyncNumber++;
  1995. if ( pVideo->VsyncNumber > 4 * ( pVideo->decSlowDown + 1 ) )
  1996. {
  1997. VideoPipeReset ();
  1998. // reset_3500();
  1999. pVideo->VsyncNumber = 0;
  2000. }
  2001. BoardWriteVideo ( DCF, 0 );
  2002. BoardWriteVideo ( DCF + 1, (BYTE)(pVideo->currDCF ));
  2003. /***** bit buffer level is high enough to continue normal decoding and display ****/
  2004. /***** count of the number of time the current picture must be displayed ****/
  2005. if ( pVideo->pictDispIndex != pVideo->pCurrDisplay->nb_display_field )
  2006. pVideo->pictDispIndex++;
  2007. if ( pVideo->pictDispIndex >= pVideo->pCurrDisplay->nb_display_field - 1 )
  2008. {
  2009. // this is the time where the next INS should be stored
  2010. // into the chip
  2011. // We verify if the VSYNC phase (cur_field) is the same
  2012. // than the first field
  2013. // of the next picture to be displayed: if this is VSYNC #
  2014. // n, the next
  2015. // decoding will start on VSYNC # n+1 (opposite phase)
  2016. // while the next frame
  2017. // display will start on VSYNC # n+2 (same phase)
  2018. /************* Youss R/2P buffer saving ***************************/
  2019. // If First Vsync after vbv is reached is of incorrect polarity,
  2020. // Program internal field inversion AND force first field to current
  2021. // field
  2022. // FistVsyncAfterVbv is a 3 state variable
  2023. // before vbv is reached FistVsyncAfterVbv = NOT_YET_VBV
  2024. // between vbv and following vsync FistVsyncAfterVbv = NOT_YET_VST
  2025. // after vsync following vbv FistVsyncAfterVbv = PAST_VBV_AND_VST
  2026. if (pVideo->FistVsyncAfterVbv == NOT_YET_VST)
  2027. {
  2028. if ( pVideo->pNextDisplay->first_field != pVideo->currField )
  2029. {
  2030. pVideo->currField = pVideo->pNextDisplay->first_field;
  2031. BoardWriteVideo(VID_LSRh, 2);// field invertion mechanism.
  2032. pVideo->InvertedField = TRUE;
  2033. }
  2034. pVideo->FistVsyncAfterVbv = PAST_VBV_AND_VST;
  2035. }
  2036. if ( pVideo->pNextDisplay->first_field != pVideo->currField )
  2037. { // this is the opposite phase
  2038. VideoWaitDec (); // put decoder in wait mode
  2039. pVideo->pictDispIndex--; // we must wait one field for
  2040. // the good phase
  2041. }
  2042. else
  2043. { // this is the good phase for
  2044. // storage
  2045. // store the next instruction that will be taken into
  2046. // account on the next BOT VSYNC
  2047. VideoStoreINS ();
  2048. if ( pVideo->VideoState == StateStep ) /* store only one
  2049. * instrcution in step
  2050. * mode */
  2051. pVideo->VideoState = StatePause;
  2052. }
  2053. }
  2054. // the current frame pointer has not been displayed enough
  2055. // times
  2056. // to start the decoding of the next frame
  2057. else // pVideo->pictDispIndex <
  2058. { // pVideo->pCurrDisplay->nb_display_fi
  2059. // eld - 1
  2060. VideoWaitDec (); // put decoder in Wait mode
  2061. }
  2062. /* pan & scan vector has to be updated on each new VSYNC */
  2063. VideoSetPSV (); // store PSV for next field and
  2064. // LSO for current one
  2065. } // end of if(!empty)
  2066. else
  2067. /*** bit buffer level was not high enough to continue normal decoding *****/
  2068. /*** decoder has been stopped during PSD interrupt. It will be re-enabled */
  2069. /*** on the good VSYNC if the bit buffer level is high enough. ****/
  2070. /*** Polarity of the VSYNC on which the decoder was stopped is into empty */
  2071. if ( pVideo->needDataInBuff == (WORD)(pVideo->currField))
  2072. {
  2073. /* This is the good VSYNC phase to restart decoding */
  2074. /* verification of the bit buffer level before restarting */
  2075. /* the decoder has been stopped for at least two VSYNC */
  2076. i = VideoGetBBL();
  2077. if ( i >= pVideo->vbvDelay )
  2078. {
  2079. // BBL is high enough to restart
  2080. // "enable decoding" bit
  2081. VideoEnableDecoding(ON);
  2082. pVideo->needDataInBuff = 0;
  2083. }
  2084. }
  2085. }
  2086. //----------------------------------------------------------------------------
  2087. //
  2088. //----------------------------------------------------------------------------
  2089. static void NEARAPI VideoChooseField(void)
  2090. {
  2091. BYTE dcf0, dcf1, bfs=0;
  2092. // to avoid flicker with slow motion or step by step, the top field is displayed
  2093. // half of the time of the picture, and then the bottom field is displayed
  2094. if ( ( pVideo->decSlowDown ) || ( pVideo->VideoState == StatePause )||(pVideo->perFrame == TRUE ))
  2095. {
  2096. bfs = BoardReadVideo(CFG_BFS)&0x3F;// To check if B frame optimization is on
  2097. dcf0 = BoardReadVideo ( DCF );
  2098. dcf1 = BoardReadVideo ( DCF + 1 );
  2099. if ( pVideo->HalfRes == FALSE ) /* full resolution
  2100. * picture = 2 fields */
  2101. {
  2102. dcf1 |= 0x80;
  2103. if ( ( ( ( ( pVideo->pictDispIndex + pVideo->decSlowDown ) > 0x7fff ) || ( pVideo->pictDispIndex == 1 ) ) && ( pVideo->VideoState != StatePause ) )
  2104. || ( ( pVideo->VideoState == StatePause ) && ( !pVideo->displaySecondField ) ) )
  2105. {
  2106. /* display first field in two cases */
  2107. /* - first half of the pVideo->decSlowDownrisation time */
  2108. /* - first step() pVideo->currCommand */
  2109. if ( pVideo->pCurrDisplay->first_field == TOP )
  2110. { /* first field = TOP field */
  2111. if(!bfs)
  2112. BoardWriteVideo ( DCF, 0x4 );//FRZ set for STi3520A
  2113. else
  2114. BoardWriteVideo ( DCF, 0x15 );//FRZ set for STi3520A
  2115. BoardWriteVideo ( DCF + 1, dcf1);
  2116. }
  2117. else
  2118. { /* first field = BOT field */
  2119. if(!bfs)
  2120. BoardWriteVideo ( DCF, 0x5 );
  2121. else
  2122. BoardWriteVideo ( DCF, 0x14 );//FRZ set for STi3520A
  2123. BoardWriteVideo ( DCF + 1, dcf1);
  2124. }
  2125. }
  2126. else
  2127. {
  2128. /* display second field in two cases */
  2129. /* - second half of the pVideo->decSlowDownrisation time */
  2130. /* - second step() pVideo->currCommand */
  2131. if ( pVideo->pCurrDisplay->first_field == TOP )
  2132. {
  2133. if(!bfs)
  2134. BoardWriteVideo ( DCF, 0x5);
  2135. else
  2136. BoardWriteVideo ( DCF, 0x15 );//FRZ set for STi3520A
  2137. BoardWriteVideo ( DCF + 1, dcf1);
  2138. }
  2139. else
  2140. {
  2141. if(!bfs)
  2142. BoardWriteVideo ( DCF, 0x4);
  2143. else
  2144. BoardWriteVideo ( DCF, 0x14 );//FRZ set for STi3520A
  2145. BoardWriteVideo ( DCF + 1, dcf1);
  2146. }
  2147. }
  2148. }
  2149. }
  2150. }
  2151. static BOOL NEARAPI IsChipSTi3520(void)
  2152. {
  2153. //---- Write STi3520 DCF register to 0
  2154. BoardWriteVideo(0x78, 0);
  2155. BoardWriteVideo(0x79, 0);
  2156. //---- Read back DCF MSByte
  2157. if (BoardReadVideo(0x78) != 0)
  2158. return FALSE; // we have red STi3520A VID_REV register
  2159. else
  2160. return TRUE; // we have red STi3520 DCF register
  2161. }
  2162. //----------------------------------------------------------------------------
  2163. //
  2164. //----------------------------------------------------------------------------
  2165. WORD FARAPI SendAudioIfPossible(LPBYTE pBuffer, WORD Size)
  2166. {
  2167. if ( AudioIsEnoughPlace(Size)) {
  2168. BoardSendAudio(pBuffer, Size);
  2169. return Size;
  2170. }
  2171. return 0;
  2172. }
  2173. //----------------------------------------------------------------------------
  2174. //
  2175. //----------------------------------------------------------------------------
  2176. WORD FARAPI SendAudioToVideoIfPossible(LPBYTE Buffer, WORD Size)
  2177. {
  2178. if ( AudioIsEnoughPlace(Size)) {
  2179. BoardSendVideo((WORD *)Buffer, Size);// Here in case of system stream
  2180. // We send audio through Video Strabe
  2181. return Size;
  2182. }
  2183. return 0;
  2184. }
  2185. //----------------------------------------------------------------------------
  2186. //
  2187. //----------------------------------------------------------------------------
  2188. static void NEARAPI VideoSetABStart(WORD abg)
  2189. {
  2190. BoardWriteVideo ( AUD_ABG, (BYTE)(abg >> 8));// Initiate Write to Command
  2191. BoardWriteVideo ( AUD_ABG + 1,(BYTE)(abg & 0xFF));
  2192. }
  2193. //----------------------------------------------------------------------------
  2194. //
  2195. //----------------------------------------------------------------------------
  2196. WORD FARAPI VideoGetABL(void)
  2197. {
  2198. WORD i;
  2199. HostDisableIT();
  2200. i = (WORD)( BoardReadVideo ( AUD_ABL ) & 0x3F ) << 8;
  2201. i = i | (WORD)( BoardReadVideo ( AUD_ABL + 1 ) );
  2202. HostEnableIT();
  2203. return ( i );
  2204. }
  2205. //----------------------------------------------------------------------------
  2206. //
  2207. //----------------------------------------------------------------------------
  2208. static void NEARAPI VideoSetABStop(WORD abs)
  2209. {
  2210. BoardWriteVideo ( AUD_ABS, (BYTE)(abs >> 8 ));// Initiate Write to Command
  2211. BoardWriteVideo ( AUD_ABS + 1,(BYTE)(abs & 0xFF));
  2212. }
  2213. //----------------------------------------------------------------------------
  2214. //
  2215. //----------------------------------------------------------------------------
  2216. static void NEARAPI VideoSetABThresh(WORD abt)
  2217. {
  2218. BoardWriteVideo ( AUD_ABT, (BYTE)(abt >> 8));// Initiate Write to Command
  2219. BoardWriteVideo ( AUD_ABT + 1,(BYTE)(abt & 0xFF));
  2220. }
  2221. //----------------------------------------------------------------------------
  2222. //
  2223. //----------------------------------------------------------------------------
  2224. WORD FARAPI SendVideoIfPossible(LPBYTE Buffer, WORD Size)
  2225. {
  2226. if (VideoIsEnoughPlace(Size)) {
  2227. BoardSendVideo((WORD *)Buffer, Size);
  2228. return Size;
  2229. }
  2230. return 0;
  2231. }
  2232. //----------------------------------------------------------------------------
  2233. //
  2234. //----------------------------------------------------------------------------
  2235. static void NEARAPI VideoSetBBStart(WORD bbg)
  2236. {
  2237. pVideo = pVideo;
  2238. BoardWriteVideo ( VID_VBG, (BYTE)(bbg >> 8));// Initiate Write to Command
  2239. BoardWriteVideo ( VID_VBG + 1,(BYTE)(bbg & 0xFF));
  2240. }
  2241. //----------------------------------------------------------------------------
  2242. //
  2243. //----------------------------------------------------------------------------
  2244. static WORD NEARAPI VideoGetBBL(void)
  2245. {
  2246. WORD i;
  2247. HostDisableIT();
  2248. i = (WORD)( BoardReadVideo ( BBL ) & 0x3F ) << 8;
  2249. i = i | (WORD)( BoardReadVideo ( BBL + 1 ) );
  2250. HostEnableIT();
  2251. return ( i );
  2252. }
  2253. //----------------------------------------------------------------------------
  2254. //
  2255. //----------------------------------------------------------------------------
  2256. static void NEARAPI VideoSetBBStop(WORD bbs)
  2257. {
  2258. BoardWriteVideo ( BBS, (BYTE)(bbs >> 8));// Initiate Write to Command
  2259. BoardWriteVideo ( BBS + 1,(BYTE)(bbs & 0xFF));
  2260. }
  2261. //----------------------------------------------------------------------------
  2262. //
  2263. //----------------------------------------------------------------------------
  2264. static void NEARAPI VideoSetBBThresh(WORD bbt)
  2265. {
  2266. BoardWriteVideo ( BBT, (BYTE)(bbt >> 8));// Initiate Write to Command
  2267. BoardWriteVideo ( BBT + 1,(BYTE)(bbt & 0xFF));
  2268. }
  2269. //----------------------------------------------------------------------------
  2270. //
  2271. //----------------------------------------------------------------------------
  2272. static WORD NEARAPI VideoBlockMove(DWORD SrcAddress, DWORD DestAddress, WORD Size)
  2273. {
  2274. WORD counter;
  2275. // set block move Size
  2276. BoardWriteVideo ( BMS , (BYTE)((Size >> 8) & 0xFF));
  2277. BoardWriteVideo ( BMS , (BYTE)(Size & 0xFF));
  2278. VideoSetMWP(DestAddress);
  2279. VideoSetMRP(SrcAddress); // Launches Block Move
  2280. counter = 0;
  2281. while ( ! VideoBlockMoveIdle() )
  2282. {
  2283. counter ++;
  2284. if(counter == 0xFFFF)
  2285. return ( BAD_MEM_V );
  2286. }
  2287. // wait for the end of the block move
  2288. return ( NO_ERROR );
  2289. }
  2290. //----------------------------------------------------------------------------
  2291. //
  2292. //----------------------------------------------------------------------------
  2293. static void NEARAPI VideoStartBlockMove(DWORD SrcAddress, DWORD DestAddress, DWORD Size)
  2294. {
  2295. SrcAddress = SrcAddress;
  2296. DestAddress = DestAddress;
  2297. Size = Size;
  2298. }
  2299. //----------------------------------------------------------------------------
  2300. //
  2301. //----------------------------------------------------------------------------
  2302. static void NEARAPI VideoCommandSkip(WORD Nbpicture)
  2303. {
  2304. if(Nbpicture > 2)
  2305. {
  2306. pVideo->errCode = ERR_SKIP;
  2307. }
  2308. else
  2309. {
  2310. }
  2311. }
  2312. //----------------------------------------------------------------------------
  2313. //
  2314. //----------------------------------------------------------------------------
  2315. static void NEARAPI VideoSetSRC(WORD SrceSize, WORD DestSize)
  2316. {
  2317. DWORD lsr;
  2318. lsr = ( 256 * ( long ) ( SrceSize - 4 ) ) / (DestSize - 1);
  2319. BoardWriteVideo ( LSO, 0 ); // programmation of the SRC
  2320. BoardWriteVideo ( LSR, (BYTE)lsr );
  2321. if(lsr > 255 )
  2322. {
  2323. BoardWriteVideo ( VID_LSRh, 1);
  2324. }
  2325. BoardWriteVideo ( CSO, 0 );
  2326. VideoSRCOn ();
  2327. }
  2328. //----------------------------------------------------------------------------
  2329. // Load Quantization Matrix
  2330. //----------------------------------------------------------------------------
  2331. static void NEARAPI VideoLoadQuantTables(BOOL Intra,BYTE * Table )
  2332. {
  2333. WORD i; // loop counter
  2334. // Select Intra / Non Intra Table
  2335. if(Intra)
  2336. BoardWriteVideo(VID_HDS,QMI);
  2337. else
  2338. BoardWriteVideo(VID_HDS,(0&~QMI));
  2339. // Load Table
  2340. for (i = 0 ; i < QUANT_TAB_SIZE ; i++)
  2341. BoardWriteVideo(VID_QMW,Table[i]);
  2342. // Lock Table Again
  2343. BoardWriteVideo(VID_HDS,0);
  2344. }
  2345. //----------------------------------------------------------------------------
  2346. // Computes Instruction and stores in Ins1 Ins2 Cmd vars
  2347. //----------------------------------------------------------------------------
  2348. static void NEARAPI VideoComputeInst(void)
  2349. {
  2350. INSTRUCTION Ins = pVideo->NextInstr;// Local var.
  2351. pVideo->Ppr1 = (Ins.Pct<< 4)|(Ins.Dcp<< 2)|(Ins.Pst );
  2352. pVideo->Ppr2 = (Ins.Tff<< 5)|(Ins.Frm<<4)|(Ins.Cmv<< 3)|(Ins.Qst<< 2)|
  2353. (Ins.Ivf<< 1)|(Ins.Azz );
  2354. pVideo->Tis = (Ins.Mp2<< 6)|(Ins.Skip<< 4)|(Ins.Ovw<< 3)|(Ins.Rpt<< 1)|
  2355. (Ins.Exe );
  2356. pVideo->Pfh = (Ins.Bfh<< 4)|(Ins.Ffh );
  2357. pVideo->Pfv = (Ins.Bfv<< 4)|(Ins.Ffv );
  2358. }
  2359. //----------------------------------------------------------------------------
  2360. // put the decoder into WAIT mode
  2361. //----------------------------------------------------------------------------
  2362. /* This routine actually clears all bits of INS1/TIS registers
  2363. This is not a problem since the whole registers HAVE to
  2364. be rewritten when storing a new instruction. */
  2365. static void NEARAPI VideoWaitDec (void)
  2366. {
  2367. BoardWriteVideo ( VID_TIS, 0 );
  2368. VideoChooseField();// If Step by step decoding, set freeze bit
  2369. }
  2370. //----------------------------------------------------------------------------
  2371. // Routine storing pVideo->nextInstr1 and 2 into the instruction registers
  2372. //----------------------------------------------------------------------------
  2373. static void NEARAPI VideoStoreINS (void)
  2374. {
  2375. VideoComputeInst() ;
  2376. BoardWriteVideo ( VID_TIS , pVideo->Tis );
  2377. BoardWriteVideo ( VID_PPR1, pVideo->Ppr1 );
  2378. BoardWriteVideo ( VID_PPR2, pVideo->Ppr2 );
  2379. BoardWriteVideo ( VID_PFV , pVideo->Pfv );
  2380. BoardWriteVideo ( VID_PFH , pVideo->Pfh );
  2381. }
  2382. //----------------------------------------------------------------------------
  2383. // Routine reading the number of bytes loaded in the CD_FIFO
  2384. //----------------------------------------------------------------------------
  2385. static DWORD NEARAPI ReadCDCount (void)
  2386. {
  2387. DWORD cd;
  2388. HostDisableIT();
  2389. cd = ((DWORD)(BoardReadVideo(CDcount)&0xFF))<<16;
  2390. cd |= ((DWORD)(BoardReadVideo(CDcount)&0xFF))<<8;
  2391. cd |= (DWORD)(BoardReadVideo(CDcount)&0xFF);
  2392. HostEnableIT( );
  2393. return ( cd );
  2394. }
  2395. //----------------------------------------------------------------------------
  2396. // Routine reading the number of bytes extracted by the SCD
  2397. //----------------------------------------------------------------------------
  2398. static DWORD NEARAPI ReadSCDCount (void)
  2399. {
  2400. DWORD Scd;
  2401. HostDisableIT ( );
  2402. Scd = ((DWORD)(BoardReadVideo(SCDcount)&0xFF))<<16;
  2403. Scd |= ((DWORD)(BoardReadVideo(SCDcount)&0xFF))<<8;
  2404. Scd |= (DWORD)(BoardReadVideo(SCDcount)&0xFF);
  2405. HostEnableIT ( );
  2406. return ( Scd );
  2407. }
  2408. //----------------------------------------------------------------------------
  2409. // DRAM I/O
  2410. //----------------------------------------------------------------------------
  2411. static void NEARAPI VideoSetMWP(DWORD mwp)
  2412. {
  2413. BYTE m0, m1, m2;
  2414. m0 = (BYTE)( (mwp >> 14) & 0xFF );
  2415. m1 = (BYTE)( (mwp >> 6) & 0xFF );
  2416. m2 = (BYTE)( (mwp << 2) & 0xFF );
  2417. BoardWriteVideo(MWP , m0);
  2418. BoardWriteVideo(MWP , m1);
  2419. BoardWriteVideo(MWP , m2);
  2420. }
  2421. //----------------------------------------------------------------------------
  2422. //
  2423. //----------------------------------------------------------------------------
  2424. static void NEARAPI VideoSetMRP(DWORD mrp)
  2425. {
  2426. BYTE m0, m1, m2;
  2427. m0 = (BYTE)( (mrp >> 14) & 0xFF );
  2428. m1 = (BYTE)( (mrp >> 6) & 0xFF );
  2429. m2 = (BYTE)( (mrp << 2) & 0xFF );
  2430. BoardWriteVideo(MRP , m0);
  2431. BoardWriteVideo(MRP , m1);
  2432. BoardWriteVideo(MRP , m2);
  2433. }
  2434. //----------------------------------------------------------------------------
  2435. //
  2436. //----------------------------------------------------------------------------
  2437. static BOOL NEARAPI VideoMemWriteFifoEmpty( void )
  2438. {
  2439. return ( (BoardReadVideo ( STA ) & 0x4) );
  2440. }
  2441. //----------------------------------------------------------------------------
  2442. //
  2443. //----------------------------------------------------------------------------
  2444. static BOOL NEARAPI VideoMemReadFifoFull( void )
  2445. {
  2446. return ( (BoardReadVideo ( STA ) & 0x8) );
  2447. }
  2448. //----------------------------------------------------------------------------
  2449. //
  2450. //----------------------------------------------------------------------------
  2451. static BOOL NEARAPI VideoHeaderFifoEmpty( void )
  2452. {
  2453. BoardReadVideo ( STA );
  2454. return ( (BoardReadVideo ( STA + 1 ) & 0x4) );
  2455. }
  2456. //----------------------------------------------------------------------------
  2457. //
  2458. //----------------------------------------------------------------------------
  2459. static BOOL NEARAPI VideoBlockMoveIdle( void )
  2460. {
  2461. return ( (BoardReadVideo ( STA ) & 0x20) );
  2462. }
  2463. //----------------------------------------------------------------------------
  2464. //
  2465. //----------------------------------------------------------------------------
  2466. static void NEARAPI VideoEnableDecoding(BOOL OnOff)
  2467. {
  2468. if(OnOff)
  2469. pVideo->Ctl |= EDC;
  2470. else
  2471. pVideo->Ctl &= ~EDC;
  2472. BoardWriteVideo(CTL , (BYTE)(pVideo->Ctl & 0xFF));
  2473. }
  2474. //----------------------------------------------------------------------------
  2475. //
  2476. //----------------------------------------------------------------------------
  2477. static void NEARAPI VideoEnableErrConc(BOOL OnOff)
  2478. {
  2479. if(OnOff)
  2480. pVideo->Ctl = (pVideo->Ctl |EPR|ERS|ERU)&~DEC;
  2481. else
  2482. pVideo->Ctl = (pVideo->Ctl&~EPR&~ERS&~ERU)|DEC;
  2483. BoardWriteVideo(CTL , (BYTE)(pVideo->Ctl & 0xFF ));
  2484. }
  2485. //----------------------------------------------------------------------------
  2486. // pipeline RESET
  2487. //----------------------------------------------------------------------------
  2488. static void NEARAPI VideoPipeReset (void)
  2489. {
  2490. pVideo->Ctl |= PRS;
  2491. BoardWriteVideo(CTL , (BYTE)(pVideo->Ctl));
  2492. Delay(1000);
  2493. pVideo->Ctl &= ~PRS;
  2494. BoardWriteVideo(CTL , (BYTE)(pVideo->Ctl));
  2495. }
  2496. //----------------------------------------------------------------------------
  2497. //
  2498. //----------------------------------------------------------------------------
  2499. static void NEARAPI VideoSoftReset (void)
  2500. {
  2501. pVideo->Ctl |= SRS;
  2502. BoardWriteVideo(CTL , (BYTE)(pVideo->Ctl));
  2503. Delay(1000);
  2504. pVideo->Ctl &= ~SRS;
  2505. BoardWriteVideo(CTL , (BYTE)(pVideo->Ctl));
  2506. }
  2507. //----------------------------------------------------------------------------
  2508. //
  2509. //----------------------------------------------------------------------------
  2510. static void NEARAPI VideoEnableInterfaces (BOOL OnOff )
  2511. {
  2512. if(OnOff)
  2513. pVideo->Ccf = pVideo->Ccf |EVI|EDI|ECK|EC2|EC3;
  2514. else
  2515. pVideo->Ccf = pVideo->Ccf&~EVI&~EDI&~ECK&~EC2&~EC3;
  2516. BoardWriteVideo(CFG_CCF, (BYTE)(pVideo->Ccf));
  2517. }
  2518. //----------------------------------------------------------------------------
  2519. //
  2520. //----------------------------------------------------------------------------
  2521. static void NEARAPI VideoPreventOvf(BOOL OnOff )
  2522. {
  2523. if(OnOff)
  2524. pVideo->Ccf = pVideo->Ccf |PBO;
  2525. else
  2526. pVideo->Ccf = pVideo->Ccf&~PBO;
  2527. BoardWriteVideo(CFG_CCF,(BYTE)(pVideo->Ccf));
  2528. }
  2529. //----------------------------------------------------------------------------
  2530. //
  2531. //----------------------------------------------------------------------------
  2532. static void NEARAPI VideoSetFullRes(void)
  2533. {
  2534. pVideo->HalfRes = FALSE;
  2535. pVideo->currDCF = pVideo->currDCF | pVideo->fullVerFilter;
  2536. BoardWriteVideo ( DCF, 0 );
  2537. BoardWriteVideo ( DCF + 1, (BYTE)(pVideo->currDCF));
  2538. }
  2539. //----------------------------------------------------------------------------
  2540. //
  2541. //----------------------------------------------------------------------------
  2542. static void NEARAPI VideoSetHalfRes(void)
  2543. {
  2544. pVideo->HalfRes = TRUE;
  2545. // No PAL optimization in Half Res
  2546. BoardWriteVideo(CFG_BFS , 0);
  2547. pVideo->currDCF = pVideo->currDCF | pVideo->halfVerFilter;
  2548. BoardWriteVideo ( DCF, 0 );
  2549. BoardWriteVideo ( DCF + 1, (BYTE)(pVideo->currDCF));
  2550. }
  2551. //----------------------------------------------------------------------------
  2552. //
  2553. //----------------------------------------------------------------------------
  2554. static void NEARAPI VideoSelect8M(BOOL OnOff)
  2555. {
  2556. if(OnOff)
  2557. pVideo->Ccf = pVideo->Ccf |M32;
  2558. else
  2559. pVideo->Ccf = pVideo->Ccf&~M32;
  2560. BoardWriteVideo(CFG_CCF, (BYTE)(pVideo->Ccf));
  2561. }
  2562. //----------------------------------------------------------------------------
  2563. // GCF1 register Routines
  2564. //----------------------------------------------------------------------------
  2565. static void NEARAPI VideoSetDramRefresh(WORD Refresh)
  2566. {
  2567. pVideo->Gcf = pVideo->Gcf |(Refresh & RFI);
  2568. BoardWriteVideo(CFG_MCF, (BYTE)(pVideo->Gcf));
  2569. }
  2570. //----------------------------------------------------------------------------
  2571. //
  2572. //----------------------------------------------------------------------------
  2573. static void NEARAPI VideoSelect20M(BOOL OnOff)
  2574. {
  2575. if(OnOff)
  2576. pVideo->Gcf = pVideo->Gcf | M20;
  2577. else
  2578. pVideo->Gcf = pVideo->Gcf &~M20;
  2579. BoardWriteVideo(CFG_MCF, (BYTE)(pVideo->Gcf));
  2580. }
  2581. //----------------------------------------------------------------------------
  2582. //
  2583. //----------------------------------------------------------------------------
  2584. static void NEARAPI VideoSetDFA(WORD dfa)
  2585. {
  2586. BoardWriteVideo(VID_DFA , (BYTE)(dfa>>8));
  2587. BoardWriteVideo(VID_DFA , (BYTE)(dfa));
  2588. }
  2589. //----------------------------------------------------------------------------
  2590. //
  2591. //----------------------------------------------------------------------------
  2592. static void NEARAPI VideoEnableDisplay(void)
  2593. {
  2594. pVideo->currDCF = pVideo->currDCF |0x20;
  2595. BoardWriteVideo ( DCF, 0 );
  2596. BoardWriteVideo ( DCF + 1, (BYTE)(pVideo->currDCF));
  2597. }
  2598. //----------------------------------------------------------------------------
  2599. //
  2600. //----------------------------------------------------------------------------
  2601. static void NEARAPI VideoDisableDisplay(void)
  2602. {
  2603. pVideo->currDCF = pVideo->currDCF &(~0x20);
  2604. BoardWriteVideo ( DCF, 0 );
  2605. BoardWriteVideo ( DCF + 1, (BYTE)(pVideo->currDCF));
  2606. }
  2607. //----------------------------------------------------------------------------
  2608. //
  2609. //----------------------------------------------------------------------------
  2610. void FARAPI VideoInitPesParser(STREAMTYPE StreamType )
  2611. {
  2612. switch(StreamType)
  2613. {
  2614. case SYSTEM_STREAM:
  2615. case VIDEO_PACKET:
  2616. case AUDIO_PACKET:
  2617. case VIDEO_PES:
  2618. case AUDIO_PES:
  2619. BoardWriteVideo( PES_VID, 0x30);
  2620. BoardWriteVideo( PES_AUD, 0x0);
  2621. break;
  2622. case DUAL_PES:
  2623. BoardWriteVideo( PES_VID, 0xB0 );
  2624. BoardWriteVideo( PES_AUD, 0X0 );
  2625. break;
  2626. case DUAL_ES:
  2627. case VIDEO_STREAM:
  2628. case AUDIO_STREAM:
  2629. BoardWriteVideo( PES_VID, 0 );
  2630. BoardWriteVideo( PES_AUD, 0 );
  2631. break;
  2632. }
  2633. }
  2634. //----------------------------------------------------------------------------
  2635. // reads PTS value from STi3520A
  2636. //----------------------------------------------------------------------------
  2637. DWORD FARAPI BoardReadVideoPTS(void)
  2638. {
  2639. DWORD pts;
  2640. pts = ( (DWORD)BoardReadVideo(PES_TS4 ) & 0xFFL ) << 24;
  2641. pts = pts | ( (DWORD)( BoardReadVideo(PES_TS3 ) & 0xFFL ) << 16);
  2642. pts = pts | ( (DWORD)( BoardReadVideo(PES_TS2 ) & 0xFFL ) << 8);
  2643. pts = pts | ( (DWORD) BoardReadVideo(PES_TS1 ) & 0xFFL );
  2644. return pts;
  2645. }
  2646. //----------------------------------------------------------------------------
  2647. // Returns TRUE if current PTS is Valid
  2648. //----------------------------------------------------------------------------
  2649. BOOL FARAPI VideoIsValidPTS(void)
  2650. {
  2651. if( BoardReadVideo(PES_TS5 ) & 0x2 ) // read TSA bit
  2652. return TRUE;
  2653. }
  2654. WORD FARAPI VideoTestReg(void)
  2655. {
  2656. BoardWriteVideo(MWP , 0x05);
  2657. BoardWriteVideo(MWP , 0x55);
  2658. BoardWriteVideo(MWP , 0xAA);
  2659. if ((BoardReadVideo(MWP) & 0x1F) != 0x05)
  2660. goto Error;
  2661. if (BoardReadVideo(MWP) != 0x55)
  2662. goto Error;
  2663. if ((BoardReadVideo(MWP) & 0xFC) != 0xA8)
  2664. goto Error;
  2665. return NO_ERROR;
  2666. Error :
  2667. DPF((Trace,"VideoTestReg failed !!"));
  2668. SetErrorCode(ERR_VIDEO_REG_TEST_FAILED);
  2669. return BAD_REG_V;
  2670. }
  2671. //----------------------------------------------------------------------------
  2672. //
  2673. //----------------------------------------------------------------------------
  2674. WORD FARAPI VideoTestMemPat(WORD pattern, WORD pattern1)
  2675. {
  2676. // Configure memory refresh = 36
  2677. #define MAXMEM 0x7FF
  2678. WORD i, j;
  2679. WORD counter;
  2680. VideoSetMWP(0L);
  2681. counter = 0;
  2682. for (i = 0; i < MAXMEM; i++) {
  2683. for (j = 0; j < 16; j++)
  2684. {
  2685. while (!(BoardReadVideo ( STA ) & 0x4)) {
  2686. counter ++;
  2687. if (counter == 0xFF0)
  2688. goto Error;
  2689. DPF((Trace,"Waiting Write Fifo Empty"));
  2690. }
  2691. BoardWriteVideo(MWF, 0);
  2692. }
  2693. }
  2694. VideoSetMWP(0L);
  2695. counter = 0;
  2696. for (i = 0; i < MAXMEM; i++) {
  2697. for(j = 0; j < 8; j++ )
  2698. {
  2699. while (!(BoardReadVideo ( STA ) & 0x4)) {
  2700. counter ++;
  2701. if (counter == 0xFF0)
  2702. goto Error;
  2703. DPF((Trace,"Waiting Write Fifo Empty"));
  2704. }
  2705. BoardWriteVideo(MWF, (BYTE)pattern);
  2706. }
  2707. counter = 0;
  2708. for(j = 0; j < 8; j++ ){
  2709. while (!VideoMemWriteFifoEmpty()) { // ACCESS TO MEM FIFO IS SLOWER !!!
  2710. DPF((Trace,"Waiting Write Fifo Empty"));
  2711. counter ++;
  2712. if (counter == 0xFF0)
  2713. goto Error;
  2714. }
  2715. BoardWriteVideo(MWF, (BYTE)pattern1);
  2716. }
  2717. }
  2718. VideoSetMRP(0L);
  2719. counter = 0;
  2720. // test Read Fifo Full
  2721. for(i = 0; i < MAXMEM; i++) {
  2722. for (j = 0; j < 8; j++) {
  2723. while (!VideoMemReadFifoFull()) {
  2724. DPF((Trace,"Waiting Read Fifo Full"));
  2725. counter ++;
  2726. if (counter == 0xFF0)
  2727. goto Error;
  2728. }
  2729. counter = BoardReadVideo(MRF);
  2730. if (counter !=pattern) {
  2731. DPF((Trace,"Counter = %x, pattern = %x, j = %x", counter, pattern, j));
  2732. goto Error;
  2733. }
  2734. }
  2735. counter = 0;
  2736. for (j = 0; j < 8; j++) {
  2737. counter = BoardReadVideo(MRF);
  2738. while (!VideoMemReadFifoFull()) {
  2739. DPF((Trace,"Waiting Read Fifo Full"));
  2740. counter ++;
  2741. if (counter == 0xFF0)
  2742. goto Error;
  2743. }
  2744. if ((WORD)counter != pattern1) {
  2745. DPF((Trace,"Counter = %x, pattern = %x, j = %x", counter, pattern, j));
  2746. goto Error;
  2747. }
  2748. }
  2749. }
  2750. return NO_ERROR;
  2751. Error :
  2752. DPF((Trace,"VideoTestMemPat failed !!"));
  2753. SetErrorCode(ERR_TEST_MEMORY_FAILED);
  2754. return BAD_MEM_V;
  2755. }
  2756. //----------------------------------------------------------------------------
  2757. //
  2758. //----------------------------------------------------------------------------
  2759. WORD FARAPI VideoTestMem(void)
  2760. {
  2761. // if (VideoTestMemPat(0x55, 0xAA) == NO_ERROR)
  2762. // return VideoTestMemPat(0xAA, 0x55);
  2763. // else
  2764. // return BAD_MEM_V;
  2765. return NO_ERROR;
  2766. }
  2767. //----------------------------------------------------------------------------
  2768. //
  2769. //----------------------------------------------------------------------------
  2770. static void NEARAPI VideoInitVar(STREAMTYPE StreamType)
  2771. {
  2772. Sequence =1;
  2773. pVideo->currDCF = 0x40; /* one clock delay + force black
  2774. * background */
  2775. pVideo->LastCdCount = 0;
  2776. pVideo->fullVerFilter = 0x0;
  2777. pVideo->halfVerFilter = 0x4;
  2778. pVideo->Xdo = pCard->OriginX; /* pre initialise XDO */
  2779. pVideo->Ydo = pCard->OriginY; /* pre initialise YDO */
  2780. pVideo->Xd1 = 0xFFFF; /* pre initialise end of video
  2781. * window */
  2782. pVideo->Yd1 = 0xFFFF; /* pre initialisa end of video
  2783. * window */
  2784. pVideo->fastForward = 0; /* accelerate if set */
  2785. pVideo->decSlowDown = 0;
  2786. pVideo->perFrame = FALSE;
  2787. pVideo->LastPipeReset = 2;
  2788. pVideo->errCode = 0;
  2789. pVideo->StreamInfo.countGOP = 0;
  2790. pVideo->StreamInfo.frameRate = 5; // just to avoid erroneous warning
  2791. pVideo->useSRC = 0x0; // disable SRC
  2792. pVideo->seqDispExt = 0;
  2793. pVideo->skipMode = 0;
  2794. pVideo->currCommand = 0;
  2795. pVideo->needDataInBuff = 0;
  2796. pVideo->currPictCount = 0; /* first picture of the bit stream */
  2797. pVideo->defaultTbl = 0; /* To know if default tables are already into the chip */
  2798. pVideo->GOPindex = 0;
  2799. // initialisation of the picture structures
  2800. pVideo->pictArray[0].tempRef = 1025;
  2801. pVideo->pictArray[1].tempRef = 1023;
  2802. pVideo->pictArray[2].tempRef = 1025;
  2803. pVideo->pictArray[3].tempRef = 1025;
  2804. pVideo->currTempRef = 1022; /* display pVideo->decSlowDownral reference */
  2805. pVideo->pNextDisplay = &pVideo->pictArray[3];
  2806. pVideo->pCurrDisplay = &pVideo->pictArray[3]; // this is only for correct
  2807. // start up
  2808. pVideo->pictArray[0].nb_display_field = 2;
  2809. // 2 field display time for MPEG1
  2810. pVideo->pictArray[1].nb_display_field = 2;
  2811. pVideo->pictArray[2].nb_display_field = 2;
  2812. pVideo->pictArray[3].nb_display_field = 2;
  2813. pVideo->pictArray[0].first_field = TOP; // default for MPEG1 bit streams
  2814. pVideo->pictArray[1].first_field = TOP; // top field first
  2815. pVideo->pictArray[2].first_field = TOP;
  2816. pVideo->pictArray[3].first_field = TOP;
  2817. pVideo->fieldMode = 0; // indicates frame picture by
  2818. // default
  2819. pVideo->frameStoreAttr = FORWARD_PRED;
  2820. pVideo->vbvReached = 0;
  2821. pVideo->notInitDone = 1; // timing generator,picture size
  2822. // initialised only once
  2823. pVideo->intMask = 0x0;
  2824. pVideo->Gcf = 0; // GCF set to 0 by default
  2825. pVideo->Ctl = A35; // CTL set to 0 by default
  2826. pVideo->InvertedField = FALSE;
  2827. pVideo->FistVsyncAfterVbv = NOT_YET_VBV;
  2828. pVideo->Ccf = 0; // GCF set to 0 by default
  2829. pVideo->NextInstr.Tff = 1 ;
  2830. pVideo->NextInstr.Seq = 1 ;
  2831. pVideo->NextInstr.Exe = 1 ;
  2832. }
  2833. static void NEARAPI VideoReset35XX(STREAMTYPE StreamType)
  2834. {
  2835. WORD Abg, Abs, Vbg, Vbs;
  2836. pVideo->AudioBufferSize = 0xFF;
  2837. switch(StreamType)
  2838. {
  2839. case SYSTEM_STREAM:
  2840. case AUDIO_PACKET:
  2841. case VIDEO_PACKET:
  2842. pVideo->VideoBufferSize = BUF_FULL/3 - pVideo->AudioBufferSize-1;
  2843. break;
  2844. default:
  2845. pVideo->VideoBufferSize = BUF_FULL - pVideo->AudioBufferSize-1;
  2846. break;
  2847. }
  2848. Vbg = 0;
  2849. Vbs = Vbg + pVideo->VideoBufferSize;
  2850. Abg = Vbs+1;
  2851. Abs = Abg + pVideo->AudioBufferSize;
  2852. pVideo->StreamInfo.modeMPEG2 = 0;
  2853. pVideo->NextInstr = pVideo->ZeroInstr;// Clear Next Instruction
  2854. VideoInitPLL();
  2855. VideoWaitDec(); // put decoder in Wait mode
  2856. VideoSetABStart( Abg);// Set Bit Buffer parameters before Soft Reset
  2857. VideoSetABStop(Abs);
  2858. VideoSetABThresh(pVideo->AudioBufferSize);
  2859. VideoSetBBStart(Vbg);// Set Bit Buffer parameters before Soft Reset
  2860. VideoSetBBStop(Vbs);
  2861. VideoSetBBThresh(pVideo->VideoBufferSize);
  2862. VideoEnableInterfaces(ON);
  2863. VideoEnableErrConc(ON);
  2864. VideoSoftReset();
  2865. VideoEnableDecoding(ON );
  2866. VideoSetDramRefresh(36); // Set DRAM refresh to 36 default DRAM ref period
  2867. VideoDisableDisplay();
  2868. VideoMaskInt();
  2869. BoardReadVideo(ITS); /* to clear ITS */
  2870. BoardReadVideo(ITS +1);
  2871. BoardReadVideo(ITS1);
  2872. }
  2873. static void NEARAPI VideoSeek(STREAMTYPE StreamType)
  2874. {
  2875. WORD Abg, Abs, Vbg, Vbs;
  2876. pVideo->AudioBufferSize = 0xFF;
  2877. switch(StreamType)
  2878. {
  2879. case SYSTEM_STREAM:
  2880. case AUDIO_PACKET:
  2881. case VIDEO_PACKET:
  2882. pVideo->VideoBufferSize = BUF_FULL/3 - pVideo->AudioBufferSize-1;
  2883. break;
  2884. default:
  2885. pVideo->VideoBufferSize = BUF_FULL - pVideo->AudioBufferSize-1;
  2886. break;
  2887. }
  2888. Vbg = 0;
  2889. Vbs = Vbg + pVideo->VideoBufferSize;
  2890. Abg = Vbs+1;
  2891. Abs = Abg + pVideo->AudioBufferSize;
  2892. pVideo->StreamInfo.modeMPEG2 = 0;
  2893. pVideo->NextInstr = pVideo->ZeroInstr;// Clear Next Instruction
  2894. // VideoInitPLL();
  2895. VideoWaitDec(); // put decoder in Wait mode
  2896. // VideoSetABStart( Abg);// Set Bit Buffer parameters before Soft Reset
  2897. // VideoSetABStop(Abs);
  2898. // VideoSetABThresh(pVideo->AudioBufferSize);
  2899. // VideoSetBBStart(Vbg);// Set Bit Buffer parameters before Soft Reset
  2900. // VideoSetBBStop(Vbs);
  2901. // VideoSetBBThresh(pVideo->VideoBufferSize);
  2902. VideoEnableInterfaces(ON);
  2903. VideoEnableErrConc(ON);
  2904. VideoSoftReset();
  2905. VideoEnableDecoding(ON );
  2906. VideoSetDramRefresh(36); // Set DRAM refresh to 36 default DRAM ref period
  2907. // VideoDisableDisplay();
  2908. VideoMaskInt();
  2909. BoardReadVideo(ITS); /* to clear ITS */
  2910. BoardReadVideo(ITS +1);
  2911. BoardReadVideo(ITS1);
  2912. }
  2913. //----------------------------------------------------------------------------
  2914. // PLL initialization
  2915. //----------------------------------------------------------------------------
  2916. static void NEARAPI VideoInitPLL(void)
  2917. {
  2918. BoardWriteVideo(CKG_PLL, 0xD9);
  2919. BoardWriteVideo(CKG_VID, 0x22);
  2920. BoardWriteVideo(CKG_VID, 0x08);
  2921. BoardWriteVideo(CKG_VID, 0x5f);
  2922. BoardWriteVideo(CKG_VID, 0x0f);
  2923. BoardWriteVideo(CKG_AUD, 0x2b);
  2924. BoardWriteVideo(CKG_AUD, 0x02);
  2925. BoardWriteVideo(CKG_AUD, 0x5f);
  2926. BoardWriteVideo(CKG_AUD, 0x5f);
  2927. BoardWriteVideo(CKG_CFG, 0x83);
  2928. }
  2929. #define SIZE_OF_PICT 540
  2930. //----------------------------------------------------------------------------
  2931. // Enable OSD
  2932. //----------------------------------------------------------------------------
  2933. static void NEARAPI VideoOsdOn(void)
  2934. {
  2935. pVideo->currDCF = pVideo->currDCF | 0x10;
  2936. HostDisableIT();
  2937. BoardWriteVideo(DCF, 0);
  2938. BoardWriteVideo(DCF + 1, (BYTE)pVideo->currDCF);
  2939. HostEnableIT();
  2940. }
  2941. //----------------------------------------------------------------------------
  2942. // Disable OSD
  2943. //----------------------------------------------------------------------------
  2944. static void NEARAPI VideoOsdOff (void)
  2945. {
  2946. pVideo->currDCF = pVideo->currDCF & 0xEF;
  2947. HostDisableIT();
  2948. BoardWriteVideo(DCF, 0);
  2949. BoardWriteVideo(DCF + 1,(BYTE) pVideo->currDCF);
  2950. HostEnableIT();
  2951. }
  2952. //----------------------------------------------------------------------------
  2953. // initialisation of the OSD pointers
  2954. //----------------------------------------------------------------------------
  2955. static void NEARAPI VideoInitOEP (DWORD point_oep)
  2956. {
  2957. BYTE x;
  2958. // Bugy code!! generates compiler error
  2959. // Needs tp be fixed - JBS
  2960. /*
  2961. x = (BYTE)(point_oep >> 13);
  2962. BoardWriteVideo(VID_OBP,x);
  2963. x = (BYTE)(point_oep >> 5);
  2964. BoardWriteVideo(VID_OBP, x);
  2965. x = (BYTE)(point_oep >> 13);
  2966. BoardWriteVideo(VID_OTP, x);
  2967. x = (BYTE)(point_oep >> 5);
  2968. BoardWriteVideo(VID_OTP, x);
  2969. */
  2970. }
  2971. //----------------------------------------------------------------------------
  2972. // Set video window position and size (top left=X0,Y0) (bottom right=X1,Y1)
  2973. //----------------------------------------------------------------------------
  2974. void FARAPI VideoSetVideoWindow (WORD a, WORD b, WORD c, WORD d )
  2975. {
  2976. a=a|1;
  2977. pVideo->Xdo = a;
  2978. pVideo->Ydo = b;
  2979. pVideo->Xd1 = c;
  2980. pVideo->Yd1 = d;
  2981. VideoInitXY ();
  2982. }
  2983. //----------------------------------------------------------------------------
  2984. // Initialisation of the horizontal & vertical offsets
  2985. //----------------------------------------------------------------------------
  2986. void FARAPI VideoInitXY(void)
  2987. {
  2988. WORD yds, xds;
  2989. // set vertical stop position
  2990. if ( pVideo->StreamInfo.verSize <= 288 ) // half res decoding
  2991. yds = pVideo->StreamInfo.verSize + pVideo->Ydo - 129;
  2992. /* number of lines + offset - 128 - 1 */
  2993. else // full resolution decoding
  2994. yds = ( pVideo->StreamInfo.verSize >> 1 ) + pVideo->Ydo - 129;
  2995. /* number of lines + offset - 128 - 1 */
  2996. if ( yds > pVideo->Yd1 )
  2997. yds = pVideo->Yd1;
  2998. // set horizontal stop position: we always display 720 pixels
  2999. // XDS given by the relation: 2*XDO + 40 + 2*L = 2*XDS + 28
  3000. // XDS = XDO + 726 with 720 displayed pixels.
  3001. xds = pVideo->Xdo + 726;
  3002. if ( xds > 800 ) /* 800 = max number of pels allowed per line */
  3003. xds = 800;
  3004. if ( xds > pVideo->Xd1 )
  3005. xds = pVideo->Xd1; /* not bigger than the video window */
  3006. SetXY(xds, yds );
  3007. }
  3008. //----------------------------------------------------------------------------
  3009. // Storage of the horizontal & vertical offsets
  3010. //----------------------------------------------------------------------------
  3011. void FARAPI SetXY(WORD xds, WORD yds)
  3012. {
  3013. BoardWriteVideo ( XDO , (BYTE)(pVideo->Xdo >> 8 ));
  3014. BoardWriteVideo ( XDO+1 , (BYTE)(pVideo->Xdo & 0xFF ));
  3015. BoardWriteVideo ( YDO , (BYTE)(pVideo->Ydo ));
  3016. BoardWriteVideo ( XDS , (BYTE)(xds >> 8 ));
  3017. BoardWriteVideo ( XDS+1 , (BYTE)(xds & 0xFF ));
  3018. BoardWriteVideo ( YDS , (BYTE)yds );
  3019. }
  3020. //----------------------------------------------------------------------------
  3021. // Set next display frame pointer
  3022. //----------------------------------------------------------------------------
  3023. /*
  3024. This routine determines which is the next frame pointer that
  3025. must be used for display. It takes care about the fact that
  3026. the temporal references may not be consecutive in case of
  3027. sikipped pictures...
  3028. */
  3029. static void NEARAPI VideoDisplayCtrl(void)
  3030. {
  3031. WORD comput1, index;
  3032. WORD min_temp_ref;
  3033. WORD cur_ref;
  3034. min_temp_ref = ( pVideo->currTempRef & 0xF000 ) + 1024;
  3035. // keep current pVideo->GOPindex
  3036. index = 5;
  3037. pVideo->currTempRef++; /* increment display temporal ref */
  3038. /************** WARNING ************/
  3039. // this routine will not work properly if GOP size > 1023
  3040. if ( ( pVideo->currTempRef & 0xFFF ) > 1023 ) // 2 msb are used as pVideo->GOPindex
  3041. pVideo->currTempRef = pVideo->currTempRef & 0xF000; /* max temp ref is 1023: reset to 0 */
  3042. /* search frame store to display */
  3043. for (comput1 = 0; comput1 <= 3; comput1++) {
  3044. cur_ref = pVideo->pictArray[comput1].tempRef & 0xFFF;
  3045. if ( ( ( pVideo->currTempRef & 0xF000 ) == ( pVideo->pictArray[comput1].tempRef & 0xF000 ) )
  3046. && ( pVideo->currTempRef <= pVideo->pictArray[comput1].tempRef )
  3047. && ( min_temp_ref > cur_ref ) ) {
  3048. // pVideo->currTempRef and pVideo->pictArray[comput1] refer to the same GOP
  3049. // we want to extract the minimum temporal reference
  3050. min_temp_ref = cur_ref;
  3051. index = comput1;
  3052. }
  3053. }
  3054. if (index == 5) {
  3055. /*
  3056. There is a group of pictures change: reset pVideo->currTempRef and
  3057. increment pVideo->GOPindex
  3058. */
  3059. pVideo->currTempRef = ( pVideo->currTempRef & 0xF000 ) + 0x4000;
  3060. min_temp_ref = min_temp_ref + 0x4000;
  3061. /* search frame store to display */
  3062. for (comput1 = 0; comput1 <= 3; comput1++) {
  3063. cur_ref = pVideo->pictArray[comput1].tempRef & 0xFFF;
  3064. if ( ( ( pVideo->currTempRef & 0xF000 ) == ( pVideo->pictArray[comput1].tempRef & 0xF000 ) )
  3065. && ( pVideo->currTempRef <= pVideo->pictArray[comput1].tempRef )
  3066. && ( min_temp_ref > cur_ref ) ) {
  3067. // pVideo->currTempRef and pVideo->pictArray[comput1] refer to the same GOP
  3068. // we want to extract the minimum temporal reference
  3069. min_temp_ref = cur_ref;
  3070. index = comput1;
  3071. }
  3072. }
  3073. }
  3074. if (index == 5) {
  3075. if (!pVideo->errCode)
  3076. pVideo->errCode = TEMP_REF; /* No pVideo->currTempRef corresponding to the display one */
  3077. SetErrorCode(ERR_NO_TEMPORAL_REFERENCE);
  3078. }
  3079. else {
  3080. pVideo->pNextDisplay->tempRef = 1025;
  3081. // to release the previous pointer for next decoding
  3082. pVideo->pNextDisplay = &pVideo->pictArray[index];
  3083. if ( pVideo->pNextDisplay->validPTS == FALSE ) {
  3084. /* PTS not available: compute a theoretical value */
  3085. WORD lattency = 3000; /* two 60Hz fields lattency */
  3086. if ( pVideo->StreamInfo.displayMode == 0 )
  3087. lattency = 3600; /* two 50Hz fields lattency */
  3088. pVideo->pNextDisplay->dwPTS = pVideo->pCurrDisplay->dwPTS + lattency;
  3089. // HostDirectPutChar('?', BLACK, LIGHTGREEN);
  3090. }
  3091. else{
  3092. // HostDirectPutChar('G', BLACK, LIGHTGREEN);
  3093. }
  3094. // set next display pointer
  3095. pVideo->currTempRef = pVideo->pictArray[index].tempRef;
  3096. pVideo->pictArray[index].tempRef = 1024;
  3097. /* this pVideo->currTempRef must not interfer on next tests */
  3098. }
  3099. }
  3100. //----------------------------------------------------------------------------
  3101. // Set parameters related to picture size
  3102. //----------------------------------------------------------------------------
  3103. /*
  3104. This routine will always program the sample rate converter
  3105. in order to display 720 horizontal pixels
  3106. */
  3107. void FARAPI VideoSetPictureSize(void)
  3108. {
  3109. WORD compute, comput1;
  3110. // If PAL Switch on optimization
  3111. if ( pVideo->StreamInfo.frameRate == 3)
  3112. {
  3113. // Choose B Optimization for PAL for both Luma and Chroma
  3114. BoardWriteVideo(CFG_BFS,NB_ROW_OF_MB);
  3115. // Select Full Res vertical filter without interpolation
  3116. // Interpollation NOT ALLOWED if Optimization
  3117. pVideo->fullVerFilter = 0x01;
  3118. }
  3119. if ( (pVideo->StreamInfo.horSize > 720 ) ||
  3120. (pVideo->StreamInfo.verSize > 576 ))
  3121. {
  3122. if ( !pVideo->errCode )
  3123. pVideo->errCode = HIGH_CCIR601; // picture size higher than CCIR601 format
  3124. SetErrorCode(ERR_HIGHER_THAN_CCIR601);
  3125. return;
  3126. }
  3127. // set SRC depending on the horizontal size in order to display 720
  3128. // pixels
  3129. if ( pVideo->StreamInfo.horSize < 720 ) {
  3130. // lsr = 256 * (pVideo->StreamInfo.horSize-4) / (display size - 1)
  3131. VideoSetSRC(pVideo->StreamInfo.horSize, 720);
  3132. }
  3133. else {
  3134. VideoSRCOff();
  3135. }
  3136. if ( ( pVideo->StreamInfo.horSize >= 544 ) &&
  3137. ( ( pVideo->StreamInfo.pixelRatio == 0x3 ) ||
  3138. ( pVideo->StreamInfo.pixelRatio == 0x6 ) ) )
  3139. {
  3140. // picture size = 720 but pixel aspect ratio is 16/9
  3141. // Program the SRC for display on a 4/3 screen
  3142. // 544 pixels of the decoded picture extended into 720 pixels
  3143. // for display
  3144. VideoSetSRC(544, 720);
  3145. }
  3146. // set vertical filter and half/full resolution depending on the
  3147. // vertical picture size
  3148. if ( pVideo->StreamInfo.verSize > 288 ) {
  3149. // typically 480 or 576 lines
  3150. VideoSetFullRes();
  3151. }
  3152. else {
  3153. // typically 240 or 288 lines
  3154. // VideoSetFullRes(pVideo);
  3155. VideoSetHalfRes();
  3156. }
  3157. // set picture sizes into the decoder
  3158. comput1 = pVideo->StreamInfo.horSize + 15; // Horizontal size + 15
  3159. comput1 = ( comput1 >> 4 ) & 0xFF; // divide by 16
  3160. BoardWriteVideo ( DFW, (BYTE)comput1 );
  3161. // Decoded Frame Width in number of MB
  3162. compute = ( pVideo->StreamInfo.verSize + 15 ) >> 4;
  3163. compute = ( compute * comput1 ) & 0x3FFF;
  3164. BoardWriteVideo ( DFS, (BYTE)( ( compute >> 8 ) & 0xFF ) );
  3165. /* Decoded Frame Size in number of MB */
  3166. BoardWriteVideo ( DFS , (BYTE)( compute & 0xFF ) );
  3167. BoardWriteVideo ( VID_DFA , 0 );
  3168. BoardWriteVideo ( VID_DFA , 0 );
  3169. BoardWriteVideo ( VID_XFW, (BYTE)comput1 );
  3170. BoardWriteVideo ( VID_XFS, (BYTE)( ( compute >> 8 ) & 0xFF ) );
  3171. BoardWriteVideo ( VID_XFS, (BYTE)( compute & 0xFF ) );
  3172. BoardWriteVideo ( VID_XFA , 0 );
  3173. BoardWriteVideo ( VID_XFA , 0 );
  3174. }
  3175. //----------------------------------------------------------------------------
  3176. // store the next pan vector
  3177. //----------------------------------------------------------------------------
  3178. static void NEARAPI VideoSetPSV(void)
  3179. {
  3180. }
  3181. //----------------------------------------------------------------------------
  3182. // Enable/disable the SRC
  3183. //----------------------------------------------------------------------------
  3184. void FARAPI VideoSwitchSRC (void)
  3185. {
  3186. if (pVideo->useSRC != 0x0) {
  3187. pVideo->currDCF = pVideo->currDCF ^ DSR; /* Switch SRC */
  3188. BoardWriteVideo (DCF, 0);
  3189. BoardWriteVideo (DCF + 1, (BYTE)(pVideo->currDCF));
  3190. }
  3191. else {
  3192. // what ?
  3193. }
  3194. }
  3195. //----------------------------------------------------------------------------
  3196. // enable the SRC
  3197. //----------------------------------------------------------------------------
  3198. static void NEARAPI VideoSRCOn(void)
  3199. {
  3200. pVideo->useSRC = 0xFF;
  3201. pVideo->currDCF = pVideo->currDCF & ~DSR ; /* Enable SRC */
  3202. BoardWriteVideo ( DCF, 0 );
  3203. BoardWriteVideo ( DCF + 1, (BYTE)(pVideo->currDCF));
  3204. }
  3205. //----------------------------------------------------------------------------
  3206. // Disable the SRC
  3207. //----------------------------------------------------------------------------
  3208. static void NEARAPI VideoSRCOff (void)
  3209. {
  3210. pVideo->useSRC = 0x00;
  3211. pVideo->currDCF = pVideo->currDCF | DSR ; /* Enable SRC */
  3212. BoardWriteVideo ( DCF, 0 );
  3213. BoardWriteVideo ( DCF + 1, (BYTE)(pVideo->currDCF));
  3214. }
  3215. //----------------------------------------------------------------------------
  3216. // display a full screen OSD with a uniform color (just as example) */
  3217. //----------------------------------------------------------------------------
  3218. /*
  3219. color 0 is green
  3220. color 1 is yellow
  3221. color 2 is cyan
  3222. color 3 is magenta
  3223. the OSD area is here defined from address zero
  3224. in normal application this area is reserved for the bit buffer
  3225. and the OSD will be typically defined after the bit buffer.
  3226. Note: The bit buffer is defined in multiple of 256 bytes while
  3227. MWP, OEP and OOP are memory addresses in mulitple of 64 bits
  3228. */
  3229. static void NEARAPI VideoFullOSD (WORD col)
  3230. {
  3231. long big;
  3232. WORD counter;
  3233. VideoSetMWP(0L);
  3234. counter = 0;
  3235. while ( !VideoMemWriteFifoEmpty()) {
  3236. counter ++;
  3237. if (counter == 0xFF) {
  3238. pVideo->errCode = BAD_MEM_V;
  3239. SetErrorCode(ERR_MEM_WRITE_FIFO_NEVER_EMPTY);
  3240. return ;
  3241. }
  3242. }
  3243. BoardWriteVideo ( MWF, 19 ); /* line 19 */
  3244. BoardWriteVideo ( MWF, 0x1 ); /* stop row */
  3245. BoardWriteVideo ( MWF, 0x02 ); /* 19 + 240 - 1 */
  3246. BoardWriteVideo ( MWF, 0x00 ); /* start column */
  3247. BoardWriteVideo ( MWF, 100 ); /* column 100 */
  3248. BoardWriteVideo ( MWF, 0x3 ); /* stop column = 100 + 700 - 1=
  3249. * 31F */
  3250. BoardWriteVideo ( MWF, 0x1F ); /* end init display size and
  3251. * position */
  3252. BoardWriteVideo ( MWF, 0x90 ); /* color 0 = green */
  3253. BoardWriteVideo ( MWF, 0x32 );
  3254. BoardWriteVideo ( MWF, 0xD0 ); /* color 1 = yellow */
  3255. BoardWriteVideo ( MWF, 0x19 );
  3256. BoardWriteVideo ( MWF, 0xA0 ); /* color 2 = cyan */
  3257. BoardWriteVideo ( MWF, 0xA1 );
  3258. BoardWriteVideo ( MWF, 0x60 ); /* color 3 = magenta */
  3259. BoardWriteVideo ( MWF, 0xDE ); // 6/D/E
  3260. if ( col == 1 )
  3261. col = 0x55;
  3262. else if ( col == 2 )
  3263. col = 0xAA;
  3264. else if ( col == 3 )
  3265. col = 0xFF;
  3266. for ( big = 0; big < 42000L; big++ ) // 42000 = 240 * 700 / 4
  3267. {
  3268. BoardWriteVideo ( MWF, (BYTE)col );
  3269. // select color
  3270. }
  3271. for ( big = 0; big < 8; big++ ) // add a dummy window outside
  3272. // the display
  3273. BoardWriteVideo ( MWF, 0xFF );
  3274. // to stop OSD
  3275. VideoInitOEP ( 0 ); // set OEP and OOP to start of
  3276. // bit map address
  3277. BoardWriteVideo ( DCF, 0 );
  3278. BoardWriteVideo ( DCF + 1, (BYTE)(pVideo->currDCF | 0x30));
  3279. // enable OSD
  3280. }