TV Tuner Control (2)
This page shows you how to use control a TV tuner device using IAMTVTuner. Please note that error handling codes are omitted to keep the sample code simple.
Sample code
This sample code simply tries to get a IAMTVTuner interface from the first found capture device. If IAMTVTuner inteface can not be obtained, this sample will simply exit. If the IAMTVTuner is found, this sample tunes to channel 10, and starts playing the video using the TV tuner. You can change the channel number being used by changing the value "10" used by put_Channel. Please change the channel number into a suitable number.
#include <stdio.h>
#include <dshow.h>
int
main()
{
IGraphBuilder *pGraphBuilder;
ICaptureGraphBuilder2 *pCaptureGraphBuilder2;
ICreateDevEnum *pCreateDevEnum = NULL;
IEnumMoniker *pEnumMoniker = NULL;
IMoniker *pMoniker = NULL;
ULONG nFetched = 0;
IBaseFilter *pDeviceFilter;
// initialize COM
CoInitialize(NULL);
// create FilterGraph
CoCreateInstance(CLSID_FilterGraph,
NULL,
CLSCTX_INPROC,
IID_IGraphBuilder,
(LPVOID *)&pGraphBuilder);
// create CaptureGraphBuilder2
CoCreateInstance(CLSID_CaptureGraphBuilder2, NULL, CLSCTX_INPROC,
IID_ICaptureGraphBuilder2,
(LPVOID *)&pCaptureGraphBuilder2);
// set FilterGraph
pCaptureGraphBuilder2->SetFiltergraph(pGraphBuilder);
// create CreateDevEnum to list device
CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER,
IID_ICreateDevEnum, (PVOID *)&pCreateDevEnum);
// create EnumMoniker to list VideoInputDevice
pCreateDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory,
&pEnumMoniker, 0);
if (pEnumMoniker == NULL) {
// this will be shown if there is no capture device
printf("no device\n");
return 0;
}
// reset EnumMoniker
pEnumMoniker->Reset();
// get the first Moniker
pEnumMoniker->Next(1, &pMoniker, &nFetched);
// bind Monkier to Filter
pMoniker->BindToObject(0, 0, IID_IBaseFilter, (void**)&pDeviceFilter );
// add device filter to FilterGraph
pGraphBuilder->AddFilter(pDeviceFilter, L"Device Filter");
// Monkier and Enumerator can be freed now
pMoniker->Release();
pEnumMoniker->Release();
pCreateDevEnum->Release();
/*
* IAMTVTuner
*/
HRESULT hr;
IAMTVTuner *pTvTuner;
// Get IAMTVTuner from Graph.
// If there are more than 1 TV Tuner devices,
// you will need to use FindInterface again.
hr = pCaptureGraphBuilder2->FindInterface(&LOOK_UPSTREAM_ONLY,
NULL, pDeviceFilter,
IID_IAMTVTuner, (LPVOID *)&pTvTuner);
if (hr != S_OK) {
printf("could not get TV Tuner\n");
return 1;
}
// Build Graph
pCaptureGraphBuilder2->RenderStream(&PIN_CATEGORY_CAPTURE,
NULL, pDeviceFilter, NULL, NULL);
// get IMediaControl to Run Graph
IMediaControl *pMediaControl;
pGraphBuilder->QueryInterface(IID_IMediaControl,
(LPVOID *)&pMediaControl);
// Set the channel to 10
pTvTuner->put_Channel(10,
AMTUNER_SUBCHAN_DEFAULT, AMTUNER_SUBCHAN_DEFAULT);
// Start playing
pMediaControl->Run();
// Block execution using MessageBox
// The video will be played until the OK is pressed
MessageBox(NULL, "Press OK to end", "block", MB_OK);
// stop playing
pMediaControl->Stop();
// release
pTvTuner->Release();
pMediaControl->Release();
pCaptureGraphBuilder2->Release();
pGraphBuilder->Release();
// finalize COM
CoUninitialize();
return 0;
}
The MessageBox used in this sample is to block the execution of the main thread. The background thread that is playing video will continue until the "OK" button is pressed. This sample application will end when the "OK" button is pressed.
Please note that this sample only tries to retrive the IAMTVTuner interface from the first capture device found. If you want to know how to handle multiple capture devices, please see "Selecting and playing from a video input device".