📄 dvdcmd.c
字号:
/*++
Copyright (c) 1998 Microsoft Corporation
Module Name:
dvdcmd.c
Abstract:
main command processing module for DVDTS
Environment:
Kernel mode only
Notes:
THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
PURPOSE.
Copyright (c) 1998 Microsoft Corporation. All Rights Reserved.
Some portions adapted with permission from code Copyright (c) 1997-1998 Toshiba Corporation
Revision History:
5/1/98: created
--*/
#include "strmini.h"
#include "ks.h"
#include <mmsystem.h>
#include "ksmedia.h"
#include "debug.h"
#include "dvdinit.h"
#include "que.h"
#include "DvdTDCod.h" // header for DvdTDCod.lib routines hiding proprietary HW stuff
#include "dvdcmd.h"
#include "strmid.h"
//#include "ddkmapi.h"
HANDLE hClk;
HANDLE hMaster;
BOOL fClkPause;
ULONGLONG LastSysTime = 0;
ULONGLONG PauseTime = 0;
static ULONGLONG LastStamp;
static ULONGLONG LastSys;
static BOOLEAN fValid;
extern BOOLEAN fProgrammed;
extern BOOLEAN fStarted;
BOOLEAN fProgrammed;
BOOLEAN fStarted;
static ULONGLONG StartSys;
KSPIN_MEDIUM VPMedium = {
STATIC_KSMEDIUMSETID_VPBus,
0,
0
};
VOID STREAMAPI AdapterCancelPacket( IN PHW_STREAM_REQUEST_BLOCK pSrb )
/*++
Routine Description:
routine to cancel a packet that may be in progress
Arguments:
pSrb - pointer to stream request block to be cancelled
Return Value:
none
--*/
{
PHW_DEVICE_EXTENSION pHwDevExt = (PHW_DEVICE_EXTENSION)pSrb->HwDeviceExtension;
DebugPrint(( DebugLevelVerbose, "DVDTS:AdapterCancelPacket\r\n" ));
DebugPrint(( DebugLevelVerbose, "DVDTS: pSrb = 0x%x\r\n", pSrb ));
if( pHwDevExt->pSrbDMA0 == pSrb ) {
DebugPrint( (DebugLevelTrace, "DVDTS: pSrb == pSrbDMA0\r\n" ) );
pHwDevExt->pSrbDMA0 = NULL;
pHwDevExt->fSrbDMA0last = FALSE;
}
if( pHwDevExt->pSrbDMA1 == pSrb ) {
DebugPrint( (DebugLevelTrace, "DVDTS: pSrb == pSrbDMA1\r\n" ) );
pHwDevExt->pSrbDMA1 = NULL;
pHwDevExt->fSrbDMA1last = FALSE;
}
pSrb->Status = STATUS_CANCELLED;
// need to find this packet, pull it off our queues, and cancel it
switch (pSrb->Flags & (SRB_HW_FLAGS_DATA_TRANSFER |
SRB_HW_FLAGS_STREAM_REQUEST)) {
//
// find all stream commands, and do stream notifications
//
case SRB_HW_FLAGS_STREAM_REQUEST | SRB_HW_FLAGS_DATA_TRANSFER:
DebugPrint(( DebugLevelVerbose, "DVDTS: SRB_HW_FLAGS_STREAM_REQUEST | SRB_HW_FLAGS_DATA_TRANSFER\r\n", pSrb ));
DeviceQueue_remove( pHwDevExt,pSrb );
CCQueue_remove( pHwDevExt, pSrb );
StreamClassStreamNotification( StreamRequestComplete,
pSrb->StreamObject,
pSrb);
break;
case SRB_HW_FLAGS_STREAM_REQUEST:
DebugPrint( (DebugLevelTrace, "DVDTS: SRB_HW_FLAGS_STREAM_REQUEST\r\n", pSrb ) );
StreamClassStreamNotification( ReadyForNextStreamControlRequest,
pSrb->StreamObject);
StreamClassStreamNotification( StreamRequestComplete,
pSrb->StreamObject,
pSrb);
break;
default:
DebugPrint( (DebugLevelTrace, "DVDTS: default\r\n", pSrb ) );
StreamClassDeviceNotification( ReadyForNextDeviceRequest,
pSrb->HwDeviceExtension );
StreamClassDeviceNotification( DeviceRequestComplete,
pSrb->HwDeviceExtension,
pSrb );
break;
}
}
/*
** AdapterTimeoutPacket()
*/
VOID STREAMAPI AdapterTimeoutPacket( IN PHW_STREAM_REQUEST_BLOCK pSrb )
{
PHW_DEVICE_EXTENSION pHwDevExt = (PHW_DEVICE_EXTENSION)pSrb->HwDeviceExtension;
DebugPrint( (DebugLevelTrace, "DVDTS:AdapterTimeoutPacket\r\n") );
if( decGetVideoPlayMode( pHwDevExt ) == PLAY_MODE_FREEZE ) {
DebugPrint( (DebugLevelTrace, "DVDTS: pause mode\r\n") );
pSrb->TimeoutCounter = pSrb->TimeoutOriginal;
return;
}
TRAP;
// pSrb->TimeoutCounter = pSrb->TimeoutOriginal;
if( pHwDevExt->pSrbDMA0 ) {
DebugPrint(( DebugLevelTrace, "DVDTS: pSrbDMA0 exist\r\n" ));
pHwDevExt->pSrbDMA0 = NULL;
pHwDevExt->fSrbDMA0last = FALSE;
}
if( pHwDevExt->pSrbDMA1 ) {
DebugPrint(( DebugLevelTrace, "DVDTS: pSrbDMA1 exist\r\n" ));
pHwDevExt->pSrbDMA1 = NULL;
pHwDevExt->fSrbDMA1last = FALSE;
}
if( pHwDevExt->pstroVid ) {
StreamClassScheduleTimer(
pHwDevExt->pstroVid,
pHwDevExt,
0,
NULL,
pHwDevExt->pstroVid
);
}
if( pHwDevExt->pstroAud ) {
StreamClassScheduleTimer(
pHwDevExt->pstroAud,
pHwDevExt,
0,
NULL,
pHwDevExt->pstroAud
);
}
if( pHwDevExt->pstroSP ) {
StreamClassScheduleTimer(
pHwDevExt->pstroSP,
pHwDevExt,
0,
NULL,
pHwDevExt->pstroSP
);
}
// init the main and closed-caption SRB queues
DeviceQueue_init(pHwDevExt);
CCQueue_init(pHwDevExt);
pHwDevExt->pSrbCpp = NULL;
pHwDevExt->bDMAstop = FALSE;
StreamClassAbortOutstandingRequests( pHwDevExt, NULL, STATUS_CANCELLED );
}
/*
** AdapterReceivePacket()
*/
VOID STREAMAPI AdapterReceivePacket( IN PHW_STREAM_REQUEST_BLOCK pSrb )
{
PHW_DEVICE_EXTENSION pHwDevExt = (PHW_DEVICE_EXTENSION)pSrb->HwDeviceExtension;
// DWORD st, et;
DebugPrint( (DebugLevelTrace, "DVDTS:AdapterReceivePacket\r\n") );
switch( pSrb->Command ){
case SRB_GET_STREAM_INFO:
DebugPrint( (DebugLevelTrace, "DVDTS: SRB_GET_STREAM_INFO\r\n") );
AdapterStreamInfo( pSrb );
break;
case SRB_OPEN_STREAM:
DebugPrint( (DebugLevelTrace, "DVDTS: SRB_OPEN_STREAM\r\n") );
AdapterOpenStream( pSrb );
break;
case SRB_CLOSE_STREAM:
DebugPrint( (DebugLevelTrace, "DVDTS: SRB_CLOSE_STREAM\r\n") );
AdapterCloseStream( pSrb );
break;
case SRB_INITIALIZE_DEVICE:
DebugPrint( (DebugLevelTrace, "DVDTS: SRB_INITIALIZE_DEVICE\r\n") );
//
// schedule a low priority callback to get the config
// space. processing will continue when this runs.
//
StreamClassCallAtNewPriority(
NULL,
pSrb->HwDeviceExtension,
Low,
(PHW_PRIORITY_ROUTINE) GetPCIConfigSpace,
pSrb
);
return;
// st = GetCurrentTime_ms();
//
// HwInitialize( pSrb );
//
// et = GetCurrentTime_ms();
// DebugPrint( (DebugLevelTrace, "DVDTS:init %dms\r\n", et - st ) );
//
// break;
case SRB_OPEN_DEVICE_INSTANCE:
DebugPrint( (DebugLevelTrace, "DVDTS: SRB_OPEN_DEVICE_INSTANCE\r\n") );
pSrb->Status = STATUS_NOT_IMPLEMENTED;
break;
case SRB_CLOSE_DEVICE_INSTANCE:
DebugPrint( (DebugLevelTrace, "DVDTS: SRB_CLOSE_DEVICE_INSTANCE\r\n") );
pSrb->Status = STATUS_NOT_IMPLEMENTED;
break;
case SRB_GET_DEVICE_PROPERTY:
DebugPrint( (DebugLevelTrace, "DVDTS: SRB_GET_DEVICE_PROPERTY\r\n") );
TRAP;
pSrb->Status = STATUS_NOT_IMPLEMENTED;
break;
case SRB_SET_DEVICE_PROPERTY:
DebugPrint( (DebugLevelTrace, "DVDTS: SRB_SET_DEVICE_PROPERTY\r\n") );
TRAP;
pSrb->Status = STATUS_NOT_IMPLEMENTED;
break;
case SRB_CHANGE_POWER_STATE:
DebugPrint( (DebugLevelTrace, "DVDTS: SRB_CHANGE_POWER_STATE\r\n") );
if (pSrb->CommandData.DeviceState == PowerDeviceD0) {
//
// should turn power back on here if was off; we're not sleeping in this sample.
//
} else {
//
// disable interrupts.
//
decDisableInt( pHwDevExt );
}
pSrb->Status = STATUS_SUCCESS;
break;
case SRB_UNINITIALIZE_DEVICE:
DebugPrint( (DebugLevelTrace, "DVDTS: SRB_UNINITIALIZE_DEVICE\r\n") );
decDisableInt( pHwDevExt );
pSrb->Status = STATUS_SUCCESS;
break;
case SRB_UNKNOWN_DEVICE_COMMAND:
DebugPrint( (DebugLevelTrace, "DVDTS: SRB_UNKNOWN_DEVICE_COMMAND\r\n") );
pSrb->Status = STATUS_NOT_IMPLEMENTED;
break;
// case SRB_QUERY_UNLOAD:
// DebugPrint( (DebugLevelTrace, "DVDTS: SRB_QUERY_UNLOAD\r\n") );
// pSrb->Status = STATUS_NOT_IMPLEMENTED;
// break;
case SRB_PAGING_OUT_DRIVER:
DebugPrint( (DebugLevelTrace, "DVDTS: SRB_PAGING_OUT_DRIVER\r\n") );
decDisableInt( pHwDevExt );
pSrb->Status = STATUS_SUCCESS;
break;
case SRB_GET_DATA_INTERSECTION:
DebugPrint( (DebugLevelTrace, "DVDTS: SRB_GET_DATA_INTERSECTION\r\n") );
HwProcessDataIntersection( pSrb );
break;
default:
if( pSrb->Command == 0x10D ) {
DebugPrint( (DebugLevelTrace, "DVDTS: ---------------------------------------------\r\n" ) );
DebugPrint( (DebugLevelTrace, "DVDTS: -------- UNKNOWN SRB COMMAND (0x10D) --------\r\n" ) );
DebugPrint( (DebugLevelTrace, "DVDTS: ---------------------------------------------\r\n" ) );
}
else {
DebugPrint( (DebugLevelTrace, "DVDTS: default %d(0x%x)\r\n", pSrb->Command, pSrb->Command ) );
TRAP;
}
pSrb->Status = STATUS_NOT_IMPLEMENTED;
}
StreamClassDeviceNotification( ReadyForNextDeviceRequest,
pSrb->HwDeviceExtension );
StreamClassDeviceNotification( DeviceRequestComplete,
pSrb->HwDeviceExtension,
pSrb );
}
/*
** AdapterStreamInfo()
*/
VOID AdapterStreamInfo( PHW_STREAM_REQUEST_BLOCK pSrb )
{
PHW_STREAM_INFORMATION pstrinfo =
&(pSrb->CommandData.StreamBuffer->StreamInfo );
// define the number of streams which this mini driver can support.
pSrb->CommandData.StreamBuffer->StreamHeader.NumberOfStreams = STREAMNUM;
pSrb->CommandData.StreamBuffer->StreamHeader.SizeOfHwStreamInformation =
sizeof(HW_STREAM_INFORMATION);
// store a pointer to the topology for the device
pSrb->CommandData.StreamBuffer->StreamHeader.Topology = (KSTOPOLOGY *)&Topology;
// pSrb->CommandData.StreamBuffer->StreamHeader.NumDevPropArrayEntries = 1;
// pSrb->CommandData.StreamBuffer->StreamHeader.DevicePropertiesArray = devicePropSet;
/* Video */
pstrinfo->NumberOfPossibleInstances = 1;
pstrinfo->DataFlow = KSPIN_DATAFLOW_IN;
pstrinfo->DataAccessible = TRUE;
pstrinfo->NumberOfFormatArrayEntries = 1;
pstrinfo->StreamFormatsArray = Mpeg2VidInfo; // see strmid.h
// pstrinfo->NumStreamPropArrayEntries = 2;
pstrinfo->NumStreamPropArrayEntries = 3;
pstrinfo->StreamPropertiesArray = mpegVidPropSet; // see strmid.h
pstrinfo++;
/* Audio */
pstrinfo->NumberOfPossibleInstances = 1;
pstrinfo->DataFlow = KSPIN_DATAFLOW_IN;
pstrinfo->DataAccessible = TRUE;
pstrinfo->NumberOfFormatArrayEntries = 2;
pstrinfo->StreamFormatsArray = AudioFormatBlocks;
// pstrinfo->NumStreamPropArrayEntries = 2;
pstrinfo->NumStreamPropArrayEntries = 3;
pstrinfo->StreamPropertiesArray = mpegAudioPropSet; // see strmid.h
pstrinfo->StreamEventsArray = ClockEventSet;
pstrinfo->NumStreamEventArrayEntries = SIZEOF_ARRAY(ClockEventSet);
pstrinfo++;
/* Sub-pic */
pstrinfo->NumberOfPossibleInstances = 1;
pstrinfo->DataFlow = KSPIN_DATAFLOW_IN;
pstrinfo->DataAccessible = TRUE;
pstrinfo->NumberOfFormatArrayEntries = 1;
pstrinfo->StreamFormatsArray = Mpeg2SubpicInfo;
// pstrinfo->NumStreamPropArrayEntries = 2;
pstrinfo->NumStreamPropArrayEntries = 3;
pstrinfo->StreamPropertiesArray = SPPropSet;
pstrinfo++;
/* V-port */
pstrinfo->NumberOfPossibleInstances = 1;
pstrinfo->DataFlow = KSPIN_DATAFLOW_OUT;
pstrinfo->DataAccessible = TRUE;
pstrinfo->NumberOfFormatArrayEntries = 1;
pstrinfo->StreamFormatsArray = VPEInfo;
pstrinfo->NumStreamPropArrayEntries = 1;
pstrinfo->StreamPropertiesArray = VideoPortPropSet;
pstrinfo->MediumsCount = 1;
pstrinfo->Mediums = &VPMedium;
pstrinfo->StreamEventsArray = VPEventSet;
pstrinfo->NumStreamEventArrayEntries = SIZEOF_ARRAY(VPEventSet);
pstrinfo++;
/* CC */
pstrinfo->NumberOfPossibleInstances = 1;
pstrinfo->DataFlow = KSPIN_DATAFLOW_OUT;
pstrinfo->DataAccessible = TRUE;
pstrinfo->NumberOfFormatArrayEntries = 1;
pstrinfo->StreamFormatsArray = CCInfo;
pstrinfo->NumStreamPropArrayEntries = 1;
pstrinfo->StreamPropertiesArray = CCPropSet;
pSrb->Status = STATUS_SUCCESS;
}
/*
** HwProcessDataIntersection()
*/
VOID HwProcessDataIntersection( PHW_STREAM_REQUEST_BLOCK pSrb )
{
NTSTATUS Status = STATUS_SUCCESS;
PSTREAM_DATA_INTERSECT_INFO IntersectInfo;
PKSDATARANGE DataRange;
PKSDATAFORMAT pFormat = NULL;
ULONG formatSize;
//
// We need to compare
// the data types passed in and error if the ranges don't overlap.
// we also need to return valid format blocks, not just the data range.
//
IntersectInfo = pSrb->CommandData.IntersectInfo;
DataRange = IntersectInfo->DataRange;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -