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.
 
 
 
 
 
 

1011 lines
24 KiB

//******************************************************************************/
//* *
//* ccaption.c - *
//* *
//* Copyright (c) C-Cube Microsystems 1996 *
//* All Rights Reserved. *
//* *
//* Use of C-Cube Microsystems code is governed by terms and conditions *
//* stated in the accompanying licensing statement. *
//* *
//******************************************************************************/
#include "strmini.h"
#include "ksmedia.h"
#include "zivawdm.h"
#include "adapter.h"
#include "monovxd.h"
#include "cl6100.h"
#include <ccaption.h>
typedef struct _STREAMEX {
DWORD EventCount;
KSSTATE state;
} STREAMEX, *PSTREAMEX;
HANDLE hMaster;
HANDLE hClk;
void GetCCProperty(PHW_STREAM_REQUEST_BLOCK pSrb)
{
PHW_DEVICE_EXTENSION pHwDevExt = ((PHW_DEVICE_EXTENSION)pSrb->HwDeviceExtension);
PKSALLOCATOR_FRAMING pfrm = (PKSALLOCATOR_FRAMING)pSrb->CommandData.PropertyInfo->PropertyInfo;
PKSSTATE State;
if(!pSrb)
{
#ifdef DBG
DbgPrint(" ERROR : CCGetProp invalid SRB !!!!\n");
DEBUG_BREAKPOINT();
#endif
return;
}
pSrb->Status = STATUS_SUCCESS;//STATUS_NOT_IMPLEMENTED;
if (pSrb->CommandData.PropertyInfo->PropertySetID)
{
#ifdef DBG
DbgPrint(" ERROR : CCGetProp returning NO MATCH !!!\n");
#endif
// invalid property
pSrb->Status = STATUS_NO_MATCH;
return;
}
switch(pSrb->CommandData.PropertyInfo->Property->Id)
{
case KSPROPERTY_CONNECTION_ALLOCATORFRAMING:
{
//This read-only property is used to retrieve any allocator framing requirements
#ifdef DBG
DbgPrint(" : CCGetProp - KSPROPERTY_CONNECTION_ALLOCATORFRAMING\n");
#endif
pfrm->OptionsFlags = 0;
pfrm->PoolType = NonPagedPool;
pfrm->Frames = 10;
pfrm->FrameSize = 200;
pfrm->FileAlignment = 0;
pfrm->Reserved = 0;
pSrb->ActualBytesTransferred = sizeof(KSALLOCATOR_FRAMING);
pSrb->Status = STATUS_SUCCESS;
break;
}
case KSPROPERTY_CONNECTION_STATE:
State= (PKSSTATE) pSrb->CommandData.PropertyInfo->PropertyInfo;
pSrb->ActualBytesTransferred = sizeof (State);
// A very odd rule:
// When transitioning from stop to pause, DShow tries to preroll
// the graph. Capture sources can't preroll, and indicate this
// by returning VFW_S_CANT_CUE in user mode. To indicate this
// condition from drivers, they must return ERROR_NO_DATA_DETECTED
if(pHwDevExt->pstroCC)
{
*State = ((PSTREAMEX)(pHwDevExt->pstroCC->HwStreamExtension))->state;
if (((PSTREAMEX)pHwDevExt->pstroCC->HwStreamExtension)->state == KSSTATE_PAUSE)
{
// wierd stuff for capture type state change. When you transition
// from stop to pause, we need to indicate that this device cannot
// preroll, and has no data to send.
pSrb->Status = STATUS_NO_DATA_DETECTED;
// break;
}
}
pSrb->Status = STATUS_SUCCESS;
break;
default:
#ifdef DBG
DbgPrint(" : CCGetProp Error - invalid cmd !!!\n");
#endif
pSrb->Status = STATUS_NOT_IMPLEMENTED;
break;
}
}
///////////////////////////////////////////////////////////////////////////////////////////
void CCEnqueue(PHW_STREAM_REQUEST_BLOCK pSrb)
{
PHW_DEVICE_EXTENSION pHwDevExt = pSrb->HwDeviceExtension;
PHW_STREAM_REQUEST_BLOCK pSrbTmp;
ULONG cSrb;
// if(pHwDevExt->pCCDevEx == NULL)
// return;
// pSrbTmp = CONTAINING_RECORD((&(pHwDevExt->pCCDevEx->pSrbQ)), HW_STREAM_REQUEST_BLOCK, NextSRB);
// if(pSrbTmp == NULL)
// return;
// enqueue the given SRB on the device extension queue
for (cSrb =0, pSrbTmp = CONTAINING_RECORD((&(pHwDevExt->pCCDevEx->pSrbQ)), HW_STREAM_REQUEST_BLOCK, NextSRB);
pSrbTmp->NextSRB;
pSrbTmp = pSrbTmp->NextSRB, cSrb++);
pSrbTmp->NextSRB = pSrb;
pSrb->NextSRB = NULL;
pHwDevExt->cCCQ++;
}
///////////////////////////////////////////////////////////////////////////////////////////
PHW_STREAM_REQUEST_BLOCK
CCDequeue(
PHW_DEVICE_EXTENSION pHwDevExt
)
/*++
Routine Description:
Dequeue the CC queue
Arguments:
pHwDevExt - device exetension pointer
Return Value:
Dequeued SRB
--*/
{
PHW_STREAM_REQUEST_BLOCK pRet = NULL;
if(pHwDevExt->pCCDevEx == NULL)
return NULL;
if (pHwDevExt->pCCDevEx->pSrbQ)
{
pHwDevExt->cCCDeq++;
pRet = pHwDevExt->pCCDevEx->pSrbQ;
pHwDevExt->pCCDevEx->pSrbQ = pRet->NextSRB;
pHwDevExt->cCCQ--;
}
return(pRet);
}
/////////////////////////////////////////////////////////////////////////////////////////////////////
void CallBackError(PHW_STREAM_REQUEST_BLOCK pSrb)
{
PHW_DEVICE_EXTENSION pHwDevExt = pSrb->HwDeviceExtension;
if(!pSrb)
{
#ifdef DBG
DbgPrint(" ERROR : CallBackError - invalid arg !!!\n");
#endif
return;
}
pSrb->Status = STATUS_SUCCESS;
// if (pHwDevExt->pSPstrmex)
// {
//
// pHwDevExt->pSPstrmex->pdecctl.curData = 0;
// pHwDevExt->pSPstrmex->pdecctl.decFlags = 0;
//
// }
// StreamClassStreamNotification(StreamRequestComplete,
// pSrb->StreamObject,
//sri pSrb);
}
///////////////////////////////////////////////////////////////////////////////////////////
void
CleanCCQueue(
PHW_DEVICE_EXTENSION pHwDevExt
)
/*++
Routine Description:
Clean CC Queue
Arguments:
pHwDevExt - pointer to device extension
Return Value:
none
--*/
{
PHW_STREAM_REQUEST_BLOCK pSrb;
while (pSrb = CCDequeue(pHwDevExt))
{
CallBackError(pSrb);
}
}
///////////////////////////////////////////////////////////////////////////////////////////
VOID STREAMAPI
CCReceiveDataPacket(
IN PHW_STREAM_REQUEST_BLOCK pSrb
)
/*++
Routine Description:
Receive the data packets to send to the close-caption decoder
Arguments:
pSrb - pointer to stream request block
Return Value:
none
--*/
{
PHW_DEVICE_EXTENSION pHwDevExt = ((PHW_DEVICE_EXTENSION) pSrb->HwDeviceExtension);
//
// determine the type of packet.
//
switch (pSrb->Command)
{
case SRB_READ_DATA:
pHwDevExt->cCCRec++;
CCEnqueue(pSrb);
#ifdef DBG
//DbgPrint(" : CC Data Packet - pHwDevExt->cCCQ = %d\n",pHwDevExt->cCCQ);
#endif
//NEW
pSrb->Status = STATUS_PENDING;
pSrb->TimeoutCounter = 0;
StreamClassStreamNotification(ReadyForNextStreamDataRequest,pSrb->StreamObject);
return;
case SRB_WRITE_DATA:
pSrb->Status = STATUS_NOT_IMPLEMENTED;
break;
default: // invalid / unsupported command. Fail it as such
#ifdef DBG
DbgPrint(" : CCReceiveDataPacket - invalid cmd !!!\n");
#endif
pSrb->Status = STATUS_NOT_IMPLEMENTED;
break;
}
StreamClassStreamNotification(ReadyForNextStreamDataRequest,
pSrb->StreamObject);
StreamClassStreamNotification(StreamRequestComplete,
pSrb->StreamObject,
pSrb);
}
/*
** CCReceiveCtrlPacket()
*/
VOID STREAMAPI CCReceiveCtrlPacket( IN PHW_STREAM_REQUEST_BLOCK pSrb )
{
PHW_DEVICE_EXTENSION pHwDevExt = (PHW_DEVICE_EXTENSION)pSrb->HwDeviceExtension;
DebugPrint(( DebugLevelTrace, ":CCReceiveCtrlPacket---------\r\n" ));
switch( pSrb->Command ) {
case SRB_SET_STREAM_STATE:
AdapterSetState( pSrb );
if(pHwDevExt->pstroCC)
((PSTREAMEX)(pHwDevExt->pstroCC->HwStreamExtension))->state = pSrb->CommandData.StreamState;
pSrb->Status = STATUS_SUCCESS;
break;
case SRB_GET_STREAM_STATE:
DebugPrint(( DebugLevelTrace, ": SRB_GET_STREAM_STATE\r\n" ));
pSrb->Status = STATUS_SUCCESS;
break;
case SRB_GET_STREAM_PROPERTY:
DebugPrint(( DebugLevelTrace, ": SRB_GET_STREAM_PROPERTY\r\n" ));
GetCCProperty( pSrb );
break;
case SRB_SET_STREAM_PROPERTY:
DebugPrint(( DebugLevelTrace, ": SRB_SET_STREAM_PROPERTY\r\n" ));
// SetCCProperty( pSrb );
pSrb->Status = STATUS_NOT_IMPLEMENTED;
break;
case SRB_OPEN_MASTER_CLOCK:
DebugPrint( (DebugLevelTrace, ": SRB_OPEN_MASTER_CLOCK\r\n") );
hMaster = pSrb->CommandData.MasterClockHandle;
pSrb->Status = STATUS_SUCCESS;
break;
case SRB_CLOSE_MASTER_CLOCK:
DebugPrint(( DebugLevelTrace, ": SRB_CLOSE_MASTER_CLOCK\r\n" ));
hMaster = pSrb->CommandData.MasterClockHandle;
pSrb->Status = STATUS_SUCCESS;
break;
case SRB_INDICATE_MASTER_CLOCK:
DebugPrint(( DebugLevelTrace, ": SRB_INDICATE_MASTER_CLOCK\r\n" ));
hClk = pSrb->CommandData.MasterClockHandle;
pSrb->Status = STATUS_SUCCESS;
break;
case SRB_BEGIN_FLUSH : // beginning flush state
MonoOutStr("CC::BeginFlush");
pSrb->Status = STATUS_SUCCESS;
break;
case SRB_UNKNOWN_STREAM_COMMAND:
DebugPrint(( DebugLevelTrace, ": SRB_UNKNOWN_STREAM_COMMAND\r\n" ));
// TRAP;
pSrb->Status = STATUS_NOT_IMPLEMENTED;
break;
case SRB_SET_STREAM_RATE:
DebugPrint(( DebugLevelTrace, ": SRB_SET_STREAM_RATE\r\n" ));
// TRAP;
pSrb->Status = STATUS_NOT_IMPLEMENTED;
break;
case SRB_PROPOSE_DATA_FORMAT:
DebugPrint(( DebugLevelTrace, ": SRB_PROPOSE_DATA_FORMAT\r\n" ));
// TRAP;
pSrb->Status = STATUS_NOT_IMPLEMENTED;
break;
default:
DebugPrint(( DebugLevelTrace, ": default %d(0x%x)\r\n", pSrb->Command, pSrb->Command ));
// TRAP;
pSrb->Status = STATUS_NOT_IMPLEMENTED;
break;
}
StreamClassStreamNotification( ReadyForNextStreamControlRequest,
pSrb->StreamObject );
StreamClassStreamNotification( StreamRequestComplete,
pSrb->StreamObject,
pSrb );
}
static ULONGLONG ConvertPTStoStrm( ULONG pts )
{
ULONGLONG strm;
strm = (ULONGLONG)pts;
strm = (strm * 1000) / 9;
return strm;
}
////////////////////////////////////////////////////////////////////////////////
/*
void UserDataEvents(PHW_DEVICE_EXTENSION pHwDevExt)
{
PBYTE pDest;
PHW_STREAM_REQUEST_BLOCK pSrb;
PKSSTREAM_HEADER pPacket;
DWORD *pdw;
BYTE *pb;
DWORD USR_Read_Ptr, USR_Write_Ptr, Data,UserDataBufferStart,UserDataBufferEnd;
WORD wByteLen, wCount=0;
WORD i = 0,j;
WORD wPhase = 0;
BYTE CC_Len;
WORD CC_Data;
// pdw = (DWORD *)LUXVideoUserData(pHwDevExt);
USR_Read_Ptr = DVD_ReadDRAM( USER_DATA_READ );
USR_Write_Ptr = DVD_ReadDRAM( USER_DATA_WRITE );
UserDataBufferStart = DVD_ReadDRAM( USER_DATA_BUFFER_START );
UserDataBufferEnd = DVD_ReadDRAM( USER_DATA_BUFFER_END );
// Check for DRAM Buffer Overflow
if ( USR_Read_Ptr == 0xFFFFFFFF )
{
// Set Read Ptr
DVD_WriteDRAM( USER_DATA_READ, USR_Write_Ptr );
return;
}
while( USR_Read_Ptr != USR_Write_Ptr )
{
// Get Data from USER_DATA DRAM Buffer
Data = DVD_ReadDRAM( USR_Read_Ptr );
// Store to Local Buffer
USR_Data_Buff[ i++ ] = Data;//CL6100_DWSwap( Data );
// Adjust Data Pointer
USR_Read_Ptr += 4L;
if ( USR_Read_Ptr >= UserDataBufferEnd)
USR_Read_Ptr = UserDataBufferStart;
}
// Save DWORD Count
wCount = i;
// Set Read End Address to DRAM
DVD_WriteDRAM( USER_DATA_READ, USR_Read_Ptr );
if( (USR_Data_Buff[ 0 ] & 0x0000FFFF) == 0x0000EDFE )
{
// Get Data Count and Field Flag
CC_Len = * ( ( ( LPBYTE )USR_Data_Buff ) + 8 );
wCount = ( BYTE )( CC_Len & 0x3F );
wCount = (wCount-1)*3 + sizeof(KSGOP_USERDATA);
if (pHwDevExt->pstroCC && ((PSTREAMEX)(pHwDevExt->pstroCC->HwStreamExtension))->state==KSSTATE_RUN )
{
if (pSrb = CCDequeue(pHwDevExt))
{
//
// check the SRB to ensure it can take at least the header
// information from the GOP packet
//
if (pSrb->CommandData.DataBufferArray->FrameExtent < sizeof(KSGOP_USERDATA))
{
pSrb->Status = STATUS_INVALID_BUFFER_SIZE;
pSrb->ActualBytesTransferred = 0;
StreamClassStreamNotification(StreamRequestComplete,
pSrb->StreamObject,
pSrb);
return;
}
pDest = pSrb->CommandData.DataBufferArray->Data;
// move pdw pointer to the size of CC
// pb = ((BYTE*)pdw)+8;
//
// numb = (DWORD)(*pb)&0x3f;
// numb = (numb-1)*3 + sizeof(KSGOP_USERDATA);
if (pSrb->CommandData.DataBufferArray->FrameExtent < wCount)
{
pSrb->Status = STATUS_INVALID_BUFFER_SIZE;
pSrb->ActualBytesTransferred = 0;
StreamClassStreamNotification(StreamRequestComplete,
pSrb->StreamObject,
pSrb);
return;
}
pSrb->CommandData.DataBufferArray->DataUsed =
pSrb->ActualBytesTransferred = wCount;
// soff = (DWORD)pdw-pHwDevExt->luxbase;
//
// DVReadStr(luxbase,(DWORD)pDest,soff,numb);
memcpy(pDest,USR_Data_Buff,wCount);
pSrb->Status = STATUS_SUCCESS;
pPacket = pSrb->CommandData.DataBufferArray;
pPacket->OptionsFlags = KSSTREAM_HEADER_OPTIONSF_TIMEVALID |
KSSTREAM_HEADER_OPTIONSF_DURATIONVALID;
pSrb->NumberOfBuffers = 1;
pPacket->PresentationTime.Time = ConvertPTStoStrm(DVD_GetSTC());
pPacket->Duration = 1000;
StreamClassStreamNotification(StreamRequestComplete,
pSrb->StreamObject,
pSrb);
// return;
}
}
}
return;
for( i = 0; i < wCount; i++ )
{
Data = USR_Data_Buff[ i ];
switch( wPhase )
{
case 0:
// Check USER_DATA DRAM Sync
if ( ( Data & 0xFFFF0000 ) == 0xFEED0000)//0x0000EDFE )
{
wPhase = 1;
}
break;
case 1:
// Check USER_DATA ID (Closed Caption)
if ( Data == 0xF8014343 )
wPhase = 2;
break;
case 2:
// Get Data Count and Field Flag
CC_Len = * ( ( ( LPBYTE )USR_Data_Buff ) + 8 );
wCount = ( BYTE )( CC_Len & 0x3F );
wCount = (wCount-1)*3 + sizeof(KSGOP_USERDATA);
if (pHwDevExt->pstroCC && ((PSTREAMEX)(pHwDevExt->pstroCC->HwStreamExtension))->state==KSSTATE_RUN )
{
if (pSrb = CCDequeue(pHwDevExt))
{
//
// check the SRB to ensure it can take at least the header
// information from the GOP packet
//
if (pSrb->CommandData.DataBufferArray->FrameExtent < sizeof(KSGOP_USERDATA))
{
pSrb->Status = STATUS_INVALID_BUFFER_SIZE;
pSrb->ActualBytesTransferred = 0;
StreamClassStreamNotification(StreamRequestComplete,
pSrb->StreamObject,
pSrb);
return;
}
pDest = pSrb->CommandData.DataBufferArray->Data;
// move pdw pointer to the size of CC
// pb = ((BYTE*)pdw)+8;
//
// numb = (DWORD)(*pb)&0x3f;
// numb = (numb-1)*3 + sizeof(KSGOP_USERDATA);
//
if (pSrb->CommandData.DataBufferArray->FrameExtent < wCount)
{
pSrb->Status = STATUS_INVALID_BUFFER_SIZE;
pSrb->ActualBytesTransferred = 0;
StreamClassStreamNotification(StreamRequestComplete,
pSrb->StreamObject,
pSrb);
return;
}
pSrb->CommandData.DataBufferArray->DataUsed =
pSrb->ActualBytesTransferred = wCount;
// soff = (DWORD)pdw-pHwDevExt->luxbase;
//
// DVReadStr(luxbase,(DWORD)pDest,soff,numb);
memcpy(pDest,USR_Data_Buff,wCount);
pSrb->Status = STATUS_SUCCESS;
pPacket = pSrb->CommandData.DataBufferArray;
pPacket->OptionsFlags = KSSTREAM_HEADER_OPTIONSF_TIMEVALID |
KSSTREAM_HEADER_OPTIONSF_DURATIONVALID;
pSrb->NumberOfBuffers = 1;
pPacket->PresentationTime.Time = ConvertPTStoStrm(DVD_GetSTC());
pPacket->Duration = 1000;
StreamClassStreamNotification(StreamRequestComplete,
pSrb->StreamObject,
pSrb);
return;
}
}
}
}
// if( *pdw != 0xB2010000)
// {
// pb = (BYTE *)pdw;
// pb++;
// pdw = (DWORD *)pb;
// if( *pdw != 0xB2010000)
// {
// return;
// }
// }
// check if the close caption pin is open and running, and that
// we have a data packet avaiable
}*/
////////////////////////////////////////////////////////////////////////////////
void CCSendDiscontinuity(PHW_DEVICE_EXTENSION pHwDevExt)
{
PHW_STREAM_REQUEST_BLOCK pSrb;
PKSSTREAM_HEADER pPacket;
if (pHwDevExt->pstroCC && ((PSTREAMEX)(pHwDevExt->pstroCC->HwStreamExtension))->state == KSSTATE_RUN )
{
if (pSrb = CCDequeue(pHwDevExt))
{
// we have a request, send a discontinuity
pSrb->Status = STATUS_SUCCESS;
pPacket = pSrb->CommandData.DataBufferArray;
pPacket->OptionsFlags = KSSTREAM_HEADER_OPTIONSF_DATADISCONTINUITY |
KSSTREAM_HEADER_OPTIONSF_TIMEVALID | KSSTREAM_HEADER_OPTIONSF_DURATIONVALID;
pPacket->DataUsed = 0;
pSrb->NumberOfBuffers = 0;
pPacket->PresentationTime.Time = ConvertPTStoStrm(DVD_GetSTC());
pPacket->Duration = 1000;
StreamClassStreamNotification(StreamRequestComplete,
pSrb->StreamObject,
pSrb);
}
}
}
/*VOID HighPrioritySend( IN PHW_STREAM_REQUEST_BLOCK pSrb )
{
StreamClassStreamNotification(StreamRequestComplete,
pSrb->StreamObject,
pSrb);
}*/
/*VOID PassiveSend(IN PHW_STREAM_REQUEST_BLOCK pSrb )
{
PBYTE pDest;
// PHW_STREAM_REQUEST_BLOCK pSrb;
PKSSTREAM_HEADER pPacket;
DWORD *pdw;
BYTE *pb;
DWORD dwData;
PHW_DEVICE_EXTENSION pHwDevExt = (PHW_DEVICE_EXTENSION)pSrb->HwDeviceExtension;
dwData = pHwDevExt->dwUserDataBuffer[0];
if( (dwData & 0xFFFF0000 ) == 0xFEED0000)
MonoOutStr("Feed");
if(pHwDevExt->dwUserDataBuffer[1] == 0x434301F8)
MonoOutStr("CCID");
// check if the close caption pin is open and running, and that
// we have a data packet avaiable
if (pHwDevExt->pstroCC && ((PSTREAMEX)(pHwDevExt->pstroCC->HwStreamExtension))->state==KSSTATE_RUN )
{
// if (pSrb = CCDequeue(pHwDevExt))
{
//
// check the SRB to ensure it can take at least the header
// information from the GOP packet
//
if (pSrb->CommandData.DataBufferArray->FrameExtent < sizeof(KSGOP_USERDATA))
{
pSrb->Status = STATUS_INVALID_BUFFER_SIZE;
pSrb->ActualBytesTransferred = 0;
StreamClassCallAtNewPriority(NULL, pHwDevExt, LowToHigh, HighPrioritySend, pSrb);
return;
}
pDest = pSrb->CommandData.DataBufferArray->Data;
// move pdw pointer to the size of CC
pb = ((BYTE*)pdw)+8;
// numb = (DWORD)(*pb)&0x3f;
// numb = (numb-1)*3 + sizeof(KSGOP_USERDATA);
numb = pHwDevExt->dwUserDataBufferSize;
if (pSrb->CommandData.DataBufferArray->FrameExtent < numb)
{
pSrb->Status = STATUS_INVALID_BUFFER_SIZE;
pSrb->ActualBytesTransferred = 0;
StreamClassCallAtNewPriority(NULL, pHwDevExt, LowToHigh, HighPrioritySend, pSrb);
MonoOutStr("Size<Req. ");
return;
}
pSrb->CommandData.DataBufferArray->DataUsed = pSrb->ActualBytesTransferred = numb;
RtlCopyMemory(pDest,pHwDevExt->pDiscKeyBufferLinear,numb);
pSrb->Status = STATUS_SUCCESS;
pPacket = pSrb->CommandData.DataBufferArray;
pPacket->OptionsFlags = KSSTREAM_HEADER_OPTIONSF_TIMEVALID |
KSSTREAM_HEADER_OPTIONSF_DURATIONVALID;
pSrb->NumberOfBuffers = 1;
pPacket->PresentationTime.Time = ConvertPTStoStrm(DVD_GetSTC());
pPacket->Duration = 1000;
StreamClassCallAtNewPriority(NULL, pHwDevExt, LowToHigh, HighPrioritySend, pSrb);
return;
}
}
}*/
/*void BeginSendingData(IN PHW_STREAM_REQUEST_BLOCK pSrb)
{
PHW_DEVICE_EXTENSION pHwDevExt = (PHW_DEVICE_EXTENSION)pSrb->HwDeviceExtension;
StreamClassCallAtNewPriority(NULL, pHwDevExt, Low, PassiveSend, pSrb);
return;
}*/
////////////////////////////////////////////////////////////////////////////////
void UserDataEvents(PHW_DEVICE_EXTENSION pHwDevExt)
{
DWORD dwUserGopSize;
PBYTE pDest;
PHW_STREAM_REQUEST_BLOCK pSrb;
PKSSTREAM_HEADER pPacket;
int i=0;
BOOL fCCData = FALSE;
fCCData = ZivaHw_GetUserData(pHwDevExt);
if(!fCCData )
{
MonoOutStr(" ReturnBecauseOfNoCCID ");
return;
}
/* if(pHwDevExt->dwUserDataBufferSize == 0)
{
MonoOutStr(" ReturnBecauseOfNoData ");
return;
}
else
/* {
RtlCopyMemory((void*)pHwDevExt->pDiscKeyBufferLinear,(void*)pHwDevExt->dwUserDataBuffer,pHwDevExt->dwUserDataBufferSize );
if (pSrb = CCDequeue(pHwDevExt))
{
BeginSendingData(pSrb);
return;
}
else
{
MonoOutStr("NoBufInQue");
return;
}
}
{
// RtlCopyMemory((void*)pHwDevExt->pDiscKeyBufferLinear,(void*)pHwDevExt->dwUserDataBuffer,pHwDevExt->dwUserDataBufferSize );
}*/
/* dwData = pHwDevExt->dwUserDataBuffer[0];
dwData = (((dwData & 0x000000FF) << 24) | ((dwData & 0x0000FF00) << 8)
|((dwData & 0x00FF0000) >> 8)|((dwData & 0xFF000000) >> 24));
if( (dwData & 0xFFFF0000 ) == 0xFEED0000)
MonoOutStr(" Feed ");
dwUserDataSize = dwData & 0x00000FFF;
MonoOutStr(" SizeSpecifiedByFirst3Bytes ");
MonoOutULong(dwUserDataSize);
pHwDevExt->dwUserDataBuffer[0]= 0xB2010000;*/
/* if(pHwDevExt->dwUserDataBuffer[1] == 0x434301F8)
{
MonoOutStr(" CCID ");
fCCData = TRUE;
}*/
/* if( *pdw != 0x0000EDFE)
{
pb = (BYTE *)pdw;
pb++;
pdw = (DWORD *)pb;
if( *pdw != 0xB2010000)
{
return;
}
}*/
// check if the close caption pin is open and running, and that
// we have a data packet avaiable
if (fCCData && pHwDevExt->pstroCC && ((PSTREAMEX)(pHwDevExt->pstroCC->HwStreamExtension))->state==KSSTATE_RUN )
{
fCCData = FALSE;
if (pSrb = CCDequeue(pHwDevExt))
{
MonoOutStr(" Dequeued new SRB ");
//
// check the SRB to ensure it can take at least the header
// information from the GOP packet
//
if (pSrb->CommandData.DataBufferArray->FrameExtent < sizeof(KSGOP_USERDATA))
{
pSrb->Status = STATUS_INVALID_BUFFER_SIZE;
pSrb->ActualBytesTransferred = 0;
StreamClassStreamNotification(StreamRequestComplete,
pSrb->StreamObject,
pSrb);
MonoOutStr(" ReturnBecauseSRBSize<KSGOP ");
return;
}
pDest = pSrb->CommandData.DataBufferArray->Data;
// move pdw pointer to the size of CC
// pb = ((BYTE*)pHwDevExt->dwUserDataBuffer)+11;
dwUserGopSize = (pHwDevExt->dwUserDataBuffer[2]&0x0000003F);
// dwUserGopSize = (DWORD)(*pb)&0x3f;
dwUserGopSize = (dwUserGopSize-1)*3 + sizeof(KSGOP_USERDATA);
MonoOutStr(" SizeOfCCData+StartCode+CCID ");
MonoOutULong(dwUserGopSize);
// dwUserGopSize = pHwDevExt->dwUserDataBufferSize;
// dwUserGopSize = dwUserDataSize;
if (pSrb->CommandData.DataBufferArray->FrameExtent < dwUserGopSize)
{
pSrb->Status = STATUS_INVALID_BUFFER_SIZE;
pSrb->ActualBytesTransferred = 0;
StreamClassStreamNotification(StreamRequestComplete,
pSrb->StreamObject,
pSrb);
MonoOutStr(" ReturnBacauseOfSRBBufSize<Req.");
return;
}
pSrb->CommandData.DataBufferArray->DataUsed = pSrb->ActualBytesTransferred = dwUserGopSize;
// *pDest = 's';
RtlCopyMemory(pDest,(PBYTE)pHwDevExt->dwUserDataBuffer,dwUserGopSize);
// for(i =0; i< dwUserGopSize ; i++)
// *pDest++ = *pHwDevExt->pDiscKeyBufferLinear++;
pSrb->Status = STATUS_SUCCESS;
pPacket = pSrb->CommandData.DataBufferArray;
pPacket->OptionsFlags = KSSTREAM_HEADER_OPTIONSF_TIMEVALID |
KSSTREAM_HEADER_OPTIONSF_DURATIONVALID;
pSrb->NumberOfBuffers = 1;
pPacket->PresentationTime.Time = ConvertPTStoStrm(DVD_GetSTC());
pPacket->Duration = 1000;
StreamClassStreamNotification(StreamRequestComplete,
pSrb->StreamObject,
pSrb);
MonoOutStr(" USR Req Complete ");
return;
}
else
{
MonoOutStr(" NoSRBAvailableToFill");
}
}
else
MonoOutStr(" NoCCData/NotInRunState");
}