📄 vidstrm.cpp
字号:
*/
VOID CWDMVideoStream::VideoSetProperty(PHW_STREAM_REQUEST_BLOCK pSrb)
{
DBGERROR(("CWDMVideoStream::VideoSetProperty called"));
pSrb->Status = STATUS_NOT_IMPLEMENTED;
}
/*
** VideoGetProperty()
**
** Routine to process video property requests
**
** Arguments:
**
** pSrb - pointer to the stream request block for properties
**
** Returns:
**
** Side Effects: none
*/
VOID CWDMVideoStream::VideoGetProperty(PHW_STREAM_REQUEST_BLOCK pSrb)
{
PSTREAM_PROPERTY_DESCRIPTOR pSPD = pSrb->CommandData.PropertyInfo;
if (IsEqualGUID (KSPROPSETID_Connection, pSPD->Property->Set)) {
VideoStreamGetConnectionProperty (pSrb);
}
else {
pSrb->Status = STATUS_NOT_IMPLEMENTED;
}
}
/*
** VideoSetState()
**
** Sets the current state of the requested stream
**
** Arguments:
**
** pSrb - pointer to the stream request block for properties
**
** Returns:
**
** Side Effects: none
*/
VOID CWDMVideoStream::VideoSetState(PHW_STREAM_REQUEST_BLOCK pSrb, BOOL bVPConnected, BOOL bVPVBIConnected)
{
//
// For each stream, the following states are used:
//
// Stop: Absolute minimum resources are used. No outstanding IRPs.
// Pause: Getting ready to run. Allocate needed resources so that
// the eventual transition to Run is as fast as possible.
// SRBs will be queued at either the Stream class or in your
// driver.
// Run: Streaming.
//
// Moving to Stop or Run ALWAYS transitions through Pause, so that ONLY
// the following transitions are possible:
//
// Stop -> Pause
// Pause -> Run
// Run -> Pause
// Pause -> Stop
//
// Note that it is quite possible to transition repeatedly between states:
// Stop -> Pause -> Stop -> Pause -> Run -> Pause -> Run -> Pause -> Stop
//
DBGINFO(("CWDMVideoStream::VideoSetState for stream %d\n", pSrb->StreamObject->StreamNumber));
pSrb->Status = STATUS_SUCCESS;
switch (pSrb->CommandData.StreamState)
{
case KSSTATE_STOP:
DBGINFO((" state KSSTATE_STOP"));
// Reset the overridden flag so that the next time we go to the
// Run state, output will be enabled (unless the app overrides
// it again later). We should really do this after the graph
// has been stopped so that if a filter that has yet to be stopped
// cleans up by clearing the flag, it is not considered to be
// overriding it again. Since we are not called after the graph
// has been fully stopped, this is the best we can do.
//
// An alternative (and probably less confusing) approach is to
// leave the overridden flag set and force the app to control
// the output enabled feature if it changes it once.
//
// We have decided to follow the latter approach.
// m_pDevice->SetOutputEnabledOverridden(FALSE);
break;
case KSSTATE_ACQUIRE:
DBGINFO((" state KSSTATE_ACQUIRE"));
ASSERT(m_KSState == KSSTATE_STOP);
break;
case KSSTATE_PAUSE:
DBGINFO((" state KSSTATE_PAUSE"));
if (m_pVideoDecoder->PreEventOccurred() &&
(!m_pDevice->IsOutputEnabledOverridden() || m_pDevice->IsOutputEnabled()) &&
(m_KSState == KSSTATE_STOP || m_KSState == KSSTATE_ACQUIRE))
{
DBGERROR(("VidStrm Pause: Overridden = %d, OutputEnabled = %d",
m_pDevice->IsOutputEnabledOverridden(),
m_pDevice->IsOutputEnabled()
));
pSrb->Status = STATUS_UNSUCCESSFUL;
}
break;
case KSSTATE_RUN:
DBGINFO((" state KSSTATE_RUN"));
ASSERT(m_KSState == KSSTATE_ACQUIRE || m_KSState == KSSTATE_PAUSE);
if (m_pVideoDecoder->PreEventOccurred() &&
(!m_pDevice->IsOutputEnabledOverridden() || m_pDevice->IsOutputEnabled()))
{
DBGERROR(("VidStrm Run: Overridden = %d, OutputEnabled = %d",
m_pDevice->IsOutputEnabledOverridden(),
m_pDevice->IsOutputEnabled()
));
pSrb->Status = STATUS_UNSUCCESSFUL;
}
break;
}
if (pSrb->Status == STATUS_SUCCESS) {
m_KSState = pSrb->CommandData.StreamState;
DBGINFO((" entered\n"));
}
else
DBGINFO((" NOT entered ***\n"));
}
/*
** VideoGetState()
**
** Gets the current state of the requested stream
**
** Arguments:
**
** pSrb - pointer to the stream request block for properties
**
** Returns:
**
** Side Effects: none
*/
VOID CWDMVideoStream::VideoGetState(PHW_STREAM_REQUEST_BLOCK pSrb)
{
pSrb->CommandData.StreamState = m_KSState;
pSrb->ActualBytesTransferred = sizeof (KSSTATE);
// 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 (m_KSState == KSSTATE_PAUSE) {
pSrb->Status = STATUS_NO_DATA_DETECTED;
}
}
VOID CWDMVideoStream::VideoStreamGetConnectionProperty (PHW_STREAM_REQUEST_BLOCK pSrb)
{
PSTREAM_PROPERTY_DESCRIPTOR pSPD = pSrb->CommandData.PropertyInfo;
PKSALLOCATOR_FRAMING Framing = (PKSALLOCATOR_FRAMING) pSPD->PropertyInfo;
ASSERT(pSPD->Property->Id == KSPROPERTY_CONNECTION_ALLOCATORFRAMING);
if (pSPD->Property->Id == KSPROPERTY_CONNECTION_ALLOCATORFRAMING) {
RtlZeroMemory(Framing, sizeof(KSALLOCATOR_FRAMING));
Framing->RequirementsFlags =
KSALLOCATOR_REQUIREMENTF_PREFERENCES_ONLY |
KSALLOCATOR_REQUIREMENTF_INPLACE_MODIFIER |
KSALLOCATOR_REQUIREMENTF_SYSTEM_MEMORY;
Framing->PoolType = NonPagedPool;
Framing->Frames = 1;
Framing->FrameSize =
pSrb->StreamObject->StreamNumber == STREAM_AnalogVideoInput ?
sizeof(KS_TVTUNER_CHANGE_INFO) : 1;
Framing->FileAlignment = 0;//FILE_QUAD_ALIGNMENT;// PAGE_SIZE - 1;
pSrb->ActualBytesTransferred = sizeof(KSALLOCATOR_FRAMING);
}
else {
pSrb->Status = STATUS_NOT_IMPLEMENTED;
}
}
//==========================================================================;
// Clock Handling Routines
//==========================================================================;
/*
** VideoIndicateMasterClock ()
**
** If this stream is not being used as the master clock, this function
** is used to provide us with a handle to the clock to use.
**
** Arguments:
**
** pSrb - pointer to the stream request block for properties
**
** Returns:
**
** Side Effects: none
*/
VOID CWDMVideoStream::VideoIndicateMasterClock(PHW_STREAM_REQUEST_BLOCK pSrb)
{
m_hMasterClock = pSrb->CommandData.MasterClockHandle;
}
DWORD FAR PASCAL DirectDrawEventCallback(DWORD dwEvent, PVOID pContext, DWORD dwParam1, DWORD dwParam2)
{
CDecoderVideoPort* pCDecoderVideoPort = (CDecoderVideoPort*) pContext;
CWDMVideoPortStream* pCWDMVideoPortStream = (CWDMVideoPortStream*) pContext;
CWDMCaptureStream* pCWDMCaptureStream = (CWDMVideoCaptureStream*) pContext;
switch (dwEvent)
{
case DDNOTIFY_PRERESCHANGE:
pCWDMVideoPortStream->PreResChange();
break;
case DDNOTIFY_POSTRESCHANGE:
pCWDMVideoPortStream->PostResChange();
break;
case DDNOTIFY_PREDOSBOX:
pCWDMVideoPortStream->PreDosBox();
break;
case DDNOTIFY_POSTDOSBOX:
pCWDMVideoPortStream->PostDosBox();
break;
case DDNOTIFY_CLOSECAPTURE:
pCWDMCaptureStream->CloseCapture();
break;
case DDNOTIFY_CLOSEDIRECTDRAW:
pCDecoderVideoPort->CloseDirectDraw();
break;
case DDNOTIFY_CLOSEVIDEOPORT:
pCDecoderVideoPort->CloseVideoPort();
break;
default:
TRAP();
break;
}
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -