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.

553 lines
12 KiB

  1. /*******************************************************************
  2. *
  3. * MPVIDEO.C
  4. *
  5. * Copyright (C) 1995 SGS-THOMSON Microelectronics.
  6. *
  7. *
  8. * PORT/MINIPORT Interface Video Routines
  9. *
  10. *******************************************************************/
  11. #include "common.h"
  12. #include "strmini.h"
  13. #include "mpst.h"
  14. #include "mpinit.h"
  15. #include "mpvideo.h"
  16. #include "debug.h"
  17. #include "dmpeg.h"
  18. void mpstCommandComplete(PHW_STREAM_REQUEST_BLOCK pSrb);
  19. ULONG miniPortCancelVideo(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->VideoDeviceExt.pCurrentSRB != NULL)
  25. {
  26. // Still to send a packet
  27. pHwDevExt->VideoDeviceExt.pCurrentSRB->Status = STATUS_CANCELLED;
  28. //MpegPortNotification(RequestComplete,VideoDevice,pHwDevExt,
  29. // pHwDevExt->VideoDeviceExt.pCurrentSRB);
  30. //MpegPortNotification(NextRequest,VideoDevice,pHwDevExt);
  31. // Now kill the timer
  32. //MpegPortNotification(RequestTimerCall, VideoDevice,
  33. // pHwDevExt, NULL, 0);
  34. pHwDevExt->VideoDeviceExt.pCurrentSRB = NULL;
  35. }
  36. return dwErrCode;
  37. }
  38. ULONG miniPortClearVideoBuffer(PHW_STREAM_REQUEST_BLOCK pMrb, PHW_DEVICE_EXTENSION pHwDevExt)
  39. {
  40. ULONG dwErrCode = NO_ERROR;
  41. // STB
  42. pHwDevExt = pHwDevExt; // Remove Warning
  43. pMrb = pMrb; // Remove Warning
  44. dwErrCode = ERROR_COMMAND_NOT_IMPLEMENTED;
  45. return dwErrCode;
  46. }
  47. ULONG miniPortVideoEnable(PHW_STREAM_REQUEST_BLOCK pMrb, PHW_DEVICE_EXTENSION pHwDevExt)
  48. {
  49. ULONG dwErrCode = NO_ERROR;
  50. pHwDevExt = pHwDevExt; // Remove Warning
  51. pMrb = pMrb; // Remove Warning
  52. // mpstEnableVideo ( TRUE );
  53. return dwErrCode;
  54. }
  55. ULONG miniPortVideoDisable(PHW_STREAM_REQUEST_BLOCK pMrb, PHW_DEVICE_EXTENSION pHwDevExt)
  56. {
  57. ULONG dwErrCode = NO_ERROR;
  58. pHwDevExt = pHwDevExt; // Remove Warning
  59. pMrb = pMrb; // Remove Warning
  60. // mpstEnableVideo(FALSE);
  61. return dwErrCode;
  62. }
  63. ULONG miniPortVideoEndOfStream(PHW_STREAM_REQUEST_BLOCK pMrb, PHW_DEVICE_EXTENSION pHwDevExt)
  64. {
  65. ULONG dwErrCode = NO_ERROR;
  66. miniPortVideoStop(pMrb, pHwDevExt);
  67. return dwErrCode;
  68. }
  69. ULONG miniPortVideoGetAttribute(PHW_STREAM_REQUEST_BLOCK pMrb, PHW_DEVICE_EXTENSION pHwDevExt)
  70. {
  71. ULONG dwErrCode = NO_ERROR;
  72. pHwDevExt = pHwDevExt; // Remove Warning
  73. #ifdef DEFINEME
  74. switch(pMrb->CommandData.pAttribute->Attribute)
  75. {
  76. // STB
  77. case MpegAttrVideoAGC :
  78. case MpegAttrVideoChannel :
  79. case MpegAttrVideoClamp :
  80. case MpegAttrVideoCoring :
  81. case MpegAttrVideoGain :
  82. case MpegAttrVideoGenLock :
  83. case MpegAttrVideoHue :
  84. case MpegAttrVideoMode :
  85. case MpegAttrVideoSaturation :
  86. case MpegAttrVideoSharpness :
  87. case MpegAttrVideoSignalType :
  88. pMrb->Status = STATUS_INVALID_PARAMETER;
  89. break;
  90. }
  91. #endif
  92. return dwErrCode;
  93. }
  94. ULONG miniPortVideoGetStc(PHW_STREAM_REQUEST_BLOCK pMrb, PHW_DEVICE_EXTENSION pHwDevExt)
  95. {
  96. ULONG dwErrCode = NO_ERROR;
  97. pHwDevExt = pHwDevExt; // Remove Warning
  98. pMrb = pMrb; // Remove Warning
  99. #if 0
  100. // TBI
  101. *pMrb->CommandData.pPresentationDelta = pHwDevExt->VideoDeviceExt.videoSTC;
  102. // pMrb->Status = STATUS_INVALID_PARAMETER;
  103. #endif
  104. return dwErrCode;
  105. }
  106. void VideoPacketStub(PHW_STREAM_OBJECT pstrm)
  107. {
  108. //
  109. // VideoTimerCallBack(pSrb->StreamObject);
  110. //
  111. dmpgDisableIRQ();
  112. StreamClassCallAtNewPriority(pstrm, pstrm->HwDeviceExtension,
  113. Dispatch,
  114. VideoTimerCallBack, pstrm);
  115. }
  116. VOID miniPortVideoPacket(PHW_STREAM_REQUEST_BLOCK pSrb)
  117. {
  118. ULONG dwErrCode = NO_ERROR;
  119. ULONG uSent=0;
  120. PHW_DEVICE_EXTENSION pHwDevExt =
  121. ((PHW_DEVICE_EXTENSION)pSrb->HwDeviceExtension);
  122. PVIDEO_DEVICE_EXTENSION pvidex =
  123. &(((PHW_DEVICE_EXTENSION)pSrb->HwDeviceExtension)->VideoDeviceExt);
  124. //
  125. // set up for initial parsing of the scatter gather packet.
  126. //
  127. pvidex->cPacket = pvidex->cOffs = 0;
  128. if (!pSrb->CommandData.DataBuffer) {
  129. return(miniPortVideoEndOfStream(pSrb, pHwDevExt));
  130. }
  131. pvidex->pPacket = &(pSrb->CommandData.DataBuffer->DataPacket);
  132. pvidex->pCurrentSRB = pSrb;
  133. pHwDevExt->VideoDeviceExt.videoSTC =
  134. pvidex->pPacket->PresentationDelta;
  135. VideoPacketStub(pSrb->StreamObject);
  136. }
  137. VOID miniPortGetProperty(PHW_STREAM_REQUEST_BLOCK pSrb)
  138. {
  139. PHW_DEVICE_EXTENSION phwdevext =
  140. ((PHW_DEVICE_EXTENSION)pSrb->HwDeviceExtension);
  141. TRAP
  142. switch (pSrb->CommandData.PropertyInfo->PropertySetID)
  143. {
  144. case 0:
  145. TRAP
  146. // mpstGetVidLvl(pSrb);
  147. break;
  148. default:
  149. break;
  150. }
  151. pSrb->Status = STATUS_SUCCESS;
  152. mpstCtrlCommandComplete(pSrb);
  153. }
  154. VOID miniPortSetState(PHW_STREAM_REQUEST_BLOCK pSrb)
  155. {
  156. PHW_DEVICE_EXTENSION phwdevext =
  157. ((PHW_DEVICE_EXTENSION)pSrb->HwDeviceExtension);
  158. switch (pSrb->CommandData.StreamState)
  159. {
  160. case KSSTATE_STOP:
  161. miniPortVideoStop(pSrb, phwdevext);
  162. break;
  163. case KSSTATE_PAUSE:
  164. miniPortVideoPause(pSrb, phwdevext);
  165. break;
  166. case KSSTATE_RUN:
  167. miniPortVideoPlay(pSrb, phwdevext);
  168. }
  169. pSrb->Status = STATUS_SUCCESS;
  170. mpstCtrlCommandComplete(pSrb);
  171. }
  172. ULONG miniPortVideoPause(PHW_STREAM_REQUEST_BLOCK pSrb, PHW_DEVICE_EXTENSION pHwDevExt)
  173. {
  174. ULONG dwErrCode = NO_ERROR;
  175. pSrb = pSrb; // Remove Warning
  176. // mpstVideoPause ();
  177. dmpgPause();
  178. pHwDevExt->VideoDeviceExt.DeviceState = KSSTATE_PAUSE;
  179. return dwErrCode;
  180. }
  181. ULONG miniPortVideoPlay(PHW_STREAM_REQUEST_BLOCK pSrb, PHW_DEVICE_EXTENSION pHwDevExt)
  182. {
  183. ULONG dwErrCode = NO_ERROR;
  184. // mpstVideoPlay();
  185. DebugPrint((DebugLevelVerbose, "Calling Play!!!!"));
  186. dmpgPlay();
  187. pHwDevExt->VideoDeviceExt.DeviceState = KSSTATE_RUN;
  188. pSrb = pSrb; // Remove Warning
  189. return dwErrCode;
  190. }
  191. ULONG miniPortVideoQueryInfo (PHW_STREAM_REQUEST_BLOCK pSrb, PHW_DEVICE_EXTENSION pHwDevExt)
  192. {
  193. ULONG dwErrCode = NO_ERROR;
  194. #ifdef DEFINEME
  195. pSrb -> CommandData.pDeviceInfo->DeviceState =
  196. pHwDevExt->VideoDeviceExt.DeviceState;
  197. pSrb -> CommandData.pDeviceInfo->DecoderBufferSize = mpstVideoDecoderBufferSize();
  198. pSrb -> CommandData.pDeviceInfo->DecoderBufferFullness = mpstVideoDecoderBufferFullness();
  199. #endif
  200. return dwErrCode;
  201. }
  202. ULONG miniPortVideoReset(PHW_STREAM_REQUEST_BLOCK pSrb, PHW_DEVICE_EXTENSION pHwDevExt)
  203. {
  204. ULONG dwErrCode = NO_ERROR;
  205. // TBC
  206. // mpstVideoReset();
  207. dmpgSeek();
  208. pHwDevExt->VideoDeviceExt.DeviceState = KSSTATE_PAUSE;
  209. pSrb->Status = STATUS_SUCCESS;
  210. return dwErrCode;
  211. }
  212. ULONG miniPortVideoSetAttribute(PHW_STREAM_REQUEST_BLOCK pSrb, PHW_DEVICE_EXTENSION pHwDevExt)
  213. {
  214. ULONG dwErrCode = NO_ERROR;
  215. pHwDevExt = pHwDevExt; // Remove Warning
  216. // STB
  217. #ifdef DEFINEME
  218. switch(pSrb->CommandData.pAttribute->Attribute)
  219. {
  220. case MpegAttrVideoAGC :
  221. case MpegAttrVideoChannel :
  222. case MpegAttrVideoClamp :
  223. case MpegAttrVideoCoring :
  224. case MpegAttrVideoGain :
  225. case MpegAttrVideoGenLock :
  226. case MpegAttrVideoHue :
  227. case MpegAttrVideoMode :
  228. case MpegAttrVideoSaturation :
  229. case MpegAttrVideoSharpness :
  230. case MpegAttrVideoSignalType :
  231. dwErrCode = ERROR_COMMAND_NOT_IMPLEMENTED;
  232. break;
  233. }
  234. #endif
  235. return dwErrCode;
  236. }
  237. ULONG miniPortVideoSetStc(PHW_STREAM_REQUEST_BLOCK pSrb, PHW_DEVICE_EXTENSION pHwDevExt)
  238. {
  239. ULONG dwErrCode = NO_ERROR;
  240. pHwDevExt = pHwDevExt; // Remove Warning
  241. pSrb = pSrb; // Remove Warning
  242. #if 0
  243. // TBI
  244. // pSrb->Status = STATUS_INVALID_PARAMETER;
  245. #endif
  246. return dwErrCode;
  247. }
  248. ULONG miniPortVideoStop (PHW_STREAM_REQUEST_BLOCK pSrb, PHW_DEVICE_EXTENSION pHwDevExt)
  249. {
  250. ULONG dwErrCode = NO_ERROR;
  251. // TBC
  252. pHwDevExt->VideoDeviceExt.DeviceState = KSSTATE_PAUSE;
  253. if(pHwDevExt->VideoDeviceExt.pCurrentSRB != NULL)
  254. {
  255. // Still to send a packet
  256. pHwDevExt->VideoDeviceExt.pCurrentSRB->Status = STATUS_CANCELLED;
  257. StreamClassStreamNotification(ReadyForNextStreamDataRequest,
  258. pHwDevExt->VideoDeviceExt.pCurrentSRB->StreamObject);
  259. StreamClassStreamNotification(StreamRequestComplete,
  260. pHwDevExt->VideoDeviceExt.pCurrentSRB->StreamObject,
  261. pHwDevExt->VideoDeviceExt.pCurrentSRB);
  262. //
  263. // request a timer callback
  264. //
  265. StreamClassScheduleTimer(pSrb->StreamObject, pSrb->HwDeviceExtension,
  266. 0, VideoPacketStub, pSrb->StreamObject);
  267. pHwDevExt->VideoDeviceExt.pCurrentSRB =
  268. pHwDevExt->pCurSrb = NULL;
  269. }
  270. // mpstVideoStop();
  271. dmpgStop();
  272. pSrb->Status = STATUS_SUCCESS;
  273. return dwErrCode;
  274. }
  275. VOID VideoTimerCallBack(PHW_STREAM_OBJECT pstrm)
  276. {
  277. PHW_DEVICE_EXTENSION pdevext = pstrm->HwDeviceExtension;
  278. PHW_STREAM_REQUEST_BLOCK pSrb;
  279. ULONG uSent;
  280. PVIDEO_DEVICE_EXTENSION pvidex = &(pdevext->VideoDeviceExt);
  281. pSrb = pvidex->pCurrentSRB;
  282. // dmpgEnableIRQ();
  283. if (!pSrb)
  284. {
  285. TRAP
  286. return;
  287. }
  288. do
  289. {
  290. uSent = mpstVideoPacket(pSrb);
  291. pvidex->cOffs += uSent;
  292. //
  293. // check if we finished this packet. If so, go on to the
  294. // next packet
  295. //
  296. if (pvidex->cOffs >=
  297. pvidex->pPacket->DataPacketLength)
  298. {
  299. pvidex->pPacket++;
  300. //
  301. // reset the packet offset
  302. //
  303. pvidex->cOffs = 0;
  304. pvidex->cPacket = (ULONG)pvidex->cPacket
  305. + sizeof (KSDATA_PACKET);
  306. //
  307. // if we have finished all the packets, then we are done
  308. //
  309. if (pvidex->cPacket >=
  310. pSrb->CommandData.DataBuffer->DataHeader.DataSize)
  311. {
  312. pSrb->Status = STATUS_SUCCESS;
  313. pvidex->pCurrentSRB = 0;
  314. mpstCommandComplete(pSrb);
  315. StreamClassCallAtNewPriority(pstrm,
  316. pstrm->HwDeviceExtension,
  317. High,
  318. StubMpegEnableIRQ,
  319. pstrm);
  320. return;
  321. }
  322. }
  323. } while (uSent);
  324. //
  325. // request a timer callback
  326. //
  327. StreamClassScheduleTimer(pstrm, pstrm->HwDeviceExtension,
  328. VIDEO_PACKET_TIMER, VideoPacketStub, pstrm);
  329. StreamClassCallAtNewPriority(pstrm,
  330. pstrm->HwDeviceExtension,
  331. High,
  332. StubMpegEnableIRQ,
  333. pstrm);
  334. }
  335. void StubMpegEnableIRQ(PHW_STREAM_OBJECT pstrm)
  336. {
  337. dmpgEnableIRQ();
  338. }
  339. ULONG mpstVideoPacket(PHW_STREAM_REQUEST_BLOCK pSrb)
  340. {
  341. PVIDEO_DEVICE_EXTENSION pvidex =
  342. &(((PHW_DEVICE_EXTENSION)pSrb->HwDeviceExtension)->VideoDeviceExt);
  343. PUCHAR pPacket;
  344. ULONG uLen;
  345. ULONG cPacket;
  346. PUCHAR p;
  347. #define MAX_SIZE 8192
  348. //
  349. // find out how many bytes we can squeeze in
  350. //
  351. uLen = MAX_SIZE; //(BUF_FULL - VideoGetBBL()) * 256;
  352. if(pvidex -> cOffs == 0)
  353. {
  354. p = (PUCHAR)(pvidex->pPacket->DataPacket);
  355. pvidex->cOffs = p[8]+9;
  356. }
  357. cPacket = pvidex->pPacket->DataPacketLength - pvidex->cOffs;
  358. uLen = uLen > cPacket ? cPacket : uLen;
  359. if(uLen > MAX_SIZE)
  360. uLen = MAX_SIZE;
  361. // AVSYNC BUG to be fixed here.
  362. // Dont Latch PTS every time.
  363. if (uLen)
  364. {
  365. //
  366. // send the bytes that we can fit
  367. //
  368. return dmpgSendVideo((PDWORD)(((ULONG)pvidex->pPacket->DataPacket) + pvidex->cOffs), uLen);
  369. }
  370. return uLen;
  371. }
  372. /////////////////////////////////////////////////////////////////////////
  373. //
  374. // Function : mpstCommandComplete
  375. // Args : SRB
  376. // Returns : none
  377. //
  378. // Purpose:
  379. // Performs a completion callback on a given request,
  380. // and then dequeues any outstanding requests
  381. //
  382. // Last Modified 10.1.96 by JBS
  383. //
  384. /////////////////////////////////////////////////////////////////////////
  385. void mpstCommandComplete(PHW_STREAM_REQUEST_BLOCK pSrb)
  386. {
  387. PHW_STREAM_REQUEST_BLOCK pNextSrb;
  388. PHW_DEVICE_EXTENSION pHwDevExt =
  389. ((PHW_DEVICE_EXTENSION)pSrb->HwDeviceExtension);
  390. //
  391. // see if there is a request outstanding on either queue.
  392. // if there is, go ahead and start it.
  393. //
  394. //
  395. // Note: this code cannot be re-entered!
  396. //
  397. pHwDevExt ->pCurSrb = 0;
  398. StreamStartCommand(pHwDevExt);
  399. //
  400. // now, go ahead and complete this request
  401. //
  402. StreamClassStreamNotification(ReadyForNextStreamDataRequest,
  403. pSrb->StreamObject);
  404. StreamClassStreamNotification(StreamRequestComplete,
  405. pSrb->StreamObject,
  406. pSrb);
  407. }
  408.