Advanced Capture Application for C
The following code demonstrates an advanced capture application. It utilizes most of the functions available in the ltmmCapture object.
// define helper macros for using interfaces under C
The following code demonstrates an advanced capture application. It utilizes most of the functions available in the ltmmCapture object.
// define helper macros for using interfaces under C #ifndef COBJMACROS #define COBJMACROS #endif #define UNUSED_PARAMETER(x) (void) (x) // include the LEAD Multimedia TOOLKIT header #include "ltmm.h" #include "resource.h" #include <tchar.h> #include <stdio.h> #include <olectl.h> #include <math.h> #include <assert.h> #define SZ_WNDCLASS_CAPTURE _T("CAPTURE WNDCLASS") #define WM_CAPTURENOTIFY (WM_USER + 1000) HINSTANCE g_hInstance; // application instance handle HWND g_hwndCapture; // video frame window IltmmCapture* g_pCapture; // capture object interface pointer // // FreeTarget // resets target and free asssociated resources // void FreeTarget(void) { long type; VARIANT var; IltmmCapture_get_TargetType(g_pCapture, &type); if(type == ltmmCapture_Target_Array) { IltmmCapture_get_TargetArray(g_pCapture, &var); IltmmCapture_ResetTarget(g_pCapture); VariantClear(&var); } else { IltmmCapture_ResetTarget (g_pCapture); } } // // SnapFrameToVideo // resizes the frame window to match the video width and height // void SnapFrameToVideo(void) { HWND hwnd; RECT rcWindow, rcClient; long cx, cy; // get the frame window IltmmCapture_get_VideoWindowFrame(g_pCapture, (long*) &hwnd); // get the video dimensions IltmmCapture_get_VideoWidth(g_pCapture, &cx); IltmmCapture_get_VideoHeight(g_pCapture, &cy); // adjust by the border dimensions GetWindowRect(hwnd, &rcWindow); GetClientRect(hwnd, &rcClient); cx += ((rcWindow.right - rcWindow.left) - (rcClient.right - rcClient.left)); cy += ((rcWindow.bottom - rcWindow.top) - (rcClient.bottom - rcClient.top)); // resize the window SetWindowPos(hwnd, NULL, 0, 0, cx, cy, SWP_NOMOVE | SWP_NOZORDER); } // // CaptureWndProc // video frame window procedure // LRESULT CALLBACK CaptureWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { VARIANT_BOOL f; HRESULT hr; HGLOBAL hDIB; IPictureDisp* pPictureDisp; BSTR bstr; IltmmDevices* pDevices; IltmmTargetDevices* pTargetDevices; long index; IltmmCompressors* pCompressors; long l; long l2; BOOL fActive; ltmmSizeMode sm; TCHAR sz[2048]; LPTSTR p; double d; VARIANT var; long x, y, cx, cy; RECT rc; POINT pt; IltmmVCRControl* pVCR; switch (message) { case WM_CREATE: g_hwndCapture = hwnd; // window is the video window frame IltmmCapture_put_VideoWindowFrame(g_pCapture, (long) hwnd); // want notification messages as well IltmmCapture_SetNotifyWindow(g_pCapture, (long) hwnd, WM_CAPTURENOTIFY); // set preview source video only IltmmCapture_put_PreviewSource(g_pCapture, ltmmCapture_Preview_Video); // enable preview IltmmCapture_put_Preview(g_pCapture, VARIANT_TRUE); // disable close captioning IltmmCapture_put_CloseCaptioning(g_pCapture, VARIANT_FALSE); // assign initial frame delay IltmmCapture_put_FrameDelay(g_pCapture, 1.0); // assign a target file bstr = SysAllocString(L"c:\\target.avi"); IltmmCapture_put_TargetFile(g_pCapture, bstr); SysFreeString(bstr); // 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); if(index >= 0) IltmmCompressors_put_Selection(pCompressors, index); IUnknown_Release(pCompressors); // select the MP3 audio video compressor IltmmCapture_get_AudioCompressors(g_pCapture, &pCompressors); bstr = SysAllocString(L"@device:cm:{33D9A761-90C8-11D0-BD43-00A0C911CE86}\\85MPEG Layer-3"); IltmmCompressors_Find(pCompressors, bstr, &index); SysFreeString(bstr); if(index >= 0) IltmmCompressors_put_Selection(pCompressors, index); IUnknown_Release(pCompressors); // target format is AVI IltmmCapture_put_TargetFormat(g_pCapture, ltmmCapture_TargetFormat_Avi); // preallocate file to 10 MB IltmmCapture_AllocTarget(g_pCapture, 10); // select the first audio device available IltmmCapture_get_AudioDevices(g_pCapture, &pDevices); IltmmDevices_put_Selection(pDevices, 0); IUnknown_Release(pDevices); // select the first video device available IltmmCapture_get_VideoDevices(g_pCapture, &pDevices); IltmmDevices_put_Selection(pDevices, 0); IUnknown_Release(pDevices); SnapFrameToVideo(); return 0; break; case WM_CAPTURENOTIFY: switch(wParam) { case ltmmCapture_Notify_Started: _stprintf(sz, _T("Started")); SetWindowText(hwnd, sz); break; case ltmmCapture_Notify_Complete: // stop recording, if vcr output IltmmCapture_get_TargetVCRControl(g_pCapture, &pVCR); IltmmVCRControl_Stop(pVCR); IUnknown_Release(pVCR); IltmmCapture_get_Mode(g_pCapture, &l); if(l == ltmmCapture_Mode_Still) { _stprintf(sz, _T("Complete - [still]")); } else { IltmmCapture_get_TargetType(g_pCapture, &l); if(l == ltmmCapture_Target_Array) { _stprintf(sz, _T("Complete - [array]")); } else if(l == ltmmCapture_Target_Device) { _stprintf(sz, _T("Complete - [device]")); } else { IltmmCapture_get_TargetFile(g_pCapture, &bstr); _stprintf(sz, _T("Complete - [%ls]"), bstr); SysFreeString(bstr); } } SetWindowText(hwnd, sz); break; case ltmmCapture_Notify_ErrorAbort: // stop recording, if vcr output IltmmCapture_get_TargetVCRControl(g_pCapture, &pVCR); IltmmVCRControl_Stop (pVCR); IUnknown_Release(pVCR); _stprintf(sz, _T("Error 0x%.8X. Capture stopped."), lParam); MessageBox(hwnd, sz, _T("Play"), MB_ICONEXCLAMATION | MB_OK); break; case ltmmCapture_Notify_Progress: p = sz; *p = _T('\0'); hr = IltmmCapture_get_NumDropped(g_pCapture, &l); if(SUCCEEDED(hr)) { if(p != sz) p += _stprintf(p, _T(", ")); p += _stprintf(p, _T("Dropped: %d"), l); } hr = IltmmCapture_get_NumNotDropped(g_pCapture, &l); if(SUCCEEDED(hr)) { if(p != sz) p += _stprintf(p, _T(", ")); p += _stprintf(p, _T("Not Dropped: %d"), l); } hr = IltmmCapture_get_AverageFrameSize(g_pCapture, &l); if(SUCCEEDED(hr)) { if(p != sz) p += _stprintf(p, _T(", ")); p += _stprintf(p, _T("Frame Size: %d"), l); } IltmmCapture_get_Mode(g_pCapture, &l); if(l != ltmmCapture_Mode_Still || l != ltmmCapture_Mode_ManualFrames) { // only display the capture time for free running captures hr = IltmmCapture_get_CaptureTime(g_pCapture, &d); if(SUCCEEDED(hr)) { if(p != sz) p += _stprintf(p, _T(", ")); p += _stprintf(p, _T("Time: %f"), d); } } SetWindowText(hwnd, sz); break; } return 0; break; case WM_KEYDOWN: if(wParam == VK_ESCAPE) { // if fullscreen mode then exit it IltmmCapture_get_FullScreenMode(g_pCapture, &f); if(f) { IltmmCapture_put_FullScreenMode(g_pCapture, VARIANT_FALSE); return 0; } } break; case WM_DESTROY: // no more notifications FreeTarget(); IltmmCapture_SetNotifyWindow(g_pCapture, (long) NULL, 0); PostQuitMessage(0); break; case WM_INITMENUPOPUP: if(GetSubMenu(GetMenu(hwnd), 0) == (HMENU)wParam) { // determine whether the object is active IltmmCapture_get_State(g_pCapture, &l); fActive = (l == ltmmCapture_State_Pending || l == ltmmCapture_State_Running || l == ltmmCapture_State_Paused); // enable stop if active EnableMenuItem((HMENU) wParam, ID_CONTROL_STOPCAPTURE, fActive ? MF_ENABLED : MF_GRAYED); // enable run if paused EnableMenuItem((HMENU) wParam, ID_CONTROL_RUN, (l == ltmmCapture_State_Paused) ? MF_ENABLED : MF_GRAYED); // enable pause if running or pending EnableMenuItem((HMENU) wParam, ID_CONTROL_PAUSE, (l == ltmmCapture_State_Paused || l == ltmmCapture_State_Pending) ? MF_ENABLED : MF_GRAYED); // determine if capture properties are available IltmmCapture_HasDialog(g_pCapture, ltmmCapture_Dlg_Capture, &f); EnableMenuItem((HMENU) wParam, ID_CONTROL_CAPTUREPROPERTIES, (!fActive && f) ? MF_ENABLED : MF_GRAYED); // can perform normal capture? IltmmCapture_IsModeAvailable(g_pCapture, ltmmCapture_Mode_VideoOrAudio, &f); EnableMenuItem((HMENU) wParam, ID_CONTROL_STARTCAPTURE, f ? MF_ENABLED : MF_GRAYED); // can perform auto frame capture? IltmmCapture_IsModeAvailable(g_pCapture, ltmmCapture_Mode_AutoFrames, &f); EnableMenuItem((HMENU) wParam, ID_CONTROL_CAPTUREAUTOFRAMES, f ? MF_ENABLED : MF_GRAYED); // can perform manual frame capture? IltmmCapture_IsModeAvailable(g_pCapture, ltmmCapture_Mode_ManualFrames, &f); EnableMenuItem((HMENU) wParam, ID_CONTROL_CAPTUREMANUALFRAMES, f ? MF_ENABLED : MF_GRAYED); // can perform still image capture? IltmmCapture_IsModeAvailable(g_pCapture, ltmmCapture_Mode_Still, &f); EnableMenuItem((HMENU) wParam, ID_CONTROL_CAPTUREDIB, f ? MF_ENABLED : MF_GRAYED); EnableMenuItem((HMENU) wParam, ID_CONTROL_CAPTUREPICTURE, f ? MF_ENABLED : MF_GRAYED); EnableMenuItem((HMENU) wParam, ID_CONTROL_GETSTILLDIB, f ? MF_ENABLED : MF_GRAYED); EnableMenuItem((HMENU) wParam, ID_CONTROL_GETSTILLPICTURE, f ? MF_ENABLED : MF_GRAYED); // check the current video size mode IltmmCapture_get_VideoWindowSizeMode(g_pCapture, &sm); CheckMenuItem((HMENU) wParam, ID_CONTROL_FITTOWINDOW, (sm == ltmmFit) ? MF_CHECKED : MF_UNCHECKED); CheckMenuItem((HMENU) wParam, ID_CONTROL_STRETCHTOWINDOW, (sm == ltmmStretch) ? MF_CHECKED : MF_UNCHECKED); // check preview IltmmCapture_get_Preview(g_pCapture, &f); CheckMenuItem((HMENU) wParam, ID_CONTROL_PREVIEW, f ? MF_CHECKED : MF_UNCHECKED); EnableMenuItem((HMENU) wParam, ID_CONTROL_PREVIEW, !fActive ? MF_ENABLED : MF_GRAYED); // check preview audio IltmmCapture_get_PreviewSource(g_pCapture, &l); CheckMenuItem((HMENU) wParam, ID_CONTROL_PREVIEWVIDEOANDAUDIO, (l == ltmmCapture_Preview_VideoAndAudio) ? MF_CHECKED : MF_UNCHECKED); EnableMenuItem((HMENU) wParam, ID_CONTROL_PREVIEWVIDEOANDAUDIO, !fActive ? MF_ENABLED : MF_GRAYED); // check close captioning IltmmCapture_get_CloseCaptioning(g_pCapture, &f); CheckMenuItem((HMENU) wParam, ID_CONTROL_CLOSECAPTIONING, f ? MF_CHECKED : MF_UNCHECKED); IltmmCapture_get_CloseCaptionAvailable(g_pCapture, &f); EnableMenuItem((HMENU) wParam, ID_CONTROL_CLOSECAPTIONING, (!fActive && f) ? MF_ENABLED : MF_GRAYED); // check master stream IltmmCapture_get_MasterStream(g_pCapture, &l); CheckMenuItem((HMENU) wParam, ID_CONTROL_MASTERSTREAM_NONE, (l == ltmmCapture_MasterStream_None) ? MF_CHECKED : MF_UNCHECKED); CheckMenuItem((HMENU) wParam, ID_CONTROL_MASTERSTREAM_AUDIO, (l == ltmmCapture_MasterStream_Audio) ? MF_CHECKED : MF_UNCHECKED); CheckMenuItem((HMENU) wParam, ID_CONTROL_MASTERSTREAM_VIDEO, (l == ltmmCapture_MasterStream_Video) ? MF_CHECKED : MF_UNCHECKED); EnableMenuItem((HMENU) wParam, ID_CONTROL_MASTERSTREAM_NONE, (!fActive) ? MF_ENABLED : MF_GRAYED); EnableMenuItem((HMENU) wParam, ID_CONTROL_MASTERSTREAM_AUDIO, (!fActive) ? MF_ENABLED : MF_GRAYED); EnableMenuItem((HMENU) wParam, ID_CONTROL_MASTERSTREAM_VIDEO, (!fActive) ? MF_ENABLED : MF_GRAYED); // check frame rate IltmmCapture_get_UseFrameRate(g_pCapture, &f); IltmmCapture_get_FrameRate(g_pCapture, &d); CheckMenuItem((HMENU) wParam, ID_CONTROL_FRAMERATE_DEFAULT, (!f) ? MF_CHECKED : MF_UNCHECKED); CheckMenuItem((HMENU) wParam, ID_CONTROL_FRAMERATE_15FPS, (f && fabs(d - 15.0) < 0.1) ? MF_CHECKED : MF_UNCHECKED); CheckMenuItem((HMENU) wParam, ID_CONTROL_FRAMERATE_30FPS, (f && fabs(d - 30.0) < 0.1) ? MF_CHECKED : MF_UNCHECKED); EnableMenuItem((HMENU) wParam, ID_CONTROL_FRAMERATE_DEFAULT, (!fActive) ? MF_ENABLED : MF_GRAYED); EnableMenuItem((HMENU) wParam, ID_CONTROL_FRAMERATE_15FPS, (!fActive) ? MF_ENABLED : MF_GRAYED); EnableMenuItem((HMENU) wParam, ID_CONTROL_FRAMERATE_30FPS, (!fActive) ? MF_ENABLED : MF_GRAYED); // check time limit IltmmCapture_get_UseTimeLimit(g_pCapture, &f); IltmmCapture_get_TimeLimit(g_pCapture, &d); CheckMenuItem((HMENU) wParam, ID_CONTROL_TIMELIMIT_NONE, (!f) ? MF_CHECKED : MF_UNCHECKED); CheckMenuItem((HMENU) wParam, ID_CONTROL_TIMELIMIT_15SEC, (f && fabs(d - 15.0) < 0.1) ? MF_CHECKED : MF_UNCHECKED); CheckMenuItem((HMENU) wParam, ID_CONTROL_TIMELIMIT_30SEC, (f && fabs(d - 30.0) < 0.1) ? MF_CHECKED : MF_UNCHECKED); EnableMenuItem((HMENU) wParam, ID_CONTROL_TIMELIMIT_NONE, (!fActive) ? MF_ENABLED : MF_GRAYED); EnableMenuItem((HMENU) wParam, ID_CONTROL_TIMELIMIT_15SEC, (!fActive) ? MF_ENABLED : MF_GRAYED); EnableMenuItem((HMENU) wParam, ID_CONTROL_TIMELIMIT_30SEC, (!fActive) ? MF_ENABLED : MF_GRAYED); // check frame delay IltmmCapture_get_FrameDelay(g_pCapture, &d); CheckMenuItem((HMENU) wParam, ID_CONTROL_FRAMEDELAY_1SEC, (fabs(d - 1.0) < 0.1) ? MF_CHECKED : MF_UNCHECKED); CheckMenuItem((HMENU) wParam, ID_CONTROL_FRAMEDELAY_5SEC, (fabs(d - 5.0) < 0.1) ? MF_CHECKED : MF_UNCHECKED); EnableMenuItem((HMENU) wParam, ID_CONTROL_FRAMEDELAY_1SEC, (!fActive) ? MF_ENABLED : MF_GRAYED); EnableMenuItem((HMENU) wParam, ID_CONTROL_FRAMEDELAY_5SEC, (!fActive) ? MF_ENABLED : MF_GRAYED); // check target IltmmCapture_get_TargetType(g_pCapture, &l); CheckMenuItem((HMENU) wParam, ID_CONTROL_TARGET_FILE, (l == ltmmCapture_Target_File) ? MF_CHECKED : MF_UNCHECKED); CheckMenuItem((HMENU) wParam, ID_CONTROL_TARGET_ARRAY, (l == ltmmCapture_Target_Array) ? MF_CHECKED : MF_UNCHECKED); CheckMenuItem((HMENU) wParam, ID_CONTROL_TARGET_DEVICE, (l == ltmmCapture_Target_Device) ? MF_CHECKED : MF_UNCHECKED); EnableMenuItem((HMENU) wParam, ID_CONTROL_TARGET_FILE, (!fActive) ? MF_ENABLED : MF_GRAYED); EnableMenuItem((HMENU) wParam, ID_CONTROL_TARGET_ARRAY, (!fActive) ? MF_ENABLED : MF_GRAYED); EnableMenuItem((HMENU) wParam, ID_CONTROL_TARGET_DEVICE, (!fActive) ? MF_ENABLED : MF_GRAYED); IltmmCapture_get_TargetFormat(g_pCapture, &l); IltmmCapture_get_TargetType(g_pCapture, &l2); CheckMenuItem((HMENU) wParam, ID_CONTROL_TARGETFORMAT_AVI, (l == ltmmCapture_TargetFormat_Avi) ? MF_CHECKED : MF_UNCHECKED); CheckMenuItem((HMENU) wParam, ID_CONTROL_TARGETFORMAT_WAVE, (l == ltmmCapture_TargetFormat_WAVE) ? MF_CHECKED : MF_UNCHECKED); CheckMenuItem((HMENU) wParam, ID_CONTROL_TARGETFORMAT_MPEG1AUDIO, (l == ltmmCapture_TargetFormat_MPEG1Audio) ? MF_CHECKED : MF_UNCHECKED); EnableMenuItem((HMENU) wParam, ID_CONTROL_TARGETFORMAT_AVI, (!fActive && l2 != ltmmCapture_Target_Device) ? MF_ENABLED : MF_GRAYED); EnableMenuItem((HMENU) wParam, ID_CONTROL_TARGETFORMAT_WAVE, (!fActive && l2 != ltmmCapture_Target_Device) ? MF_ENABLED : MF_GRAYED); EnableMenuItem((HMENU) wParam, ID_CONTROL_TARGETFORMAT_MPEG1AUDIO, (!fActive && l2 != ltmmCapture_Target_Device) ? MF_ENABLED : MF_GRAYED); // check processor preview IltmmCapture_get_PreviewTap(g_pCapture, &l); CheckMenuItem((HMENU) wParam, ID_CONTROL_PREVIEWPROCESSORS, (l == ltmmCapture_PreviewTap_Processors) ? MF_CHECKED : MF_UNCHECKED); // check properties preview IltmmCapture_get_ShowDialogPreview(g_pCapture, &f); CheckMenuItem((HMENU) wParam, ID_CONTROL_PROPERTIESPREVIEW, (f) ? MF_CHECKED : MF_UNCHECKED); // enable vcr controls IltmmCapture_get_CaptureVCRControl(g_pCapture, &pVCR); IltmmVCRControl_get_DeviceType(pVCR, &l); // if no tape is loaded, then disallow vcr control IltmmVCRControl_get_MediaType(pVCR, &l2); if(l2 == ltmmVCRControl_MediaType_NotPresent) l = ltmmVCRControl_DeviceType_NotPresent; // get the current vcr mode IltmmVCRControl_get_Mode(pVCR, &l2); EnableMenuItem((HMENU) wParam, ID_CONTROL_VCR_PLAY, (l != ltmmVCRControl_DeviceType_NotPresent && l != ltmmVCRControl_DeviceType_Camera && l2 != ltmmVCRControl_Mode_Play) ? MF_ENABLED : MF_GRAYED); EnableMenuItem((HMENU) wParam, ID_CONTROL_VCR_STOP, (l != ltmmVCRControl_DeviceType_NotPresent && l != ltmmVCRControl_DeviceType_Camera && l2 != ltmmVCRControl_Mode_Stop) ? MF_ENABLED : MF_GRAYED); EnableMenuItem((HMENU) wParam, ID_CONTROL_VCR_PAUSE, (l != ltmmVCRControl_DeviceType_NotPresent && l != ltmmVCRControl_DeviceType_Camera && l2 != ltmmVCRControl_Mode_Pause) ? MF_ENABLED : MF_GRAYED); EnableMenuItem((HMENU) wParam, ID_CONTROL_VCR_REWIND, (l != ltmmVCRControl_DeviceType_NotPresent && l != ltmmVCRControl_DeviceType_Camera && l2 != ltmmVCRControl_Mode_Rewind) ? MF_ENABLED : MF_GRAYED); EnableMenuItem((HMENU) wParam, ID_CONTROL_VCR_FASTFORWARD, (l != ltmmVCRControl_DeviceType_NotPresent && l != ltmmVCRControl_DeviceType_Camera && l2 != ltmmVCRControl_Mode_FastForward) ? MF_ENABLED : MF_GRAYED); EnableMenuItem((HMENU) wParam, ID_CONTROL_VCR_STEPFORWARD, (l != ltmmVCRControl_DeviceType_NotPresent && l != ltmmVCRControl_DeviceType_Camera && l2 != ltmmVCRControl_Mode_StepForward) ? MF_ENABLED : MF_GRAYED); EnableMenuItem((HMENU) wParam, ID_CONTROL_VCR_STEPBACKWARD, (l != ltmmVCRControl_DeviceType_NotPresent && l != ltmmVCRControl_DeviceType_Camera && l2 != ltmmVCRControl_Mode_StepBackward) ? MF_ENABLED : MF_GRAYED); EnableMenuItem((HMENU) wParam, ID_CONTROL_VCR_FASTESTFORWARD, (l != ltmmVCRControl_DeviceType_NotPresent && l != ltmmVCRControl_DeviceType_Camera && l2 != ltmmVCRControl_Mode_FastestForward) ? MF_ENABLED : MF_GRAYED); EnableMenuItem((HMENU) wParam, ID_CONTROL_VCR_FASTESTREVERSE, (l != ltmmVCRControl_DeviceType_NotPresent && l != ltmmVCRControl_DeviceType_Camera && l2 != ltmmVCRControl_Mode_FastestReverse) ? MF_ENABLED : MF_GRAYED); EnableMenuItem((HMENU) wParam, ID_CONTROL_VCR_SLOWESTFORWARD, (l != ltmmVCRControl_DeviceType_NotPresent && l != ltmmVCRControl_DeviceType_Camera && l2 != ltmmVCRControl_Mode_SlowestForward) ? MF_ENABLED : MF_GRAYED); EnableMenuItem((HMENU) wParam, ID_CONTROL_VCR_SLOWESTREVERSE, (l != ltmmVCRControl_DeviceType_NotPresent && l != ltmmVCRControl_DeviceType_Camera && l2 != ltmmVCRControl_Mode_SlowestReverse) ? MF_ENABLED : MF_GRAYED); EnableMenuItem((HMENU) wParam, ID_CONTROL_VCR_RECORD, (l != ltmmVCRControl_DeviceType_NotPresent && l2 != ltmmVCRControl_Mode_Record) ? MF_ENABLED : MF_GRAYED); EnableMenuItem((HMENU) wParam, ID_CONTROL_VCR_PAUSERECORDING, (l != ltmmVCRControl_DeviceType_NotPresent && l2 != ltmmVCRControl_Mode_PauseRecording) ? MF_ENABLED : MF_GRAYED); IltmmVCRControl_ReadTimecode(pVCR, &l2); EnableMenuItem((HMENU) wParam, ID_CONTROL_VCR_SEEKSTART, (l != ltmmVCRControl_DeviceType_NotPresent && l != ltmmVCRControl_DeviceType_Camera && l2 != 0) ? MF_ENABLED : MF_GRAYED); IUnknown_Release(pVCR); // check audio buffer size IltmmCapture_get_AudioBufferSize(g_pCapture, &d); CheckMenuItem((HMENU) wParam, ID_CONTROL_AUDIOBUFFERING_05SECONDS, (fabs(d - 0.5) < 0.01) ? MF_CHECKED : MF_UNCHECKED); CheckMenuItem((HMENU) wParam, ID_CONTROL_AUDIOBUFFERING_005SECONDS, (fabs(d - 0.05) < 0.01) ? MF_CHECKED : MF_UNCHECKED); } break; case WM_COMMAND: switch(LOWORD(wParam)) { case ID_CONTROL_FITTOWINDOW: // fit the video to the window IltmmCapture_put_VideoWindowSizeMode(g_pCapture, ltmmFit); return 0; break; case ID_CONTROL_STRETCHTOWINDOW: // stretch the video to the window IltmmCapture_put_VideoWindowSizeMode(g_pCapture, ltmmStretch); return 0; break; case ID_CONTROL_FULLSCREEN: // toggle fullscreen mode IltmmCapture_ToggleFullScreenMode(g_pCapture); return 0; break; case ID_CONTROL_PREVIEW: // toggle preview IltmmCapture_TogglePreview(g_pCapture); return 0; break; case ID_CONTROL_PREVIEWVIDEOANDAUDIO: // toggle audio preview IltmmCapture_get_PreviewSource(g_pCapture, &l); if(l == ltmmCapture_Preview_VideoAndAudio) IltmmCapture_put_PreviewSource(g_pCapture, ltmmCapture_Preview_Video); else IltmmCapture_put_PreviewSource(g_pCapture, ltmmCapture_Preview_VideoAndAudio); return 0; break; case ID_CONTROL_CLOSECAPTIONING: // toggle close captioning IltmmCapture_ToggleCloseCaptioning(g_pCapture); return 0; break; case ID_CONTROL_STOPCAPTURE: // stop capturing IltmmCapture_StopCapture(g_pCapture); return 0; break; case ID_CONTROL_CAPTUREPROPERTIES: // set capture properties IltmmCapture_ShowDialog(g_pCapture, ltmmCapture_Dlg_Capture, (long) hwnd); return 0; break; case ID_CONTROL_STARTCAPTURE: // ready capture to eliminate start delays hr = IltmmCapture_ReadyCapture(g_pCapture, ltmmCapture_Mode_VideoOrAudio); if(SUCCEEDED(hr)) { // start recording, if vcr output IltmmCapture_get_TargetVCRControl(g_pCapture, &pVCR); hr = IltmmVCRControl_Record(pVCR); IUnknown_Release(pVCR); // uncomment the following line to view the the graph in DirectShow GraphEdit // IltmmCapture_EditGraph(g_pCapture); if(MessageBox(hwnd, _T("Ready to capture. Click 'ok' to start."), _T("Capture"), MB_OKCANCEL) == IDOK) { // start capturing IltmmCapture_StartCapture(g_pCapture, ltmmCapture_Mode_VideoOrAudio); } else { // cancel capture IltmmCapture_StopCapture(g_pCapture); // stop recording, if vcr output IltmmCapture_get_TargetVCRControl(g_pCapture, &pVCR); IltmmVCRControl_Stop (pVCR); IUnknown_Release(pVCR); } } return 0; break; case ID_CONTROL_RUN: // run the capture graph IltmmCapture_RunCapture(g_pCapture); return 0; break; case ID_CONTROL_PAUSE: // pause the capture graph IltmmCapture_PauseCapture(g_pCapture); return 0; break; case ID_CONTROL_CAPTUREAUTOFRAMES: hr = IltmmCapture_ReadyCapture(g_pCapture, ltmmCapture_Mode_AutoFrames); if(SUCCEEDED(hr)) { // start recording, if vcr output IltmmCapture_get_TargetVCRControl(g_pCapture, &pVCR); hr = IltmmVCRControl_Record(pVCR); IUnknown_Release(pVCR); if(SUCCEEDED(hr)) Sleep(2000); // start capturing automatic frame sequence IltmmCapture_StartCapture(g_pCapture, ltmmCapture_Mode_AutoFrames); } return 0; break; case ID_CONTROL_CAPTUREMANUALFRAMES: hr = IltmmCapture_ReadyCapture(g_pCapture, ltmmCapture_Mode_ManualFrames); if(SUCCEEDED(hr)) { // start recording, if vcr output IltmmCapture_get_TargetVCRControl(g_pCapture, &pVCR); hr = IltmmVCRControl_Record(pVCR); IUnknown_Release(pVCR); if(SUCCEEDED(hr)) Sleep(2000); // start capturing automatic frame sequence hr = IltmmCapture_StartCapture(g_pCapture, ltmmCapture_Mode_ManualFrames); if(SUCCEEDED(hr)) { while(MessageBox(hwnd, _T("Press 'ok' to capture frame."), _T("Capture Manual Frames"), MB_OKCANCEL) == IDOK) IltmmCapture_CaptureFrame(g_pCapture); IltmmCapture_StopCapture(g_pCapture); } // stop recording, if vcr output IltmmCapture_get_TargetVCRControl(g_pCapture, &pVCR); IltmmVCRControl_Stop(pVCR); IUnknown_Release(pVCR); } return 0; break; case ID_CONTROL_CAPTUREDIB: // capture device independent bitmap hr = IltmmCapture_CaptureDIB(g_pCapture, (long*) &hDIB); if(SUCCEEDED(hr)) { // copy to the clipboard OpenClipboard(hwnd); EmptyClipboard(); SetClipboardData(CF_DIB, hDIB); CloseClipboard(); } return 0; break; case ID_CONTROL_CAPTUREPICTURE: // capture ole picture object hr = IltmmCapture_CapturePicture(g_pCapture, &pPictureDisp); if(SUCCEEDED(hr)) { // save the picture bstr = SysAllocString(L"c:\\still.bmp"); OleSavePictureFile((IDispatch*) pPictureDisp, bstr); SysFreeString(bstr); IUnknown_Release(pPictureDisp); } return 0; break; case ID_CONTROL_GETSTILLDIB: // alternate method of capturing a device independent bitmap hr = IltmmCapture_StartCapture(g_pCapture, ltmmCapture_Mode_Still); if(SUCCEEDED(hr)) { hr = IltmmCapture_GetStillDIB(g_pCapture, INFINITE, (long*) &hDIB); IltmmCapture_StopCapture(g_pCapture); if(SUCCEEDED(hr)) { // copy to the clipboard OpenClipboard(hwnd); EmptyClipboard(); SetClipboardData(CF_DIB, hDIB); CloseClipboard(); } } return 0; break; case ID_CONTROL_GETSTILLPICTURE: // alternate method of capturing an ole picture object hr = IltmmCapture_StartCapture(g_pCapture, ltmmCapture_Mode_Still); if(SUCCEEDED(hr)) { hr = IltmmCapture_GetStillPicture(g_pCapture, INFINITE, &pPictureDisp); IltmmCapture_StopCapture(g_pCapture); if(SUCCEEDED(hr)) { // save the picture bstr = SysAllocString(L"c:\\still.bmp"); OleSavePictureFile((IDispatch*) pPictureDisp, bstr); SysFreeString(bstr); IUnknown_Release(pPictureDisp); } } return 0; break; case ID_CONTROL_COPYTARGET: // copy target file bstr = SysAllocString(L"c:\\targetcopy.avi"); IltmmCapture_CopyTarget(g_pCapture, bstr, VARIANT_FALSE); SysFreeString(bstr); return 0; break; case ID_CONTROL_MASTERSTREAM_NONE: // no master stream IltmmCapture_put_MasterStream(g_pCapture, ltmmCapture_MasterStream_None); return 0; break; case ID_CONTROL_MASTERSTREAM_AUDIO: // set audio master IltmmCapture_put_MasterStream(g_pCapture, ltmmCapture_MasterStream_Audio); return 0; break; case ID_CONTROL_MASTERSTREAM_VIDEO: // set video master IltmmCapture_put_MasterStream(g_pCapture, ltmmCapture_MasterStream_Video); return 0; break; case ID_CONTROL_FRAMERATE_DEFAULT: // set rate to default IltmmCapture_put_UseFrameRate(g_pCapture, VARIANT_FALSE); return 0; break; case ID_CONTROL_FRAMERATE_15FPS: // set rate to 15 fps IltmmCapture_put_FrameRate(g_pCapture, 15.0); IltmmCapture_put_UseFrameRate(g_pCapture, VARIANT_TRUE); return 0; break; case ID_CONTROL_FRAMERATE_30FPS: // set rate to 30 fps IltmmCapture_put_FrameRate(g_pCapture, 30.0); IltmmCapture_put_UseFrameRate(g_pCapture, VARIANT_TRUE); return 0; break; case ID_CONTROL_TIMELIMIT_NONE: // no time limit IltmmCapture_put_UseTimeLimit(g_pCapture, VARIANT_FALSE); return 0; break; case ID_CONTROL_TIMELIMIT_15SEC: // 15 sec time limit IltmmCapture_put_TimeLimit(g_pCapture, 15.0); IltmmCapture_put_UseTimeLimit(g_pCapture, VARIANT_TRUE); return 0; break; case ID_CONTROL_TIMELIMIT_30SEC: // 30 sec time limit IltmmCapture_put_TimeLimit(g_pCapture, 30.0); IltmmCapture_put_UseTimeLimit(g_pCapture, VARIANT_TRUE); return 0; break; case ID_CONTROL_FRAMEDELAY_1SEC: // 1 sec frame delay IltmmCapture_put_FrameDelay(g_pCapture, 1.0); return 0; break; case ID_CONTROL_FRAMEDELAY_5SEC: // 5 sec frame delay IltmmCapture_put_FrameDelay(g_pCapture, 5.0); return 0; break; case ID_CONTROL_TARGET_FILE: // assign a target file FreeTarget(); // 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); if(index >= 0) IltmmCompressors_put_Selection(pCompressors, index); IUnknown_Release(pCompressors); // select the MP3 audio video compressor IltmmCapture_get_AudioCompressors(g_pCapture, &pCompressors); bstr = SysAllocString(L"@device:cm:{33D9A761-90C8-11D0-BD43-00A0C911CE86}\\85MPEG Layer-3"); IltmmCompressors_Find(pCompressors, bstr, &index); SysFreeString(bstr); if(index >= 0) IltmmCompressors_put_Selection(pCompressors, index); IUnknown_Release(pCompressors); IltmmCapture_put_TargetFormat(g_pCapture, ltmmCapture_TargetFormat_Avi); bstr = SysAllocString(L"c:\\target.avi"); IltmmCapture_put_TargetFile(g_pCapture, bstr); SysFreeString(bstr); return 0; break; case ID_CONTROL_TARGET_ARRAY: // assign a target array FreeTarget(); // 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); if(index >= 0) IltmmCompressors_put_Selection(pCompressors, index); IUnknown_Release(pCompressors); // select the MP3 audio video compressor IltmmCapture_get_AudioCompressors(g_pCapture, &pCompressors); bstr = SysAllocString(L"@device:cm:{33D9A761-90C8-11D0-BD43-00A0C911CE86}\\85MPEG Layer-3"); IltmmCompressors_Find(pCompressors, bstr, &index); SysFreeString(bstr); if(index >= 0) IltmmCompressors_put_Selection(pCompressors, index); IUnknown_Release(pCompressors); IltmmCapture_put_TargetFormat(g_pCapture, ltmmCapture_TargetFormat_Avi); VariantInit(&var); V_VT(&var) = (VT_ARRAY | VT_UI1); V_ARRAY(&var) = SafeArrayCreateVector(VT_UI1, 0, 0); IltmmCapture_put_TargetArray(g_pCapture, var); return 0; break; case ID_CONTROL_TARGET_DEVICE: // assign a target device FreeTarget(); // deselect video compressor IltmmCapture_get_VideoCompressors(g_pCapture, &pCompressors); IltmmCompressors_put_Selection(pCompressors, -1); IUnknown_Release(pCompressors); // deselect audio compressor IltmmCapture_get_AudioCompressors(g_pCapture, &pCompressors); IltmmCompressors_put_Selection(pCompressors, -1); IUnknown_Release(pCompressors); IltmmCapture_put_TargetFormat(g_pCapture, ltmmCapture_TargetFormat_dvsd); // select the first output device IltmmCapture_get_TargetDevices(g_pCapture, &pTargetDevices); IltmmTargetDevices_put_Selection(pTargetDevices, 0); IUnknown_Release(pTargetDevices); return 0; break; case ID_CONTROL_TARGETFORMAT_AVI: // is target a file? IltmmCapture_get_TargetType(g_pCapture, &l); if(l == ltmmCapture_Target_File) { // rename it bstr = SysAllocString(L"c:\\target.avi"); IltmmCapture_put_TargetFile(g_pCapture, bstr); SysFreeString(bstr); } IltmmCapture_put_TargetFormat(g_pCapture, ltmmCapture_TargetFormat_Avi); return 0; break; case ID_CONTROL_TARGETFORMAT_WAVE: // is target a file? IltmmCapture_get_TargetType(g_pCapture, &l); if(l == ltmmCapture_Target_File) { // rename it bstr = SysAllocString(L"c:\\target.wav"); IltmmCapture_put_TargetFile(g_pCapture, bstr); SysFreeString(bstr); } IltmmCapture_put_TargetFormat(g_pCapture, ltmmCapture_TargetFormat_WAVE); return 0; break; case ID_CONTROL_TARGETFORMAT_MPEG1AUDIO: // is target a file? IltmmCapture_get_TargetType(g_pCapture, &l); if(l == ltmmCapture_Target_File) { // rename it bstr = SysAllocString(L"c:\\target.mp3"); IltmmCapture_put_TargetFile(g_pCapture, bstr); SysFreeString(bstr); } // we have already selected the MP3 compressor IltmmCapture_put_TargetFormat(g_pCapture, ltmmCapture_TargetFormat_MPEG1Audio); return 0; break; case ID_CONTROL_AUDIOPROCESSORS: // edit audio processors IltmmCapture_ShowDialog(g_pCapture, ltmmCapture_Dlg_AudioProcessors, (long) hwnd); return 0; break; case ID_CONTROL_VIDEOPROCESSORS: // edit video processors IltmmCapture_ShowDialog(g_pCapture, ltmmCapture_Dlg_VideoProcessors, (long) hwnd); return 0; break; case ID_CONTROL_PREVIEWPROCESSORS: // toggle processor preview IltmmCapture_get_PreviewTap(g_pCapture, &l); IltmmCapture_put_PreviewTap(g_pCapture, (l == ltmmCapture_PreviewTap_Processors) ? ltmmCapture_PreviewTap_Source : ltmmCapture_PreviewTap_Processors); return 0; break; case ID_CONTROL_PROPERTIESPREVIEW: // toggle preview while editing properties IltmmCapture_get_ShowDialogPreview(g_pCapture, &f); IltmmCapture_put_ShowDialogPreview(g_pCapture, f ? VARIANT_FALSE : VARIANT_TRUE); return 0; break; case ID_CONTROL_VCR_PLAY: // vcr play IltmmCapture_get_CaptureVCRControl(g_pCapture, &pVCR); IltmmVCRControl_Play(pVCR); IUnknown_Release(pVCR); return 0; break; case ID_CONTROL_VCR_STOP: // vcr stop IltmmCapture_get_CaptureVCRControl(g_pCapture, &pVCR); IltmmVCRControl_Stop (pVCR); IUnknown_Release(pVCR); return 0; break; case ID_CONTROL_VCR_PAUSE: // vcr pause IltmmCapture_get_CaptureVCRControl(g_pCapture, &pVCR); IltmmVCRControl_Pause(pVCR); IUnknown_Release(pVCR); return 0; break; case ID_CONTROL_VCR_FASTFORWARD: // vcr fast forward IltmmCapture_get_CaptureVCRControl(g_pCapture, &pVCR); IltmmVCRControl_FastForward(pVCR); IUnknown_Release(pVCR); return 0; break; case ID_CONTROL_VCR_REWIND: // vcr rewind IltmmCapture_get_CaptureVCRControl(g_pCapture, &pVCR); IltmmVCRControl_Rewind(pVCR); IUnknown_Release(pVCR); return 0; break; case ID_CONTROL_VCR_RECORD: // vcr record IltmmCapture_get_CaptureVCRControl(g_pCapture, &pVCR); IltmmVCRControl_Record(pVCR); IUnknown_Release(pVCR); return 0; break; case ID_CONTROL_VCR_PAUSERECORDING: // vcr pause recording IltmmCapture_get_CaptureVCRControl(g_pCapture, &pVCR); IltmmVCRControl_PauseRecording(pVCR); IUnknown_Release(pVCR); return 0; break; case ID_CONTROL_VCR_STEPFORWARD: // vcr step forward IltmmCapture_get_CaptureVCRControl(g_pCapture, &pVCR); IltmmVCRControl_StepForward(pVCR); IUnknown_Release(pVCR); return 0; break; case ID_CONTROL_VCR_STEPBACKWARD: // vcr step backward IltmmCapture_get_CaptureVCRControl(g_pCapture, &pVCR); IltmmVCRControl_StepBackward(pVCR); IUnknown_Release(pVCR); return 0; break; case ID_CONTROL_VCR_FASTESTFORWARD: // vcr fastest forward IltmmCapture_get_CaptureVCRControl(g_pCapture, &pVCR); IltmmVCRControl_FastestForward(pVCR); IUnknown_Release(pVCR); return 0; break; case ID_CONTROL_VCR_FASTESTREVERSE: // vcr fastest reverse IltmmCapture_get_CaptureVCRControl(g_pCapture, &pVCR); IltmmVCRControl_FastestReverse(pVCR); IUnknown_Release(pVCR); return 0; break; case ID_CONTROL_VCR_SLOWESTFORWARD: // vcr slowest forward IltmmCapture_get_CaptureVCRControl(g_pCapture, &pVCR); IltmmVCRControl_SlowestForward(pVCR); IUnknown_Release(pVCR); return 0; break; case ID_CONTROL_VCR_SLOWESTREVERSE: // vcr slowest reverse IltmmCapture_get_CaptureVCRControl(g_pCapture, &pVCR); IltmmVCRControl_SlowestReverse(pVCR); IUnknown_Release(pVCR); return 0; break; case ID_CONTROL_VCR_SEEKSTART: // vcr seek start IltmmCapture_get_CaptureVCRControl(g_pCapture, &pVCR); IltmmVCRControl_SeekTimecode(pVCR, 0); IUnknown_Release(pVCR); return 0; break; case ID_CONTROL_AUDIOBUFFERING_05SECONDS: // set 0.5 second audio buffer IltmmCapture_put_AudioBufferSize(g_pCapture, 0.5); return 0; break; case ID_CONTROL_AUDIOBUFFERING_005SECONDS: // set 0.05 second audio buffer IltmmCapture_put_AudioBufferSize(g_pCapture, 0.05); return 0; break; } break; case WM_LBUTTONDOWN: IltmmCapture_get_State(g_pCapture, &l); if(l != ltmmCapture_State_Pending || l != ltmmCapture_State_Running) { IltmmCapture_get_VideoWindowLeft(g_pCapture, &x); IltmmCapture_get_VideoWindowTop(g_pCapture, &y); IltmmCapture_get_VideoWindowWidth(g_pCapture, &cx); IltmmCapture_get_VideoWindowHeight(g_pCapture, &cy); SetRect(&rc, x, y, x + cx, y + cy); pt.x = (short) LOWORD(lParam); pt.y = (short) HIWORD(lParam); if(PtInRect(&rc, pt)) { // set capture properties IltmmCapture_ShowDialog(g_pCapture, ltmmCapture_Dlg_Capture, (long) hwnd); } } return 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; UNUSED_PARAMETER (hPrevInstance); UNUSED_PARAMETER (lpCmdLine); 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 = CaptureWndProc; 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 = (LPCSTR)IDR_MENU; wcex.lpszClassName = SZ_WNDCLASS_CAPTURE; wcex.hIconSm = NULL; if(!RegisterClassEx(&wcex)) 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 video frame window if(!CreateWindow(SZ_WNDCLASS_CAPTURE, _T("Capture"), WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN, CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, g_hInstance, NULL)) goto error; ShowWindow(g_hwndCapture, nCmdShow); UpdateWindow(g_hwndCapture); // process until done while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } error: if(g_pCapture) IUnknown_Release(g_pCapture); CoUninitialize(); return 0; }