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.

394 lines
8.0 KiB

  1. //
  2. // MODULE : DMPEG.C
  3. // PURPOSE : Entry point to lowlevel driver
  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 "dmpeg.h"
  19. #include "memio.h"
  20. #include "codedma.h"
  21. #include "sti3520A.h"
  22. #include "staudio.h"
  23. #include "board.h"
  24. #include "error.h"
  25. #include "debug.h"
  26. #include "i20reg.h"
  27. #include "zac3.h"
  28. #include "staudio.h"
  29. #define CTRL_POWER_UP 0 // After reset
  30. #define CTRL_INIT 1 // Initialisation + test of the decoders
  31. #define CTRL_READY 2 // File openned
  32. #define CTRL_INIT_SYNC 3 // Initial sync.: defines start of audio and video
  33. #define CTRL_DECODE 4 // Normal decode
  34. #define CTRL_IDLE 5 // idle state
  35. #define SLOW_MODE 0
  36. #define PLAY_MODE 1
  37. #define FAST_MODE 2
  38. CARD Card, *pCard = NULL;
  39. CTRL Ctrl, *pCtrl;
  40. DWORD OldlatchedSTC;
  41. DWORD OldvideoPTS;
  42. static BOOL Avsync;
  43. static BOOL synchronizing;
  44. static BYTE *tmpBuf;
  45. static ULONG tmpBase;
  46. static DWORD tmpAdr;
  47. static BYTE I20Intr;
  48. static BOOL IntCtrl(void);
  49. static BYTE Irq;
  50. BOOL dmpgOpen(ULONG Base, BYTE *DmaBuf, DWORD PhysicalAddress)
  51. {
  52. BOOL Found=FALSE;
  53. tmpBuf = DmaBuf;
  54. tmpBase = Base;
  55. tmpAdr = PhysicalAddress;
  56. if(!BoardOpen(Base))
  57. {
  58. DPF((Trace,"Board initialization failed!!\n"));
  59. }
  60. // Open Audio and Video
  61. pCard = &Card;
  62. pCard->pVideo = &(pCard->Video);
  63. VideoOpen();
  64. pCard->pAudio = &(pCard->Audio);
  65. AudioOpen (pCard->pAudio);
  66. pCtrl = &Ctrl;
  67. pCtrl->ErrorMsg = NO_ERROR;
  68. pCtrl->CtrlState = CTRL_POWER_UP;
  69. pCtrl->AudioOn = FALSE;
  70. pCtrl->VideoOn = FALSE;
  71. Avsync = FALSE;
  72. BoardDisableIRQ();
  73. VideoInitDecoder(DUAL_PES);// Initialise video in PES by default
  74. pCtrl->CtrlState = CTRL_INIT_SYNC;
  75. VideoInitPesParser(VIDEO_STREAM);
  76. InitAC3Decoder();
  77. AudioInitPesParser(AUDIO_STREAM);
  78. BoardEnableIRQ();
  79. VideoMaskInt (); // Restore Video interrupt mask
  80. DPF((Trace,"Calling Code DMA open!!\n"));
  81. return CodeDmaOpen(DmaBuf, PhysicalAddress);
  82. }
  83. BOOL dmpgClose(void)
  84. {
  85. DPF((Trace,"dmpgClose!!\n"));
  86. if(pCard == NULL)
  87. return FALSE;
  88. VideoClose( );
  89. AudioClose( );
  90. BoardClose();
  91. CodeDmaClose();
  92. return TRUE;
  93. }
  94. BOOL dmpgPlay()
  95. {
  96. DPF((Trace,"dmpgPlay!!\n"));
  97. if(pCard == NULL)
  98. return FALSE;
  99. VideoRestoreInt (); // Restore Video interrupt mask
  100. pCtrl->DecodeMode = PLAY_MODE;
  101. AudioSetMode(pCtrl->DecodeMode, 0);
  102. VideoSetMode(pCtrl->DecodeMode, 0);
  103. if (pCtrl->CtrlState == CTRL_IDLE)
  104. pCtrl->CtrlState = CTRL_DECODE;
  105. VideoDecode();
  106. AudioDecode();
  107. AC3Command(AC3_UNMUTE); //ckw
  108. AC3Command(AC3_PLAY); //ckw
  109. AudioTransfer(TRUE); //ckw
  110. return TRUE;
  111. }
  112. void dmpgReset(void)
  113. {
  114. dmpgPause();
  115. dmpgSeek();
  116. VideoMaskInt();
  117. }
  118. BOOL dmpgPause(void)
  119. {
  120. DPF((Trace,"dmpgPause!!\n"));
  121. if(pCard == NULL)
  122. return FALSE;
  123. switch(pCtrl->CtrlState)
  124. {
  125. case CTRL_POWER_UP:
  126. case CTRL_INIT:
  127. case CTRL_READY:
  128. break;
  129. case CTRL_INIT_SYNC:
  130. AudioPause();
  131. VideoPause();
  132. AudioTransfer(FALSE); //ckw
  133. AC3Command(AC3_MUTE); //ckw
  134. pCtrl->AudioOn = FALSE;
  135. pCtrl->VideoOn = FALSE;
  136. pCtrl->ActiveState = CTRL_INIT_SYNC;
  137. pCtrl->CtrlState = CTRL_IDLE;
  138. break;
  139. case CTRL_DECODE:
  140. AudioPause();
  141. VideoPause();
  142. AudioTransfer(FALSE); //ckw
  143. AC3Command(AC3_MUTE); //ckw
  144. pCtrl->ActiveState = CTRL_DECODE;
  145. pCtrl->CtrlState = CTRL_IDLE;
  146. break;
  147. case CTRL_IDLE:
  148. break;
  149. }
  150. return TRUE;
  151. }
  152. BOOL dmpgSeek(void)
  153. {
  154. DPF((Trace,"dmpgSeek!!\n"));
  155. if(pCard == NULL)
  156. return FALSE;
  157. CodeDmaFlush();
  158. pCtrl->CtrlState = CTRL_INIT_SYNC;
  159. VideoSeekDecoder(DUAL_PES);
  160. return TRUE;
  161. }
  162. BOOL dmpgStop(void)
  163. {
  164. DPF((Trace,"dmpgStop!!\n"));
  165. if(pCard == NULL)
  166. return FALSE;
  167. VideoMaskInt();
  168. dmpgPause();
  169. // dmpgClose();
  170. // dmpgOpen(tmpBase, tmpBuf, tmpAdr);
  171. return TRUE;
  172. }
  173. UINT dmpgSendVideo(BYTE *pPacket, DWORD uLen)
  174. {
  175. // DPF((Trace,"dmpgSendVideo!!\n"));
  176. UINT uRet;
  177. if(pCard == NULL)
  178. return FALSE;
  179. uRet = (UINT)CodeDmaSendData(pPacket, uLen);
  180. return uRet;
  181. }
  182. UINT dmpgSendAudio(BYTE *pPacket, DWORD uLen)
  183. {
  184. LONG abl, abf;
  185. // DPF((Trace,"dmpgSendAudio!!\n"));
  186. if(pCard == NULL)
  187. return 0;
  188. abl = VideoGetABL();
  189. if((LONG)pCard->pVideo->AudioBufferSize - abl <= 2L)
  190. {
  191. // DebugPrint((DebugLevelTrace, "Audio Buffer FULL!!\n"));
  192. return 0;
  193. }
  194. abf = (pCard->pVideo->AudioBufferSize - abl -1) << 8;
  195. // DebugPrint((DebugLevelError,"SendAudio : %X %X %X %X %X %X, BBL = %x Size = %x\n",pPacket[0], pPacket[1], pPacket[2], pPacket[3], pPacket[4], pPacket[5], abl, pCard->pVideo->AudioBufferSize));
  196. if(abf < uLen)
  197. {
  198. SendAC3Data(pPacket, abf);
  199. return abf;
  200. }
  201. else
  202. {
  203. SendAC3Data(pPacket, uLen);
  204. return uLen;
  205. }
  206. }
  207. BOOL dmpgInterrupt(void)
  208. {
  209. BOOL bRet = FALSE;
  210. I20Intr = memInByte(I20_INTRSTATUS);
  211. memOutByte(I20_INTRSTATUS, I20Intr);
  212. if(I20Intr & IFLAG_CODEDMA)
  213. {
  214. bRet = TRUE;
  215. CodeDmaInterrupt();
  216. }
  217. if(I20Intr & IFLAG_GIRQ1)
  218. {
  219. bRet = TRUE;
  220. IntCtrl();
  221. }
  222. return bRet;
  223. }
  224. void dmpgEnableIRQ()
  225. {
  226. DPF((Trace,"IrqEnabled!!\n"));
  227. VideoRestoreInt();
  228. BoardEnableIRQ();
  229. }
  230. void dmpgDisableIRQ()
  231. {
  232. DPF((Trace,"IrqDisabled!!\n"));
  233. VideoMaskInt();
  234. BoardDisableIRQ();
  235. }
  236. void CtrlInitSync(void)
  237. {
  238. switch (pCtrl->CtrlState) {
  239. case CTRL_INIT_SYNC:
  240. /*
  241. Initial synchronisation: the video decoder is always started.
  242. In case of system stream, the STC is initialised in interrupt with first
  243. video PTS available the video state becomes VIDEO_DECODE
  244. When the STC becomes equal (or higher) than the first Audio PTS the audio
  245. decoding can be enabled
  246. In case of Audio only bitstreams the video is stopped and audio enabled
  247. In case of Video only bitstreams, the video decoding continues while
  248. audio is disabled
  249. */
  250. if (VideoGetState() == StateDecode) {
  251. // the STC is initialized in interrupt with (first video PTS - 3 fields)
  252. DWORD Stc;
  253. DWORD PtsAudio;
  254. Stc = AudioGetSTC();
  255. if (AudioIsFirstPTS()) {
  256. PtsAudio = AudioGetPTS();
  257. // if (Stc >= PtsAudio)
  258. {
  259. // AudioDecode();
  260. pCtrl->CtrlState = CTRL_DECODE;
  261. }
  262. }
  263. }
  264. pCtrl->ErrorMsg = VideoGetErrorMsg();
  265. break;
  266. case CTRL_DECODE: // Audio and Video decoders are running
  267. if (pCtrl->ErrorMsg == NO_ERROR)
  268. pCtrl->ErrorMsg = VideoGetErrorMsg();
  269. if (pCtrl->ErrorMsg == NO_ERROR)
  270. pCtrl->ErrorMsg = AudioGetErrorMsg();
  271. break;
  272. default :
  273. break;
  274. }
  275. }
  276. static BOOL IntCtrl(void)
  277. {
  278. long diff;
  279. WORD lattency;
  280. BOOL STIntr = FALSE;
  281. BoardEnterInterrupt();
  282. VideoMaskInt();
  283. // AudioMaskInt();
  284. // STIntr|=AudioAudioInt();
  285. STIntr = VideoVideoInt();
  286. if (Avsync) {
  287. CtrlInitSync();
  288. if (VideoIsFirstDTS()) {
  289. // True only on the start of decode of the first picture with an assoicated valid PTS
  290. DWORD FirstStc;
  291. FirstStc = VideoGetFirstDTS();
  292. AudioInitSTC(FirstStc);
  293. synchronizing = 0;
  294. }
  295. if (AudioGetState() == AUDIO_DECODE) {
  296. if (VideoIsFirstField()) {
  297. synchronizing++;
  298. if (synchronizing >= 20)
  299. {
  300. // We must verify the synchronisation of the video on the audio STC
  301. DWORD latchedSTC, videoPTS;
  302. WORD mode;
  303. latchedSTC = AudioGetVideoSTC();
  304. videoPTS = VideoGetPTS();
  305. mode =pCard->pVideo->StreamInfo.displayMode;
  306. lattency = 2200; /* 1.5 field duration for 60 Hz video */
  307. if (mode == 0) {
  308. lattency = 2700; /* 1.5 field duration for 50 Hz video */
  309. }
  310. diff = latchedSTC - videoPTS;
  311. OldlatchedSTC = latchedSTC;
  312. OldvideoPTS = videoPTS;
  313. //---- If desynchronized
  314. if (labs(diff) > (long)lattency) {
  315. if (diff < 0)
  316. {
  317. VideoRepeat ();
  318. }
  319. else
  320. {
  321. VideoSkip ();
  322. }
  323. }
  324. synchronizing = 0;
  325. }
  326. }
  327. }
  328. }
  329. BoardLeaveInterrupt();
  330. VideoRestoreInt();
  331. // AudioRestoreInt();
  332. return STIntr;
  333. }
  334.