📄 wdmvdec.cpp
字号:
//==========================================================================;
//
// WDM Video Decoder common SRB dispatcher
//
// $Date: 02 Oct 1998 23:00:24 $
// $Revision: 1.2 $
// $Author: KLEBANOV $
//
// $Copyright: (c) 1997 - 1998 ATI Technologies Inc. All Rights Reserved. $
//
//==========================================================================;
extern "C"
{
#include "strmini.h"
#include "ksmedia.h"
}
#include "wdmvdec.h"
#include "wdmdrv.h"
#include "capdebug.h"
#include "VidStrm.h"
#include "DecProp.h"
#include "StrmInfo.h"
#include "Mediums.h"
#include "mytypes.h"
extern NTSTATUS STREAMAPI DeviceEventProc( PHW_EVENT_DESCRIPTOR pEventDescriptor);
CWDMVideoDecoder::CWDMVideoDecoder(PPORT_CONFIGURATION_INFORMATION pConfigInfo,
CVideoDecoderDevice* pDevice)
: m_pDeviceObject(pConfigInfo->RealPhysicalDeviceObject),
m_CDecoderVPort(pConfigInfo->RealPhysicalDeviceObject),
m_pDevice(pDevice),
m_TVTunerChangedSrb( NULL)
{
DBGTRACE(("CWDMVideoDecoder:CWDMVideoDecoder() enter\n"));
DBGINFO(("Physical Device Object = %lx\n", m_pDeviceObject));
pConfigInfo->StreamDescriptorSize = sizeof (HW_STREAM_HEADER) +
NumStreams * sizeof (HW_STREAM_INFORMATION);
InitializeListHead(&m_srbQueue);
KeInitializeSpinLock(&m_spinLock);
m_bSrbInProcess = FALSE;
if (pDevice)
{
pDevice->SetVideoDecoder(this);
}
}
CWDMVideoDecoder::~CWDMVideoDecoder()
{
DBGTRACE(("CWDMVideoDecoder:~CWDMVideoDecoder()\n"));
}
void CWDMVideoDecoder::ReceivePacket(PHW_STREAM_REQUEST_BLOCK pSrb)
{
KIRQL Irql;
PSRB_DATA_EXTENSION pSrbExt;
KeAcquireSpinLock(&m_spinLock, &Irql);
if (m_bSrbInProcess)
{
pSrbExt = (PSRB_DATA_EXTENSION)pSrb->SRBExtension;
pSrbExt->pSrb = pSrb;
InsertTailList(&m_srbQueue, &pSrbExt->srbListEntry);
KeReleaseSpinLock(&m_spinLock, Irql);
return;
}
m_bSrbInProcess = TRUE;
KeReleaseSpinLock(&m_spinLock, Irql);
for (;;) {
// Assume success. Might be changed below
pSrb->Status = STATUS_SUCCESS;
BOOL notify = TRUE;
// determine the type of packet.
switch(pSrb->Command)
{
case SRB_INITIALIZATION_COMPLETE:
DBGTRACE(("SRB_INITIALIZATION_COMPLETE; SRB=%x\n", pSrb));
// Stream class has finished initialization.
// Now create DShow Medium interface BLOBs.
// This needs to be done at low priority since it uses the registry
//
// Do we need to worry about synchronization here?
SrbInitializationComplete(pSrb);
break;
case SRB_UNINITIALIZE_DEVICE:
DBGTRACE(("SRB_UNINITIALIZE_DEVICE; SRB=%x\n", pSrb));
// close the device.
break;
case SRB_PAGING_OUT_DRIVER:
DBGTRACE(("SRB_PAGING_OUT_DRIVER; SRB=%x\n", pSrb));
//
// The driver is being paged out
// Disable Interrupts if you have them!
//
break;
case SRB_CHANGE_POWER_STATE:
DBGTRACE(("SRB_CHANGE_POWER_STATE. SRB=%x. State=%d\n",
pSrb, pSrb->CommandData.DeviceState));
SrbChangePowerState(pSrb);
break;
case SRB_OPEN_STREAM:
DBGTRACE(("SRB_OPEN_STREAM; SRB=%x\n", pSrb));
SrbOpenStream(pSrb);
break;
case SRB_CLOSE_STREAM:
DBGTRACE(("SRB_CLOSE_STREAM; SRB=%x\n", pSrb));
if (!IsListEmpty(&m_srbQueue)) // is this necessary ???
{
TRAP();
}
SrbCloseStream(pSrb);
break;
case SRB_GET_DATA_INTERSECTION:
DBGTRACE(("SRB_GET_DATA_INTERSECTION; SRB=%x\n", pSrb));
SrbGetDataIntersection(pSrb);
break;
case SRB_GET_STREAM_INFO:
SrbGetStreamInfo(pSrb);
break;
case SRB_GET_DEVICE_PROPERTY:
SrbGetProperty(pSrb);
break;
case SRB_SET_DEVICE_PROPERTY:
SrbSetProperty(pSrb);
break;
case SRB_WRITE_DATA:
DBGTRACE(("SRB_WRITE_DATA; SRB=%x\n", pSrb));
SetTunerInfo(pSrb);
StreamClassStreamNotification(StreamRequestComplete, pSrb->StreamObject, pSrb);
notify = FALSE;
break;
case SRB_UNKNOWN_DEVICE_COMMAND:
// not sure why this gets called every time.
DBGTRACE(("SRB_UNKNOWN_DEVICE_COMMAND; SRB=%x\n", pSrb));
// TRAP()();
pSrb->Status = STATUS_NOT_IMPLEMENTED;
break;
case SRB_OPEN_DEVICE_INSTANCE:
case SRB_CLOSE_DEVICE_INSTANCE:
default:
TRAP();
// this is a request that we do not understand. Indicate invalid command and complete the request
pSrb->Status = STATUS_NOT_IMPLEMENTED;
}
if (notify)
StreamClassDeviceNotification(DeviceRequestComplete, pSrb->HwDeviceExtension, pSrb);
KeAcquireSpinLock(&m_spinLock, &Irql);
if (IsListEmpty(&m_srbQueue))
{
m_bSrbInProcess = FALSE;
KeReleaseSpinLock(&m_spinLock, Irql);
return;
}
else
{
pSrbExt = (PSRB_DATA_EXTENSION)RemoveHeadList(&m_srbQueue);
KeReleaseSpinLock(&m_spinLock, Irql);
pSrb = pSrbExt->pSrb;
}
}
}
void CWDMVideoDecoder::CancelPacket( PHW_STREAM_REQUEST_BLOCK pSrbToCancel)
{
CWDMVideoStream* pVideoStream = ( CWDMVideoStream*)pSrbToCancel->StreamObject->HwStreamExtension;
DBGINFO(( "Bt829: AdapterCancelPacket, Starting attempting to cancel Srb 0x%x\n",
pSrbToCancel));
if( pVideoStream == NULL)
{
//
// Device command IRPs are not queued, so nothing to do
//
DBGINFO(( "Bt829: AdapterCancelPacketStart, no pVideoStream Srb 0x%x\n",
pSrbToCancel));
return;
}
pVideoStream->CancelPacket( pSrbToCancel);
DBGINFO(( "Bt829: AdapterCancelPacket, Exiting\n"));
}
void CWDMVideoDecoder::TimeoutPacket(PHW_STREAM_REQUEST_BLOCK pSrb)
{
CWDMVideoStream * pVideoStream = (CWDMVideoStream *)pSrb->StreamObject->HwStreamExtension;
DBGTRACE(("Timeout. SRB %8x. \n", pSrb));
pVideoStream->TimeoutPacket(pSrb);
DBGTRACE(("TimeoutPacket: SRB %8x. Resetting.\n", pSrb));
pSrb->TimeoutCounter = pSrb->TimeoutOriginal;
}
BOOL CWDMVideoDecoder::SrbInitializationComplete(PHW_STREAM_REQUEST_BLOCK pSrb)
{
NTSTATUS Status;
ULONG *tmp = (ULONG *) &CrossbarPinDirection[0];
// Create the Registry blobs that DShow uses to create
// graphs via Mediums
Status = StreamClassRegisterFilterWithNoKSPins (
m_pDeviceObject, // IN PDEVICE_OBJECT DeviceObject,
&KSCATEGORY_CROSSBAR, // IN GUID * InterfaceClassGUID,
CrossbarPins(), // IN ULONG PinCount,
(int *) CrossbarPinDirection, // IN ULONG * Flags,
(KSPIN_MEDIUM *) CrossbarMediums, // IN KSPIN_MEDIUM * MediumList,
NULL // IN GUID * CategoryList
);
// Register the Capture filter
// Note: This should be done automatically be MSKsSrv.sys,
// when that component comes on line (if ever) ...
Status = StreamClassRegisterFilterWithNoKSPins (
m_pDeviceObject, // IN PDEVICE_OBJECT DeviceObject,
&KSCATEGORY_CAPTURE, // IN GUID * InterfaceClassGUID,
CapturePins(), // IN ULONG PinCount,
(int *) CapturePinDirection, // IN ULONG * Flags,
(KSPIN_MEDIUM *) CaptureMediums, // IN KSPIN_MEDIUM * MediumList,
NULL // IN GUID * CategoryList
);
pSrb->Status = STATUS_SUCCESS;
return(TRUE);
}
BOOL CWDMVideoDecoder::SrbOpenStream(PHW_STREAM_REQUEST_BLOCK pSrb)
{
DBGTRACE(("CWDMVideoDecoder:SrbOpenStream()\n"));
PHW_STREAM_OBJECT pStreamObject = pSrb->StreamObject;
void * pStrmEx = pStreamObject->HwStreamExtension;
int StreamNumber = pStreamObject->StreamNumber;
PKSDATAFORMAT pKSDataFormat = pSrb->CommandData.OpenFormat;
CWDMVideoStream * pVideoStream;
CWDMVideoPortStream * pVPVBIStream;
UINT nErrorCode;
RtlZeroMemory(pStrmEx, streamDataExtensionSize);
DBGINFO(("SRBOPENSTREAM ------- StreamNumber=%d\n", StreamNumber));
//
// check that the stream index requested isn't too high
// or that the maximum number of instances hasn't been exceeded
//
if (StreamNumber >= (int)NumStreams || StreamNumber < 0) {
pSrb->Status = STATUS_INVALID_PARAMETER;
goto Exit;
}
//
// Check the validity of the format being requested
//
if (!AdapterVerifyFormat (pKSDataFormat, StreamNumber)) {
pSrb->Status = STATUS_INVALID_PARAMETER;
goto Exit;
}
//
// Set up pointers to the handlers for the stream data and control handlers
//
pStreamObject->ReceiveDataPacket = VideoReceiveDataPacket;
pStreamObject->ReceiveControlPacket = VideoReceiveCtrlPacket;
//
// Indicate the clock support available on this stream
//
pStreamObject->HwClockObject.HwClockFunction = NULL;
pStreamObject->HwClockObject.ClockSupportFlags = 0;
//
// The DMA flag must be set when the device will be performing DMA directly
// to the data buffer addresses passed in to the ReceiceDataPacket routines.
//
pStreamObject->Dma = Streams[StreamNumber].hwStreamObjectInfo.Dma;
//
// The PIO flag must be set when the mini driver will be accessing the data
// buffers passed in using logical addressing
//
pStreamObject->Pio = Streams[StreamNumber].hwStreamObjectInfo.Pio;
//
// How many extra bytes will be passed up from the driver for each frame?
//
pStreamObject->StreamHeaderMediaSpecific =
Streams[StreamNumber].hwStreamObjectInfo.StreamHeaderMediaSpecific;
pStreamObject->StreamHeaderWorkspace =
Streams[StreamNumber].hwStreamObjectInfo.StreamHeaderWorkspace;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -