📄 capvideo.c
字号:
**
** TRUE if the format could be set, else FALSE
**
** Side Effects: none
*/
BOOL
STREAMAPI
VideoSetFormat(
IN PHW_STREAM_REQUEST_BLOCK pSrb
)
{
PSTREAMEX pStrmEx = (PSTREAMEX)pSrb->StreamObject->HwStreamExtension;
PHW_DEVICE_EXTENSION pHwDevExt = ((PHW_DEVICE_EXTENSION)pSrb->HwDeviceExtension);
int StreamNumber = pSrb->StreamObject->StreamNumber;
UINT nSize;
PKSDATAFORMAT pKSDataFormat = pSrb->CommandData.OpenFormat;
// -------------------------------------------------------------------
// Specifier FORMAT_VideoInfo for VIDEOINFOHEADER
// -------------------------------------------------------------------
if (IsEqualGUID (&pKSDataFormat->Specifier,
&KSDATAFORMAT_SPECIFIER_VIDEOINFO)) {
PKS_DATAFORMAT_VIDEOINFOHEADER pVideoInfoHeader =
(PKS_DATAFORMAT_VIDEOINFOHEADER) pSrb->CommandData.OpenFormat;
PKS_VIDEOINFOHEADER pVideoInfoHdrRequested =
&pVideoInfoHeader->VideoInfoHeader;
nSize = KS_SIZE_VIDEOHEADER (pVideoInfoHdrRequested);
DbgLogInfo(("TestCap: New Format\n"));
DbgLogInfo(("TestCap: pVideoInfoHdrRequested=%p\n", pVideoInfoHdrRequested));
DbgLogInfo(("TestCap: KS_VIDEOINFOHEADER size=%d\n", nSize));
DbgLogInfo(("TestCap: Width=%d Height=%d BitCount=%d\n",
pVideoInfoHdrRequested->bmiHeader.biWidth,
pVideoInfoHdrRequested->bmiHeader.biHeight,
pVideoInfoHdrRequested->bmiHeader.biBitCount));
DbgLogInfo(("TestCap: biSizeImage=%d\n",
pVideoInfoHdrRequested->bmiHeader.biSizeImage));
//
// If a previous format was in use, release the memory
//
if (pStrmEx->pVideoInfoHeader) {
ExFreePool(pStrmEx->pVideoInfoHeader);
pStrmEx->pVideoInfoHeader = NULL;
}
// Since the VIDEOINFOHEADER is of potentially variable size
// allocate memory for it
pStrmEx->pVideoInfoHeader = ExAllocatePool(NonPagedPool, nSize);
if (pStrmEx->pVideoInfoHeader == NULL) {
DbgLogError(("TestCap: ExAllocatePool failed\n"));
pSrb->Status = STATUS_INSUFFICIENT_RESOURCES;
return FALSE;
}
// Copy the VIDEOINFOHEADER requested to our storage
RtlCopyMemory(
pStrmEx->pVideoInfoHeader,
pVideoInfoHdrRequested,
nSize);
// A renderer may be switching formats, and in this case, the AvgTimePerFrame
// will be zero. Don't overwrite a previously set framerate.
if (pStrmEx->pVideoInfoHeader->AvgTimePerFrame) {
pStrmEx->AvgTimePerFrame = pStrmEx->pVideoInfoHeader->AvgTimePerFrame;
}
}
// -------------------------------------------------------------------
// Specifier FORMAT_AnalogVideo for KS_ANALOGVIDEOINFO
// -------------------------------------------------------------------
else if (IsEqualGUID (&pKSDataFormat->Specifier,
&KSDATAFORMAT_SPECIFIER_ANALOGVIDEO)) {
//
// AnalogVideo DataRange == DataFormat!
//
//
// For now, don't even cache this
//
PKS_DATARANGE_ANALOGVIDEO pDataFormatAnalogVideo =
(PKS_DATARANGE_ANALOGVIDEO) pSrb->CommandData.OpenFormat;
}
// -------------------------------------------------------------------
// Specifier FORMAT_VBI for KS_VIDEO_VBI
// -------------------------------------------------------------------
else if (IsEqualGUID (&pKSDataFormat->Specifier,
&KSDATAFORMAT_SPECIFIER_VBI))
{
// On a VBI stream, we save a pointer to StreamFormatVBI, which
// has the timing info we want to get at later.
pStrmEx->pVBIStreamFormat = &StreamFormatVBI;
}
// -------------------------------------------------------------------
// Type FORMAT_NABTS for NABTS pin
// -------------------------------------------------------------------
else if (IsEqualGUID (&pKSDataFormat->SubFormat,
&KSDATAFORMAT_SUBTYPE_NABTS))
{
// On a VBI stream, we save a pointer to StreamFormatVBI, which
// has the timing info we want to get at later. (Even though
// this is really a StreamFormatNABTS pin)
pStrmEx->pVBIStreamFormat = &StreamFormatVBI;
}
// -------------------------------------------------------------------
// for CC pin
// -------------------------------------------------------------------
else if (IsEqualGUID (&pKSDataFormat->SubFormat,
&KSDATAFORMAT_SUBTYPE_CC))
{
// On a VBI stream, we save a pointer to StreamFormatVBI, which
// has the timing info we want to get at later. (Even though
// this is really a StreamFormatCC pin)
pStrmEx->pVBIStreamFormat = &StreamFormatVBI;
}
else {
// Unknown format
pSrb->Status = STATUS_INVALID_PARAMETER;
return FALSE;
}
return TRUE;
}
/*
** VideoReceiveDataPacket()
**
** Receives Video data packet commands on the output streams
**
** Arguments:
**
** pSrb - Stream request block for the Video stream
**
** Returns: nothing
**
** Side Effects: none
*/
VOID
STREAMAPI
VideoReceiveDataPacket(
IN PHW_STREAM_REQUEST_BLOCK pSrb
)
{
PHW_DEVICE_EXTENSION pHwDevExt = ((PHW_DEVICE_EXTENSION)pSrb->HwDeviceExtension);
PSTREAMEX pStrmEx = (PSTREAMEX)pSrb->StreamObject->HwStreamExtension;
int StreamNumber = pSrb->StreamObject->StreamNumber;
//
// make sure we have a device extension and are at passive level
//
DEBUG_ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL);
DEBUG_ASSERT(pHwDevExt!=NULL);
DbgLogTrace(("TestCap: Receiving Stream Data SRB %p, %x\n", pSrb, pSrb->Command));
//
// Default to success
//
pSrb->Status = STATUS_SUCCESS;
//
// determine the type of packet.
//
switch (pSrb->Command){
case SRB_READ_DATA:
// Rule:
// Only accept read requests when in either the Pause or Run
// States. If Stopped, immediately return the SRB.
if (pStrmEx->KSState == KSSTATE_STOP) {
CompleteStreamSRB (pSrb);
break;
}
//
// Put this read request on the pending queue
//
VideoQueueAddSRB (pSrb);
// Since another thread COULD HAVE MODIFIED THE STREAM STATE
// in the midst of adding it to the queue, check the stream
// state again, and cancel the SRB if necessary. Note that
// this race condition was NOT handled in the original DDK
// release of testcap!
if (pStrmEx->KSState == KSSTATE_STOP) {
VideoQueueCancelOneSRB (
pStrmEx,
pSrb);
}
break;
default:
//
// invalid / unsupported command. Fail it as such
//
TRAP;
pSrb->Status = STATUS_NOT_IMPLEMENTED;
CompleteStreamSRB (pSrb);
} // switch (pSrb->Command)
}
/*
** VideoReceiveCtrlPacket()
**
** Receives packet commands that control the Video output streams
**
** Arguments:
**
** pSrb - The stream request block for the Video stream
**
** Returns: nothing
**
** Side Effects: none
*/
VOID
STREAMAPI
VideoReceiveCtrlPacket(
IN PHW_STREAM_REQUEST_BLOCK pSrb
)
{
PHW_DEVICE_EXTENSION pHwDevExt = ((PHW_DEVICE_EXTENSION)pSrb->HwDeviceExtension);
PSTREAMEX pStrmEx = (PSTREAMEX)pSrb->StreamObject->HwStreamExtension;
int StreamNumber = pStrmEx->pStreamObject->StreamNumber;
BOOL Busy;
//
// make sure we have a device extension and are at passive level
//
DEBUG_ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL);
DEBUG_ASSERT(pHwDevExt!=NULL);
DbgLogTrace(("TestCap: Receiving Stream Control SRB %p, %x\n", pSrb, pSrb->Command));
//
// If we're already processing an SRB, add it to the queue
//
Busy = AddToListIfBusy (
pSrb,
&pHwDevExt->AdapterSpinLock,
&pHwDevExt->ProcessingControlSRB [StreamNumber],
&pHwDevExt->StreamControlSRBList[StreamNumber]);
if (Busy) {
return;
}
while (TRUE) {
//
// Default to success
//
pSrb->Status = STATUS_SUCCESS;
//
// determine the type of packet.
//
switch (pSrb->Command)
{
case SRB_PROPOSE_DATA_FORMAT:
DbgLogInfo(("TestCap: Receiving SRB_PROPOSE_DATA_FORMAT SRB %p, StreamNumber= %d\n", pSrb, StreamNumber));
if (!(AdapterVerifyFormat (
pSrb->CommandData.OpenFormat,
pSrb->StreamObject->StreamNumber))) {
pSrb->Status = STATUS_NO_MATCH;
DbgLogInfo(("TestCap: SRB_PROPOSE_DATA_FORMAT FAILED\n"));
}
// KS support for dynamic format changes is BROKEN right now,
// so we prevent these from happening by saying they ALL fail.
// If this is ever fixed, the next line must be removed.
pSrb->Status = STATUS_NO_MATCH; // prevent dynamic format changes
break;
case SRB_SET_DATA_FORMAT:
DbgLogInfo(("TestCap: SRB_SET_DATA_FORMAT\n"));
if (!(AdapterVerifyFormat (
pSrb->CommandData.OpenFormat,
pSrb->StreamObject->StreamNumber))) {
pSrb->Status = STATUS_NO_MATCH;
DbgLogInfo(("TestCap: SRB_SET_DATA_FORMAT FAILED\n"));
} else {
VideoSetFormat (pSrb);
DbgLogInfo(("TestCap: SRB_SET_DATA_FORMAT SUCCEEDED\n"));
}
break;
case SRB_GET_DATA_FORMAT:
DbgLogInfo(("TestCap: SRB_GET_DATA_FORMAT\n"));
pSrb->Status = STATUS_NOT_IMPLEMENTED;
break;
case SRB_SET_STREAM_STATE:
VideoSetState(pSrb);
break;
case SRB_GET_STREAM_STATE:
VideoGetState(pSrb);
break;
case SRB_GET_STREAM_PROPERTY:
VideoGetProperty(pSrb);
break;
case SRB_SET_STREAM_PROPERTY:
VideoSetProperty(pSrb);
break;
case SRB_INDICATE_MASTER_CLOCK:
//
// Assigns a clock to a stream
//
VideoIndicateMasterClock (pSrb);
break;
default:
//
// invalid / unsupported command. Fail it as such
//
TRAP;
pSrb->Status = STATUS_NOT_IMPLEMENTED;
}
CompleteStreamSRB (pSrb);
//
// See if there's anything else on the queue
//
Busy = RemoveFromListIfAvailable (
&pSrb,
&pHwDevExt->AdapterSpinLock,
&pHwDevExt->ProcessingControlSRB [StreamNumber],
&pHwDevExt->StreamControlSRBList[StreamNumber]);
if (!Busy) {
break;
}
}
}
/*
** AnalogVideoReceiveDataPacket()
**
** Receives AnalogVideo data packet commands on the input stream
**
** Arguments:
**
** pSrb - Stream request block for the Analog Video stream.
** This stream receives tuner control packets.
**
** Returns: nothing
**
** Side Effects: none
*/
VOID
STREAMAPI
AnalogVideoReceiveDataPacket(
IN PHW_STREAM_REQUEST_BLOCK pSrb
)
{
PHW_DEVICE_EXTENSION pHwDevExt = ((PHW_DEVICE_EXTENSION)pSrb->HwDeviceExtension);
PSTREAMEX pStrmEx = (PSTREAMEX)pSrb->StreamObject->HwStreamExtension;
PKSSTREAM_HEADER pDataPacket = pSrb->CommandData.DataBufferArray;
//
// make sure we have a device extension and are at passive level
//
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -