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.
 
 
 
 
 
 

355 lines
10 KiB

//**************************************************************************
//
// Title : MPEvent.cpp
//
// Date : 1997.12.09 1st making
//
// Author : Toshiba [PCS](PSY) Hideki Yagi
//
// Copyright 1997 Toshiba Corporation. All Rights Reserved.
//
// -------------------------------------------------------------------------
//
// Change log :
//
// Date Revision Description
// ------------ ---------- -----------------------------------------------
// 1997.12.09 000.0000 1st making.
//
//**************************************************************************
#include "includes.h"
#include "hal.h"
#include "classlib.h"
#include "ctime.h"
#include "schdat.h"
#include "mpevent.h"
#include "wdmbuff.h"
#include "ccque.h"
#include "userdata.h"
#include "wdmkserv.h"
#include "ctvctrl.h"
#include "hlight.h"
#include "hwdevex.h"
#include "dvdinit.h"
#define USCC_BuffSize 0x200 // OK?
////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////
void AdviceCallBack( PHW_STREAM_REQUEST_BLOCK pSrb )
{
StreamClassStreamNotification( StreamRequestComplete,
pSrb->StreamObject, pSrb );
}
IMBoardListItem *CDataXferEvent::GetNext( void )
{
return( m_Next );
}
void CDataXferEvent::SetNext( IMBoardListItem *item )
{
m_Next = item;
return;
}
HALEVENTTYPE CDataXferEvent::GetEventType( void )
{
return( m_EventType );
}
void CDataXferEvent::Advice( void *pData )
{
CWDMBuffer *ptr;
PHW_STREAM_REQUEST_BLOCK pSrb;
ptr = (CWDMBuffer *)pData;
ptr->SetNext( NULL ); // 98.04.10
pSrb = ptr->GetSRB();
if( pSrb->Status != STATUS_CANCELLED ){
pSrb->Status = STATUS_SUCCESS;
}
DBG_PRINTF( ("DataXfer-Advice: cuurent Irql = 0x%04x pSrb=0x%x\n\r", KeGetCurrentIrql(),pSrb ) );
// if( KeGetCurrentIrql() > PASSIVE_LEVEL ){
// StreamClassCallAtNewPriority( NULL,
// pSrb->HwDeviceExtension,
//// LowToigh,
// Low,
// (PHW_PRIORITY_ROUTINE)AdviceCallBack,
// pSrb
// );
// }else{
#ifndef REARRANGEMENT
if (ptr->m_EndFlag == FALSE)
return; //non last buffer
DBG_PRINTF( ("DVDWDM:Advice()---CompleteNotification Srb=%x\n\r", pSrb));
#endif REARRANGEMENT
StreamClassStreamNotification( StreamRequestComplete,
pSrb->StreamObject, pSrb );
// }
return;
}
////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////
void CUserDataEvent::Init( HW_DEVICE_EXTENSION *pHwDevExt )
{
m_Next = NULL;
m_EventType = WrapperEvent_UserData;
m_pHwDevExt = pHwDevExt;
}
IMBoardListItem *CUserDataEvent::GetNext( void )
{
return( m_Next );
}
void CUserDataEvent::SetNext( IMBoardListItem *item )
{
m_Next = item;
return;
}
HALEVENTTYPE CUserDataEvent::GetEventType( void )
{
return( m_EventType );
}
void CUserDataEvent::Advice( void *pData )
{
HW_DEVICE_EXTENSION *pHwDevExt;
pHwDevExt = m_pHwDevExt;
LONG cp;
UCHAR field;
CUserData *pUData;
DWORD dwSizeUData;
UCHAR ccbuff[ USCC_BuffSize ]; // tmp buff for USCC data
PUCHAR pDest;
// If FF or FR play mode now, no process for Closed Caption.
if( pHwDevExt->Rate < 10000 )
return;
pUData = (CUserData *)pData; // pointer to user data
dwSizeUData = pUData->GetDataSize();
PHW_STREAM_REQUEST_BLOCK pSrb; // pointer to SRB included
// SRB_READ_DATA for C.C.
// Copy User Data to temp buffer.
pUData->DataCopy( ccbuff, dwSizeUData );
// Get SRB included SRB_READ_DATA.
pSrb = pHwDevExt->ccque.get();
cp = 0;
if( pSrb!=NULL ){
if( pSrb->CommandData.DataBufferArray->FrameExtent < sizeof( KSGOP_USERDATA ) ){
pSrb->Status = STATUS_INVALID_BUFFER_SIZE;
pSrb->ActualBytesTransferred = 0;
StreamClassStreamNotification( StreamRequestComplete,
pSrb->StreamObject,
pSrb );
return;
}
pDest = (PUCHAR)(pSrb->CommandData.DataBufferArray->Data);
*(PULONG)pDest = 0xB2010000; // user_data_start_code
pDest += 4;
*pDest++ = ccbuff[cp++]; // line21_indicator
*pDest++ = ccbuff[cp++];
*pDest++ = ccbuff[cp++]; // reserved
*pDest++ = ccbuff[cp++];
field = *pDest++ = ccbuff[cp++]; // top_field_flag_of_gop &
field &= 0x3f; // number_of_displayed_field
if( pSrb->CommandData.DataBufferArray->FrameExtent <
(field-1)*3 + sizeof(KSGOP_USERDATA) ){
pSrb->Status = STATUS_INVALID_BUFFER_SIZE;
pSrb->ActualBytesTransferred = 0;
StreamClassStreamNotification( StreamRequestComplete,
pSrb->StreamObject,
pSrb );
return;
}
pSrb->CommandData.DataBufferArray->DataUsed =
pSrb->ActualBytesTransferred =
(field-1)*3 + sizeof(KSGOP_USERDATA);
//
// copy line21_data()
//
for( ;field ; field-- ){
*pDest++ = ccbuff[cp++]; // marker_bits & line21_switch
*pDest++ = ccbuff[cp++]; // line21_data1
*pDest++ = ccbuff[cp++]; // line21_data2
}
PKSSTREAM_HEADER pPacket;
pPacket = pSrb->CommandData.DataBufferArray;
pPacket->OptionsFlags = KSSTREAM_HEADER_OPTIONSF_TIMEVALID |
KSSTREAM_HEADER_OPTIONSF_DURATIONVALID;
pSrb->NumberOfBuffers = 1;
pPacket->PresentationTime.Time = pHwDevExt->ticktime.GetStreamTime();
pPacket->Duration = 1000;
pSrb->Status = STATUS_SUCCESS;
StreamClassStreamNotification( StreamRequestComplete,
pSrb->StreamObject,
pSrb );
}
return;
}
////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////
void CVSyncEvent::Init( HW_DEVICE_EXTENSION *pHwDevExt )
{
m_Next = NULL;
m_EventType = WrapperEvent_VSync;
m_pHwDevExt = pHwDevExt;
m_Vcount = 0;
}
IMBoardListItem *CVSyncEvent::GetNext( void )
{
return( m_Next );
}
void CVSyncEvent::SetNext( IMBoardListItem *item )
{
m_Next = item;
return;
}
HALEVENTTYPE CVSyncEvent::GetEventType( void )
{
return( m_EventType );
}
void CVSyncEvent::Advice( void *pData )
{
HW_DEVICE_EXTENSION *pHwDevExt;
pHwDevExt = m_pHwDevExt;
PKSEVENT_ENTRY pEvent, pLast;
PMYTIME pTim;
LONGLONG MinIntTime;
LONGLONG strmTime;
ULONGLONG sysTime;
// do this process every 5 Vsyncs.
if( m_Vcount<=5 ){
m_Vcount++;
return;
}
m_Vcount = 0;
sysTime = pHwDevExt->ticktime.GetSystemTime();
if( !pHwDevExt || !pHwDevExt->pstroAud || !pHwDevExt->pstroSP ){
return;
}
strmTime = pHwDevExt->ticktime.GetStreamTime();
//
// loop through all time_mark events
//
pEvent = NULL;
pLast = NULL;
while((pEvent = StreamClassGetNextEvent( pHwDevExt,
pHwDevExt->pstroAud,
(GUID *)&KSEVENTSETID_Clock,
KSEVENT_CLOCK_POSITION_MARK,
pLast)) != NULL )
{
if( ((PKSEVENT_TIME_MARK)(pEvent+1))->MarkTime <= strmTime ){
//
// signal the event here
//
StreamClassStreamNotification( SignalStreamEvent,
pHwDevExt->pstroAud,
pEvent );
}
pLast = pEvent;
}
//
// loop through all time_interval events
//
pEvent = NULL;
pLast = NULL;
while( (pEvent = StreamClassGetNextEvent( pHwDevExt,
pHwDevExt->pstroAud,
(GUID *)&KSEVENTSETID_Clock,
KSEVENT_CLOCK_INTERVAL_MARK,
pLast)) !=NULL )
{
//
// check if this event has been used for this interval yet
//
pTim = ((PMYTIME)(pEvent + 1 ));
if( pTim && pTim->tim.Interval ){
if( pTim->tim.TimeBase <= strmTime){
MinIntTime = (strmTime - pTim->tim.TimeBase)/pTim->tim.Interval;
MinIntTime *= pTim->tim.Interval;
MinIntTime += pTim->tim.TimeBase;
if( MinIntTime > pTim->LastTime ){
//
// signal the event here
//
StreamClassStreamNotification( SignalStreamEvent,
pHwDevExt->pstroAud,
pEvent );
pTim->LastTime = strmTime;
}
}
}else{
;
DBG_BREAK();
}
pLast = pEvent;
}
}