|
|
/******************************************************************************\
* * * AUDSTRM.C - Audio stream control related code. * * * * Copyright (c) C-Cube Microsystems 1998 * * All Rights Reserved. * * * * Use of C-Cube Microsystems code is governed by terms and conditions * * stated in the accompanying licensing statement. * * * \******************************************************************************/
#include "Headers.h"
#pragma hdrstop
#include "copyprot.h"
#include "audstrm.h"
#include "bmaster.h"
#include "cl6100.h"
#define TRAP MonoOutStr("TRAP");
typedef struct _MYTIME{ KSEVENT_TIME_INTERVAL tim; LONGLONG LastTime; } MYTIME, *PMYTIME;
extern PHW_DEVICE_EXTENSION pDevEx; //*****************************************************************************
// STATIC FUNCTIONS DECLARATION
//*****************************************************************************
static void GetAudioProperty( PHW_STREAM_REQUEST_BLOCK pSrb ); static void SetAudioProperty( PHW_STREAM_REQUEST_BLOCK pSrb ); static void GetAudioRateChange( PHW_STREAM_REQUEST_BLOCK pSrb ); static void SetAudioRateChange( PHW_STREAM_REQUEST_BLOCK pSrb ); static void AudioSendPacket( PHW_STREAM_REQUEST_BLOCK pSrb ); static void AudioQueryAccept( PHW_STREAM_REQUEST_BLOCK pSrb ); static ULONGLONG GetSystemTime(); static ULONGLONG ConvertPTStoStrm( ULONG pts );
extern BOOL bJustHighLight;
BOOL fClkPause; static ULONGLONG LastStamp;
extern PHW_DEVICE_EXTENSION pDevEx; /*
** AudioReceiveCtrlPacket() ** ** Receives packet commands that control the Audio stream ** ** Arguments: ** ** pSrb - The stream request block for the Audio stream ** ** Returns: ** ** Side Effects: none */
VOID STREAMAPI AudioReceiveCtrlPacket( IN PHW_STREAM_REQUEST_BLOCK pSrb ) { PHW_DEVICE_EXTENSION pdevext = (PHW_DEVICE_EXTENSION)pSrb->HwDeviceExtension;
DebugPrint(( DebugLevelVerbose, "ZiVA: Begin AudioReceiveCtrlPacket -> " ));
// set default status
switch( pSrb->Command ) { case SRB_SET_STREAM_STATE: DebugPrint(( DebugLevelVerbose, "SRB_SET_STREAM_STATE\n" )); AdapterSetState( pSrb ); break;
case SRB_GET_STREAM_PROPERTY: DebugPrint(( DebugLevelVerbose, "SRB_GET_STREAM_PROPERTY\n" )); GetAudioProperty( pSrb ); break;
case SRB_SET_STREAM_PROPERTY: DebugPrint(( DebugLevelVerbose, "SRB_SET_STREAM_PROPERTY\n" )); SetAudioProperty( pSrb ); break;
case SRB_OPEN_MASTER_CLOCK: // indicates that the master clock is on this stream
case SRB_INDICATE_MASTER_CLOCK: // supplies the handle to the master clock
case SRB_CLOSE_MASTER_CLOCK: // indicates that the master clock is closed
pSrb->Status = STATUS_SUCCESS; break;
case SRB_PROPOSE_DATA_FORMAT: // propose a new format, DOES NOT CHANGE IT!
DebugPrint(( DebugLevelVerbose, "SRB_PROPOSE_DATA_FORMAT\n" )); AudioQueryAccept( pSrb ); break;
case SRB_PROPOSE_STREAM_RATE: // propose a new rate, DOES NOT CHANGE IT!
pSrb->Status = STATUS_SUCCESS; DebugPrint(( DebugLevelVerbose, "SRB_PROPOSE_STREAM_RATE\n" )); break;
case SRB_SET_STREAM_RATE: // set the rate at which the stream should run
pSrb->Status = STATUS_SUCCESS; DebugPrint(( DebugLevelVerbose, "SRB_SET_STREAM_RATE\n" )); break;
case SRB_BEGIN_FLUSH : // beginning flush state
MonoOutStr(" Aud : SRB_BEGIN_FLUSH "); #ifndef DECODER_DVDPC
pdevext->bInterruptPending = FALSE; #endif
if (pdevext->pCurrentAudioSrb != NULL) { ZivaHw_Abort(); // adapterUpdateNextSrbOrderNumberOnDiscardSrb(pdevext->pCurrentAudioSrb);
pdevext->pCurrentAudioSrb->Status = STATUS_SUCCESS; AdapterReleaseRequest( pdevext->pCurrentAudioSrb ); pdevext->pCurrentAudioSrb = NULL; pdevext->dwCurrentAudioSample = 0; pdevext->dwCurrentAudioPage = 0; }
pSrb->Status = STATUS_SUCCESS; break;
case SRB_END_FLUSH : // ending flush state
MonoOutStr(" Aud : SRB_END_FLUSH "); pSrb->Status = STATUS_SUCCESS; if (pdevext->pCurrentAudioSrb != NULL) {
// adapterUpdateNextSrbOrderNumberOnDiscardSrb(pdevext->pCurrentAudioSrb);
pdevext->pCurrentAudioSrb->Status = STATUS_SUCCESS; AdapterReleaseRequest( pdevext->pCurrentAudioSrb ); pdevext->pCurrentAudioSrb = NULL; pdevext->dwCurrentAudioSample = 0; pdevext->dwCurrentAudioPage = 0; }
// ZivaHw_Play();
pdevext->bPlayCommandPending = TRUE; pdevext->bEndFlush = TRUE; // FinishCurrentPacketAndSendNextOne( pdevext );
break;
case SRB_UNKNOWN_STREAM_COMMAND:// IRP function is unknown to class driver
default: DebugPrint(( DebugLevelInfo, "!!!! UNKNOWN COMMAND !!!! :::> %X\n", pSrb->Command )); pSrb->Status = STATUS_NOT_IMPLEMENTED; }
AdapterReleaseRequest( pSrb ); DebugPrint(( DebugLevelVerbose, "ZiVA: End AudioReceiveCtrlPacket\n" )); }
/*
** AudioReceiveDataPacket() ** ** Receives Audio data packet commands ** ** Arguments: ** ** pSrb - Stream request block for the Audio device ** ** Returns: ** ** Side Effects: none */
VOID STREAMAPI AudioReceiveDataPacket(IN PHW_STREAM_REQUEST_BLOCK pSrb) { PHW_DEVICE_EXTENSION pdevext = ((PHW_DEVICE_EXTENSION)pSrb->HwDeviceExtension);
switch (pSrb->Command) { case SRB_WRITE_DATA: if(bJustHighLight) { pSrb->TimeoutCounter = pSrb->TimeoutOriginal = pSrb->TimeoutCounter / 5; bJustHighLight = FALSE; MonoOutStr("Audio TimeOut Counter Reduced"); }
AudioSendPacket(pSrb); break;
default:
DebugPrint(( DebugLevelWarning, "!!!! UNKNOWN COMMAND !!!! :::> %X\n", pSrb->Command ));
pSrb->Status = STATUS_NOT_IMPLEMENTED;
AdapterReleaseRequest( pSrb ); }
}
//
// default to downmixed stereo output
//
ULONG audiodecoutmode = KSAUDDECOUTMODE_STEREO_ANALOG;
/*
** GetAudioProperty() ** ** Routine to process Audio property requests ** ** Arguments: ** ** pSrb - pointer to the stream request block for properties ** ** Returns: ** ** Side Effects: none */ static void GetAudioProperty(PHW_STREAM_REQUEST_BLOCK pSrb) { PHW_DEVICE_EXTENSION phwdevext = (PHW_DEVICE_EXTENSION)pSrb->HwDeviceExtension; PSTREAM_PROPERTY_DESCRIPTOR pSPD = pSrb->CommandData.PropertyInfo;
DebugPrint(( DebugLevelVerbose, "ZiVA: Begin GetAudioProperty\n" )); pSrb->Status = STATUS_SUCCESS;
if( IsEqualGUID( &KSPROPSETID_AudioDecoderOut, &pSPD->Property->Set ) ) { // this is audio decoder output property, handle it
switch( pSrb->CommandData.PropertyInfo->Property->Id ) { case KSPROPERTY_AUDDECOUT_MODES: //
// enumerate the supported modes
//
*(PULONG)(pSrb->CommandData.PropertyInfo->PropertyInfo) = KSAUDDECOUTMODE_STEREO_ANALOG | KSAUDDECOUTMODE_SPDIFF;
pSrb->ActualBytesTransferred = sizeof (ULONG); break;
case KSPROPERTY_AUDDECOUT_CUR_MODE: //TRAP
*(PULONG)(pSrb->CommandData.PropertyInfo->PropertyInfo) = audiodecoutmode; pSrb->ActualBytesTransferred = sizeof (ULONG); break;
default: pSrb->Status = STATUS_NOT_IMPLEMENTED; } } else if( IsEqualGUID( &KSPROPSETID_CopyProt, &pSPD->Property->Set ) ) { // this is a copy protection property go handle it there
CopyProtGetProp( pSrb ); } else if( IsEqualGUID( &KSPROPSETID_TSRateChange, &pSPD->Property->Set ) ) { // this is a transfer rate change property go handle it there
GetAudioRateChange( pSrb ); } else pSrb->Status = STATUS_NOT_IMPLEMENTED;
DebugPrint(( DebugLevelVerbose, "ZiVA: End GetAudioProperty\n" )); }
/*
** SetAudioProperty() ** ** Routine to process Audio property requests ** ** Arguments: ** ** pSrb - pointer to the stream request block for properties ** ** Returns: ** ** Side Effects: none */ static void SetAudioProperty( PHW_STREAM_REQUEST_BLOCK pSrb ) { PHW_DEVICE_EXTENSION phwdevext = (PHW_DEVICE_EXTENSION)pSrb->HwDeviceExtension; PSTREAM_PROPERTY_DESCRIPTOR pSPD = pSrb->CommandData.PropertyInfo;
pSrb->Status = STATUS_SUCCESS;
if( IsEqualGUID( &KSPROPSETID_AudioDecoderOut, &pSPD->Property->Set ) ) { switch( pSrb->CommandData.PropertyInfo->Property->Id ) { case KSPROPERTY_AUDDECOUT_CUR_MODE: if (*(PULONG)(pSrb->CommandData.PropertyInfo->PropertyInfo) != audiodecoutmode) { if ( (*(PULONG)(pSrb->CommandData.PropertyInfo->PropertyInfo)) & (!(KSAUDDECOUTMODE_STEREO_ANALOG | KSAUDDECOUTMODE_SPDIFF)) ) { break; } audiodecoutmode = *(PULONG)(pSrb->CommandData.PropertyInfo->PropertyInfo); } break;
default: pSrb->Status = STATUS_NOT_IMPLEMENTED; break; } } else if( IsEqualGUID( &KSPROPSETID_CopyProt, &pSPD->Property->Set ) ) { // this is a copy protection property
CopyProtSetPropIfAdapterReady( pSrb ); } else if( IsEqualGUID( &KSPROPSETID_TSRateChange, &pSPD->Property->Set ) ) { // this is a transfer rate change property go handle it there
SetAudioRateChange( pSrb ); } else pSrb->Status = STATUS_NOT_IMPLEMENTED; }
static void GetAudioRateChange( PHW_STREAM_REQUEST_BLOCK pSrb ) { PHW_DEVICE_EXTENSION pHwDevExt = (PHW_DEVICE_EXTENSION)pSrb->HwDeviceExtension;
DebugPrint(( DebugLevelVerbose, "ZiVA: GetAudioRateChange()->" ));
switch( pSrb->CommandData.PropertyInfo->Property->Id ) {
case KS_AM_RATE_SimpleRateChange: { KS_AM_SimpleRateChange* pRateChange;
DebugPrint(( DebugLevelVerbose, "KS_AM_RATE_SimpleRateChange\n" ));
pSrb->ActualBytesTransferred = sizeof (KS_AM_RATE_SimpleRateChange); pRateChange = (KS_AM_SimpleRateChange*)pSrb->CommandData.PropertyInfo->PropertyInfo; pRateChange->StartTime = 0/*pHwDevExt->AudioStartTime*/; pRateChange->Rate = 10000 /*pHwDevExt->AudioRate*/; }
pSrb->Status = STATUS_SUCCESS; break;
case KS_AM_RATE_ExactRateChange: DebugPrint(( DebugLevelVerbose, "KS_AM_RATE_ExactRateChange (NOT IMPLEMENTED)\n" )); pSrb->Status = STATUS_NOT_IMPLEMENTED; break;
case KS_AM_RATE_MaxFullDataRate: { KS_AM_MaxFullDataRate* pMaxRate;
DebugPrint(( DebugLevelVerbose, "KS_AM_RATE_MaxFullDataRate\n" ));
pSrb->ActualBytesTransferred = sizeof (KS_AM_RATE_MaxFullDataRate); pMaxRate = (KS_AM_MaxFullDataRate*)pSrb->CommandData.PropertyInfo->PropertyInfo; *pMaxRate = 10000 /*pHwDevExt->AudioMaxFullRate*/; } pSrb->Status = STATUS_SUCCESS; break;
case KS_AM_RATE_Step: DebugPrint(( DebugLevelTrace, "KS_AM_RATE_Step (NOT IMPLEMENTED)\n" )); pSrb->Status = STATUS_NOT_IMPLEMENTED; break; } }
static void SetAudioRateChange( PHW_STREAM_REQUEST_BLOCK pSrb ) { PHW_DEVICE_EXTENSION pHwDevExt = (PHW_DEVICE_EXTENSION)pSrb->HwDeviceExtension; DebugPrint(( DebugLevelVerbose, "ZiVA: SetAudioRateChange()->" ));
switch( pSrb->CommandData.PropertyInfo->Property->Id ) {
case KS_AM_RATE_SimpleRateChange: { KS_AM_SimpleRateChange* pRateChange; REFERENCE_TIME NewStartTime; LONG NewRate;
DebugPrint(( DebugLevelVerbose, "KS_AM_RATE_SimpleRateChange\n" ));
pRateChange = (KS_AM_SimpleRateChange*)pSrb->CommandData.PropertyInfo->PropertyInfo; NewStartTime = pRateChange->StartTime; NewRate = ( pRateChange->Rate < 0 ) ? -pRateChange->Rate : pRateChange->Rate;
DebugPrint(( DebugLevelVerbose, "ZiVA: Received Data\r\n" )); DebugPrint(( DebugLevelVerbose, "ZiVA: StartTime = 0x%08x\r\n", NewStartTime )); DebugPrint(( DebugLevelVerbose, "ZiVA: Rate = 0x%08x\r\n", NewRate )); } pSrb->Status = STATUS_SUCCESS; break;
case KS_AM_RATE_ExactRateChange : pSrb->Status = STATUS_NOT_IMPLEMENTED; break;
case KS_AM_RATE_MaxFullDataRate : pSrb->Status = STATUS_NOT_IMPLEMENTED; break;
case KS_AM_RATE_Step : pSrb->Status = STATUS_NOT_IMPLEMENTED; break; } }
#if 0
static BOOLEAN PreparePageTable(PHW_STREAM_REQUEST_BLOCK pSrb) { DWORD i = 0; DWORD k = 0; DWORD j = 0; PKSSCATTER_GATHER pSGList; DWORD dwSum = 0; PHW_DEVICE_EXTENSION pHwDevExt = (PHW_DEVICE_EXTENSION)pSrb->HwDeviceExtension;
if(pSrb == NULL) { #ifdef DEBUG
MonoOutStr("PreparePageTable::pSrb is NULL"); #endif
return FALSE; } pSGList = pSrb->ScatterGatherBuffer;
if(pSGList == NULL) { #ifdef DEBUG
MonoOutStr("PreparePageTable::pSGList is NULL"); #endif
return FALSE; } while( j < pSrb->NumberOfBuffers) { dwSum = 0; k = 0; do { dwSum += pSGList[i].Length; i++; k++;
}while(dwSum < pHwDevExt->AudBufferSize[j]);
pHwDevExt->AudioPageTable[j] = k; j++; if(j > 50) { #ifdef DEBUG
MonoOutStr("PreparePageTable::ArrayCrossingLimit"); #endif
return FALSE; }
} return TRUE; }
#endif
/*
** AudioSendPacket() ** ** Routine to initialise the stream data packet handling ** ** Arguments: ** ** pSrb - Pointer to the stream request block ** ** Returns: ** ** Side Effects: none */ static VOID AudioSendPacket( PHW_STREAM_REQUEST_BLOCK pSrb ) { PHW_DEVICE_EXTENSION pHwDevExt = ((PHW_DEVICE_EXTENSION)pSrb->HwDeviceExtension); KSSTREAM_HEADER *pHeader; BYTE *pData; DWORD dwDataUsed; ULONG ulSample;
//
// Lets check what we've got in this Srb
//
if (CheckAndReleaseIfCtrlPkt(pSrb)) return; for( ulSample = 0; ulSample < pSrb->NumberOfBuffers; ulSample++ ) { pHeader = ((PKSSTREAM_HEADER)pSrb->CommandData.DataBufferArray) + ulSample; pData = pHeader->Data; dwDataUsed = pHeader->DataUsed;
// Check header flags
#if 0 //defined( DEBUG )
if ( pHeader->OptionsFlags ) { MonoOutSetBlink( TRUE ); MonoOutChar( '(' );
if ( pHeader->OptionsFlags & KSSTREAM_HEADER_OPTIONSF_SPLICEPOINT ) MonoOutChar( 's'/*"SPLICEPOINT"*/ ); if ( pHeader->OptionsFlags & KSSTREAM_HEADER_OPTIONSF_PREROLL ) MonoOutChar( 'p'/*"PREROLL"*/ ); if ( pHeader->OptionsFlags & KSSTREAM_HEADER_OPTIONSF_DATADISCONTINUITY ) MonoOutChar( 'd'/*"DATADISCONTINUITY"*/ ); if ( pHeader->OptionsFlags & KSSTREAM_HEADER_OPTIONSF_TYPECHANGED ) MonoOutChar( 'c'/*"TYPECHANGED"*/ ); if ( pHeader->OptionsFlags & KSSTREAM_HEADER_OPTIONSF_TIMEVALID ) MonoOutChar( 'v'/*"TIMEVALID"*/ ); if ( pHeader->OptionsFlags & KSSTREAM_HEADER_OPTIONSF_TIMEDISCONTINUITY ) MonoOutChar( 't'/*"TIMEDISCONTINUITY"*/ ); if ( pHeader->OptionsFlags & KSSTREAM_HEADER_OPTIONSF_FLUSHONPAUSE ) MonoOutChar( 'f'/*"FLUSHONPAUSE"*/ ); if ( pHeader->OptionsFlags & KSSTREAM_HEADER_OPTIONSF_DURATIONVALID ) MonoOutChar( 'u'/*"DURATIONVALID"*/ ); if ( pHeader->OptionsFlags & KSSTREAM_HEADER_OPTIONSF_ENDOFSTREAM ) MonoOutChar( 'e'/*"ENDOFSTREAM"*/ ); if ( pHeader->OptionsFlags & KSSTREAM_HEADER_OPTIONSF_LOOPEDDATA ) MonoOutChar( 'l'/*"LOOPEDDATA"*/ );
if ( pHeader->OptionsFlags & ~( KSSTREAM_HEADER_OPTIONSF_SPLICEPOINT | KSSTREAM_HEADER_OPTIONSF_PREROLL | KSSTREAM_HEADER_OPTIONSF_DATADISCONTINUITY | KSSTREAM_HEADER_OPTIONSF_TYPECHANGED | KSSTREAM_HEADER_OPTIONSF_TIMEVALID | KSSTREAM_HEADER_OPTIONSF_TIMEDISCONTINUITY | KSSTREAM_HEADER_OPTIONSF_FLUSHONPAUSE | KSSTREAM_HEADER_OPTIONSF_DURATIONVALID | KSSTREAM_HEADER_OPTIONSF_ENDOFSTREAM | KSSTREAM_HEADER_OPTIONSF_LOOPEDDATA ) ) MonoOutStr( "!!! UNKNOWN FLAG !!!" );
MonoOutChar( ')' ); MonoOutSetBlink( FALSE ); } #endif // DEBUG
#if defined( DEBUG )
//tmp MonoOutChar('A');
//tmp MonoOutULong( (pHeader->TypeSpecificFlags) >> 16 );
//tmp MonoOutChar( '.' );
// MonoOutStr("pTime");
// MonoOutULong(pHeader->PresentationTime);
#endif // DEBUG
if(pHwDevExt->dwFirstAudioOrdNum == -1) { pHwDevExt->dwFirstAudioOrdNum = (pHeader->TypeSpecificFlags) >> 16; MonoOutStr("FirstAudioBuffer"); MonoOutULong( (pHeader->TypeSpecificFlags) >> 16 ); }
if ( pHeader->OptionsFlags & KSSTREAM_HEADER_OPTIONSF_DATADISCONTINUITY ) { MonoOutStr(" A->DISCONT "); pHwDevExt->bStreamNumberCouldBeChanged = TRUE; }
if ( pHeader->OptionsFlags & KSSTREAM_HEADER_OPTIONSF_TYPECHANGED ) { DebugPrint(( DebugLevelVerbose, "ZiVA: Processing audio stream format.\n" )); MonoOutStr(" A->TYPECHANGED "); pHwDevExt->bStreamNumberCouldBeChanged = TRUE; }
//
// Check for the stream number
//
if( ( pHwDevExt->bStreamNumberCouldBeChanged ) || (pHwDevExt->fAtleastOne)) { if ( pData && dwDataUsed ) { WORD wStuffingLength; WORD wPesHeaderLength; WORD wOffset; WORD wNewStream;
if(dwDataUsed < 22) { pHwDevExt->bStreamNumberCouldBeChanged = FALSE; continue; } //
// Find the location of the stream ID and number
//
wStuffingLength = *(pData+13) & 0x03; wPesHeaderLength = *(pData+22); wOffset = 22;
if ( wPesHeaderLength >= 5 ) { //
// PTS is present here
//
}
wOffset = wOffset + wPesHeaderLength + 1; // wOffset = wOffset + wStuffingLength + 1;
if(dwDataUsed < wOffset) { pHwDevExt->bStreamNumberCouldBeChanged = FALSE; continue; } //
// Get Stream Number
//
//WORD wNewStream = *(pData+31);
wNewStream = *(pData+wOffset);
if ( (*(pData+17) & 0xE8) == 0xC0 )//|| (*(pData+17) & 0xF0) == 0xD0 )
{ wNewStream = *(pData+17) & 0x07 ; if ( wNewStream != pHwDevExt->wCurrentStreamNumber ) { pHwDevExt->wCurrentStreamNumber = wNewStream;
//
// Select the current stream number for MPEG audio
//
DVD_SetStreams( 3, pHwDevExt->wCurrentStreamNumber ); pHwDevExt->fAtleastOne = FALSE;
}
pHwDevExt->bStreamNumberCouldBeChanged = FALSE; }
else if ( ((wNewStream & 0xE0) == 0x80) ) { if ( wNewStream != pHwDevExt->wCurrentStreamNumber ) { pHwDevExt->wCurrentStreamNumber = wNewStream;
//
// Select the current stream number for AC-3 audio
//
DVD_SetStreams( 2, pHwDevExt->wCurrentStreamNumber & 0x1F ); pHwDevExt->fAtleastOne = FALSE;
}
pHwDevExt->bStreamNumberCouldBeChanged = FALSE; } else if ( ((wNewStream & 0xE0) == 0xA0) ) { if ( wNewStream != pHwDevExt->wCurrentStreamNumber ) { pHwDevExt->wCurrentStreamNumber = wNewStream;
//
// Select the current stream number for LPCM audio
//
DVD_SetStreams( 4, pHwDevExt->wCurrentStreamNumber & 0x1F ); pHwDevExt->fAtleastOne = FALSE;
}
pHwDevExt->bStreamNumberCouldBeChanged = FALSE; }
else { MonoOutStr( " !!! Audio Pack with wrong ID !!! " ); }
} } }
//
// Register this Srb
//
#if defined( DEBUG )
if ( pHwDevExt->pCurrentAudioSrb ) { DebugPrint(( DebugLevelWarning, "ZiVA: !!!!!!!!!!! ERROR: Audio slot is not empty !!!!!!!!!!\n" )); MonoOutStr("!!!!!!!AudioSlotIsNotEmpty!!!!!!"); } #endif // DEBUG
// if(!PreparePageTable(pSrb))
// MonoOutStr("Audio PageTable Prep failed");
pHwDevExt->pCurrentAudioSrb = pSrb;
AdapterSendData( pHwDevExt ); }
/*
** AudioQueryAccept() ** ** ** ** Arguments: ** ** pSrb - Pointer to the stream request block ** ** Returns: ** ** Side Effects: none */ static void AudioQueryAccept( PHW_STREAM_REQUEST_BLOCK pSrb ) { DebugPrint(( DebugLevelVerbose, "ZiVA: Begin AudioQueryAccept()\n" ));
pSrb->Status = STATUS_SUCCESS; DebugPrint(( DebugLevelVerbose, "ZiVA: End AudioQueryAccept()\n" )); }
/******************************************************************************/ /********************** MASTER CLOCK RELATED FUNCTIONS **********************/ /******************************************************************************/
/*
** AudioClockFunction ** ** Routine to be called by the Class Driver to obtain Master ** Clock information. ** */ void STREAMAPI AudioClockFunction( IN PHW_TIME_CONTEXT TimeContext ) { ULONGLONG sysTime = GetSystemTime();
DebugPrint(( DebugLevelVerbose, "ZiVA: AudioClockFunction() -> " ));
/* if (fClkPause)
{ TimeContext->Time = LastStamp + PauseTime - LastSysTime; return TRUE; }*/
switch ( TimeContext->Function ) { case TIME_GET_STREAM_TIME: DebugPrint(( DebugLevelVerbose, "TIME_GET_STREAM_TIME\n" )); TimeContext->Time = ConvertPTStoStrm( DVD_GetSTC() ); TimeContext->SystemTime = sysTime; DebugPrint(( DebugLevelVerbose,"------->return PTS: %X\n", TimeContext->Time )); break;
case TIME_READ_ONBOARD_CLOCK: DebugPrint(( DebugLevelVerbose, "TIME_READ_ONBOARD_CLOCK\n" )); break;
case TIME_SET_ONBOARD_CLOCK: DebugPrint(( DebugLevelVerbose, "TIME_SET_ONBOARD_CLOCK\n" )); break;
default: DebugPrint(( DebugLevelWarning, "!!! Unknown value for TimeContext->Function !!!\n" )); break; }
DebugPrint(( DebugLevelVerbose, "ZiVA: End AudioClockFunction()\n" )); }
/*
** ReleaseClockEvents () ** ** handle any time event mark events ** ** Arguments: ** ** ** ** Returns: ** ** Side Effects: */
void ReleaseClockEvents(PHW_DEVICE_EXTENSION pdevex,BOOL fMarkInterval) { PKSEVENT_ENTRY pEvent,pLast; PMYTIME pTim; // LONGLONG MinIntTime;
LONGLONG strmTime; LONGLONG MarkTime;
if (!pdevex || !pdevex->pstroAud) { return; }
// strmTime = ConvertPTStoStrm( DVD_GetSTC() );
//
// loop through all time_mark events
//
pEvent = NULL; pLast = NULL;
while(pEvent = StreamClassGetNextEvent( pdevex, pdevex->pstroAud, (GUID *)&KSEVENTSETID_Clock, KSEVENT_CLOCK_POSITION_MARK, pLast)) { strmTime = ConvertPTStoStrm( DVD_GetSTC() ); TRAP MarkTime = ((PKSEVENT_TIME_MARK)(pEvent +1))->MarkTime; MonoOutStr(" MT "); MonoOutULong(MarkTime); MonoOutStr(" ST "); MonoOutULong(strmTime);
if (((PKSEVENT_TIME_MARK)(pEvent +1))->MarkTime <= strmTime ) { // TRAP
//
// signal the event here
//
StreamClassStreamNotification( SignalStreamEvent, pdevex->pstroAud, pEvent ); //
// tell the stream class to disable this event
//
/* StreamClassStreamNotification(
DeleteStreamEvent, pdevex->pstroAud, pEvent );*/ } else if(((PKSEVENT_TIME_MARK)(pEvent +1))->MarkTime - strmTime > 100000000) { StreamClassStreamNotification( SignalStreamEvent, pdevex->pstroAud, pEvent ); }
pLast = pEvent; }
//
// loop through all time_interval events
//
if(!fMarkInterval) return;
pEvent = NULL;
while ( pEvent = StreamClassGetNextEvent( pdevex, pdevex->pstroAud, (GUID *)&KSEVENTSETID_Clock, KSEVENT_CLOCK_INTERVAL_MARK, pEvent)) { pTim = ((PMYTIME)(pEvent + 1)); if (pTim && pTim->tim.Interval) { // if( strmTime >= pTim->tim.TimeBase+ pTim->tim.Interval)
{ StreamClassStreamNotification(SignalStreamEvent,pdevex->pstroAud,pEvent); // DbgPrint(" SEN ");
} }
MonoOutStr("StreamClass Event Notification"); }
}
void CallReleaseEvent( PHW_DEVICE_EXTENSION pHwDevExt ) { ReleaseClockEvents(pHwDevExt,TRUE); AdapterSendData( pHwDevExt ); }
/*
** AudioEvent () ** ** receives notification for audio clock enable / disable events ** ** Arguments: ** ** ** ** Returns: ** ** Side Effects: */ NTSTATUS STREAMAPI AudioEventFunction( IN PHW_EVENT_DESCRIPTOR pEventDescriptor ) { PUCHAR pCopy = (PUCHAR)( pEventDescriptor->EventEntry + 1 ); PUCHAR pSrc = (PUCHAR)pEventDescriptor->EventData; ULONG cCopy=0;
DebugPrint(( DebugLevelVerbose, "ZiVA: AudioEventFunction() -> " ));
if ( pEventDescriptor->Enable ) { switch ( pEventDescriptor->EventEntry->EventItem->EventId ) { case KSEVENT_CLOCK_POSITION_MARK: DbgPrint("KSEVENT_CLOCK_POSITION_MARK\n"); cCopy = sizeof( KSEVENT_TIME_MARK ); break;
case KSEVENT_CLOCK_INTERVAL_MARK: DbgPrint("KSEVENT_CLOCK_INTERVAL_MARK\n" ); pDevEx->dwVSyncCount=0; cCopy = sizeof( KSEVENT_TIME_INTERVAL ); break;
default: DebugPrint(( DebugLevelWarning, "!!! Unknown value for EventId !!!\n" )); return STATUS_NOT_IMPLEMENTED; }
if (pEventDescriptor->EventEntry->EventItem->DataInput != cCopy ) { DebugPrint(( DebugLevelWarning, "ZiVA: !!! STATUS_INVALID_BUFFER_SIZE !!!\n" ));
return STATUS_INVALID_BUFFER_SIZE; }
//
// copy the input buffer
//
for (;cCopy > 0; cCopy--) { *pCopy++ = *pSrc++; } }
DebugPrint(( DebugLevelVerbose, "ZiVA: End AudioEventFunction()\n" ));
return STATUS_SUCCESS; }
static ULONGLONG GetSystemTime() { ULONGLONG ticks; ULONGLONG rate;
ticks = (ULONGLONG)KeQueryPerformanceCounter((PLARGE_INTEGER)&rate).QuadPart;
//
// convert from ticks to 100ns clock
//
ticks = (ticks & 0xFFFFFFFF00000000) / rate * 10000000 + (ticks & 0xFFFFFFFF) * 10000000 / rate;
return ticks; }
/////////////////////////////////////////////////////////////////////////
//
// Function : ConvertPTStoStrm
// Args : PTS
// Returns :
//
// Purpose:
// converts a PTS to a Stream class 100 NS clock
//
//
//
//
/////////////////////////////////////////////////////////////////////////
static ULONGLONG ConvertPTStoStrm( ULONG pts ) { ULONGLONG strm;
strm = (ULONGLONG)pts; strm = (strm * 1000) / 9;
/* if((strm-pDevEx->prevStrm) > 100000000000)
{ MonoOutStr( " VeryHigh STC " ); strm = pDevEx->prevStrm; } pDevEx->prevStrm = strm;*/ return strm; }
ULONGLONG ConvertStrmToPTS( ULONGLONG stc ) { ULONGLONG pts;
pts = (ULONGLONG)stc; pts = (stc * 9) / 1000;
return pts; }
|