📄 hwsim.cpp
字号:
/**************************************************************************
AVStream Simulated Hardware Sample
Copyright (c) 2001, Microsoft Corporation.
File:
hwsim.cpp
Abstract:
This file contains the hardware simulation. It fakes "DMA" transfers,
scatter gather mapping handling, ISR's, etc... The ISR routine in
here will be called when an ISR would be generated by the fake hardware
and it will directly call into the device level ISR for more accurate
simulation.
History:
created 3/9/2001
**************************************************************************/
#include "BDACap.h"
/**************************************************************************
PAGEABLE CODE
**************************************************************************/
#ifdef ALLOC_PRAGMA
#pragma code_seg("PAGE")
#endif // ALLOC_PRAGMA
CHardwareSimulation::
CHardwareSimulation (
IN IHardwareSink *HardwareSink
) :
m_HardwareSink (HardwareSink),
m_ScatterGatherMappingsMax (SCATTER_GATHER_MAPPINGS_MAX)
/*++
Routine Description:
Construct a hardware simulation
Arguments:
HardwareSink -
The hardware sink interface. This is used to trigger
fake interrupt service routines from.
Return Value:
Success / Failure
--*/
{
PAGED_CODE();
//
// Initialize the DPC's, timer's, and locks necessary to simulate
// this capture hardware.
//
KeInitializeDpc (
&m_IsrFakeDpc,
reinterpret_cast <PKDEFERRED_ROUTINE>
(CHardwareSimulation::SimulatedInterrupt),
this
);
KeInitializeEvent (
&m_HardwareEvent,
SynchronizationEvent,
FALSE
);
KeInitializeTimer (&m_IsrTimer);
KeInitializeSpinLock (&m_ListLock);
}
/*************************************************/
NTSTATUS
CHardwareSimulation::
Start (
IN CTsSynthesizer *TsSynth,
IN LONGLONG TimePerFrame,
IN ULONG PacketSize,
IN ULONG PacketsPerSample
)
/*++
Routine Description:
Start the hardware simulation. This will kick the interrupts on,
begin issuing DPC's, filling in capture information, etc...
We keep track of starvation starting at this point.
Arguments:
TsSynth -
The transport stream synthesizer to use to generate TS packets
on the capture buffer.
TimePerFrame -
The time per frame... we issue interrupts this often.
PacketSize -
The size of a single transport stream packet.
PacketsPerSample -
The number of packets in a single capture sample
Return Value:
Success / Failure (typical failure will be out of memory on the
scratch buffer, etc...)
--*/
{
PAGED_CODE();
NTSTATUS Status = STATUS_SUCCESS;
m_TsSynth = TsSynth;
m_TimePerFrame = TimePerFrame;
m_SampleSize = PacketSize * PacketsPerSample;
m_PacketSize = PacketSize;
m_PacketsPerSample = PacketsPerSample;
InitializeListHead (&m_ScatterGatherMappings);
m_NumMappingsCompleted = 0;
m_ScatterGatherMappingsQueued = 0;
m_NumFramesSkipped = 0;
m_InterruptTime = 0;
KeQuerySystemTime (&m_StartTime);
//
// Allocate a scratch buffer for the synthesizer.
//
m_SynthesisBuffer = reinterpret_cast <PUCHAR> (
ExAllocatePool (
NonPagedPool,
m_SampleSize
)
);
if (!m_SynthesisBuffer) {
Status = STATUS_INSUFFICIENT_RESOURCES;
}
//
// If everything is ok, start issuing interrupts.
//
if (NT_SUCCESS (Status)) {
//
// Initialize the entry lookaside.
//
ExInitializeNPagedLookasideList (
&m_ScatterGatherLookaside,
NULL,
NULL,
0,
sizeof (SCATTER_GATHER_ENTRY),
'nEGS',
0
);
//
// Set up the synthesizer with the width, height, and scratch buffer.
//
m_TsSynth -> SetSampleSize (m_PacketSize, m_PacketsPerSample);
m_TsSynth -> SetBuffer (m_SynthesisBuffer);
LARGE_INTEGER NextTime;
NextTime.QuadPart = m_StartTime.QuadPart + m_TimePerFrame;
m_HardwareState = HardwareRunning;
KeSetTimer (&m_IsrTimer, NextTime, &m_IsrFakeDpc);
}
return Status;
}
/*************************************************/
NTSTATUS
CHardwareSimulation::
Pause (
BOOLEAN Pausing
)
/*++
Routine Description:
Pause the hardware simulation... When the hardware simulation is told
to pause, it stops issuing interrupts, etc... but it does not reset
the counters
Arguments:
Pausing -
Indicates whether the hardware is pausing or not.
TRUE -
Pause the hardware
FALSE -
Unpause the hardware from a previous pause
Return Value:
Success / Failure
--*/
{
PAGED_CODE();
if (Pausing && m_HardwareState == HardwareRunning) {
//
// If we were running, stop completing mappings, etc...
//
m_StopHardware = TRUE;
KeWaitForSingleObject (
&m_HardwareEvent,
Suspended,
KernelMode,
FALSE,
NULL
);
ASSERT (m_StopHardware == FALSE);
m_HardwareState = HardwarePaused;
} else if (!Pausing && m_HardwareState == HardwarePaused) {
//
// For unpausing the hardware, we need to compute the relative time
// and restart interrupts.
//
LARGE_INTEGER UnpauseTime;
KeQuerySystemTime (&UnpauseTime);
m_InterruptTime = (ULONG) (
(UnpauseTime.QuadPart - m_StartTime.QuadPart) /
m_TimePerFrame
);
UnpauseTime.QuadPart = m_StartTime.QuadPart +
(m_InterruptTime + 1) * m_TimePerFrame;
m_HardwareState = HardwareRunning;
KeSetTimer (&m_IsrTimer, UnpauseTime, &m_IsrFakeDpc);
}
return STATUS_SUCCESS;
}
/*************************************************/
NTSTATUS
CHardwareSimulation::
Stop (
)
/*++
Routine Description:
Stop the hardware simulation.... Wait until the hardware simulation
has successfully stopped and then return.
Arguments:
None
Return Value:
Success / Failure
--*/
{
PAGED_CODE();
//
// If the hardware is told to stop while it's running, we need to
// halt the interrupts first. If we're already paused, this has
// already been done.
//
if (m_HardwareState == HardwareRunning) {
m_StopHardware = TRUE;
KeWaitForSingleObject (
&m_HardwareEvent,
Suspended,
KernelMode,
FALSE,
NULL
);
ASSERT (m_StopHardware == FALSE);
}
m_HardwareState = HardwareStopped;
//
// The image synthesizer may still be around. Just for safety's
// sake, NULL out the image synthesis buffer and toast it.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -