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.

1032 lines
25 KiB

  1. /******************************************************************************\
  2. * *
  3. * AUDSTRM.C - Audio stream control related code. *
  4. * *
  5. * Copyright (c) C-Cube Microsystems 1998 *
  6. * All Rights Reserved. *
  7. * *
  8. * Use of C-Cube Microsystems code is governed by terms and conditions *
  9. * stated in the accompanying licensing statement. *
  10. * *
  11. \******************************************************************************/
  12. #include "Headers.h"
  13. #pragma hdrstop
  14. #include "copyprot.h"
  15. #include "audstrm.h"
  16. #include "bmaster.h"
  17. #include "cl6100.h"
  18. #define TRAP MonoOutStr("TRAP");
  19. typedef struct _MYTIME{
  20. KSEVENT_TIME_INTERVAL tim;
  21. LONGLONG LastTime;
  22. } MYTIME, *PMYTIME;
  23. extern PHW_DEVICE_EXTENSION pDevEx;
  24. //*****************************************************************************
  25. // STATIC FUNCTIONS DECLARATION
  26. //*****************************************************************************
  27. static void GetAudioProperty( PHW_STREAM_REQUEST_BLOCK pSrb );
  28. static void SetAudioProperty( PHW_STREAM_REQUEST_BLOCK pSrb );
  29. static void GetAudioRateChange( PHW_STREAM_REQUEST_BLOCK pSrb );
  30. static void SetAudioRateChange( PHW_STREAM_REQUEST_BLOCK pSrb );
  31. static void AudioSendPacket( PHW_STREAM_REQUEST_BLOCK pSrb );
  32. static void AudioQueryAccept( PHW_STREAM_REQUEST_BLOCK pSrb );
  33. static ULONGLONG GetSystemTime();
  34. static ULONGLONG ConvertPTStoStrm( ULONG pts );
  35. extern BOOL bJustHighLight;
  36. BOOL fClkPause;
  37. static ULONGLONG LastStamp;
  38. extern PHW_DEVICE_EXTENSION pDevEx;
  39. /*
  40. ** AudioReceiveCtrlPacket()
  41. **
  42. ** Receives packet commands that control the Audio stream
  43. **
  44. ** Arguments:
  45. **
  46. ** pSrb - The stream request block for the Audio stream
  47. **
  48. ** Returns:
  49. **
  50. ** Side Effects: none
  51. */
  52. VOID STREAMAPI AudioReceiveCtrlPacket( IN PHW_STREAM_REQUEST_BLOCK pSrb )
  53. {
  54. PHW_DEVICE_EXTENSION pdevext = (PHW_DEVICE_EXTENSION)pSrb->HwDeviceExtension;
  55. DebugPrint(( DebugLevelVerbose, "ZiVA: Begin AudioReceiveCtrlPacket -> " ));
  56. // set default status
  57. switch( pSrb->Command )
  58. {
  59. case SRB_SET_STREAM_STATE:
  60. DebugPrint(( DebugLevelVerbose, "SRB_SET_STREAM_STATE\n" ));
  61. AdapterSetState( pSrb );
  62. break;
  63. case SRB_GET_STREAM_PROPERTY:
  64. DebugPrint(( DebugLevelVerbose, "SRB_GET_STREAM_PROPERTY\n" ));
  65. GetAudioProperty( pSrb );
  66. break;
  67. case SRB_SET_STREAM_PROPERTY:
  68. DebugPrint(( DebugLevelVerbose, "SRB_SET_STREAM_PROPERTY\n" ));
  69. SetAudioProperty( pSrb );
  70. break;
  71. case SRB_OPEN_MASTER_CLOCK: // indicates that the master clock is on this stream
  72. case SRB_INDICATE_MASTER_CLOCK: // supplies the handle to the master clock
  73. case SRB_CLOSE_MASTER_CLOCK: // indicates that the master clock is closed
  74. pSrb->Status = STATUS_SUCCESS;
  75. break;
  76. case SRB_PROPOSE_DATA_FORMAT: // propose a new format, DOES NOT CHANGE IT!
  77. DebugPrint(( DebugLevelVerbose, "SRB_PROPOSE_DATA_FORMAT\n" ));
  78. AudioQueryAccept( pSrb );
  79. break;
  80. case SRB_PROPOSE_STREAM_RATE: // propose a new rate, DOES NOT CHANGE IT!
  81. pSrb->Status = STATUS_SUCCESS;
  82. DebugPrint(( DebugLevelVerbose, "SRB_PROPOSE_STREAM_RATE\n" ));
  83. break;
  84. case SRB_SET_STREAM_RATE: // set the rate at which the stream should run
  85. pSrb->Status = STATUS_SUCCESS;
  86. DebugPrint(( DebugLevelVerbose, "SRB_SET_STREAM_RATE\n" ));
  87. break;
  88. case SRB_BEGIN_FLUSH : // beginning flush state
  89. MonoOutStr(" Aud : SRB_BEGIN_FLUSH ");
  90. #ifndef DECODER_DVDPC
  91. pdevext->bInterruptPending = FALSE;
  92. #endif
  93. if (pdevext->pCurrentAudioSrb != NULL)
  94. {
  95. ZivaHw_Abort();
  96. // adapterUpdateNextSrbOrderNumberOnDiscardSrb(pdevext->pCurrentAudioSrb);
  97. pdevext->pCurrentAudioSrb->Status = STATUS_SUCCESS;
  98. AdapterReleaseRequest( pdevext->pCurrentAudioSrb );
  99. pdevext->pCurrentAudioSrb = NULL;
  100. pdevext->dwCurrentAudioSample = 0;
  101. pdevext->dwCurrentAudioPage = 0;
  102. }
  103. pSrb->Status = STATUS_SUCCESS;
  104. break;
  105. case SRB_END_FLUSH : // ending flush state
  106. MonoOutStr(" Aud : SRB_END_FLUSH ");
  107. pSrb->Status = STATUS_SUCCESS;
  108. if (pdevext->pCurrentAudioSrb != NULL)
  109. {
  110. // adapterUpdateNextSrbOrderNumberOnDiscardSrb(pdevext->pCurrentAudioSrb);
  111. pdevext->pCurrentAudioSrb->Status = STATUS_SUCCESS;
  112. AdapterReleaseRequest( pdevext->pCurrentAudioSrb );
  113. pdevext->pCurrentAudioSrb = NULL;
  114. pdevext->dwCurrentAudioSample = 0;
  115. pdevext->dwCurrentAudioPage = 0;
  116. }
  117. // ZivaHw_Play();
  118. pdevext->bPlayCommandPending = TRUE;
  119. pdevext->bEndFlush = TRUE;
  120. // FinishCurrentPacketAndSendNextOne( pdevext );
  121. break;
  122. case SRB_UNKNOWN_STREAM_COMMAND:// IRP function is unknown to class driver
  123. default:
  124. DebugPrint(( DebugLevelInfo, "!!!! UNKNOWN COMMAND !!!! :::> %X\n", pSrb->Command ));
  125. pSrb->Status = STATUS_NOT_IMPLEMENTED;
  126. }
  127. AdapterReleaseRequest( pSrb );
  128. DebugPrint(( DebugLevelVerbose, "ZiVA: End AudioReceiveCtrlPacket\n" ));
  129. }
  130. /*
  131. ** AudioReceiveDataPacket()
  132. **
  133. ** Receives Audio data packet commands
  134. **
  135. ** Arguments:
  136. **
  137. ** pSrb - Stream request block for the Audio device
  138. **
  139. ** Returns:
  140. **
  141. ** Side Effects: none
  142. */
  143. VOID STREAMAPI AudioReceiveDataPacket(IN PHW_STREAM_REQUEST_BLOCK pSrb)
  144. {
  145. PHW_DEVICE_EXTENSION pdevext =
  146. ((PHW_DEVICE_EXTENSION)pSrb->HwDeviceExtension);
  147. switch (pSrb->Command)
  148. {
  149. case SRB_WRITE_DATA:
  150. if(bJustHighLight)
  151. {
  152. pSrb->TimeoutCounter = pSrb->TimeoutOriginal = pSrb->TimeoutCounter / 5;
  153. bJustHighLight = FALSE;
  154. MonoOutStr("Audio TimeOut Counter Reduced");
  155. }
  156. AudioSendPacket(pSrb);
  157. break;
  158. default:
  159. DebugPrint(( DebugLevelWarning, "!!!! UNKNOWN COMMAND !!!! :::> %X\n", pSrb->Command ));
  160. pSrb->Status = STATUS_NOT_IMPLEMENTED;
  161. AdapterReleaseRequest( pSrb );
  162. }
  163. }
  164. //
  165. // default to downmixed stereo output
  166. //
  167. ULONG audiodecoutmode = KSAUDDECOUTMODE_STEREO_ANALOG;
  168. /*
  169. ** GetAudioProperty()
  170. **
  171. ** Routine to process Audio property requests
  172. **
  173. ** Arguments:
  174. **
  175. ** pSrb - pointer to the stream request block for properties
  176. **
  177. ** Returns:
  178. **
  179. ** Side Effects: none
  180. */
  181. static void GetAudioProperty(PHW_STREAM_REQUEST_BLOCK pSrb)
  182. {
  183. PHW_DEVICE_EXTENSION phwdevext = (PHW_DEVICE_EXTENSION)pSrb->HwDeviceExtension;
  184. PSTREAM_PROPERTY_DESCRIPTOR pSPD = pSrb->CommandData.PropertyInfo;
  185. DebugPrint(( DebugLevelVerbose, "ZiVA: Begin GetAudioProperty\n" ));
  186. pSrb->Status = STATUS_SUCCESS;
  187. if( IsEqualGUID( &KSPROPSETID_AudioDecoderOut, &pSPD->Property->Set ) )
  188. { // this is audio decoder output property, handle it
  189. switch( pSrb->CommandData.PropertyInfo->Property->Id )
  190. {
  191. case KSPROPERTY_AUDDECOUT_MODES:
  192. //
  193. // enumerate the supported modes
  194. //
  195. *(PULONG)(pSrb->CommandData.PropertyInfo->PropertyInfo) =
  196. KSAUDDECOUTMODE_STEREO_ANALOG | KSAUDDECOUTMODE_SPDIFF;
  197. pSrb->ActualBytesTransferred = sizeof (ULONG);
  198. break;
  199. case KSPROPERTY_AUDDECOUT_CUR_MODE:
  200. //TRAP
  201. *(PULONG)(pSrb->CommandData.PropertyInfo->PropertyInfo) = audiodecoutmode;
  202. pSrb->ActualBytesTransferred = sizeof (ULONG);
  203. break;
  204. default:
  205. pSrb->Status = STATUS_NOT_IMPLEMENTED;
  206. }
  207. }
  208. else if( IsEqualGUID( &KSPROPSETID_CopyProt, &pSPD->Property->Set ) )
  209. { // this is a copy protection property go handle it there
  210. CopyProtGetProp( pSrb );
  211. }
  212. else if( IsEqualGUID( &KSPROPSETID_TSRateChange, &pSPD->Property->Set ) )
  213. { // this is a transfer rate change property go handle it there
  214. GetAudioRateChange( pSrb );
  215. }
  216. else
  217. pSrb->Status = STATUS_NOT_IMPLEMENTED;
  218. DebugPrint(( DebugLevelVerbose, "ZiVA: End GetAudioProperty\n" ));
  219. }
  220. /*
  221. ** SetAudioProperty()
  222. **
  223. ** Routine to process Audio property requests
  224. **
  225. ** Arguments:
  226. **
  227. ** pSrb - pointer to the stream request block for properties
  228. **
  229. ** Returns:
  230. **
  231. ** Side Effects: none
  232. */
  233. static void SetAudioProperty( PHW_STREAM_REQUEST_BLOCK pSrb )
  234. {
  235. PHW_DEVICE_EXTENSION phwdevext = (PHW_DEVICE_EXTENSION)pSrb->HwDeviceExtension;
  236. PSTREAM_PROPERTY_DESCRIPTOR pSPD = pSrb->CommandData.PropertyInfo;
  237. pSrb->Status = STATUS_SUCCESS;
  238. if( IsEqualGUID( &KSPROPSETID_AudioDecoderOut, &pSPD->Property->Set ) )
  239. {
  240. switch( pSrb->CommandData.PropertyInfo->Property->Id )
  241. {
  242. case KSPROPERTY_AUDDECOUT_CUR_MODE:
  243. if (*(PULONG)(pSrb->CommandData.PropertyInfo->PropertyInfo) != audiodecoutmode)
  244. {
  245. if ( (*(PULONG)(pSrb->CommandData.PropertyInfo->PropertyInfo)) &
  246. (!(KSAUDDECOUTMODE_STEREO_ANALOG | KSAUDDECOUTMODE_SPDIFF)) )
  247. {
  248. break;
  249. }
  250. audiodecoutmode = *(PULONG)(pSrb->CommandData.PropertyInfo->PropertyInfo);
  251. }
  252. break;
  253. default:
  254. pSrb->Status = STATUS_NOT_IMPLEMENTED;
  255. break;
  256. }
  257. }
  258. else if( IsEqualGUID( &KSPROPSETID_CopyProt, &pSPD->Property->Set ) )
  259. { // this is a copy protection property
  260. CopyProtSetPropIfAdapterReady( pSrb );
  261. }
  262. else if( IsEqualGUID( &KSPROPSETID_TSRateChange, &pSPD->Property->Set ) )
  263. { // this is a transfer rate change property go handle it there
  264. SetAudioRateChange( pSrb );
  265. }
  266. else
  267. pSrb->Status = STATUS_NOT_IMPLEMENTED;
  268. }
  269. static void GetAudioRateChange( PHW_STREAM_REQUEST_BLOCK pSrb )
  270. {
  271. PHW_DEVICE_EXTENSION pHwDevExt = (PHW_DEVICE_EXTENSION)pSrb->HwDeviceExtension;
  272. DebugPrint(( DebugLevelVerbose, "ZiVA: GetAudioRateChange()->" ));
  273. switch( pSrb->CommandData.PropertyInfo->Property->Id )
  274. {
  275. case KS_AM_RATE_SimpleRateChange:
  276. {
  277. KS_AM_SimpleRateChange* pRateChange;
  278. DebugPrint(( DebugLevelVerbose, "KS_AM_RATE_SimpleRateChange\n" ));
  279. pSrb->ActualBytesTransferred = sizeof (KS_AM_RATE_SimpleRateChange);
  280. pRateChange = (KS_AM_SimpleRateChange*)pSrb->CommandData.PropertyInfo->PropertyInfo;
  281. pRateChange->StartTime = 0/*pHwDevExt->AudioStartTime*/;
  282. pRateChange->Rate = 10000 /*pHwDevExt->AudioRate*/;
  283. }
  284. pSrb->Status = STATUS_SUCCESS;
  285. break;
  286. case KS_AM_RATE_ExactRateChange:
  287. DebugPrint(( DebugLevelVerbose, "KS_AM_RATE_ExactRateChange (NOT IMPLEMENTED)\n" ));
  288. pSrb->Status = STATUS_NOT_IMPLEMENTED;
  289. break;
  290. case KS_AM_RATE_MaxFullDataRate:
  291. {
  292. KS_AM_MaxFullDataRate* pMaxRate;
  293. DebugPrint(( DebugLevelVerbose, "KS_AM_RATE_MaxFullDataRate\n" ));
  294. pSrb->ActualBytesTransferred = sizeof (KS_AM_RATE_MaxFullDataRate);
  295. pMaxRate = (KS_AM_MaxFullDataRate*)pSrb->CommandData.PropertyInfo->PropertyInfo;
  296. *pMaxRate = 10000 /*pHwDevExt->AudioMaxFullRate*/;
  297. }
  298. pSrb->Status = STATUS_SUCCESS;
  299. break;
  300. case KS_AM_RATE_Step:
  301. DebugPrint(( DebugLevelTrace, "KS_AM_RATE_Step (NOT IMPLEMENTED)\n" ));
  302. pSrb->Status = STATUS_NOT_IMPLEMENTED;
  303. break;
  304. }
  305. }
  306. static void SetAudioRateChange( PHW_STREAM_REQUEST_BLOCK pSrb )
  307. {
  308. PHW_DEVICE_EXTENSION pHwDevExt = (PHW_DEVICE_EXTENSION)pSrb->HwDeviceExtension;
  309. DebugPrint(( DebugLevelVerbose, "ZiVA: SetAudioRateChange()->" ));
  310. switch( pSrb->CommandData.PropertyInfo->Property->Id )
  311. {
  312. case KS_AM_RATE_SimpleRateChange:
  313. {
  314. KS_AM_SimpleRateChange* pRateChange;
  315. REFERENCE_TIME NewStartTime;
  316. LONG NewRate;
  317. DebugPrint(( DebugLevelVerbose, "KS_AM_RATE_SimpleRateChange\n" ));
  318. pRateChange = (KS_AM_SimpleRateChange*)pSrb->CommandData.PropertyInfo->PropertyInfo;
  319. NewStartTime = pRateChange->StartTime;
  320. NewRate = ( pRateChange->Rate < 0 ) ? -pRateChange->Rate : pRateChange->Rate;
  321. DebugPrint(( DebugLevelVerbose, "ZiVA: Received Data\r\n" ));
  322. DebugPrint(( DebugLevelVerbose, "ZiVA: StartTime = 0x%08x\r\n", NewStartTime ));
  323. DebugPrint(( DebugLevelVerbose, "ZiVA: Rate = 0x%08x\r\n", NewRate ));
  324. }
  325. pSrb->Status = STATUS_SUCCESS;
  326. break;
  327. case KS_AM_RATE_ExactRateChange :
  328. pSrb->Status = STATUS_NOT_IMPLEMENTED;
  329. break;
  330. case KS_AM_RATE_MaxFullDataRate :
  331. pSrb->Status = STATUS_NOT_IMPLEMENTED;
  332. break;
  333. case KS_AM_RATE_Step :
  334. pSrb->Status = STATUS_NOT_IMPLEMENTED;
  335. break;
  336. }
  337. }
  338. #if 0
  339. static BOOLEAN PreparePageTable(PHW_STREAM_REQUEST_BLOCK pSrb)
  340. {
  341. DWORD i = 0;
  342. DWORD k = 0;
  343. DWORD j = 0;
  344. PKSSCATTER_GATHER pSGList;
  345. DWORD dwSum = 0;
  346. PHW_DEVICE_EXTENSION pHwDevExt = (PHW_DEVICE_EXTENSION)pSrb->HwDeviceExtension;
  347. if(pSrb == NULL)
  348. {
  349. #ifdef DEBUG
  350. MonoOutStr("PreparePageTable::pSrb is NULL");
  351. #endif
  352. return FALSE;
  353. }
  354. pSGList = pSrb->ScatterGatherBuffer;
  355. if(pSGList == NULL)
  356. {
  357. #ifdef DEBUG
  358. MonoOutStr("PreparePageTable::pSGList is NULL");
  359. #endif
  360. return FALSE;
  361. }
  362. while( j < pSrb->NumberOfBuffers)
  363. {
  364. dwSum = 0;
  365. k = 0;
  366. do
  367. {
  368. dwSum += pSGList[i].Length;
  369. i++;
  370. k++;
  371. }while(dwSum < pHwDevExt->AudBufferSize[j]);
  372. pHwDevExt->AudioPageTable[j] = k;
  373. j++;
  374. if(j > 50)
  375. {
  376. #ifdef DEBUG
  377. MonoOutStr("PreparePageTable::ArrayCrossingLimit");
  378. #endif
  379. return FALSE;
  380. }
  381. }
  382. return TRUE;
  383. }
  384. #endif
  385. /*
  386. ** AudioSendPacket()
  387. **
  388. ** Routine to initialise the stream data packet handling
  389. **
  390. ** Arguments:
  391. **
  392. ** pSrb - Pointer to the stream request block
  393. **
  394. ** Returns:
  395. **
  396. ** Side Effects: none
  397. */
  398. static VOID AudioSendPacket( PHW_STREAM_REQUEST_BLOCK pSrb )
  399. {
  400. PHW_DEVICE_EXTENSION pHwDevExt = ((PHW_DEVICE_EXTENSION)pSrb->HwDeviceExtension);
  401. KSSTREAM_HEADER *pHeader;
  402. BYTE *pData;
  403. DWORD dwDataUsed;
  404. ULONG ulSample;
  405. //
  406. // Lets check what we've got in this Srb
  407. //
  408. if (CheckAndReleaseIfCtrlPkt(pSrb))
  409. return;
  410. for( ulSample = 0; ulSample < pSrb->NumberOfBuffers; ulSample++ )
  411. {
  412. pHeader = ((PKSSTREAM_HEADER)pSrb->CommandData.DataBufferArray) + ulSample;
  413. pData = pHeader->Data;
  414. dwDataUsed = pHeader->DataUsed;
  415. // Check header flags
  416. #if 0 //defined( DEBUG )
  417. if ( pHeader->OptionsFlags )
  418. {
  419. MonoOutSetBlink( TRUE );
  420. MonoOutChar( '(' );
  421. if ( pHeader->OptionsFlags & KSSTREAM_HEADER_OPTIONSF_SPLICEPOINT )
  422. MonoOutChar( 's'/*"SPLICEPOINT"*/ );
  423. if ( pHeader->OptionsFlags & KSSTREAM_HEADER_OPTIONSF_PREROLL )
  424. MonoOutChar( 'p'/*"PREROLL"*/ );
  425. if ( pHeader->OptionsFlags & KSSTREAM_HEADER_OPTIONSF_DATADISCONTINUITY )
  426. MonoOutChar( 'd'/*"DATADISCONTINUITY"*/ );
  427. if ( pHeader->OptionsFlags & KSSTREAM_HEADER_OPTIONSF_TYPECHANGED )
  428. MonoOutChar( 'c'/*"TYPECHANGED"*/ );
  429. if ( pHeader->OptionsFlags & KSSTREAM_HEADER_OPTIONSF_TIMEVALID )
  430. MonoOutChar( 'v'/*"TIMEVALID"*/ );
  431. if ( pHeader->OptionsFlags & KSSTREAM_HEADER_OPTIONSF_TIMEDISCONTINUITY )
  432. MonoOutChar( 't'/*"TIMEDISCONTINUITY"*/ );
  433. if ( pHeader->OptionsFlags & KSSTREAM_HEADER_OPTIONSF_FLUSHONPAUSE )
  434. MonoOutChar( 'f'/*"FLUSHONPAUSE"*/ );
  435. if ( pHeader->OptionsFlags & KSSTREAM_HEADER_OPTIONSF_DURATIONVALID )
  436. MonoOutChar( 'u'/*"DURATIONVALID"*/ );
  437. if ( pHeader->OptionsFlags & KSSTREAM_HEADER_OPTIONSF_ENDOFSTREAM )
  438. MonoOutChar( 'e'/*"ENDOFSTREAM"*/ );
  439. if ( pHeader->OptionsFlags & KSSTREAM_HEADER_OPTIONSF_LOOPEDDATA )
  440. MonoOutChar( 'l'/*"LOOPEDDATA"*/ );
  441. if ( pHeader->OptionsFlags & ~( KSSTREAM_HEADER_OPTIONSF_SPLICEPOINT |
  442. KSSTREAM_HEADER_OPTIONSF_PREROLL |
  443. KSSTREAM_HEADER_OPTIONSF_DATADISCONTINUITY |
  444. KSSTREAM_HEADER_OPTIONSF_TYPECHANGED |
  445. KSSTREAM_HEADER_OPTIONSF_TIMEVALID |
  446. KSSTREAM_HEADER_OPTIONSF_TIMEDISCONTINUITY |
  447. KSSTREAM_HEADER_OPTIONSF_FLUSHONPAUSE |
  448. KSSTREAM_HEADER_OPTIONSF_DURATIONVALID |
  449. KSSTREAM_HEADER_OPTIONSF_ENDOFSTREAM |
  450. KSSTREAM_HEADER_OPTIONSF_LOOPEDDATA ) )
  451. MonoOutStr( "!!! UNKNOWN FLAG !!!" );
  452. MonoOutChar( ')' );
  453. MonoOutSetBlink( FALSE );
  454. }
  455. #endif // DEBUG
  456. #if defined( DEBUG )
  457. //tmp MonoOutChar('A');
  458. //tmp MonoOutULong( (pHeader->TypeSpecificFlags) >> 16 );
  459. //tmp MonoOutChar( '.' );
  460. // MonoOutStr("pTime");
  461. // MonoOutULong(pHeader->PresentationTime);
  462. #endif // DEBUG
  463. if(pHwDevExt->dwFirstAudioOrdNum == -1)
  464. {
  465. pHwDevExt->dwFirstAudioOrdNum = (pHeader->TypeSpecificFlags) >> 16;
  466. MonoOutStr("FirstAudioBuffer");
  467. MonoOutULong( (pHeader->TypeSpecificFlags) >> 16 );
  468. }
  469. if ( pHeader->OptionsFlags & KSSTREAM_HEADER_OPTIONSF_DATADISCONTINUITY )
  470. {
  471. MonoOutStr(" A->DISCONT ");
  472. pHwDevExt->bStreamNumberCouldBeChanged = TRUE;
  473. }
  474. if ( pHeader->OptionsFlags & KSSTREAM_HEADER_OPTIONSF_TYPECHANGED )
  475. {
  476. DebugPrint(( DebugLevelVerbose, "ZiVA: Processing audio stream format.\n" ));
  477. MonoOutStr(" A->TYPECHANGED ");
  478. pHwDevExt->bStreamNumberCouldBeChanged = TRUE;
  479. }
  480. //
  481. // Check for the stream number
  482. //
  483. if( ( pHwDevExt->bStreamNumberCouldBeChanged ) || (pHwDevExt->fAtleastOne))
  484. {
  485. if ( pData && dwDataUsed )
  486. {
  487. WORD wStuffingLength;
  488. WORD wPesHeaderLength;
  489. WORD wOffset;
  490. WORD wNewStream;
  491. if(dwDataUsed < 22)
  492. {
  493. pHwDevExt->bStreamNumberCouldBeChanged = FALSE;
  494. continue;
  495. }
  496. //
  497. // Find the location of the stream ID and number
  498. //
  499. wStuffingLength = *(pData+13) & 0x03;
  500. wPesHeaderLength = *(pData+22);
  501. wOffset = 22;
  502. if ( wPesHeaderLength >= 5 )
  503. {
  504. //
  505. // PTS is present here
  506. //
  507. }
  508. wOffset = wOffset + wPesHeaderLength + 1;
  509. // wOffset = wOffset + wStuffingLength + 1;
  510. if(dwDataUsed < wOffset)
  511. {
  512. pHwDevExt->bStreamNumberCouldBeChanged = FALSE;
  513. continue;
  514. }
  515. //
  516. // Get Stream Number
  517. //
  518. //WORD wNewStream = *(pData+31);
  519. wNewStream = *(pData+wOffset);
  520. if ( (*(pData+17) & 0xE8) == 0xC0 )//|| (*(pData+17) & 0xF0) == 0xD0 )
  521. {
  522. wNewStream = *(pData+17) & 0x07 ;
  523. if ( wNewStream != pHwDevExt->wCurrentStreamNumber )
  524. {
  525. pHwDevExt->wCurrentStreamNumber = wNewStream;
  526. //
  527. // Select the current stream number for MPEG audio
  528. //
  529. DVD_SetStreams( 3, pHwDevExt->wCurrentStreamNumber );
  530. pHwDevExt->fAtleastOne = FALSE;
  531. }
  532. pHwDevExt->bStreamNumberCouldBeChanged = FALSE;
  533. }
  534. else if ( ((wNewStream & 0xE0) == 0x80) )
  535. {
  536. if ( wNewStream != pHwDevExt->wCurrentStreamNumber )
  537. {
  538. pHwDevExt->wCurrentStreamNumber = wNewStream;
  539. //
  540. // Select the current stream number for AC-3 audio
  541. //
  542. DVD_SetStreams( 2, pHwDevExt->wCurrentStreamNumber & 0x1F );
  543. pHwDevExt->fAtleastOne = FALSE;
  544. }
  545. pHwDevExt->bStreamNumberCouldBeChanged = FALSE;
  546. }
  547. else if ( ((wNewStream & 0xE0) == 0xA0) )
  548. {
  549. if ( wNewStream != pHwDevExt->wCurrentStreamNumber )
  550. {
  551. pHwDevExt->wCurrentStreamNumber = wNewStream;
  552. //
  553. // Select the current stream number for LPCM audio
  554. //
  555. DVD_SetStreams( 4, pHwDevExt->wCurrentStreamNumber & 0x1F );
  556. pHwDevExt->fAtleastOne = FALSE;
  557. }
  558. pHwDevExt->bStreamNumberCouldBeChanged = FALSE;
  559. }
  560. else
  561. {
  562. MonoOutStr( " !!! Audio Pack with wrong ID !!! " );
  563. }
  564. }
  565. }
  566. }
  567. //
  568. // Register this Srb
  569. //
  570. #if defined( DEBUG )
  571. if ( pHwDevExt->pCurrentAudioSrb )
  572. {
  573. DebugPrint(( DebugLevelWarning, "ZiVA: !!!!!!!!!!! ERROR: Audio slot is not empty !!!!!!!!!!\n" ));
  574. MonoOutStr("!!!!!!!AudioSlotIsNotEmpty!!!!!!");
  575. }
  576. #endif // DEBUG
  577. // if(!PreparePageTable(pSrb))
  578. // MonoOutStr("Audio PageTable Prep failed");
  579. pHwDevExt->pCurrentAudioSrb = pSrb;
  580. AdapterSendData( pHwDevExt );
  581. }
  582. /*
  583. ** AudioQueryAccept()
  584. **
  585. **
  586. **
  587. ** Arguments:
  588. **
  589. ** pSrb - Pointer to the stream request block
  590. **
  591. ** Returns:
  592. **
  593. ** Side Effects: none
  594. */
  595. static void AudioQueryAccept( PHW_STREAM_REQUEST_BLOCK pSrb )
  596. {
  597. DebugPrint(( DebugLevelVerbose, "ZiVA: Begin AudioQueryAccept()\n" ));
  598. pSrb->Status = STATUS_SUCCESS;
  599. DebugPrint(( DebugLevelVerbose, "ZiVA: End AudioQueryAccept()\n" ));
  600. }
  601. /******************************************************************************/
  602. /********************** MASTER CLOCK RELATED FUNCTIONS **********************/
  603. /******************************************************************************/
  604. /*
  605. ** AudioClockFunction
  606. **
  607. ** Routine to be called by the Class Driver to obtain Master
  608. ** Clock information.
  609. **
  610. */
  611. void STREAMAPI AudioClockFunction( IN PHW_TIME_CONTEXT TimeContext )
  612. {
  613. ULONGLONG sysTime = GetSystemTime();
  614. DebugPrint(( DebugLevelVerbose, "ZiVA: AudioClockFunction() -> " ));
  615. /* if (fClkPause)
  616. {
  617. TimeContext->Time = LastStamp + PauseTime - LastSysTime;
  618. return TRUE;
  619. }*/
  620. switch ( TimeContext->Function )
  621. {
  622. case TIME_GET_STREAM_TIME:
  623. DebugPrint(( DebugLevelVerbose, "TIME_GET_STREAM_TIME\n" ));
  624. TimeContext->Time = ConvertPTStoStrm( DVD_GetSTC() );
  625. TimeContext->SystemTime = sysTime;
  626. DebugPrint(( DebugLevelVerbose,"------->return PTS: %X\n", TimeContext->Time ));
  627. break;
  628. case TIME_READ_ONBOARD_CLOCK:
  629. DebugPrint(( DebugLevelVerbose, "TIME_READ_ONBOARD_CLOCK\n" ));
  630. break;
  631. case TIME_SET_ONBOARD_CLOCK:
  632. DebugPrint(( DebugLevelVerbose, "TIME_SET_ONBOARD_CLOCK\n" ));
  633. break;
  634. default:
  635. DebugPrint(( DebugLevelWarning, "!!! Unknown value for TimeContext->Function !!!\n" ));
  636. break;
  637. }
  638. DebugPrint(( DebugLevelVerbose, "ZiVA: End AudioClockFunction()\n" ));
  639. }
  640. /*
  641. ** ReleaseClockEvents ()
  642. **
  643. ** handle any time event mark events
  644. **
  645. ** Arguments:
  646. **
  647. **
  648. **
  649. ** Returns:
  650. **
  651. ** Side Effects:
  652. */
  653. void ReleaseClockEvents(PHW_DEVICE_EXTENSION pdevex,BOOL fMarkInterval)
  654. {
  655. PKSEVENT_ENTRY pEvent,pLast;
  656. PMYTIME pTim;
  657. // LONGLONG MinIntTime;
  658. LONGLONG strmTime;
  659. LONGLONG MarkTime;
  660. if (!pdevex || !pdevex->pstroAud)
  661. {
  662. return;
  663. }
  664. // strmTime = ConvertPTStoStrm( DVD_GetSTC() );
  665. //
  666. // loop through all time_mark events
  667. //
  668. pEvent = NULL;
  669. pLast = NULL;
  670. while(pEvent = StreamClassGetNextEvent(
  671. pdevex,
  672. pdevex->pstroAud,
  673. (GUID *)&KSEVENTSETID_Clock,
  674. KSEVENT_CLOCK_POSITION_MARK,
  675. pLast))
  676. {
  677. strmTime = ConvertPTStoStrm( DVD_GetSTC() );
  678. TRAP
  679. MarkTime = ((PKSEVENT_TIME_MARK)(pEvent +1))->MarkTime;
  680. MonoOutStr(" MT ");
  681. MonoOutULong(MarkTime);
  682. MonoOutStr(" ST ");
  683. MonoOutULong(strmTime);
  684. if (((PKSEVENT_TIME_MARK)(pEvent +1))->MarkTime <= strmTime )
  685. {
  686. // TRAP
  687. //
  688. // signal the event here
  689. //
  690. StreamClassStreamNotification(
  691. SignalStreamEvent,
  692. pdevex->pstroAud,
  693. pEvent
  694. );
  695. //
  696. // tell the stream class to disable this event
  697. //
  698. /* StreamClassStreamNotification(
  699. DeleteStreamEvent,
  700. pdevex->pstroAud,
  701. pEvent
  702. );*/
  703. }
  704. else if(((PKSEVENT_TIME_MARK)(pEvent +1))->MarkTime - strmTime > 100000000)
  705. {
  706. StreamClassStreamNotification(
  707. SignalStreamEvent,
  708. pdevex->pstroAud,
  709. pEvent
  710. );
  711. }
  712. pLast = pEvent;
  713. }
  714. //
  715. // loop through all time_interval events
  716. //
  717. if(!fMarkInterval)
  718. return;
  719. pEvent = NULL;
  720. while ( pEvent = StreamClassGetNextEvent(
  721. pdevex,
  722. pdevex->pstroAud,
  723. (GUID *)&KSEVENTSETID_Clock,
  724. KSEVENT_CLOCK_INTERVAL_MARK,
  725. pEvent))
  726. {
  727. pTim = ((PMYTIME)(pEvent + 1));
  728. if (pTim && pTim->tim.Interval)
  729. {
  730. // if( strmTime >= pTim->tim.TimeBase+ pTim->tim.Interval)
  731. {
  732. StreamClassStreamNotification(SignalStreamEvent,pdevex->pstroAud,pEvent);
  733. // DbgPrint(" SEN ");
  734. }
  735. }
  736. MonoOutStr("StreamClass Event Notification");
  737. }
  738. }
  739. void CallReleaseEvent( PHW_DEVICE_EXTENSION pHwDevExt )
  740. {
  741. ReleaseClockEvents(pHwDevExt,TRUE);
  742. AdapterSendData( pHwDevExt );
  743. }
  744. /*
  745. ** AudioEvent ()
  746. **
  747. ** receives notification for audio clock enable / disable events
  748. **
  749. ** Arguments:
  750. **
  751. **
  752. **
  753. ** Returns:
  754. **
  755. ** Side Effects:
  756. */
  757. NTSTATUS STREAMAPI AudioEventFunction( IN PHW_EVENT_DESCRIPTOR pEventDescriptor )
  758. {
  759. PUCHAR pCopy = (PUCHAR)( pEventDescriptor->EventEntry + 1 );
  760. PUCHAR pSrc = (PUCHAR)pEventDescriptor->EventData;
  761. ULONG cCopy=0;
  762. DebugPrint(( DebugLevelVerbose, "ZiVA: AudioEventFunction() -> " ));
  763. if ( pEventDescriptor->Enable )
  764. {
  765. switch ( pEventDescriptor->EventEntry->EventItem->EventId )
  766. {
  767. case KSEVENT_CLOCK_POSITION_MARK:
  768. DbgPrint("KSEVENT_CLOCK_POSITION_MARK\n");
  769. cCopy = sizeof( KSEVENT_TIME_MARK );
  770. break;
  771. case KSEVENT_CLOCK_INTERVAL_MARK:
  772. DbgPrint("KSEVENT_CLOCK_INTERVAL_MARK\n" );
  773. pDevEx->dwVSyncCount=0;
  774. cCopy = sizeof( KSEVENT_TIME_INTERVAL );
  775. break;
  776. default:
  777. DebugPrint(( DebugLevelWarning, "!!! Unknown value for EventId !!!\n" ));
  778. return STATUS_NOT_IMPLEMENTED;
  779. }
  780. if (pEventDescriptor->EventEntry->EventItem->DataInput != cCopy )
  781. {
  782. DebugPrint(( DebugLevelWarning, "ZiVA: !!! STATUS_INVALID_BUFFER_SIZE !!!\n" ));
  783. return STATUS_INVALID_BUFFER_SIZE;
  784. }
  785. //
  786. // copy the input buffer
  787. //
  788. for (;cCopy > 0; cCopy--)
  789. {
  790. *pCopy++ = *pSrc++;
  791. }
  792. }
  793. DebugPrint(( DebugLevelVerbose, "ZiVA: End AudioEventFunction()\n" ));
  794. return STATUS_SUCCESS;
  795. }
  796. static ULONGLONG GetSystemTime()
  797. {
  798. ULONGLONG ticks;
  799. ULONGLONG rate;
  800. ticks = (ULONGLONG)KeQueryPerformanceCounter((PLARGE_INTEGER)&rate).QuadPart;
  801. //
  802. // convert from ticks to 100ns clock
  803. //
  804. ticks = (ticks & 0xFFFFFFFF00000000) / rate * 10000000 +
  805. (ticks & 0xFFFFFFFF) * 10000000 / rate;
  806. return ticks;
  807. }
  808. /////////////////////////////////////////////////////////////////////////
  809. //
  810. // Function : ConvertPTStoStrm
  811. // Args : PTS
  812. // Returns :
  813. //
  814. // Purpose:
  815. // converts a PTS to a Stream class 100 NS clock
  816. //
  817. //
  818. //
  819. //
  820. /////////////////////////////////////////////////////////////////////////
  821. static ULONGLONG ConvertPTStoStrm( ULONG pts )
  822. {
  823. ULONGLONG strm;
  824. strm = (ULONGLONG)pts;
  825. strm = (strm * 1000) / 9;
  826. /* if((strm-pDevEx->prevStrm) > 100000000000)
  827. {
  828. MonoOutStr( " VeryHigh STC " );
  829. strm = pDevEx->prevStrm;
  830. }
  831. pDevEx->prevStrm = strm;*/
  832. return strm;
  833. }
  834. ULONGLONG ConvertStrmToPTS( ULONGLONG stc )
  835. {
  836. ULONGLONG pts;
  837. pts = (ULONGLONG)stc;
  838. pts = (stc * 9) / 1000;
  839. return pts;
  840. }