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

  

Copyright (C) GeekPage.JP. All rights reserved.