Exemplo n.º 1
0
VOID
STREAMAPI
AdapterStreamInfo (
    PHW_STREAM_REQUEST_BLOCK pSrb
    )
{
    int j;

    PHW_DEVICE_EXTENSION pHwDevExt =
        ((PHW_DEVICE_EXTENSION)pSrb->HwDeviceExtension);

    //
    // pick up the pointer to header which preceeds the stream info structs
    //

    PHW_STREAM_HEADER pstrhdr =
            (PHW_STREAM_HEADER)&(pSrb->CommandData.StreamBuffer->StreamHeader);

     //
     // pick up the pointer to the array of stream information data structures
     //

     PHW_STREAM_INFORMATION pstrinfo =
            (PHW_STREAM_INFORMATION)&(pSrb->CommandData.StreamBuffer->StreamInfo);

	DbgLogInfo(("TestCap: Enter AdapterStreamInfo\n"));	 


    //
    // verify that the buffer is large enough to hold our return data
    //

    DEBUG_ASSERT (pSrb->NumberOfBytesToTransfer >=
            sizeof (HW_STREAM_HEADER) +
            sizeof (HW_STREAM_INFORMATION) * DRIVER_STREAM_COUNT);

     //
     // Set the header
     //

     StreamHeader.NumDevPropArrayEntries = NUMBER_OF_ADAPTER_PROPERTY_SETS;
     StreamHeader.DevicePropertiesArray = (PKSPROPERTY_SET) AdapterPropertyTable;
     *pstrhdr = StreamHeader;

     //
     // stuff the contents of each HW_STREAM_INFORMATION struct
     //

     for (j = 0; j < DRIVER_STREAM_COUNT; j++) {
        *pstrinfo++ = Streams[j].hwStreamInfo;
     }

	DbgLogInfo(("TestCap: Leave AdapterStreamInfo\n"));	 	 

}
Exemplo n.º 2
0
VOID
STREAMAPI
AdapterCancelPacket(
    PHW_STREAM_REQUEST_BLOCK pSrb
    )
{
    PHW_DEVICE_EXTENSION        pHwDevExt = (PHW_DEVICE_EXTENSION)pSrb->HwDeviceExtension;
    PSTREAMEX                   pStrmEx;
    int                         StreamNumber;
    BOOL                        Found = FALSE;

    //
    // Run through all the streams the driver has available
    //

    for (StreamNumber = 0; !Found && (StreamNumber < DRIVER_STREAM_COUNT); StreamNumber++) {

        //
        // Check to see if the stream is in use
        //

        if (pStrmEx = (PSTREAMEX) pHwDevExt->pStrmEx[StreamNumber]) {

            Found = VideoQueueCancelOneSRB (
                pStrmEx,
                pSrb
                );

        } // if the stream is open
    } // for all streams

    DbgLogInfo(("TestCap: Cancelling SRB %8x Succeeded=%d\n", pSrb, Found));
}
Exemplo n.º 3
0
VOID
STREAMAPI 
AdapterGetProperty(
    PHW_STREAM_REQUEST_BLOCK pSrb
    )

{
    PSTREAM_PROPERTY_DESCRIPTOR pSPD = pSrb->CommandData.PropertyInfo;

	DbgLogInfo(("TestCap: Enter AdapterGetProperty\n"));	 

    if (IsEqualGUID(&PROPSETID_VIDCAP_VIDEOPROCAMP, &pSPD->Property->Set)) {
        AdapterGetVideoProcAmpProperty (pSrb);
    }
    else if (IsEqualGUID(&PROPSETID_VIDCAP_CAMERACONTROL, &pSPD->Property->Set)) {
        AdapterGetCameraControlProperty (pSrb);
    }
    else if (IsEqualGUID(&PROPSETID_VIDCAP_VIDEOCONTROL, &pSPD->Property->Set)) {
        AdapterGetVideoControlProperty (pSrb);
    }
    else if (IsEqualGUID (&PROPSETID_VIDCAP_VIDEOCOMPRESSION, &pSPD->Property->Set)) {
        AdapterGetVideoCompressionProperty (pSrb);
    }
    else {
        //
        // We should never get here
        //

        TRAP;
        pSrb->Status = STATUS_NOT_IMPLEMENTED;
    }
}
Exemplo n.º 4
0
ULONG
DriverEntry (
    IN PDRIVER_OBJECT DriverObject,
    IN PUNICODE_STRING RegistryPath
    )
{

    HW_INITIALIZATION_DATA      HwInitData;
    ULONG                       ReturnValue;

    DbgLogInfo(("TestCap: DriverEntry\n"));

    RtlZeroMemory(&HwInitData, sizeof(HwInitData));

    HwInitData.HwInitializationDataSize = sizeof(HwInitData);

    //
    // Set the Adapter entry points for the driver
    //

    HwInitData.HwInterrupt              = NULL; // HwInterrupt;

    HwInitData.HwReceivePacket          = AdapterReceivePacket;
    HwInitData.HwCancelPacket           = AdapterCancelPacket;
    HwInitData.HwRequestTimeoutHandler  = AdapterTimeoutPacket;

    HwInitData.DeviceExtensionSize      = sizeof(HW_DEVICE_EXTENSION);
    HwInitData.PerRequestExtensionSize  = sizeof(SRB_EXTENSION);
    HwInitData.FilterInstanceExtensionSize = 0;
    HwInitData.PerStreamExtensionSize   = sizeof(STREAMEX);
    HwInitData.BusMasterDMA             = FALSE;
    HwInitData.Dma24BitAddresses        = FALSE;
    HwInitData.BufferAlignment          = 3;
    HwInitData.DmaBufferSize            = 0;

    // Don't rely on the stream class using raised IRQL to synchronize
    // execution.  This single paramter most affects the overall structure
    // of the driver.

    HwInitData.TurnOffSynchronization   = TRUE;

    ReturnValue = StreamClassRegisterAdapter(DriverObject, RegistryPath, &HwInitData);

    DbgLogInfo(("Testcap: StreamClassRegisterAdapter = %x\n", ReturnValue));

    return ReturnValue;
}
Exemplo n.º 5
0
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
    //

    DEBUG_ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL);
    DEBUG_ASSERT(pHwDevExt!=NULL);

    DbgLogInfo(("TestCap: Receiving Tuner packet    SRB %p, %x\n", pSrb, pSrb->Command));

    //
    // Default to success
    //

    pSrb->Status = STATUS_SUCCESS;

    //
    // determine the type of packet.
    //

    switch (pSrb->Command){

    case SRB_WRITE_DATA:

        CompleteStreamSRB (pSrb);

        break;

    default:

        //
        // invalid / unsupported command. Fail it as such
        //

        TRAP;

        pSrb->Status = STATUS_NOT_IMPLEMENTED;

        CompleteStreamSRB (pSrb);

    }  // switch (pSrb->Command)
}
Exemplo n.º 6
0
void DbgLogMediaTypeInfo(DWORD type, DWORD level, const CMediaType* pmt)
{
	DbgLogInfo(type, level,
		TEXT(" MediaType Info : %s %s %s %s SampleSize=%ld"),
			FindName(g_MediaTypes, &pmt->majortype),
			FindName(g_MediaSubTypes, &pmt->subtype),
			(pmt->bFixedSizeSamples 
				? TEXT("FixedSamples")
				: TEXT("NotFixedSamples")),
			(pmt->bTemporalCompression
				? TEXT("TemporalCompression")
				: TEXT("NotTemporalCompression")),
			pmt->lSampleSize);
}
Exemplo n.º 7
0
VOID
STREAMAPI
AdapterTimeoutPacket(
    PHW_STREAM_REQUEST_BLOCK pSrb
    )
{
    //
    // Unlike most devices, we need to hold onto data SRBs indefinitely,
    // since the graph could be in a pause state indefinitely
    //

    DbgLogInfo(("TestCap: Timeout    Adapter SRB %8x\n", pSrb));

    pSrb->TimeoutCounter = pSrb->TimeoutOriginal;

}
Exemplo n.º 8
0
VOID
STREAMAPI
AdapterCloseStream (
    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;
    PKSDATAFORMAT           pKSDataFormat = pSrb->CommandData.OpenFormat;
    KS_VIDEOINFOHEADER      *pVideoInfoHdr = pStrmEx->pVideoInfoHeader;

    DbgLogInfo(("TestCap: -------- ADAPTERCLOSESTREAM ------ StreamNumber=%d\n", StreamNumber));

    if (pHwDevExt->StreamSRBListSize > 0) {
        VideoQueueCancelAllSRBs (pStrmEx);
        DbgLogError(("TestCap: Outstanding SRBs at stream close!!!\n"));
    }

    pHwDevExt->ActualInstances[StreamNumber]--;

    ASSERT (pHwDevExt->pStrmEx [StreamNumber] != 0);

    pHwDevExt->pStrmEx [StreamNumber] = 0;

    //
    // the minidriver should free any resources that were allocate at
    // open stream time etc.
    //

    // Free the variable length VIDEOINFOHEADER

    if (pVideoInfoHdr) {
        ExFreePool(pVideoInfoHdr);
        pStrmEx->pVideoInfoHeader = NULL;
    }

    // Make sure we no longer reference the clock
    pStrmEx->hMasterClock = NULL;

    // Make sure the state is reset to stopped,
    pStrmEx->KSState = KSSTATE_STOP;

}
Exemplo n.º 9
0
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;
        }
    }
}
Exemplo n.º 10
0
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;
        }
    }

    else {
        // Unknown format
        pSrb->Status = STATUS_INVALID_PARAMETER;
        return FALSE;
    }

    return TRUE;
}
Exemplo n.º 11
0
BOOL
STREAMAPI
VideoQueueCancelOneSRB (
    PSTREAMEX pStrmEx,
    PHW_STREAM_REQUEST_BLOCK pSrbToCancel
    )
{
    PHW_DEVICE_EXTENSION        pHwDevExt = (PHW_DEVICE_EXTENSION)pStrmEx->pHwDevExt;
    int                         StreamNumber = pStrmEx->pStreamObject->StreamNumber;
    KIRQL                       oldIrql;
    BOOL                        Found = FALSE;
    PIRP                        pIrp;
    PHW_STREAM_REQUEST_BLOCK    pSrb;
    PLIST_ENTRY                 Entry;

    KeAcquireSpinLock (&pHwDevExt->StreamSRBSpinLock[StreamNumber], &oldIrql);

    Entry = pHwDevExt->StreamSRBList[StreamNumber].Flink;

    //
    // Loop through the linked list from the beginning to end,
    // trying to find the SRB to cancel
    //

    while (Entry != &pHwDevExt->StreamSRBList[StreamNumber]) {

        pIrp = (PIRP) (((PUCHAR) Entry) -
                     FIELDOFFSET(IRP, Tail.Overlay.ListEntry));

        pSrb = (PHW_STREAM_REQUEST_BLOCK) pIrp->Tail.Overlay.DriverContext[0];

        if (pSrb == pSrbToCancel) {
            RemoveEntryList(Entry);
            Found = TRUE;
            break;
        }

        Entry = Entry->Flink;
    }

    KeReleaseSpinLock (&pHwDevExt->StreamSRBSpinLock[StreamNumber], oldIrql);

    if (Found) {

        pHwDevExt->StreamSRBListSize[StreamNumber]--;

        //
        // Make the length zero, and status cancelled
        //

        pSrbToCancel->CommandData.DataBufferArray->DataUsed = 0;
        pSrbToCancel->Status = STATUS_CANCELLED;

        CompleteStreamSRB (pSrbToCancel);

        DbgLogInfo(("TestCap: VideoQueueCancelOneSRB FOUND Srb=%p, Stream=%d\n", pSrb, StreamNumber));

    }

    DbgLogInfo(("TestCap: VideoQueueCancelOneSRB Completed Stream=%d\n", StreamNumber));

    return Found;
}
Exemplo n.º 12
0
VOID
STREAMAPI
VideoQueueCancelAllSRBs (
    PSTREAMEX pStrmEx
    )
{
    PHW_DEVICE_EXTENSION        pHwDevExt = (PHW_DEVICE_EXTENSION)pStrmEx->pHwDevExt;
    int                         StreamNumber = pStrmEx->pStreamObject->StreamNumber;
    PUCHAR                      ptr;
    PIRP                        pIrp;
    PHW_STREAM_REQUEST_BLOCK    pSrb;
    KIRQL                       oldIrql;

    if (pStrmEx->KSState != KSSTATE_STOP) {

        DbgLogInfo(("TestCap: VideoQueueCancelAllSRBs without being in the stopped state\n"));
        // May need to force the device to a stopped state here
        // may need to disable interrupts here !
    }

    //
    // The stream class will cancel all outstanding IRPs for us
    // (but only if we've set TurnOffSynchronization = FALSE)
    //

    KeAcquireSpinLock (&pHwDevExt->StreamSRBSpinLock[StreamNumber], &oldIrql);

    //
    // Get the SRB out of the IRP out of the pending list
    //
    while (!IsListEmpty (&pHwDevExt->StreamSRBList[StreamNumber])) {

        ptr = (PUCHAR) RemoveHeadList(
                         &pHwDevExt->StreamSRBList[StreamNumber]);

        pIrp = (PIRP) (((PUCHAR) ptr) -
                     FIELDOFFSET(IRP, Tail.Overlay.ListEntry));

        pSrb = (PHW_STREAM_REQUEST_BLOCK) pIrp->Tail.Overlay.DriverContext[0];

        // Decrement the count of SRBs in this queue
        pHwDevExt->StreamSRBListSize[StreamNumber]--;

        //
        // Make the length zero, and status cancelled
        //

        pSrb->CommandData.DataBufferArray->DataUsed = 0;
        pSrb->Status = STATUS_CANCELLED;

        DbgLogInfo(("TestCap: VideoQueueCancelALLSRBs FOUND Srb=%p, Stream=%d\n", pSrb, StreamNumber));

        CompleteStreamSRB (pSrb);

    }

    KeReleaseSpinLock (&pHwDevExt->StreamSRBSpinLock[StreamNumber], oldIrql);

    DbgLogInfo(("TestCap: VideoQueueCancelAll Completed\n"));

}
Exemplo n.º 13
0
VOID
STREAMAPI
VideoSetState(
    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;
    KSSTATE                     PreviousState;

    //
    // For each stream, the following states are used:
    //
    // Stop:    Absolute minimum resources are used.  No outstanding IRPs.
    // Acquire: KS only state that has no DirectShow correpondence
    //          Acquire needed resources.
    // Pause:   Getting ready to run.  Allocate needed resources so that
    //          the eventual transition to Run is as fast as possible.
    //          Read SRBs will be queued at either the Stream class
    //          or in your driver (depending on when you send "ReadyForNext")
    //          and whether you're using the Stream class for synchronization
    // Run:     Streaming.
    //
    // Moving to Stop to Run always transitions through Pause.
    //
    // But since a client app could crash unexpectedly, drivers should handle
    // the situation of having outstanding IRPs cancelled and open streams
    // being closed WHILE THEY ARE STREAMING!
    //
    // Note that it is quite possible to transition repeatedly between states:
    // Stop -> Pause -> Stop -> Pause -> Run -> Pause -> Run -> Pause -> Stop
    //

    //
    // Remember the state we're transitioning away from
    //

    PreviousState = pStrmEx->KSState;

    //
    // Set the new state
    //

    pStrmEx->KSState = pSrb->CommandData.StreamState;

    switch (pSrb->CommandData.StreamState)

    {
    case KSSTATE_STOP:

        //
        // The stream class will cancel all outstanding IRPs for us
        // (but only if it is maintaining the queue ie. using Stream Class synchronization)
        // Since Testcap is not using Stream Class synchronization, we must clear the queue here

        VideoQueueCancelAllSRBs (pStrmEx);

        DbgLogInfo(("TestCap: STATE Stopped, Stream=%d\n", StreamNumber));
        break;

    case KSSTATE_ACQUIRE:

        //
        // This is a KS only state, that has no correspondence in DirectShow
        //
        DbgLogInfo(("TestCap: STATE Acquire, Stream=%d\n", StreamNumber));
        break;

    case KSSTATE_PAUSE:

        //
        // On a transition to pause from acquire or stop, start our timer running.
        //

        if (PreviousState == KSSTATE_ACQUIRE || PreviousState == KSSTATE_STOP) {

            // Zero the frame counters
            pStrmEx->FrameInfo.PictureNumber = 0;
            pStrmEx->FrameInfo.DropCount = 0;
            pStrmEx->FrameInfo.dwFrameFlags = 0;

            // Setup the next timer callback(s)
            VideoTimerRoutine(pStrmEx);
        }
        DbgLogInfo(("TestCap: STATE Pause, Stream=%d\n", StreamNumber));
        break;

    case KSSTATE_RUN:

        //
        // Begin Streaming.
        //

        // Reset the discontinuity flag

        pStrmEx->fDiscontinuity = FALSE;

        // Setting the NextFrame time to zero will cause the value to be
        // reset from the stream time

        pStrmEx->QST_NextFrame = 0;

        DbgLogInfo(("TestCap: STATE Run, Stream=%d\n", StreamNumber));
        break;

    } // end switch (pSrb->CommandData.StreamState)
}
Exemplo n.º 14
0
VOID
STREAMAPI
VideoCaptureRoutine(
    IN PSTREAMEX pStrmEx
    )
{
    PHW_DEVICE_EXTENSION    pHwDevExt = pStrmEx->pHwDevExt;
    int                     StreamNumber = pStrmEx->pStreamObject->StreamNumber;
    PKSSTREAM_HEADER        pDataPacket;
    PKS_FRAME_INFO          pFrameInfo;

    // If we're stopped and the timer is still running, just return.
    // This will stop the timer.

    if (pStrmEx->KSState == KSSTATE_STOP) {
        return;
    }


    // Find out what time it is, if we're using a clock

    if (pStrmEx->hMasterClock ) {
        HW_TIME_CONTEXT TimeContext;

        TimeContext.HwDeviceExtension = pHwDevExt;
        TimeContext.HwStreamObject = pStrmEx->pStreamObject;
        TimeContext.Function = TIME_GET_STREAM_TIME;

        StreamClassQueryMasterClockSync (
                pStrmEx->hMasterClock,
                &TimeContext);

        pStrmEx->QST_StreamTime = TimeContext.Time;
        pStrmEx->QST_Now = TimeContext.SystemTime;

        if (pStrmEx->QST_NextFrame == 0) {
            pStrmEx->QST_NextFrame = pStrmEx->QST_StreamTime + pStrmEx->AvgTimePerFrame;
        }

#ifdef CREATE_A_FLURRY_OF_TIMING_SPEW
        DbgLogTrace(("TestCap: Time=%6d mS at SystemTime=%I64d\n", 
                     (LONG) ((LONGLONG) TimeContext.Time / 10000), 
                     TimeContext.SystemTime));
#endif
    }


    // Only capture in the RUN state

    if (pStrmEx->KSState == KSSTATE_RUN) {

        //
        // Determine if it is time to capture a frame based on
        // how much time has elapsed since capture started.
        // If there isn't a clock available, then capture immediately.
        //

        if ((!pStrmEx->hMasterClock) ||
             (pStrmEx->QST_StreamTime >= pStrmEx->QST_NextFrame)) {

            PHW_STREAM_REQUEST_BLOCK pSrb;

            // Increment the picture count (usually this is VSYNC count)

            pStrmEx->FrameInfo.PictureNumber++;

            //
            // Get the next queue SRB (if any)
            //

            pSrb = VideoQueueRemoveSRB (
                            pHwDevExt,
                            StreamNumber);

            if (pSrb) {

                pDataPacket = pSrb->CommandData.DataBufferArray;
                pFrameInfo = (PKS_FRAME_INFO) (pDataPacket + 1);

                //
                // Call the routine which synthesizes images
                //

                ImageSynth (pSrb,
                            IMAGE_XFER_GRAY_INCREASING,
                            pStrmEx->VideoControlMode & KS_VideoControlFlag_FlipHorizontal);

                // Set additional info fields about the data captured such as:
                //   Frames Captured
                //   Frames Dropped
                //   Field Polarity

                pStrmEx->FrameInfo.ExtendedHeaderSize = pFrameInfo->ExtendedHeaderSize;

                *pFrameInfo = pStrmEx->FrameInfo;

                // Init the flags to zero
                pDataPacket->OptionsFlags = 0;

                // Set the discontinuity flag if frames have been previously
                // dropped, and then reset our internal flag

                if (pStrmEx->fDiscontinuity) {
                    pDataPacket->OptionsFlags |= KSSTREAM_HEADER_OPTIONSF_DATADISCONTINUITY;
                    pStrmEx->fDiscontinuity = FALSE;
                }

                //
                // Return the timestamp for the frame
                //
                pDataPacket->PresentationTime.Numerator = 1;
                pDataPacket->PresentationTime.Denominator = 1;
                pDataPacket->Duration = pStrmEx->AvgTimePerFrame;

                //
                // if we have a master clock AND this is the capture stream
                //
                if (pStrmEx->hMasterClock && (StreamNumber == 0)) {

                    pDataPacket->PresentationTime.Time = pStrmEx->QST_StreamTime;
                    pDataPacket->OptionsFlags |=
                        KSSTREAM_HEADER_OPTIONSF_TIMEVALID |
                        KSSTREAM_HEADER_OPTIONSF_DURATIONVALID;
                }
                else {
                    //
                    // no clock or the preview stream, so just mark the time as unknown
                    //
                    pDataPacket->PresentationTime.Time = 0;
                    // clear the timestamp valid flags
                    pDataPacket->OptionsFlags &=
                        ~(KSSTREAM_HEADER_OPTIONSF_TIMEVALID |
                          KSSTREAM_HEADER_OPTIONSF_DURATIONVALID);
                }

                // Every frame we generate is a key frame (aka SplicePoint)
                // Delta frames (B or P) should not set this flag

                pDataPacket->OptionsFlags |= KSSTREAM_HEADER_OPTIONSF_SPLICEPOINT;

                // Output a frame count every 100th frame in Debug mode
                if (pStrmEx->FrameInfo.PictureNumber % 100 == 0) {
                   DbgLogInfo(("TestCap: Picture %u, Stream=%d\n", 
                               (unsigned int)pStrmEx->FrameInfo.PictureNumber, 
                               StreamNumber));
                }

                CompleteStreamSRB (pSrb);

            } // if we have an SRB

            else {

                //
                // No buffer was available when we should have captured one

                // Increment the counter which keeps track of
                // dropped frames

                pStrmEx->FrameInfo.DropCount++;

                // Set the (local) discontinuity flag
                // This will cause the next packet processed to have the
                //   KSSTREAM_HEADER_OPTIONSF_DATADISCONTINUITY flag set.

                pStrmEx->fDiscontinuity = TRUE;

            }

            // Figure out when to capture the next frame
            pStrmEx->QST_NextFrame += pStrmEx->AvgTimePerFrame;

        } // endif time to capture a frame
    } // endif we're running
}
Exemplo n.º 15
0
void DbgLogMediaFormatInfo(DWORD type, DWORD level, const CMediaType* pmt)
{
	DbgLogInfo(type, level,
		TEXT(" Format Info : %s FormatSize=%ld"),
			FindName(g_MediaFormats, &pmt->formattype),
			pmt->cbFormat);

	if (pmt->formattype == FORMAT_VideoInfo) {
		if (pmt->pbFormat == NULL || pmt->cbFormat < sizeof(VIDEOINFOHEADER)) {
			DbgLogInfo(type, level, TEXT("  !! INVALID FORMAT !!"));
			return;
		}

		VIDEOINFOHEADER* pvh = (VIDEOINFOHEADER*)pmt->pbFormat;
		DbgLogInfo(type, level, TEXT("  Source : %ld, %ld, %ld, %ld"),
				pvh->rcSource.left, pvh->rcSource.top,
				pvh->rcSource.right, pvh->rcSource.bottom);
		DbgLogInfo(type, level, TEXT("  Target : %ld, %ld, %ld, %ld"),
				pvh->rcTarget.left, pvh->rcTarget.top,
				pvh->rcTarget.right, pvh->rcTarget.bottom);
		DbgLogInfo(type, level, TEXT("  BitRate / BitErrorRate : %lu / %lu"),
				pvh->dwBitRate, pvh->dwBitErrorRate);
		DbgLogInfo(type, level, TEXT("  AvgTimePerFrame : %lld"),
				pvh->AvgTimePerFrame);
		DbgLogInfo(type, level, TEXT("  Header Size=%lu"),
				pvh->bmiHeader.biSize);
		DbgLogInfo(type, level, TEXT("   Width x Height = %ld x %ld"),
				pvh->bmiHeader.biWidth, pvh->bmiHeader.biHeight);
		DbgLogInfo(type, level, TEXT("   Planes, BitCount = %u, %u"),
				pvh->bmiHeader.biPlanes, pvh->bmiHeader.biBitCount);
		DbgLogInfo(type, level, TEXT("   Compression = %lu"),
				pvh->bmiHeader.biCompression);
		DbgLogInfo(type, level, TEXT("   SizeImage = %lu"),
				pvh->bmiHeader.biSizeImage);
		DbgLogInfo(type, level, TEXT("   PelsPerMeter = %ld x %ld"),
				pvh->bmiHeader.biXPelsPerMeter,
				pvh->bmiHeader.biYPelsPerMeter);
		DbgLogInfo(type, level, TEXT("   ColorUsed(Important) = %lu(%lu)"),
				pvh->bmiHeader.biClrUsed, pvh->bmiHeader.biClrImportant);
	} else if (pmt->formattype == FORMAT_VideoInfo2) {
		if (pmt->pbFormat == NULL 
				|| pmt->cbFormat < sizeof(VIDEOINFOHEADER2)) {
			DbgLogInfo(type, level, TEXT("  !! INVALID FORMAT !!"));
			return;
		}

		VIDEOINFOHEADER2* pvh = (VIDEOINFOHEADER2*)pmt->pbFormat;
		DbgLogInfo(type, level, TEXT("  Source : %ld, %ld, %ld, %ld"),
				pvh->rcSource.left, pvh->rcSource.top,
				pvh->rcSource.right, pvh->rcSource.bottom);
		DbgLogInfo(type, level, TEXT("  Target : %ld, %ld, %ld, %ld"),
				pvh->rcTarget.left, pvh->rcTarget.top,
				pvh->rcTarget.right, pvh->rcTarget.bottom);
		DbgLogInfo(type, level, TEXT("  BitRate / BitErrorRate : %lu / %lu"),
				pvh->dwBitRate, pvh->dwBitErrorRate);
		DbgLogInfo(type, level, TEXT("  AvgTimePerFrame : %lld"),
				pvh->AvgTimePerFrame);
		DbgLogInfo(type, level, TEXT("  InterlaceFlags : 0x%08x"),
				pvh->dwInterlaceFlags);
		DbgLogInfo(type, level, TEXT("  CopyProtectFlags : 0x%08x"),
				pvh->dwCopyProtectFlags);
		DbgLogInfo(type, level, TEXT("  PictAspectRatio : %lu x %lu"),
				pvh->dwPictAspectRatioX, pvh->dwPictAspectRatioY);
		DbgLogInfo(type, level, TEXT("  ControlFlags : 0x%08x"),
				pvh->dwControlFlags);
		DbgLogInfo(type, level, TEXT("  Header Size=%lu"),
				pvh->bmiHeader.biSize);
		DbgLogInfo(type, level, TEXT("   Width x Height = %ld x %ld"),
				pvh->bmiHeader.biWidth, pvh->bmiHeader.biHeight);
		DbgLogInfo(type, level, TEXT("   Planes, BitCount = %u, %u"),
				pvh->bmiHeader.biPlanes, pvh->bmiHeader.biBitCount);
		DbgLogInfo(type, level, TEXT("   Compression = %lu"),
				pvh->bmiHeader.biCompression);
		DbgLogInfo(type, level, TEXT("   SizeImage = %lu"),
				pvh->bmiHeader.biSizeImage);
		DbgLogInfo(type, level, TEXT("   PelsPerMeter = %ld x %ld"),
				pvh->bmiHeader.biXPelsPerMeter,
				pvh->bmiHeader.biYPelsPerMeter);
		DbgLogInfo(type, level, TEXT("   ColorUsed(Important) = %lu(%lu)"),
				pvh->bmiHeader.biClrUsed, pvh->bmiHeader.biClrImportant);
	} else if (pmt->formattype == FORMAT_WaveFormatEx) {
		if (pmt->pbFormat == NULL || sizeof(WAVEFORMATEX) < pmt->cbFormat) {
			DbgLogInfo(type, level, TEXT("  !! INVALID FORMAT !!"));
			return;
		}

		WAVEFORMATEX * pvh = (WAVEFORMATEX *)pmt->pbFormat;
		DbgLogInfo(type, level, TEXT("  FormatTag : %u"), pvh->wFormatTag);
		DbgLogInfo(type, level, TEXT("  Channels : %u"), pvh->nChannels);
		DbgLogInfo(type, level, TEXT("  SamplesPerSec : %lu"),
				pvh->nSamplesPerSec);
		DbgLogInfo(type, level, TEXT("  AvgBytesPerSec : %lu"),
				pvh->nAvgBytesPerSec);
		DbgLogInfo(type, level, TEXT("  BlockAlign : %u"),
				pvh->nBlockAlign);
		DbgLogInfo(type, level, TEXT("  BitsPerSample : %u"),
				pvh->wBitsPerSample);
		DbgLogInfo(type, level, TEXT("  Size : %u"),
				pvh->cbSize);
	}

	if (pmt->formattype == FORMAT_MPEGVideo) {
		if (pmt->pbFormat == NULL || sizeof(MPEG1VIDEOINFO) < pmt->cbFormat) {
			DbgLogInfo(type, level, TEXT("  !! INVALID FORMAT !!"));
			return;
		}

		MPEG1VIDEOINFO* pvh = (MPEG1VIDEOINFO*)pmt->pbFormat;
		DbgLogInfo(type, level, TEXT("  Source : %ld, %ld, %ld, %ld"),
				pvh->hdr.rcSource.left, pvh->hdr.rcSource.top,
				pvh->hdr.rcSource.right, pvh->hdr.rcSource.bottom);
		DbgLogInfo(type, level, TEXT("  Target : %ld, %ld, %ld, %ld"),
				pvh->hdr.rcTarget.left, pvh->hdr.rcTarget.top,
				pvh->hdr.rcTarget.right, pvh->hdr.rcTarget.bottom);
		DbgLogInfo(type, level, TEXT("  BitRate / BitErrorRate : %lu / %lu"),
				pvh->hdr.dwBitRate, pvh->hdr.dwBitErrorRate);
		DbgLogInfo(type, level, TEXT("  AvgTimePerFrame : %lld"),
				pvh->hdr.AvgTimePerFrame);
		DbgLogInfo(type, level, TEXT("  Header Size=%lu"),
				pvh->hdr.bmiHeader.biSize);
		DbgLogInfo(type, level, TEXT("   Width x Height = %ld x %ld"),
				pvh->hdr.bmiHeader.biWidth, pvh->hdr.bmiHeader.biHeight);
		DbgLogInfo(type, level, TEXT("   Planes, BitCount = %u, %u"),
				pvh->hdr.bmiHeader.biPlanes, pvh->hdr.bmiHeader.biBitCount);
		DbgLogInfo(type, level, TEXT("   Compression = %lu"),
				pvh->hdr.bmiHeader.biCompression);
		DbgLogInfo(type, level, TEXT("   SizeImage = %lu"),
				pvh->hdr.bmiHeader.biSizeImage);
		DbgLogInfo(type, level, TEXT("   PelsPerMeter = %ld x %ld"),
				pvh->hdr.bmiHeader.biXPelsPerMeter,
				pvh->hdr.bmiHeader.biYPelsPerMeter);
		DbgLogInfo(type, level, TEXT("   ColorUsed(Important) = %lu(%lu)"),
				pvh->hdr.bmiHeader.biClrUsed,
				pvh->hdr.bmiHeader.biClrImportant);
		DbgLogInfo(type, level, TEXT("   StartTimeCode = %lu"),
				pvh->dwStartTimeCode);
		DbgLogInfo(type, level, TEXT("   SequenceHeader = %lu"),
				pvh->cbSequenceHeader);
	}

	// TODO:残りのフォーマット対応
	// FORMAT_MPEGStreams
	// FORMAT_DvInfo
	// FORMAT_525WSS
	// FORMAT_AnalogVideo
}
Exemplo n.º 16
0
BOOL
STREAMAPI
AdapterFormatFromRange(
    IN PHW_STREAM_REQUEST_BLOCK pSrb
    )
{
    PSTREAM_DATA_INTERSECT_INFO IntersectInfo;
    PKSDATARANGE                DataRange;
    BOOL                        OnlyWantsSize;
    BOOL                        MatchFound = FALSE;
    ULONG                       FormatSize;
    ULONG                       StreamNumber;
    ULONG                       j;
    ULONG                       NumberOfFormatArrayEntries;
    PKSDATAFORMAT               *pAvailableFormats;

DbgLogInfo(("TestCap: Enter AdapterFormatFromRange\n"));	


    IntersectInfo = pSrb->CommandData.IntersectInfo;
    StreamNumber = IntersectInfo->StreamNumber;
    DataRange = IntersectInfo->DataRange;

    //
    // Check that the stream number is valid
    //

    if (StreamNumber >= DRIVER_STREAM_COUNT) {
        pSrb->Status = STATUS_NOT_IMPLEMENTED;
        TRAP;
        return FALSE;
    }

    NumberOfFormatArrayEntries =
            Streams[StreamNumber].hwStreamInfo.NumberOfFormatArrayEntries;

    //
    // Get the pointer to the array of available formats
    //

    pAvailableFormats = Streams[StreamNumber].hwStreamInfo.StreamFormatsArray;

    //
    // Is the caller trying to get the format, or the size of the format?
    //

    OnlyWantsSize = (IntersectInfo->SizeOfDataFormatBuffer == sizeof(ULONG));

    //
    // Walk the formats supported by the stream searching for a match
    // of the three GUIDs which together define a DATARANGE
    //

    for (j = 0; j < NumberOfFormatArrayEntries; j++, pAvailableFormats++) {


        if (!AdapterCompareGUIDsAndFormatSize(
                        DataRange,
                        *pAvailableFormats,
                        TRUE /* CompareFormatSize */)) {
            continue;
        }

        //
        // Now that the three GUIDs match, do a further type-specific check
        //

        // -------------------------------------------------------------------
        // Specifier FORMAT_VideoInfo for VIDEOINFOHEADER
        // -------------------------------------------------------------------

        if (IsEqualGUID (&DataRange->Specifier,
                &KSDATAFORMAT_SPECIFIER_VIDEOINFO)) {

            PKS_DATARANGE_VIDEO DataRangeVideoToVerify =
                    (PKS_DATARANGE_VIDEO) DataRange;
            PKS_DATARANGE_VIDEO DataRangeVideo =
                    (PKS_DATARANGE_VIDEO) *pAvailableFormats;
            PKS_DATAFORMAT_VIDEOINFOHEADER DataFormatVideoInfoHeaderOut;

            //
            // Check that the other fields match
            //
            if ((DataRangeVideoToVerify->bFixedSizeSamples != DataRangeVideo->bFixedSizeSamples) ||
                (DataRangeVideoToVerify->bTemporalCompression != DataRangeVideo->bTemporalCompression) ||
                (DataRangeVideoToVerify->StreamDescriptionFlags != DataRangeVideo->StreamDescriptionFlags) ||
                (DataRangeVideoToVerify->MemoryAllocationFlags != DataRangeVideo->MemoryAllocationFlags) ||
                (RtlCompareMemory (&DataRangeVideoToVerify->ConfigCaps,
                        &DataRangeVideo->ConfigCaps,
                        sizeof (KS_VIDEO_STREAM_CONFIG_CAPS)) !=
                        sizeof (KS_VIDEO_STREAM_CONFIG_CAPS)))
            {
                continue;
            }

            // MATCH FOUND!
            MatchFound = TRUE;
			if(MatchFound)
				{
				DbgLogInfo(("TestCap: MatchFound!!!!\n"));	
				}
				
            FormatSize = sizeof (KSDATAFORMAT) +
                KS_SIZE_VIDEOHEADER (&DataRangeVideoToVerify->VideoInfoHeader);

            if (OnlyWantsSize) {
                break;
            }

            // Caller wants the full data format
            if (IntersectInfo->SizeOfDataFormatBuffer < FormatSize) {
                pSrb->Status = STATUS_BUFFER_TOO_SMALL;
                return FALSE;
            }

            // Copy over the KSDATAFORMAT, followed by the
            // actual VideoInfoHeader

            DataFormatVideoInfoHeaderOut = (PKS_DATAFORMAT_VIDEOINFOHEADER) IntersectInfo->DataFormatBuffer;

            // Copy over the KSDATAFORMAT
            RtlCopyMemory(
                &DataFormatVideoInfoHeaderOut->DataFormat,
                &DataRangeVideoToVerify->DataRange,
                sizeof (KSDATARANGE));

            DataFormatVideoInfoHeaderOut->DataFormat.FormatSize = FormatSize;

            // Copy over the callers requested VIDEOINFOHEADER

            RtlCopyMemory(
                &DataFormatVideoInfoHeaderOut->VideoInfoHeader,
                &DataRangeVideoToVerify->VideoInfoHeader,
                KS_SIZE_VIDEOHEADER (&DataRangeVideoToVerify->VideoInfoHeader));

            // Calculate biSizeImage for this request, and put the result in both
            // the biSizeImage field of the bmiHeader AND in the SampleSize field
            // of the DataFormat.
            //
            // Note that for compressed sizes, this calculation will probably not
            // be just width * height * bitdepth

            DataFormatVideoInfoHeaderOut->VideoInfoHeader.bmiHeader.biSizeImage =
                DataFormatVideoInfoHeaderOut->DataFormat.SampleSize =
                KS_DIBSIZE(DataFormatVideoInfoHeaderOut->VideoInfoHeader.bmiHeader);

            //
            // Perform other validation such as cropping and scaling checks
            //

            break;

        } // End of VIDEOINFOHEADER specifier

        // -------------------------------------------------------------------
        // Specifier FORMAT_AnalogVideo for KS_ANALOGVIDEOINFO
        // -------------------------------------------------------------------

        else if (IsEqualGUID (&DataRange->Specifier,
                &KSDATAFORMAT_SPECIFIER_ANALOGVIDEO)) {

            //
            // For analog video, the DataRange and DataFormat
            // are identical, so just copy the whole structure
            //

            PKS_DATARANGE_ANALOGVIDEO DataRangeVideo =
                    (PKS_DATARANGE_ANALOGVIDEO) *pAvailableFormats;

            // MATCH FOUND!
            MatchFound = TRUE;
            FormatSize = sizeof (KS_DATARANGE_ANALOGVIDEO);

            if (OnlyWantsSize) {
                break;
            }

            // Caller wants the full data format
            if (IntersectInfo->SizeOfDataFormatBuffer < FormatSize) {
                pSrb->Status = STATUS_BUFFER_TOO_SMALL;
                return FALSE;
            }

            RtlCopyMemory(
                IntersectInfo->DataFormatBuffer,
                DataRangeVideo,
                sizeof (KS_DATARANGE_ANALOGVIDEO));

            ((PKSDATAFORMAT)IntersectInfo->DataFormatBuffer)->FormatSize = FormatSize;

            break;

        } // End of KS_ANALOGVIDEOINFO specifier

        // -------------------------------------------------------------------
        // Specifier FORMAT_VBI for KS_VIDEO_VBI
        // -------------------------------------------------------------------

        else if (IsEqualGUID (&DataRange->Specifier,
                &KSDATAFORMAT_SPECIFIER_VBI))
        {
            PKS_DATARANGE_VIDEO_VBI pDataRangeVBI =
                (PKS_DATARANGE_VIDEO_VBI)*pAvailableFormats;
            PKS_DATAFORMAT_VBIINFOHEADER InterVBIHdr =
                (PKS_DATAFORMAT_VBIINFOHEADER)IntersectInfo->DataFormatBuffer;

            // MATCH FOUND!
            MatchFound = TRUE;

            FormatSize = sizeof (KS_DATAFORMAT_VBIINFOHEADER);

            // Is the caller trying to get the format, or the size of it?
            if (OnlyWantsSize)
                break;

            // Verify that there is enough room in the supplied buffer
            //   for the whole thing
            if (IntersectInfo->SizeOfDataFormatBuffer < FormatSize)
            {
                if (IntersectInfo->SizeOfDataFormatBuffer > 0) {
                    DbgLogError(
                        ("Testcap::AdapterFormatFromRange: "
                         "Specifier==VBI, Buffer too small=%d vs. %d\n",
                         IntersectInfo->SizeOfDataFormatBuffer,
                         FormatSize));
                }
                pSrb->Status = STATUS_BUFFER_TOO_SMALL;
                return FALSE;
            }

            // If there is room, go ahead...

            RtlCopyMemory(&InterVBIHdr->DataFormat,
                          &pDataRangeVBI->DataRange,
                          sizeof (KSDATARANGE));

            ((PKSDATAFORMAT)IntersectInfo->DataFormatBuffer)->FormatSize = FormatSize;

            RtlCopyMemory(&InterVBIHdr->VBIInfoHeader,
                          &pDataRangeVBI->VBIInfoHeader,
                          sizeof(KS_VBIINFOHEADER));

            break;

        } // End of KS_VIDEO_VBI specifier

        // -------------------------------------------------------------------
        // Type FORMAT_NABTS for NABTS pin
        // -------------------------------------------------------------------

        else if (IsEqualGUID (&DataRange->SubFormat,
                &KSDATAFORMAT_SUBTYPE_NABTS))
        {
            PKSDATARANGE pDataRange = (PKSDATARANGE)*pAvailableFormats;

            // MATCH FOUND!
            MatchFound = TRUE;

            FormatSize = sizeof (KSDATAFORMAT);

            // Is the caller trying to get the format, or the size of it?
            if (OnlyWantsSize)
                break;

            // Verify that there is enough room in the supplied buffer
            //   for the whole thing
            if (IntersectInfo->SizeOfDataFormatBuffer >= FormatSize)
            {
                RtlCopyMemory(IntersectInfo->DataFormatBuffer,
                              pDataRange,
                              FormatSize);

                ((PKSDATAFORMAT)IntersectInfo->DataFormatBuffer)->FormatSize = FormatSize;
            }
            else
            {
                if (IntersectInfo->SizeOfDataFormatBuffer > 0) {
                    DbgLogError(
                        ("Testcap::AdapterFormatFromRange: "
                         "SubFormat==NABTS, Buffer too small=%d vs. %d\n",
                         IntersectInfo->SizeOfDataFormatBuffer,
                         FormatSize));
                }
                pSrb->Status = STATUS_BUFFER_TOO_SMALL;
                return FALSE;
            }

            break;

        } // End of KS_SUBTYPE_NABTS

        // -------------------------------------------------------------------
        // for CC pin
        // -------------------------------------------------------------------

        else if (IsEqualGUID (&DataRange->SubFormat,
                &KSDATAFORMAT_SUBTYPE_CC))
        {
            PKSDATARANGE pDataRange = (PKSDATARANGE)*pAvailableFormats;

            // MATCH FOUND!
            MatchFound = TRUE;

            FormatSize = sizeof (KSDATAFORMAT);

            // Is the caller trying to get the format, or the size of it?
            if (OnlyWantsSize)
                break;

            // Verify that there is enough room in the supplied buffer
            //   for the whole thing
            if (IntersectInfo->SizeOfDataFormatBuffer >= FormatSize)
            {
                RtlCopyMemory(IntersectInfo->DataFormatBuffer,
                              pDataRange,
                              FormatSize);

                ((PKSDATAFORMAT)IntersectInfo->DataFormatBuffer)->FormatSize = FormatSize;
            }
            else
            {
                if (IntersectInfo->SizeOfDataFormatBuffer > 0) {
                    DbgLogError(
                        ("Testcap::AdapterFormatFromRange: "
                         "SubFormat==CC, Buffer too small=%d vs. %d\n",
                         IntersectInfo->SizeOfDataFormatBuffer,
                         FormatSize));
                }
                pSrb->Status = STATUS_BUFFER_TOO_SMALL;
                return FALSE;
            }

            break;

        } // End of CC pin format check

        else {
            pSrb->Status = STATUS_NO_MATCH;
            return FALSE;
        }

    } // End of loop on all formats for this stream

    if (!MatchFound) {
        pSrb->Status = STATUS_NO_MATCH;
        return FALSE;
    }

    if (OnlyWantsSize) {
        *(PULONG) IntersectInfo->DataFormatBuffer = FormatSize;
        FormatSize = sizeof(ULONG);
    }
    pSrb->ActualBytesTransferred = FormatSize;
    return TRUE;
}
Exemplo n.º 17
0
BOOLEAN
STREAMAPI
HwInitialize (
    IN OUT PHW_STREAM_REQUEST_BLOCK pSrb
    )
{
    STREAM_PHYSICAL_ADDRESS     adr;
    ULONG                       Size;
    PUCHAR                      pDmaBuf;
    int                         j;

    PPORT_CONFIGURATION_INFORMATION ConfigInfo = pSrb->CommandData.ConfigInfo;

    PHW_DEVICE_EXTENSION pHwDevExt =
        (PHW_DEVICE_EXTENSION)ConfigInfo->HwDeviceExtension;

    DbgLogInfo(("Testcap: HwInitialize()\n"));

    if (ConfigInfo->NumberOfAccessRanges != 0) {
        DbgLogError(("Testcap: illegal config info\n"));

        pSrb->Status = STATUS_NO_SUCH_DEVICE;
        return (FALSE);
    }

    DbgLogInfo(("TestCap: Number of access ranges = %lx\n", ConfigInfo->NumberOfAccessRanges));
    DbgLogInfo(("TestCap: Memory Range = %lx\n", pHwDevExt->ioBaseLocal));
    DbgLogInfo(("TestCap: IRQ = %lx\n", ConfigInfo->BusInterruptLevel));

    if (ConfigInfo->NumberOfAccessRanges != 0) {
        pHwDevExt->ioBaseLocal
                = (PULONG)(ULONG_PTR)   (ConfigInfo->AccessRanges[0].RangeStart.LowPart);
    }

    pHwDevExt->Irq  = (USHORT)(ConfigInfo->BusInterruptLevel);

    ConfigInfo->StreamDescriptorSize = sizeof (HW_STREAM_HEADER) +
                DRIVER_STREAM_COUNT * sizeof (HW_STREAM_INFORMATION);

    pDmaBuf = StreamClassGetDmaBuffer(pHwDevExt);

    adr = StreamClassGetPhysicalAddress(pHwDevExt,
            NULL, pDmaBuf, DmaBuffer, &Size);

    // Init VideoProcAmp properties
    pHwDevExt->Brightness = BrightnessDefault;
    pHwDevExt->BrightnessFlags = KSPROPERTY_VIDEOPROCAMP_FLAGS_AUTO;
    pHwDevExt->Contrast = ContrastDefault;
    pHwDevExt->ContrastFlags = KSPROPERTY_VIDEOPROCAMP_FLAGS_AUTO;
    pHwDevExt->ColorEnable = ColorEnableDefault;
    pHwDevExt->ColorEnableFlags = KSPROPERTY_VIDEOPROCAMP_FLAGS_MANUAL;

    // Init CameraControl properties
    pHwDevExt->Focus = FocusDefault;
    pHwDevExt->FocusFlags = KSPROPERTY_CAMERACONTROL_FLAGS_AUTO;
    pHwDevExt->Zoom = ZoomDefault;
    pHwDevExt->ZoomFlags = KSPROPERTY_CAMERACONTROL_FLAGS_AUTO;

    // Init VideoControl properties
    pHwDevExt->VideoControlMode = 0;

    // Init VideoCompression properties
    pHwDevExt->CompressionSettings.CompressionKeyFrameRate = 15;
    pHwDevExt->CompressionSettings.CompressionPFramesPerKeyFrame = 3;
    pHwDevExt->CompressionSettings.CompressionQuality = 5000;

    pHwDevExt->PDO = ConfigInfo->RealPhysicalDeviceObject;
    DbgLogInfo(("TestCap: Physical Device Object = %lx\n", pHwDevExt->PDO));

    for (j = 0; j < MAX_TESTCAP_STREAMS; j++){

        // For each stream, maintain a separate queue for data and control
        InitializeListHead (&pHwDevExt->StreamSRBList[j]);
        InitializeListHead (&pHwDevExt->StreamControlSRBList[j]);
        KeInitializeSpinLock (&pHwDevExt->StreamSRBSpinLock[j]);
        pHwDevExt->StreamSRBListSize[j] = 0;
    }

    // Init ProtectionStatus
    pHwDevExt->ProtectionStatus = 0;


    // The following allows multiple instance of identical hardware
    // to be installed.  GlobalDriverMediumInstanceCount is set in the Medium.Id field.

    pHwDevExt->DriverMediumInstanceCount = GlobalDriverMediumInstanceCount++;

    DbgLogInfo(("TestCap: Exit, HwInitialize()\n"));

    pSrb->Status = STATUS_SUCCESS;

    return (TRUE);

}
Exemplo n.º 18
0
VOID
STREAMAPI
AdapterOpenStream (
    PHW_STREAM_REQUEST_BLOCK pSrb
    )
{
    //
    // the stream extension structure is allocated by the stream class driver
    //

    PSTREAMEX               pStrmEx = (PSTREAMEX)pSrb->StreamObject->HwStreamExtension;
    PHW_DEVICE_EXTENSION    pHwDevExt = ((PHW_DEVICE_EXTENSION)pSrb->HwDeviceExtension);
    int                     StreamNumber = pSrb->StreamObject->StreamNumber;
    PKSDATAFORMAT           pKSDataFormat = pSrb->CommandData.OpenFormat;


    RtlZeroMemory(pStrmEx, sizeof(STREAMEX));

    DbgLogInfo(("TestCap: ------- ADAPTEROPENSTREAM ------- 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 >= DRIVER_STREAM_COUNT || StreamNumber < 0) {

        pSrb->Status = STATUS_INVALID_PARAMETER;

        return;
    }

    //
    // Check that we haven't exceeded the instance count for this stream
    //

    if (pHwDevExt->ActualInstances[StreamNumber] >=
        Streams[StreamNumber].hwStreamInfo.NumberOfPossibleInstances) {

        pSrb->Status = STATUS_INVALID_PARAMETER;

        return;
    }

    //
    // Check the validity of the format being requested
    //

    if (!AdapterVerifyFormat (pKSDataFormat, StreamNumber)) {

        pSrb->Status = STATUS_INVALID_PARAMETER;

        return;
    }

    //
    // And set the format for the stream
    //

    if (!VideoSetFormat (pSrb)) {

        return;
    }

    ASSERT (pHwDevExt->pStrmEx [StreamNumber] == NULL);

    // Maintain an array of all the StreamEx structures in the HwDevExt
    // so that we can cancel IRPs from any stream

    pHwDevExt->pStrmEx [StreamNumber] = (PSTREAMX) pStrmEx;

    // Set up pointers to the handlers for the stream data and control handlers

    pSrb->StreamObject->ReceiveDataPacket =
            (PVOID) Streams[StreamNumber].hwStreamObject.ReceiveDataPacket;
    pSrb->StreamObject->ReceiveControlPacket =
            (PVOID) Streams[StreamNumber].hwStreamObject.ReceiveControlPacket;

    //
    // 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.
    //

    pSrb->StreamObject->Dma = Streams[StreamNumber].hwStreamObject.Dma;

    //
    // The PIO flag must be set when the mini driver will be accessing the data
    // buffers passed in using logical addressing
    //

    pSrb->StreamObject->Pio = Streams[StreamNumber].hwStreamObject.Pio;

    //
    // How many extra bytes will be passed up from the driver for each frame?
    //

    pSrb->StreamObject->StreamHeaderMediaSpecific =
                Streams[StreamNumber].hwStreamObject.StreamHeaderMediaSpecific;

    pSrb->StreamObject->StreamHeaderWorkspace =
                Streams[StreamNumber].hwStreamObject.StreamHeaderWorkspace;

    //
    // Indicate the clock support available on this stream
    //

    pSrb->StreamObject->HwClockObject =
                Streams[StreamNumber].hwStreamObject.HwClockObject;

    //
    // Increment the instance count on this stream
    //
    pHwDevExt->ActualInstances[StreamNumber]++;


    // Retain a private copy of the HwDevExt and StreamObject in the stream extension
    // so we can use a timer

    pStrmEx->pHwDevExt = pHwDevExt;                     // For timer use
    pStrmEx->pStreamObject = pSrb->StreamObject;        // For timer use

    // Initialize the compression settings
    // These may have been changed from the default values in the HwDevExt
    // before the stream was opened
    pStrmEx->CompressionSettings.CompressionKeyFrameRate =
        pHwDevExt->CompressionSettings.CompressionKeyFrameRate;
    pStrmEx->CompressionSettings.CompressionPFramesPerKeyFrame =
        pHwDevExt->CompressionSettings.CompressionPFramesPerKeyFrame;
    pStrmEx->CompressionSettings.CompressionQuality =
        pHwDevExt->CompressionSettings.CompressionQuality;

    // Init VideoControl properties
    pStrmEx->VideoControlMode = pHwDevExt->VideoControlMode;

    // Init VBI variables
    pStrmEx->SentVBIInfoHeader = 0;

    DbgLogInfo(("TestCap: AdapterOpenStream Exit\n"));

}
Exemplo n.º 19
0
VOID
STREAMAPI
AdapterReceivePacket(
    IN PHW_STREAM_REQUEST_BLOCK pSrb
    )
{
    PHW_DEVICE_EXTENSION    pHwDevExt = ((PHW_DEVICE_EXTENSION)pSrb->HwDeviceExtension);
    BOOL                    Busy;

    DEBUG_ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL);

    DbgLogTrace(("TestCap: Receiving Adapter  SRB %8x, %x\n", pSrb, pSrb->Command));

    // The very first time through, we need to initialize the adapter spinlock
    // and queue
    if (!pHwDevExt->AdapterQueueInitialized) {
        InitializeListHead (&pHwDevExt->AdapterSRBList);
        KeInitializeSpinLock (&pHwDevExt->AdapterSpinLock);
        pHwDevExt->AdapterQueueInitialized = TRUE;
        pHwDevExt->ProcessingAdapterSRB = FALSE;
    }

    //
    // If we're already processing an SRB, add it to the queue
    //
    Busy = AddToListIfBusy (
                    pSrb,
                    &pHwDevExt->AdapterSpinLock,
                    &pHwDevExt->ProcessingAdapterSRB,
                    &pHwDevExt->AdapterSRBList);

    if (Busy) {
        return;
    }

    //
    // This will run until the queue is empty
    //
    while (TRUE) {
        //
        // Assume success
        //
        pSrb->Status = STATUS_SUCCESS;

        //
        // determine the type of packet.
        //

        switch (pSrb->Command)
        {

        case SRB_INITIALIZE_DEVICE:

            // open the device

            HwInitialize(pSrb);

            break;

        case SRB_UNINITIALIZE_DEVICE:

            // close the device.

            HwUnInitialize(pSrb);

            break;

        case SRB_OPEN_STREAM:

            // open a stream

            AdapterOpenStream(pSrb);

            break;

        case SRB_CLOSE_STREAM:

            // close a stream

            AdapterCloseStream(pSrb);

            break;

        case SRB_GET_STREAM_INFO:

            //
            // return a block describing all the streams
            //

            AdapterStreamInfo(pSrb);

            break;

        case SRB_GET_DATA_INTERSECTION:

            //
            // Return a format, given a range
            //

            AdapterFormatFromRange(pSrb);

            break;

        case SRB_OPEN_DEVICE_INSTANCE:
        case SRB_CLOSE_DEVICE_INSTANCE:

            //
            // We should never get these since this is a single instance device
            //

            TRAP;
            pSrb->Status = STATUS_NOT_IMPLEMENTED;
            break;

        case SRB_GET_DEVICE_PROPERTY:

            //
            // Get adapter wide properties
            //

            AdapterGetProperty (pSrb);
            break;

        case SRB_SET_DEVICE_PROPERTY:

            //
            // Set adapter wide properties
            //

            AdapterSetProperty (pSrb);
            break;

        case SRB_PAGING_OUT_DRIVER:

            //
            // The driver is being paged out
            // Disable Interrupts if you have them!
            //
            DbgLogInfo(("'Testcap: Receiving SRB_PAGING_OUT_DRIVER -- SRB=%x\n", pSrb));
            break;

        case SRB_CHANGE_POWER_STATE:

            //
            // Changing the device power state, D0 ... D3
            //
            DbgLogInfo(("'Testcap: Receiving SRB_CHANGE_POWER_STATE ------ SRB=%x\n", pSrb));
            AdapterPowerState(pSrb);
            break;

        case SRB_INITIALIZATION_COMPLETE:

            //
            // Stream class has finished initialization.
            // Now create DShow Medium interface BLOBs.
            // This needs to be done at low priority since it uses the registry
            //
            DbgLogInfo(("'Testcap: Receiving SRB_INITIALIZATION_COMPLETE-- SRB=%x\n", pSrb));

            break;


        case SRB_UNKNOWN_DEVICE_COMMAND:
        default:

            //
            // this is a request that we do not understand.  Indicate invalid
            // command and complete the request
            //
            pSrb->Status = STATUS_NOT_IMPLEMENTED;

        }

        //
        // Indicate back to the Stream Class that we're done with this SRB
        //
        CompleteDeviceSRB (pSrb);

        //
        // See if there's anything else on the queue
        //
        Busy = RemoveFromListIfAvailable (
                &pSrb,
                &pHwDevExt->AdapterSpinLock,
                &pHwDevExt->ProcessingAdapterSRB,
                &pHwDevExt->AdapterSRBList);

        if (!Busy) {
            break;
        }
    } // end of while there's anything in the queue
}
Exemplo n.º 20
0
VOID
STREAMAPI
AnalogVideoReceiveCtrlPacket(
    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 we are at passive level
    //

    DEBUG_ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL);
    DEBUG_ASSERT(pHwDevExt!=NULL);

    DbgLogTrace(("TestCap: Receiving Analog 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;
    }

    do {
        //
        // 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;
            }
            break;

        case SRB_SET_STREAM_STATE:

            //
            // Don't use VideoSetState, since we don't want to start another
            // timer running
            //

            pStrmEx->KSState = pSrb->CommandData.StreamState;
            DbgLogInfo(("TestCap: STATE=%d, Stream=%d\n", pStrmEx->KSState, StreamNumber));
            break;

        case SRB_GET_STREAM_STATE:

            VideoGetState(pSrb);
            break;

        case SRB_GET_STREAM_PROPERTY:

            VideoGetProperty(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]);

    } while ( Busy );
}
Exemplo n.º 21
0
BOOL
STREAMAPI
AdapterVerifyFormat(
    PKSDATAFORMAT pKSDataFormatToVerify,
    int StreamNumber
    )
{
    BOOL                        fOK = FALSE;
    ULONG                       j;
    ULONG                       NumberOfFormatArrayEntries;
    PKSDATAFORMAT               *pAvailableFormats;


    //
    // Check that the stream number is valid
    //

    if (StreamNumber >= DRIVER_STREAM_COUNT) {
        TRAP;
        return FALSE;
    }

    NumberOfFormatArrayEntries =
            Streams[StreamNumber].hwStreamInfo.NumberOfFormatArrayEntries;

    //
    // Get the pointer to the array of available formats
    //

    pAvailableFormats = Streams[StreamNumber].hwStreamInfo.StreamFormatsArray;


    DbgLogInfo(("TestCap: AdapterVerifyFormat, Stream=%d\n", StreamNumber));
    DbgLogInfo(("TestCap: FormatSize=%d\n",  pKSDataFormatToVerify->FormatSize));
    DbgLogInfo(("TestCap: MajorFormat=%x\n", pKSDataFormatToVerify->MajorFormat));

    //
    // Walk the formats supported by the stream
    //

    for (j = 0; j < NumberOfFormatArrayEntries; j++, pAvailableFormats++) {

        // Check for a match on the three GUIDs and format size

        if (!AdapterCompareGUIDsAndFormatSize(
                        pKSDataFormatToVerify,
                        *pAvailableFormats,
                        FALSE /* CompareFormatSize */ )) {
            continue;
        }

        //
        // Now that the three GUIDs match, switch on the Specifier
        // to do a further type-specific check
        //

        // -------------------------------------------------------------------
        // Specifier FORMAT_VideoInfo for VIDEOINFOHEADER
        // -------------------------------------------------------------------

        if (IsEqualGUID (&pKSDataFormatToVerify->Specifier,
                &KSDATAFORMAT_SPECIFIER_VIDEOINFO)) {

            PKS_DATAFORMAT_VIDEOINFOHEADER  pDataFormatVideoInfoHeader =
                    (PKS_DATAFORMAT_VIDEOINFOHEADER) pKSDataFormatToVerify;
            PKS_VIDEOINFOHEADER  pVideoInfoHdrToVerify =
                     (PKS_VIDEOINFOHEADER) &pDataFormatVideoInfoHeader->VideoInfoHeader;
            PKS_DATARANGE_VIDEO             pKSDataRangeVideo = (PKS_DATARANGE_VIDEO) *pAvailableFormats;
            KS_VIDEO_STREAM_CONFIG_CAPS    *pConfigCaps = &pKSDataRangeVideo->ConfigCaps;
            RECT                            rcImage;

            DbgLogInfo(("TestCap: AdapterVerifyFormat\n"));
            DbgLogInfo(("TestCap: pVideoInfoHdrToVerify=%x\n", pVideoInfoHdrToVerify));
            DbgLogInfo(("TestCap: KS_VIDEOINFOHEADER size=%d\n",
                    KS_SIZE_VIDEOHEADER (pVideoInfoHdrToVerify)));
            DbgLogInfo(("TestCap: Width=%d  Height=%d  BitCount=%d\n",
            pVideoInfoHdrToVerify->bmiHeader.biWidth,
            pVideoInfoHdrToVerify->bmiHeader.biHeight,
            pVideoInfoHdrToVerify->bmiHeader.biBitCount));
            DbgLogInfo(("TestCap: biSizeImage=%d\n",
                pVideoInfoHdrToVerify->bmiHeader.biSizeImage));

            /*
            **  HOW BIG IS THE IMAGE REQUESTED (pseudocode follows)
            **
            **  if (IsRectEmpty (&rcTarget) {
            **      SetRect (&rcImage, 0, 0,
            **              BITMAPINFOHEADER.biWidth,
                            BITMAPINFOHEADER.biHeight);
            **  }
            **  else {
            **      // Probably rendering to a DirectDraw surface,
            **      // where biWidth is used to expressed the "stride"
            **      // in units of pixels (not bytes) of the destination surface.
            **      // Therefore, use rcTarget to get the actual image size
            **
            **      rcImage = rcTarget;
            **  }
            */

            if ((pVideoInfoHdrToVerify->rcTarget.right -
                 pVideoInfoHdrToVerify->rcTarget.left <= 0) ||
                (pVideoInfoHdrToVerify->rcTarget.bottom -
                 pVideoInfoHdrToVerify->rcTarget.top <= 0)) {

                 rcImage.left = rcImage.top = 0;
                 rcImage.right = pVideoInfoHdrToVerify->bmiHeader.biWidth;
                 rcImage.bottom = pVideoInfoHdrToVerify->bmiHeader.biHeight;
            }
            else {
                 rcImage = pVideoInfoHdrToVerify->rcTarget;
            }

            //
            // Perform all other verification tests here!!!
            //

            //
            // HOORAY, the format passed all of the tests, so we support it
            //

            fOK = TRUE;
            break;

        } // End of VIDEOINFOHEADER specifier

        // -------------------------------------------------------------------
        // Specifier FORMAT_AnalogVideo for KS_ANALOGVIDEOINFO
        // -------------------------------------------------------------------

        else if (IsEqualGUID (&pKSDataFormatToVerify->Specifier,
                &KSDATAFORMAT_SPECIFIER_ANALOGVIDEO)) {

            //
            // For analog video, the DataRange and DataFormat
            // are identical, so just copy the whole structure
            //

            PKS_DATARANGE_ANALOGVIDEO DataRangeVideo =
                    (PKS_DATARANGE_ANALOGVIDEO) *pAvailableFormats;

            //
            // Perform all other verification tests here!!!
            //

            fOK = TRUE;
            break;

        } // End of KS_ANALOGVIDEOINFO specifier

        // -------------------------------------------------------------------
        // Specifier FORMAT_VBI for KS_VIDEO_VBI
        // -------------------------------------------------------------------

        else if (IsEqualGUID (&pKSDataFormatToVerify->Specifier,
                &KSDATAFORMAT_SPECIFIER_VBI))
        {
            //
            // Do some VBI-specific tests
            //
            PKS_DATAFORMAT_VBIINFOHEADER    pKSVBIDataFormat;

            DbgLogInfo(("Testcap: This is a VBIINFOHEADER format pin.\n" ));

            pKSVBIDataFormat = (PKS_DATAFORMAT_VBIINFOHEADER)pKSDataFormatToVerify;

            //
            // Check VideoStandard, we only support NTSC_M
            //
            if (KS_AnalogVideo_NTSC_M
                == pKSVBIDataFormat->VBIInfoHeader.VideoStandard)
            {
                fOK = TRUE;
                break;
            }
            else
            {
                DbgLogError(
                ("Testcap: AdapterVerifyFormat : VideoStandard(%d) != NTSC_M\n",
                 pKSVBIDataFormat->VBIInfoHeader.VideoStandard));
            }
        }

        // -------------------------------------------------------------------
        // Type FORMAT_NABTS for NABTS pin
        // -------------------------------------------------------------------

        else if (IsEqualGUID (&pKSDataFormatToVerify->SubFormat,
                &KSDATAFORMAT_SUBTYPE_NABTS))
        {
            fOK = TRUE;
            break;
        }

        // -------------------------------------------------------------------
        // for CC pin
        // -------------------------------------------------------------------

        else if (IsEqualGUID (&pKSDataFormatToVerify->SubFormat,
                &KSDATAFORMAT_SUBTYPE_CC))
        {
            fOK = TRUE;
            break;
        }

    } // End of loop on all formats for this stream

    return fOK;
}