mirror of https://github.com/tongzx/nt5src
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
1032 lines
25 KiB
/******************************************************************************\
|
|
* *
|
|
* 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;
|
|
}
|