NTSTATUS CCaptureFilter::GetProperty ( IN PIRP irp, IN PKSPROPERTY property, IN OUT PVOID data ) { PAGED_CODE (); NTSTATUS ntStatus = STATUS_UNSUCCESSFUL; ASSERT(irp); ASSERT(property); DBGU_TRACE("Enter CCaptureFilter::GetProperty\n"); // // Get hold of our FilterContext via pIrp // CCaptureFilter *pCaptureFilter = reinterpret_cast<CCaptureFilter *>(KsGetFilterFromIrp(irp)->Context); // // Assert that we have a valid filter context // ASSERT (pCaptureFilter); CCaptureDevice *pCaptureDevice = reinterpret_cast<CCaptureDevice *>(pCaptureFilter->m_Device->Context); ASSERT(pCaptureDevice); if (KSPROPERTY_TYPE_GET & property->Flags) ntStatus = pCaptureDevice->pdx->pVideoStream->GetDeviceProperty(irp, property, data); DBGU_TRACE("Enter CCaptureFilter::GetProperty return =%X\n",ntStatus); return ntStatus; }
NTSTATUS AnlgTunerScanAddEvent( PIRP pIrp, PKSEVENTDATA EventData, PKSEVENT_ENTRY pEventEntry ) { KIRQL OldIrql; NTSTATUS ntStatus = STATUS_SUCCESS; PKSEVENT_TUNER_INITIATE_SCAN_S ScanRequest = reinterpret_cast<PKSEVENT_TUNER_INITIATE_SCAN_S>(EventData); PEventHandlerData EventBlock; ASSERT(pIrp); PKSFILTER pFilter = KsGetFilterFromIrp(pIrp); if (!pFilter) { ntStatus = STATUS_UNSUCCESSFUL; goto error; } PKSDEVICE pDevice = KsFilterGetDevice(pFilter); if (!pDevice) { ntStatus = STATUS_UNSUCCESSFUL; goto error; } if (g_bHardwareAssistedScanning == FALSE) { return STATUS_UNSUCCESSFUL; } CEncoderDevice* pEncDevice = reinterpret_cast<CEncoderDevice *>(pDevice->Context); if (!pEncDevice ) { ntStatus = STATUS_UNSUCCESSFUL; goto error; } DbgPrint("AnlgTunerScanAddEvent enter!begin frenquency is %d,end frenquency is %d\n",ScanRequest -> StartFrequency,ScanRequest -> EndFrequency); if(ScanRequest -> StartFrequency == ScanRequest -> EndFrequency ) { if(pEncDevice->ScanInitialization) { ntStatus = STATUS_UNSUCCESSFUL; goto error; } // go ahead and tune to the frequency; ntStatus = InitializeEventing(pEncDevice); if (!NT_SUCCESS(ntStatus)) goto error; EventBlock = EventHandler; ntStatus = GetStreamLocationFromFrequency(pEncDevice, ScanRequest -> StartFrequency, &pEncDevice->FileName); if(ntStatus != STATUS_SUCCESS) // Found the frequency in the registry...so Just tune to it. { ULONG dwFreq = ( ScanRequest -> StartFrequency / (1000 * 1000) ); // fine tune algorithm .. dwFreq *= 1000000; ntStatus = GetStreamLocationFromFrequency(pEncDevice, dwFreq, &pEncDevice->FileName); if(ntStatus != STATUS_SUCCESS) { pEncDevice->CurrentFrequency = EventBlock->CurrentFrequency = ScanRequest -> StartFrequency; pEncDevice->ScanStatusCode = EventBlock->StatusCode = Tuner_LockType_None; KsGenerateEvent(pEventEntry); ntStatus = STATUS_SUCCESS; goto error; } } KeClearEvent(&(EventBlock->TuneEvent)); EventBlock->IdleTimeout.QuadPart = pEncDevice->SettlingTime / 2; EventBlock->IdleTimeout.QuadPart = EventBlock->IdleTimeout.QuadPart * 1000 * 10; // in 100 nanasecond units KeWaitForSingleObject(&(EventBlock->TuneEvent), Executive, KernelMode, FALSE, &(EventBlock->IdleTimeout)); // in 100 nano second units pEncDevice->CurrentFrequency = EventBlock->CurrentFrequency = ScanRequest -> StartFrequency; pEncDevice->SetFrequency(pEncDevice->CurrentFrequency); pEncDevice->ScanStatusCode = EventBlock->StatusCode = Tuner_LockType_Locked; KsGenerateEvent(pEventEntry); ntStatus = STATUS_SUCCESS; goto error; } else { if (pEncDevice->pScanEvent) { // only one scan operation allowed on a tuner at a time if(EventHandler->ScanData.EventData.EventHandle.Event != ScanRequest->EventData.EventHandle.Event) { DbgPrint("error:EventHandler->ScanData.EventData.EventHandle.Event != ScanRequest->EventData.EventHandle.Event\n"); ntStatus = STATUS_UNSUCCESSFUL; goto error; } else { if(pEncDevice->ScanInitialization) { KeAcquireSpinLock(&pEncDevice->EventHandlerSpinLock, &OldIrql); pEncDevice->pScanEvent = pEventEntry; EventHandler->EventEntry = pEventEntry; // Need to remove one of the references here. memcpy(&(EventHandler->ScanData),ScanRequest, sizeof(KSEVENT_TUNER_INITIATE_SCAN_S)); pEncDevice->CurrentFrequency = EventHandler->CurrentFrequency = ScanRequest->StartFrequency; pEncDevice->ScanStatusCode = EventHandler->StatusCode = Tuner_LockType_None; KeReleaseSpinLock(&pEncDevice->EventHandlerSpinLock, OldIrql); LARGE_INTEGER Timeout; Timeout.QuadPart = (-1) * EventHandler->IdleTimeout.QuadPart; KeSetTimerEx (&(EventHandler->timer), Timeout, NULL, &(EventHandler->DPCObject)); DbgPrint("AnlgTunerScanAddEvent restart scan at Frequency %d",EventHandler->CurrentFrequency); ntStatus = STATUS_SUCCESS; goto error; } } } else { KeAcquireSpinLock(&pEncDevice->EventHandlerSpinLock, &OldIrql); pEncDevice->pScanEvent = pEventEntry; KeReleaseSpinLock(&pEncDevice->EventHandlerSpinLock, OldIrql); ULONG ulTimeout=0; LARGE_INTEGER WaitForThread; WaitForThread.QuadPart = -10000; while (EventHandler != NULL) { DbgPrint("AnlgTunerScanAddEvent waiting for previous scan to end"); ulTimeout++; KeWaitForSingleObject(pEncDevice->pScanEvent, Executive, KernelMode, FALSE, &WaitForThread);//wait for the thread to end if (ulTimeout > 1000)//one second { ntStatus = STATUS_UNSUCCESSFUL; goto error; } } } if (!NT_SUCCESS(ntStatus)) goto error; // use a separate thread to do the actual scan. PEventHandlerData EventBlock; NTSTATUS WaitStatus; ntStatus = InitializeEventing(pEncDevice); if ((!NT_SUCCESS(ntStatus)) || (EventHandler == NULL)) goto error; EventBlock = EventHandler; KeAcquireSpinLock(&(EventBlock->LockAccess), &OldIrql); memcpy(&(EventBlock->ScanData),ScanRequest, sizeof(KSEVENT_TUNER_INITIATE_SCAN_S)); pEncDevice->CurrentFrequency = EventHandler->CurrentFrequency = ScanRequest->StartFrequency; if(EventBlock->ScanData.EndFrequency < EventBlock->ScanData.StartFrequency) { ULONG temp; temp = EventBlock->ScanData.EndFrequency; EventBlock->ScanData.EndFrequency= EventBlock->ScanData.StartFrequency; EventBlock->ScanData.StartFrequency = temp; } pEncDevice->FreqRange = ScanRequest->EndFrequency - ScanRequest->StartFrequency; EventBlock->EventEntry = pEventEntry; EventBlock->IdleTimeout.QuadPart = pEncDevice->SettlingTime * 1000 * 10; // in 100 nanosecond units; EventBlock->bStopScan = FALSE; EventBlock->pDevice = pEncDevice; pEncDevice->ScanStatusCode = EventBlock->StatusCode = Tuner_LockType_None; KeReleaseSpinLock(&(EventBlock->LockAccess), OldIrql); // worker thread item for reads EventBlock->ThreadItem=IoAllocateWorkItem(pDevice->PhysicalDeviceObject); IoQueueWorkItem(EventBlock->ThreadItem, TunerScanWorkItem, CriticalWorkQueue, EventBlock); pEncDevice->ScanInitialization = TRUE; WaitStatus = KeWaitForSingleObject(&(EventBlock->InitEvent), Executive, KernelMode, FALSE, NULL); if (!NT_SUCCESS(WaitStatus)) { ntStatus = STATUS_UNSUCCESSFUL; goto error; } } // remove handler wont be called for this particular pEventEntry // till KsDefaultAddEventHandler returns. So pEventEntry is "safe" ntStatus = KsDefaultAddEventHandler(pIrp, reinterpret_cast<PKSEVENTDATA>(ScanRequest), pEventEntry); error: DbgPrint("AnlgTunerScanAddEvent return -- code is %d",ntStatus); pIrp->IoStatus.Status = ntStatus; return ntStatus; }
NTSTATUS XBarRouteHandler ( IN PIRP pIrp, IN PKSPROPERTY_CROSSBAR_ROUTE_S pRequest, IN OUT PKSPROPERTY_CROSSBAR_ROUTE_S pData ) { NTSTATUS Status = STATUS_UNSUCCESSFUL; if ((!pData) || (!pRequest) || (!pIrp)) { return Status; } PKSFILTER pFilter = KsGetFilterFromIrp(pIrp); PKSDEVICE pDevice = KsFilterGetDevice(pFilter); if (!pDevice) { return Status; } CEncoderDevice* pEncDevice = reinterpret_cast<CEncoderDevice *>(pDevice->Context); if(!pEncDevice) return Status; if(pRequest->Property.Flags == KSPROPERTY_TYPE_SET) { Status = STATUS_SUCCESS; if ((0 == pRequest->IndexOutputPin) && (pRequest->IndexInputPin == 0)) //switch to tuner { DbgPrint( "MY-XBarRouteHandler switch Video to Tuner\n"); if ((pEncDevice->CurrentFrequency) && (pEncDevice->CurrentInput != 0)) { pEncDevice->SetFrequency(pEncDevice->CurrentFrequency);//restore the previously used frequency } pEncDevice->CurrentInput = 0; } else if ((1 == pRequest->IndexOutputPin) && (pRequest->IndexInputPin == 1)) //switch to tuner { DbgPrint( "MY-XBarRouteHandler switch Audio to Tuner\n"); } else if ((0 == pRequest->IndexOutputPin) && (pRequest->IndexInputPin == 2)) //switch to Composite { DbgPrint( "MY-XBarRouteHandler switch Video to Composite\n"); if (pEncDevice->CurrentInput == 0) { pEncDevice->GetFrequency(&pEncDevice->CurrentFrequency); } pEncDevice->CurrentInput = 1; pEncDevice->SetFrequency(pEncDevice->CurrentInput * 1000);//map to 1 khz } else if ((1 == pRequest->IndexOutputPin) && (pRequest->IndexInputPin == 3)) //switch to Composite { DbgPrint( "MY-XBarRouteHandler switch Audio to Composite\n"); } else if ((0 == pRequest->IndexOutputPin) && (pRequest->IndexInputPin == 4)) //switch to S-Video { DbgPrint( "MY-XBarRouteHandler switch Video to S-Video\n"); if (pEncDevice->CurrentInput == 0) { pEncDevice->GetFrequency(&pEncDevice->CurrentFrequency); } pEncDevice->CurrentInput = 2; pEncDevice->SetFrequency(pEncDevice->CurrentInput * 1000);//map to 2 khz } else if ((1 == pRequest->IndexOutputPin) && (pRequest->IndexInputPin == 5)) //switch to S-Video { DbgPrint( "MY-XBarRouteHandler switch Audio to S-Video\n"); } else { Status = STATUS_UNSUCCESSFUL; } } else //get the routing information { pData->CanRoute = 0; if (0 == pRequest->IndexOutputPin)//video out { pData->IndexInputPin = pEncDevice->CurrentInput * 2;//return the current Video input pData->IndexOutputPin = 0; pData->CanRoute = 1; Status = STATUS_SUCCESS; } else if (1 == pRequest->IndexOutputPin)//audio out { pData->IndexInputPin = pEncDevice->CurrentInput * 2 + 1;//return the current Audio input pData->IndexOutputPin = 1; pData->CanRoute = 1; Status = STATUS_SUCCESS; } //DbgPrint( "MY-XBarRouteHandler Get return Input=%d Output=%d CanRoute=%d\n", pData->IndexInputPin,pData->IndexOutputPin,pData->CanRoute ); } return Status; }