LEADTOOLS Multimedia API Help > Programming with LEADTOOLS Multimedia > C Code > Capture to Play Object Interfacing for C |
The following code demonstrates grabbing samples from the capture object and feeding them to the play object. It is intended to demonstrate the basic function set that would be required to remote the playback of media samples.
// define helper macros for using interfaces under C #ifndef COBJMACROS #define COBJMACROS #endif // include the LEAD Multimedia TOOLKIT header #include "ltmm.h" #include <tchar.h> #include <stdio.h> #include <math.h> #include <assert.h> #define UNUSED_PARAMETER(x) (void) (x) #define SZ_WNDCLASS_PLAY _T("PLAY WNDCLASS") #define WM_PLAYNOTIFY (WM_USER + 1000) HINSTANCE g_hInstance; // application instance handle HWND g_hwndPlay; // video frame window IltmmPlay* g_pPlay; // play object interface pointer IltmmCapture* g_pCapture; // capture object interface pointer IltmmSampleTarget* g_pTarget; // target object, used with capture IltmmSampleSource* g_pSource; // source object, used with play // // PlayWndProc // video frame window procedure // LRESULT CALLBACK PlayWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { case WM_CREATE: g_hwndPlay = hwnd; // window is the video window frame IltmmPlay_put_VideoWindowFrame(g_pPlay, (long) hwnd); // assign the media source IltmmPlay_put_SourceObject(g_pPlay, (IUnknown*) g_pSource); #ifdef _DEBUG { IUnknown* punk; IltmmPlay_get_SourceObject(g_pPlay, &punk); assert(punk != NULL); if(punk) IUnknown_Release(punk); } #endif return 0; break; case WM_DESTROY: PostQuitMessage(0); break; } return DefWindowProc(hwnd, message, wParam, lParam); } int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { MSG msg; HRESULT hr; WNDCLASSEX wcex; IltmmDevices* pDevices; VARIANT var; IltmmMediaTypeDisp* pMediaType; BSTR bstr; long index; IltmmCompressors* pCompressors; UNUSED_PARAMETER(lpCmdLine); UNUSED_PARAMETER(hPrevInstance); g_hInstance = hInstance; // initialize COM library hr = CoInitialize(NULL); if(FAILED(hr)) goto error; // register the video frame window class wcex.cbSize = sizeof(WNDCLASSEX); wcex.style = CS_HREDRAW | CS_VREDRAW; wcex.lpfnWndProc = PlayWndProc; wcex.cbClsExtra = 0; wcex.cbWndExtra = 0; wcex.hInstance = g_hInstance; wcex.hIcon = NULL; wcex.hCursor = LoadCursor(NULL, IDC_ARROW); wcex.hbrBackground = (HBRUSH) (COLOR_APPWORKSPACE + 1); wcex.lpszMenuName = NULL; wcex.lpszClassName = SZ_WNDCLASS_PLAY; wcex.hIconSm = NULL; if(!RegisterClassEx(&wcex)) goto error; // create the play object hr = CoCreateInstance(&CLSID_ltmmPlay, NULL, CLSCTX_INPROC_SERVER, &IID_IltmmPlay, (void**) &g_pPlay); if(FAILED(hr)) goto error; // create the capture object hr = CoCreateInstance(&CLSID_ltmmCapture, NULL, CLSCTX_INPROC_SERVER, &IID_IltmmCapture, (void**) &g_pCapture); if(FAILED(hr)) goto error; // create the target object hr = CoCreateInstance(&CLSID_ltmmSampleTarget, NULL, CLSCTX_INPROC_SERVER, &IID_IltmmSampleTarget, (void**) &g_pTarget); if(FAILED(hr)) goto error; // create the source object hr = CoCreateInstance(&CLSID_ltmmSampleSource, NULL, CLSCTX_INPROC_SERVER, &IID_IltmmSampleSource, (void**) &g_pSource); if(FAILED(hr)) goto error; // no preview IltmmCapture_put_Preview(g_pCapture, VARIANT_FALSE); // select the first video device IltmmCapture_get_VideoDevices(g_pCapture, &pDevices); IltmmDevices_put_Selection(pDevices, 0); IUnknown_Release(pDevices); // select the LEAD video compressor IltmmCapture_get_VideoCompressors(g_pCapture, &pCompressors); bstr = SysAllocString(L"@device:sw:{33D9A760-90C8-11D0-BD43-00A0C911CE86}\\LEAD MCMP/MJPEG Codec (2.0)"); IltmmCompressors_Find(pCompressors, bstr, &index); SysFreeString(bstr); IltmmCompressors_put_Selection(pCompressors, index); IUnknown_Release(pCompressors); // set the capture output object IltmmCapture_put_TargetObject(g_pCapture, (IUnknown*) g_pTarget); #ifdef _DEBUG { IUnknown* punk; IltmmCapture_get_TargetObject(g_pCapture, &punk); assert(punk != NULL); if(punk) IUnknown_Release(punk); } #endif // start running hr = IltmmCapture_StartCapture(g_pCapture, ltmmCapture_Mode_Video); if(FAILED(hr)) goto error; // retirve the video media type IltmmSampleTarget_GetConnectedMediaType(g_pTarget, &pMediaType); // could just assign the media type to the source object, // but let's get the portable type instead IltmmMediaTypeDisp_GetPortableType(pMediaType, &var); // have the portable type, don't need this anymore IUnknown_Release(pMediaType); // create a new media type CoCreateInstance(&CLSID_ltmmMediaType, NULL, CLSCTX_INPROC_SERVER, &IID_IltmmMediaTypeDisp, (void**) &pMediaType); // initialize it with the portable type IltmmMediaTypeDisp_SetPortableType(pMediaType, var); // assign it to the source object IltmmSampleSource_SetMediaType(g_pSource, pMediaType); #ifdef _DEBUG { IltmmMediaTypeDisp* punk; IltmmSampleSource_GetMediaType(g_pSource, &punk); assert(punk != NULL); if(punk) IUnknown_Release(punk); } #endif // release the media type IUnknown_Release(pMediaType); // done with portable type VariantClear(&var); // create the video frame window if(!CreateWindow(SZ_WNDCLASS_PLAY, _T("Play"), WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN, CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, g_hInstance, NULL)) goto error; ShowWindow(g_hwndPlay, nCmdShow); UpdateWindow(g_hwndPlay); // process until done for(;;) { if(PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE)) { if(!GetMessage(&msg, NULL, 0, 0)) break; TranslateMessage(&msg); DispatchMessage(&msg); } else { IltmmMediaSampleDisp* pSample; // fetch a sample hr = IltmmSampleTarget_GetSample(g_pTarget, 1000, &pSample); if(FAILED(hr)) break; // deliver it hr = IltmmSampleSource_DeliverSample(g_pSource, 1000, pSample); IUnknown_Release(pSample); if(FAILED(hr)) goto error; } } IltmmCapture_StopCapture(g_pCapture); IltmmSampleSource_DeliverEndOfStream(g_pSource, 1000); IltmmPlay_Stop(g_pPlay); error: if(g_pSource) IUnknown_Release(g_pSource); if(g_pTarget) IUnknown_Release(g_pTarget); if(g_pCapture) IUnknown_Release(g_pCapture); if(g_pPlay) IUnknown_Release(g_pPlay); CoUninitialize(); return 0; }