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.

436 lines
10 KiB

  1. /*******************************************************************
  2. *
  3. * MPAUDIO.C
  4. *
  5. * Copyright (C) 1995 SGS-THOMSON Microelectronics.
  6. *
  7. *
  8. * PORT/MINIPORT Interface Audio Routines
  9. *
  10. *******************************************************************/
  11. #include "common.h"
  12. #include "strmini.h"
  13. #include "mpst.h"
  14. #include "mpinit.h"
  15. #include "mpaudio.h"
  16. #include "debug.h"
  17. #include "dmpeg.h"
  18. void StubMpegEnableIRQ(PHW_STREAM_OBJECT pstrm);
  19. ULONG miniPortCancelAudio(PHW_STREAM_REQUEST_BLOCK pMrb, PHW_DEVICE_EXTENSION pHwDevExt)
  20. {
  21. ULONG dwErrCode = NO_ERROR;
  22. // TBD
  23. pMrb->Status = STATUS_SUCCESS;
  24. if(pHwDevExt->AudioDeviceExt.pCurrentSRB != NULL)
  25. {
  26. #if 0
  27. // Still to send a packet
  28. pHwDevExt->AudioDeviceExt.pCurrentSRB->Status = MrbStatusCancelled;
  29. //MpegPortNotification(RequestComplete,AudioDevice,pHwDevExt,
  30. pHwDevExt->AudioDeviceExt.pCurrentSRB);
  31. //MpegPortNotification(NextRequest,AudioDevice,pHwDevExt);
  32. // Now kill the timer
  33. //MpegPortNotification(RequestTimerCall, AudioDevice,
  34. pHwDevExt, NULL, 0);
  35. pHwDevExt->AudioDeviceExt.pCurrentSRB = NULL;
  36. #endif
  37. }
  38. return dwErrCode;
  39. }
  40. ULONG miniPortAudioEnable(PHW_STREAM_REQUEST_BLOCK pMrb, PHW_DEVICE_EXTENSION pHwDevExt)
  41. {
  42. ULONG dwErrCode = NO_ERROR;
  43. pHwDevExt = pHwDevExt;// Remove Warning
  44. pMrb = pMrb; // Remove Warning
  45. // mpstEnableAudio(TRUE);
  46. return dwErrCode;
  47. }
  48. VOID miniPortAudioGetProperty(PHW_STREAM_REQUEST_BLOCK pSrb)
  49. {
  50. PHW_DEVICE_EXTENSION phwdevext =
  51. ((PHW_DEVICE_EXTENSION)pSrb->HwDeviceExtension);
  52. pSrb->Status = STATUS_SUCCESS;
  53. mpstCtrlCommandComplete(pSrb);
  54. }
  55. VOID miniPortAudioSetState(PHW_STREAM_REQUEST_BLOCK pSrb)
  56. {
  57. PHW_DEVICE_EXTENSION phwdevext =
  58. ((PHW_DEVICE_EXTENSION)pSrb->HwDeviceExtension);
  59. pSrb->Status = STATUS_SUCCESS;
  60. mpstCtrlCommandComplete(pSrb);
  61. }
  62. ULONG miniPortAudioDisable(PHW_STREAM_REQUEST_BLOCK pMrb, PHW_DEVICE_EXTENSION pHwDevExt)
  63. {
  64. ULONG dwErrCode = NO_ERROR;
  65. pHwDevExt = pHwDevExt;// Remove Warning
  66. pMrb = pMrb; // Remove Warning
  67. // mpstEnableAudio(FALSE);
  68. return dwErrCode;
  69. }
  70. ULONG miniPortAudioEndOfStream(PHW_STREAM_REQUEST_BLOCK pMrb, PHW_DEVICE_EXTENSION pHwDevExt)
  71. {
  72. ULONG dwErrCode = NO_ERROR;
  73. StreamClassStreamNotification(ReadyForNextStreamDataRequest,
  74. pMrb->StreamObject);
  75. StreamClassStreamNotification(StreamRequestComplete,
  76. pMrb->StreamObject,
  77. pMrb);
  78. pMrb->Status = STATUS_SUCCESS;
  79. return dwErrCode;
  80. }
  81. ULONG miniPortAudioGetAttribute(PHW_STREAM_REQUEST_BLOCK pMrb, PHW_DEVICE_EXTENSION pHwDevExt)
  82. {
  83. ULONG dwErrCode = NO_ERROR;
  84. pHwDevExt = pHwDevExt;// Remove Warning
  85. #ifdef DEFINEME
  86. switch(pMrb->CommandData.pAttribute->Attribute)
  87. {
  88. // STB
  89. case MpegAttrAudioBass :
  90. case MpegAttrAudioChannel :
  91. case MpegAttrAudioMode :
  92. case MpegAttrMaximumAudioAttribute :
  93. case MpegAttrAudioTreble :
  94. pMrb->Status = ;
  95. break;
  96. // TBI
  97. case MpegAttrAudioVolumeLeft :
  98. pMrb->CommandData.pAttribute->Value = 20;
  99. break;
  100. case MpegAttrAudioVolumeRight :
  101. pMrb->CommandData.pAttribute->Value = 20;
  102. break;
  103. }
  104. #endif
  105. return dwErrCode;
  106. }
  107. ULONG miniPortAudioGetStc(PHW_STREAM_REQUEST_BLOCK pMrb, PHW_DEVICE_EXTENSION pHwDevExt)
  108. {
  109. ULONG dwErrCode = NO_ERROR;
  110. pHwDevExt = pHwDevExt; // Remove Warning
  111. pMrb = pMrb; // Remove Warning
  112. #if 0
  113. // TBI
  114. *pMrb->CommandData.pPresentationDelta = pHwDevExt->AudioDeviceExt.audioSTC;
  115. // pMrb->Status = MrbStatusUnsupportedComand;
  116. #endif
  117. return dwErrCode;
  118. }
  119. ULONG miniPortAudioPause(PHW_STREAM_REQUEST_BLOCK pMrb, PHW_DEVICE_EXTENSION pHwDevExt)
  120. {
  121. ULONG dwErrCode = NO_ERROR;
  122. pMrb = pMrb; // Remove Warning
  123. // mpstAudioPause();
  124. pHwDevExt->AudioDeviceExt.DeviceState = KSSTATE_PAUSE;
  125. return dwErrCode;
  126. }
  127. ULONG miniPortAudioPlay(PHW_STREAM_REQUEST_BLOCK pMrb, PHW_DEVICE_EXTENSION pHwDevExt)
  128. {
  129. ULONG dwErrCode = NO_ERROR;
  130. pHwDevExt = pHwDevExt; // Remove Warning
  131. pMrb = pMrb;
  132. pHwDevExt->AudioDeviceExt.DeviceState = KSSTATE_RUN;
  133. return dwErrCode;
  134. }
  135. ULONG miniPortAudioQueryInfo (PHW_STREAM_REQUEST_BLOCK pMrb, PHW_DEVICE_EXTENSION pHwDevExt)
  136. {
  137. ULONG dwErrCode = NO_ERROR;
  138. #ifdef DEFINEME
  139. pMrb -> CommandData.pDeviceInfo->DeviceState =
  140. pHwDevExt->AudioDeviceExt.DeviceState;
  141. pMrb -> CommandData.pDeviceInfo->DecoderBufferSize =
  142. mpstAudioDecoderBufferSize();
  143. pMrb -> CommandData.pDeviceInfo->DecoderBufferFullness =
  144. mpstAudioDecoderBufferFullness();
  145. #endif
  146. return dwErrCode;
  147. }
  148. ULONG miniPortAudioReset(PHW_STREAM_REQUEST_BLOCK pMrb, PHW_DEVICE_EXTENSION pHwDevExt)
  149. {
  150. ULONG dwErrCode = NO_ERROR;
  151. // TBC
  152. pHwDevExt->AudioDeviceExt.DeviceState = KSSTATE_PAUSE;
  153. pMrb->Status = STATUS_SUCCESS;
  154. return dwErrCode;
  155. }
  156. ULONG miniPortAudioSetAttribute(PHW_STREAM_REQUEST_BLOCK pMrb, PHW_DEVICE_EXTENSION pHwDevExt)
  157. {
  158. ULONG dwErrCode = NO_ERROR;
  159. pHwDevExt = pHwDevExt; // Remove Warning
  160. #ifdef DEFINEME
  161. switch(pMrb->CommandData.pAttribute->Attribute)
  162. {
  163. case MpegAttrAudioBass :
  164. case MpegAttrAudioChannel :
  165. case MpegAttrAudioMode :
  166. case MpegAttrAudioTreble :
  167. dwErrCode = ERROR_COMMAND_NOT_IMPLEMENTED;
  168. break;
  169. // TBI
  170. case MpegAttrMaximumAudioAttribute :
  171. case MpegAttrAudioVolumeLeft :
  172. case MpegAttrAudioVolumeRight :
  173. dwErrCode = ERROR_COMMAND_NOT_IMPLEMENTED;
  174. break;
  175. }
  176. #endif
  177. return dwErrCode;
  178. }
  179. ULONG miniPortAudioSetStc(PHW_STREAM_REQUEST_BLOCK pMrb, PHW_DEVICE_EXTENSION pHwDevExt)
  180. {
  181. ULONG dwErrCode = NO_ERROR;
  182. pHwDevExt = pHwDevExt; // Remove Warning
  183. pMrb = pMrb; // Remove Warning
  184. #if 0
  185. // TBI
  186. // pMrb->Status = MrbStatusUnsupportedComand;
  187. #endif
  188. return dwErrCode;
  189. }
  190. ULONG miniPortAudioStop (PHW_STREAM_REQUEST_BLOCK pMrb, PHW_DEVICE_EXTENSION pHwDevExt)
  191. {
  192. ULONG dwErrCode = NO_ERROR;
  193. // TBC
  194. if(pHwDevExt->AudioDeviceExt.pCurrentSRB != NULL)
  195. {
  196. // Still to send a packet
  197. pHwDevExt->AudioDeviceExt.pCurrentSRB->Status = STATUS_CANCELLED;
  198. //MpegPortNotification(RequestComplete,AudioDevice,pHwDevExt,
  199. // pHwDevExt->AudioDeviceExt.pCurrentSRB);
  200. //MpegPortNotification(NextRequest,AudioDevice,pHwDevExt);
  201. // Now kill the timer
  202. //MpegPortNotification(RequestTimerCall, AudioDevice,
  203. // pHwDevExt, NULL, 0);
  204. pHwDevExt->AudioDeviceExt.pCurrentSRB = NULL;
  205. }
  206. pHwDevExt->AudioDeviceExt.DeviceState = KSSTATE_PAUSE;
  207. pMrb->Status = STATUS_SUCCESS;
  208. return dwErrCode;
  209. }
  210. void AudioPacketStub(PHW_STREAM_OBJECT pstrm)
  211. {
  212. dmpgDisableIRQ();
  213. StreamClassCallAtNewPriority(pstrm, pstrm->HwDeviceExtension,
  214. Dispatch,
  215. AudioTimerCallBack, pstrm);
  216. }
  217. VOID miniPortAudioPacket(PHW_STREAM_REQUEST_BLOCK pSrb)
  218. {
  219. PHW_DEVICE_EXTENSION pHwDevExt =
  220. ((PHW_DEVICE_EXTENSION)pSrb->HwDeviceExtension);
  221. PAUDIO_DEVICE_EXTENSION paudex =
  222. &(((PHW_DEVICE_EXTENSION)pSrb->HwDeviceExtension)->AudioDeviceExt);
  223. //
  224. // set up for initial parsing of the scatter gather packet.
  225. //
  226. paudex->cPacket = paudex->cOffs = 0;
  227. if (!pSrb->CommandData.DataBuffer) {
  228. TRAP
  229. return(miniPortAudioEndOfStream(pSrb, pHwDevExt));
  230. }
  231. paudex->pPacket = &(pSrb->CommandData.DataBuffer->DataPacket);
  232. paudex->pCurrentSRB = pSrb;
  233. AudioPacketStub(pSrb->StreamObject);
  234. }
  235. VOID AudioTimerCallBack(PHW_STREAM_OBJECT pstrm)
  236. {
  237. PHW_DEVICE_EXTENSION pdevext = pstrm->HwDeviceExtension;
  238. PHW_STREAM_REQUEST_BLOCK pSrb;
  239. ULONG uSent;
  240. PAUDIO_DEVICE_EXTENSION paudex = &(pdevext->AudioDeviceExt);
  241. pSrb = paudex->pCurrentSRB;
  242. // dmpgEnableIRQ();
  243. if (!pSrb)
  244. {
  245. TRAP
  246. return;
  247. }
  248. do
  249. {
  250. uSent = mpstAudioPacket(pSrb);
  251. paudex->cOffs += uSent;
  252. //
  253. // check if we finished this packet. If so, go on to the
  254. // next packet
  255. //
  256. if (paudex->cOffs >=
  257. paudex->pPacket->DataPacketLength)
  258. {
  259. paudex->pPacket++;
  260. //
  261. // reset the packet offset
  262. //
  263. paudex->cOffs = 0;
  264. paudex->cPacket = (ULONG)paudex->cPacket
  265. + sizeof (KSDATA_PACKET);
  266. //
  267. // if we have finished all the packets, then we are done
  268. //
  269. if (paudex->cPacket >=
  270. pSrb->CommandData.DataBuffer->DataHeader.DataSize)
  271. {
  272. pSrb->Status = STATUS_SUCCESS;
  273. paudex->pCurrentSRB = 0;
  274. mpstCommandComplete(pSrb);
  275. return;
  276. }
  277. }
  278. } while (uSent);
  279. //
  280. // request a timer callback
  281. //
  282. StreamClassScheduleTimer(pstrm, pstrm->HwDeviceExtension,
  283. AUDIO_PACKET_TIMER, AudioPacketStub, pstrm);
  284. StreamClassCallAtNewPriority(pstrm,
  285. pstrm->HwDeviceExtension,
  286. High,
  287. StubMpegEnableIRQ,
  288. pstrm);
  289. }
  290. ULONG mpstAudioPacket(PHW_STREAM_REQUEST_BLOCK pSrb)
  291. {
  292. PAUDIO_DEVICE_EXTENSION paudex =
  293. &(((PHW_DEVICE_EXTENSION)pSrb->HwDeviceExtension)->AudioDeviceExt);
  294. PUCHAR pPacket;
  295. ULONG uLen;
  296. PUCHAR p;
  297. ULONG cPacket;
  298. #define MAX_SIZE 8192
  299. //
  300. // find out how many bytes we can squeeze in
  301. //
  302. uLen = MAX_SIZE; //(BUF_FULL - VideoGetBBL()) * 256;
  303. if(!paudex->pPacket)
  304. return 0;
  305. if(paudex -> cOffs == 0)
  306. {
  307. p = (PUCHAR)(paudex->pPacket->DataPacket);
  308. paudex->cOffs = p[8]+13;
  309. }
  310. cPacket = paudex->pPacket->DataPacketLength - paudex->cOffs;
  311. uLen = uLen > cPacket ? cPacket : uLen;
  312. if(uLen > MAX_SIZE)
  313. uLen = MAX_SIZE;
  314. // AVSYNC BUG to be fixed here.
  315. // Dont Latch PTS every time.
  316. if (uLen)
  317. {
  318. //
  319. // send the bytes that we can fit
  320. //
  321. return dmpgSendAudio((LPBYTE)(((ULONG)paudex->pPacket->DataPacket) + paudex->cOffs), uLen);
  322. }
  323. return uLen;
  324. }
  325.