home *** CD-ROM | disk | FTP | other *** search
- //------------------------------------------------------------------------------
- // File: DVApp.cpp
- //
- // Desc: DirectShow sample code - DV control/capture example.
- //
- // Copyright (c) 1993 - 2000, Microsoft Corporation. All rights reserved.
- //------------------------------------------------------------------------------
-
-
- #include "dvapp.h"
-
- /*-------------------------------------------------------------------------
- Routine: WinMain
- Purpose: Program entry point
- Arguments: Usual
- Returns: Usual
- Notes: Sets up window capabilities, initializes & creates the required DirectShow interface & filters.
- ------------------------------------------------------------------------*/
- int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
- PSTR szCmdLine, int iCmdShow)
- {
- static TCHAR szAppName[] = APPNAME ;
- MSG msg ;
- WNDCLASSEX wndclass ;
- HMENU hmenu;
-
- // Set the Window Parameters
- wndclass.cbSize = sizeof (wndclass) ;
- wndclass.style = CS_HREDRAW | CS_VREDRAW ;
- wndclass.lpfnWndProc = DV_WndProc ;
- wndclass.cbClsExtra = 0 ;
- wndclass.cbWndExtra = 0 ;
- wndclass.hInstance = hInstance ;
- wndclass.hIcon = LoadIcon (hInstance, TEXT("DVICON")) ;
- wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ;
- wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ;
- wndclass.lpszMenuName = NULL ;
- wndclass.lpszClassName = szAppName ;
- wndclass.hIconSm = LoadIcon(hInstance, TEXT("DVICON"));
- // create & setup the window
- RegisterClassEx (&wndclass) ;
- hmenu = LoadMenu(hInstance, MAKEINTRESOURCE(IDR_MENU1));
- g_hwndApp = CreateWindow (szAppName, // window class name
- DV_APPTITLE, // window caption
- WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX | WS_MAXIMIZEBOX, // window style
- CW_USEDEFAULT, // initial x position
- CW_USEDEFAULT, // initial y position
- g_iAppWidth, // initial x size
- g_iAppHeight, // initial y size
- NULL, // parent window handle
- hmenu, // window menu handle
- hInstance, // program instance handle
- NULL) ; // creation parameters
-
- ShowWindow (g_hwndApp, iCmdShow) ;
- UpdateWindow (g_hwndApp) ;
-
- // Initialize UI & Logging levels
- SetWindowText(g_hwndApp, TEXT("Initializing..."));
- CheckMenuItem(hmenu, IDM_LEVEL_SUCCINCT, MF_CHECKED);
- CheckMenuItem(hmenu, IDM_PRIORITY_ERROR, MF_CHECKED);
-
- // Register for device add/remove notifications.
- DEV_BROADCAST_DEVICEINTERFACE filterData;
- ZeroMemory(&filterData, sizeof(DEV_BROADCAST_DEVICEINTERFACE));
-
- filterData.dbcc_size = sizeof(DEV_BROADCAST_DEVICEINTERFACE);
- filterData.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
- filterData.dbcc_classguid = AM_KSCATEGORY_CAPTURE;
-
- g_pUnregisterDeviceNotification = NULL;
- g_pRegisterDeviceNotification = NULL;
- // dynload device removal APIs
- {
- HMODULE hmodUser = GetModuleHandle(TEXT("user32.dll"));
- ASSERT(hmodUser); // we link to user32
- g_pUnregisterDeviceNotification = (PUnregisterDeviceNotification)
- GetProcAddress(hmodUser, "UnregisterDeviceNotification");
-
- // m_pRegisterDeviceNotification is prototyped differently in unicode
- g_pRegisterDeviceNotification = (PRegisterDeviceNotification)
- GetProcAddress(hmodUser,
- #ifdef UNICODE
- "RegisterDeviceNotificationW"
- #else
- "RegisterDeviceNotificationA"
- #endif
- );
- // failures expected on older platforms.
- ASSERT(g_pRegisterDeviceNotification && g_pUnregisterDeviceNotification ||
- !g_pRegisterDeviceNotification && !g_pUnregisterDeviceNotification);
- }
-
- g_hDevNotify = NULL;
-
- if (g_pRegisterDeviceNotification)
- {
- g_hDevNotify = g_pRegisterDeviceNotification(g_hwndApp, &filterData, DEVICE_NOTIFY_WINDOW_HANDLE);
- ASSERT(g_hDevNotify != NULL);
- }
-
- // Setup & Initialize the device & filtergraph
- DV_AppSetup();
-
- // Message processing loop
- while (GetMessage (&msg, NULL, 0, 0))
- {
- TranslateMessage (&msg) ;
- DispatchMessage (&msg) ;
- }
- return (int) msg.wParam;
- }
-
-
- /*-------------------------------------------------------------------------
- Routine: DV_TransportCommand_WndProc
- Purpose: Message Handler to control transport state of the device & the filtergraph state
- Arguments: Usual message processing parameters
- Returns: Usual
- Notes: Handles for the Toolbar button controls
- ------------------------------------------------------------------------*/
- void CALLBACK DV_TransportCommand_WndProc (HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
- {
- HMENU hmenu;
- switch (iMsg)
- {
- case WM_COMMAND :
- hmenu = GetMenu(hwnd);
- switch (LOWORD (wParam))
- {
- /*
- The VCR Tool bar commands need to behave differently depending on the
- current graph.
-
- In Preview (default) mode, the VCR commands should simply
- control the VCR functions on the vcr device.
-
- In DV To File mode, or File To DV mode the commands should start and stop the graph,
- as well as control the vcr mode (although we will disable some buttons to avoid confusion)
- */
- case IDM_PLAY :
- {
- //check if the current graph is a transmit graph
- if (GRAPH_FILE_TO_DV == g_iCurrentGraph || GRAPH_FILE_TO_DV_NOPRE == g_iCurrentGraph ||
- GRAPH_FILE_TO_DV_TYPE2 == g_iCurrentGraph || GRAPH_FILE_TO_DV_NOPRE_TYPE2 == g_iCurrentGraph)
- {
- // update the toolbar accordingly
- SendMessage(g_hwndTBar, TB_SETSTATE, IDM_PLAY, MAKELONG(TBSTATE_INDETERMINATE, 0L));
- //update the status bar with the dropped frames information
- g_CapStartTime = GetTickCount();
- SetTimer(hwnd, DV_TIMER_FRAMES, DV_TIMERFREQ, (TIMERPROC) DV_DroppedFrameProc);
- // run the filter graph & wait for dshow events
- DV_StartGraph();
- IMediaEventEx *pMe = NULL;
- if (SUCCEEDED(g_pGraphBuilder->QueryInterface(IID_IMediaEventEx, reinterpret_cast<PVOID *>(&pMe))))
- {
- pMe->SetNotifyWindow((LONG_PTR) g_hwndApp, WM_FGNOTIFY, 0);
- SAFE_RELEASE(pMe);
- }
- }
- else
- {
- // play the tape for the capture or preview graph
- DV_PutVcrMode(ED_MODE_PLAY);
-
- // run the filter graph too if it is preview
- if(GRAPH_PREVIEW == g_iCurrentGraph)
- DV_StartGraph();
- //do we want to display timecodes?
- if (IsDlgButtonChecked(g_hwndTBar, IDC_TCCHECKBOX))
- {
- SetTimer(hwnd, DV_TIMER_ATN, DV_TIMERFREQ, (TIMERPROC) DV_TimecodeTimerProc);
- g_bUseAtnTimer = TRUE;
- }
- }
- break;
- }
-
- /*
- The record button starts the *entire* graph, so preview (if selected), won't
- start until the recording starts.
- */
- case IDM_RECORD :
- // update the toolbar accordingly
- SendMessage(g_hwndTBar, TB_SETSTATE, IDM_STEP_FWD, MAKELONG(TBSTATE_INDETERMINATE, 0L));
- SendMessage(g_hwndTBar, TB_SETSTATE, IDM_STEP_REV, MAKELONG(TBSTATE_INDETERMINATE, 0L));
-
- // check to see if it is a capture graph
- if (GRAPH_DV_TO_FILE == g_iCurrentGraph || GRAPH_DV_TO_FILE_NOPRE == g_iCurrentGraph ||
- GRAPH_DV_TO_FILE_TYPE2 == g_iCurrentGraph || GRAPH_DV_TO_FILE_NOPRE_TYPE2 == g_iCurrentGraph)
- {
- //do something here to record to an avi file on the disk - or to start recording on the vcr.
- switch (g_dwCaptureLimit)
- {
- case DV_CAPLIMIT_NONE :
- break;
- case DV_CAPLIMIT_TIME :
- SetTimer(hwnd, DV_TIMER_CAPLIMIT, g_dwTimeLimit * 1000, (TIMERPROC) DV_StopRecProc);
- break;
- case DV_CAPLIMIT_SIZE :
- //rather than monitor disk usage, we'll just do the math and set a timer
- SetTimer(hwnd, DV_TIMER_CAPLIMIT, ((g_dwDiskSpace * 100000) / DV_BYTESPERMSEC), (TIMERPROC) DV_StopRecProc);
- break;
- default :
- DV_LogOut(LOG_PRIORITY_ERROR, LOG_LEVEL_SUCCINCT, TEXT("Bad value for g_dwCaptureLimit (%d)"), g_dwCaptureLimit);
- break;
- }
- //update the status bar with the dropped frames information
- g_CapStartTime = GetTickCount();
- SetTimer(hwnd, DV_TIMER_FRAMES, DV_TIMERFREQ, (TIMERPROC) DV_DroppedFrameProc);
- //run the graph - assume that the camera is already playing if in Vcr mode
- DV_StartGraph();
- }
- else if (GRAPH_FILE_TO_DV == g_iCurrentGraph || GRAPH_FILE_TO_DV_NOPRE == g_iCurrentGraph ||
- GRAPH_FILE_TO_DV_TYPE2 == g_iCurrentGraph || GRAPH_FILE_TO_DV_NOPRE_TYPE2 == g_iCurrentGraph)
- {
- // if transmit graph then record on tape of the device
- DV_PutVcrMode(ED_MODE_RECORD);
- }
- else
- {
- //we shouldn't get here
- DV_LogOut(LOG_PRIORITY_ERROR, LOG_LEVEL_SUCCINCT, TEXT("Undefined graph mode (maybe GRAPH_PREVIEW) in IDM_RECORD message"));
- }
- break;
-
- case IDM_STOP :
- if (GRAPH_PREVIEW != g_iCurrentGraph)
- { // for transmit & capture graphs we need stats if any
- DV_GetFinalDroppedFramesStats(GetTickCount());
- }
-
- // handle the timers accordingly
- if (g_bUseAtnTimer)
- KillTimer(hwnd, DV_TIMER_ATN);
- //if we're here, these timers were set
- KillTimer(hwnd, DV_TIMER_CAPLIMIT);
- KillTimer(hwnd, DV_TIMER_FRAMES);
-
- if (GRAPH_PREVIEW != g_iCurrentGraph)
- { // for transmit & capture graphs we need stop the graph, preview graph is running all the time
- DV_StopGraph();
- }
- // Stop the transport on the device
- DV_PutVcrMode(ED_MODE_STOP);
- // update the toolbar
- SendMessage(g_hwndTBar, TB_SETSTATE, IDM_PLAY, MAKELONG(TBSTATE_ENABLED, 0L));
- SendMessage(g_hwndTBar, TB_SETSTATE, IDM_STEP_FWD, MAKELONG(TBSTATE_INDETERMINATE, 0L));
- SendMessage(g_hwndTBar, TB_SETSTATE, IDM_STEP_REV, MAKELONG(TBSTATE_INDETERMINATE, 0L));
- break;
-
- case IDM_PAUSE :
- if (GRAPH_FILE_TO_DV == g_iCurrentGraph || GRAPH_FILE_TO_DV_NOPRE == g_iCurrentGraph ||
- GRAPH_FILE_TO_DV_TYPE2 == g_iCurrentGraph || GRAPH_FILE_TO_DV_NOPRE_TYPE2 == g_iCurrentGraph)
- { // transmit graph
- DV_PauseGraph();
- }
- else
- { // capture or preview graph
- DV_PutVcrMode(ED_MODE_FREEZE);
- SendMessage(g_hwndTBar, TB_SETSTATE, IDM_STEP_FWD, MAKELONG(TBSTATE_ENABLED, 0L));
- SendMessage(g_hwndTBar, TB_SETSTATE, IDM_STEP_REV, MAKELONG(TBSTATE_ENABLED, 0L));
- }
- SendMessage(g_hwndTBar, TB_SETSTATE, IDM_PLAY, MAKELONG(TBSTATE_ENABLED, 0L));
- break;
-
- case IDM_FF :
- // all graphs just forward the tape & update the toolbar
- DV_PutVcrMode(ED_MODE_FF);
- SendMessage(g_hwndTBar, TB_SETSTATE, IDM_STEP_FWD, MAKELONG(TBSTATE_INDETERMINATE, 0L));
- SendMessage(g_hwndTBar, TB_SETSTATE, IDM_STEP_REV, MAKELONG(TBSTATE_INDETERMINATE, 0L));
- break;
-
- case IDM_REW :
- // all graphs just rewind the tape & update the toolbar
- DV_PutVcrMode(ED_MODE_REW);
- SendMessage(g_hwndTBar, TB_SETSTATE, IDM_STEP_FWD, MAKELONG(TBSTATE_INDETERMINATE, 0L));
- SendMessage(g_hwndTBar, TB_SETSTATE, IDM_STEP_REV, MAKELONG(TBSTATE_INDETERMINATE, 0L));
- break;
-
- case IDM_PLAY_FAST_FF :
- // all graphs just forward the tape & update the toolbar
- DV_PutVcrMode(ED_MODE_PLAY_FASTEST_FWD);
- SendMessage(g_hwndTBar, TB_SETSTATE, IDM_STEP_FWD, MAKELONG(TBSTATE_INDETERMINATE, 0L));
- SendMessage(g_hwndTBar, TB_SETSTATE, IDM_STEP_REV, MAKELONG(TBSTATE_INDETERMINATE, 0L));
- break;
-
- case IDM_PLAY_FAST_REV :
- // all graphs just rewind the tape & update the toolbar
- DV_PutVcrMode(ED_MODE_PLAY_FASTEST_REV);
- SendMessage(g_hwndTBar, TB_SETSTATE, IDM_STEP_FWD, MAKELONG(TBSTATE_INDETERMINATE, 0L));
- SendMessage(g_hwndTBar, TB_SETSTATE, IDM_STEP_REV, MAKELONG(TBSTATE_INDETERMINATE, 0L));
- break;
-
- case IDM_STEP_FWD :
- // all graphs just forward the tape & update the toolbar
- DV_PutVcrMode(ED_MODE_STEP_FWD);
- g_bUseAtnTimer = FALSE;
- DV_DisplayTimecode();
- break;
-
- case IDM_STEP_REV :
- // all graphs just rewind the tape & update the toolbar
- DV_PutVcrMode(ED_MODE_STEP_REV);
- g_bUseAtnTimer = FALSE;
- DV_DisplayTimecode();
- break;
-
- case IDM_SEEKTIMECODE :
- // ATN Seek & display on the toolbar
- DV_SeekATN();
- DV_DisplayTimecode();
- break;
-
- } // switch (LOWORD(wParam))
- } // switch (iMsg)
- }
-
-
-
-
- /*-------------------------------------------------------------------------
- Routine: DV_WndProc
- Purpose: Message Handler
- Arguments: Usual
- Returns: Usual
- Notes: Handles Windows UI & Command Messages, Menu Messages et al
- ------------------------------------------------------------------------*/
- LRESULT CALLBACK DV_WndProc (HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
- {
- HDC hdc ;
- PAINTSTRUCT ps ;
- RECT rect;
- HMENU hmenu;
- static HWND hWndTT;
-
- switch (iMsg)
- {
- case WM_CREATE :
- // Initializes & loads the Controls like toolbar buttons etc
- if (!DV_InitControls(hwnd, (HINSTANCE)GetWindowLongPtr(hwnd, GWLP_HINSTANCE)))
- {
- DV_LogOut(LOG_PRIORITY_ERROR, LOG_LEVEL_SUCCINCT, TEXT("DV_InitControls failed to create one of the control windows"));
- }
- break;
-
- case WM_PAINT :
- hdc = BeginPaint (hwnd, &ps) ;
- GetClientRect (hwnd, &rect) ;
- EndPaint (hwnd, &ps) ;
- // not calling default message handler
- return 0;
-
- case WM_SIZE:
- {
- RECT rcAppWin, rcClient, rcTB;
- //re-size the App window
- int cxBorder = GetSystemMetrics(SM_CXBORDER);
- int cyBorder = GetSystemMetrics(SM_CYBORDER);
- GetWindowRect(g_hwndApp, &rcAppWin);
- GetWindowRect(g_hwndTBar, &rcTB);
- MoveWindow(g_hwndApp, rcAppWin.left, rcAppWin.top, g_iAppWidth, g_iAppHeight, TRUE);
-
- // Tell the toolbar to resize itself to fill the top of the window.
- SendMessage(g_hwndTBar, TB_AUTOSIZE, 0L, 0L);
-
- //handle the status bar height
- GetClientRect(g_hwndApp, &rcClient);
- cxBorder = GetSystemMetrics(SM_CXBORDER);
- cyBorder = GetSystemMetrics(SM_CYBORDER);
- MoveWindow(g_hwndStatus, -cxBorder, rcClient.bottom - (g_statusHeight + cyBorder),
- rcClient.right + (2 * cxBorder), (g_statusHeight + (2 * cyBorder)), TRUE);
- DV_StatusParts(rcClient.right);
-
- //re-size the video window
- GetWindowRect(g_hwndTBar, &rcTB);
- if (g_pVideoWindow)
- {
- g_pVideoWindow->SetWindowPosition(0, rcTB.bottom - rcTB.top, g_iVWWidth, g_iVWHeight);
- }
- break;
- }
-
- case WM_CLOSE:
- return SendMessage(hwnd, WM_DESTROY, 0,0);
-
- case WM_DESTROY :
- // Unregister device notifications
- if (g_hDevNotify != NULL)
- {
- ASSERT(g_pUnregisterDeviceNotification);
- g_pUnregisterDeviceNotification(g_hDevNotify);
- g_hDevNotify = NULL;
- }
- // Time to Kill All
- DV_CleanUp();
- hmenu = GetMenu(hwnd);
- DestroyMenu(hmenu);
- DestroyWindow(g_hwndTBar);
- DestroyWindow(g_hwndStatus);
- PostQuitMessage (0) ;
- // not calling default message handler
- return 0;
-
- case WM_NOTIFY :
- {
- //Windows Events Notify Message handler
- switch (((LPNMHDR)lParam)->code)
- {
- case TTN_NEEDTEXT :
- LPTOOLTIPTEXT lpttt;
- TCHAR ttBuff[128];
- lpttt = (LPTOOLTIPTEXT) lParam;
- LoadString ((HINSTANCE)GetWindowLongPtr(hwnd, GWLP_HINSTANCE), (UINT) lpttt->hdr.idFrom, ttBuff, 128);
- lpttt->lpszText = ttBuff;
- break;
- }
- break;
- }
-
- case WM_DEVICECHANGE:
- {
- // We are interested in only device arrival events
- if (DBT_DEVICEARRIVAL != wParam)
- break;
- PDEV_BROADCAST_HDR pdbh = (PDEV_BROADCAST_HDR) lParam;
- if (pdbh->dbch_devicetype != DBT_DEVTYP_DEVICEINTERFACE)
- break;
-
- // Check for capture devices.
- PDEV_BROADCAST_DEVICEINTERFACE pdbi = (PDEV_BROADCAST_DEVICEINTERFACE) lParam;
- if (pdbi->dbcc_classguid != AM_KSCATEGORY_CAPTURE)
- break;
-
- // Check for device arrival.
- if (g_bDeviceFound == FALSE)
- {
- MessageBox(g_hwndApp, TEXT("There is a new capture device on this system..."), APPNAME, MB_OK);
- DV_CleanUp();
- DV_AppSetup();
- }
- break;
- }
-
- case WM_FGNOTIFY :
- {
- //Filter Graph Events Notify Message handler
- IMediaEventEx *pMe = NULL;
- if(g_pGraphBuilder == NULL)
- break;
- else if (SUCCEEDED(g_pGraphBuilder->QueryInterface(IID_IMediaEventEx, reinterpret_cast<PVOID *>(&pMe))))
- {
- long event;
- LONG_PTR l1, l2;
- // Get the corresponding filtergraph directshow media event to handle
- while (SUCCEEDED(pMe->GetEvent(&event, &l1, &l2, 0L)))
- {
- switch (event)
- {
- case EC_USERABORT :
- case EC_COMPLETE :
- // filtergraph is done, time to stop the filtergraph or transport state
- SendMessage(g_hwndApp, WM_COMMAND, IDM_STOP, 0);
- break;
-
- case EC_ERRORABORT :
- //something bad happened during capture
- MBOX(TEXT("Error during preview, capture or transmit"));
- break;
- case EC_DEVICE_LOST :
- // Check if we have lost a capture filter being used.
- // lParam2 of EC_DEVICE_LOST event == 0 indicates device removed
- // lParam2 of EC_DEVICE_LOST event == 1 indicates removed device added again
- if (l2 == 0)
- {
- IBaseFilter *pf;
- IUnknown *punk = (IUnknown *) l1;
- if (S_OK == punk->QueryInterface(IID_IBaseFilter, (void **) &pf))
- {
- if (::IsEqualObject(g_pDVCamera, pf))
- {
- pMe->FreeEventParams(event, l1, l2);
-
- // handle the timers accordingly
- if (g_bUseAtnTimer)
- KillTimer(hwnd, DV_TIMER_ATN);
- KillTimer(hwnd, DV_TIMER_CAPLIMIT);
- KillTimer(hwnd, DV_TIMER_FRAMES);
- // Cleanup the old device's filtergraph &
- // Search for other DV camcorders or the same DV camcorder being plugged in again,
- // if found set it up else exit the app
- MBOX("DV Camcorder Device in use was removed");
- g_bDeviceFound = FALSE;
- DV_CleanUp();
- DV_AppSetup();
- }
- pf->Release();
- }
- }
- break;
-
- default :
- DV_LogOut(LOG_PRIORITY_INFO, LOG_LEVEL_VERBOSE, TEXT("Unhandled Event Code (0x%x)"), event);
- break;
- }
- pMe->FreeEventParams(event, l1, l2);
- }
- SAFE_RELEASE(pMe);
- }
- SAFE_RELEASE(pMe);
- break;
- }
-
-
- case WM_COMMAND :
- // Handle menu commands
- hmenu = GetMenu(hwnd);
- switch (LOWORD (wParam))
- {
- // Help Menu
- case IDM_ABOUT:
- DialogBox((HINSTANCE)GetWindowLongPtr(hwnd, GWLP_HINSTANCE), MAKEINTRESOURCE(IDD_ABOUT), hwnd, (DLGPROC)DV_AboutDlgProc);
- break;
-
- // The File Menu
- /*
- The globals for input file and output file are TCHAR. When compiled ANSI,
- GetOpenFileName (obviously) return ANSI buffers. DShow functions use Unicode
- names exclusively, so these are converted to Unicode within the functions
- that need to use these variables (DV_Make...To... functions).
- */
- case IDM_SETINPUT : //fall through
- case IDM_SETOUTPUT :
- case IDM_OPTIONS_SAVEGRAPH :
- {
- OPENFILENAME ofn = {0};
- OSVERSIONINFO osi = {0};
- //need to adjust the ofn struct size if we are running on win98 vs. nt5
- osi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
- GetVersionEx(&osi);
- if (osi.dwMajorVersion >=5 && osi.dwPlatformId == VER_PLATFORM_WIN32_NT)
- {
- ofn.lStructSize = sizeof (OPENFILENAME);
- }
- else
- {
- ofn.lStructSize = sizeof(OPENFILENAME);
- }
-
- ofn.hwndOwner = g_hwndApp;
- ofn.nMaxFile = _MAX_PATH;
- if (IDM_OPTIONS_SAVEGRAPH == LOWORD (wParam))
- {
- ofn.lpstrFilter = TEXT("Filter Graph\0*.grf\0\0");
- ofn.lpstrTitle = TEXT("Set FilterGraph File Name");
- ofn.lpstrFile = g_FilterGraphFileName;
- }
- else if (IDM_SETOUTPUT == LOWORD (wParam))
- {
- ofn.lpstrFilter = TEXT("Microsoft AVI\0*.avi\0\0");
- ofn.lpstrTitle = TEXT("Set output File Name");
- ofn.lpstrFile = g_OutputFileName;
- }
- else
- {
- ofn.lpstrFilter = TEXT("Microsoft AVI\0*.avi\0\0");
- ofn.lpstrTitle = TEXT("Set input File Name");
- ofn.lpstrFile = g_InputFileName;
- }
-
- if (GetOpenFileName(&ofn))
- {
- if (IDM_OPTIONS_SAVEGRAPH == LOWORD (wParam))
- {
- lstrcpy(g_FilterGraphFileName, ofn.lpstrFile);
- // Save the current built filter graph to a *.grf file
- DV_SaveGraph(g_FilterGraphFileName);
- }
- else if (IDM_SETOUTPUT == LOWORD (wParam))
- {
- lstrcpy(g_OutputFileName, ofn.lpstrFile);
- }
- else
- {
- lstrcpy(g_InputFileName, ofn.lpstrFile);
- }
- }
- break;
- }
-
- case IDM_CAPSIZE:
- DialogBox((HINSTANCE)GetWindowLongPtr(hwnd, GWLP_HINSTANCE), MAKEINTRESOURCE(IDD_DIALOG_CAPSIZE), hwnd, (DLGPROC)DV_CapSizeDlgProc);
- break;
-
- case IDM_EXIT :
- return SendMessage(hwnd, WM_DESTROY, 0,0);
-
- // Graph Mode Menu
- //Change the Current Graph Mode
- case IDM_PREVIEW :
- case IDM_FILETODV :
- case IDM_FILETODV_NOPRE :
- case IDM_DVTOFILE :
- case IDM_DVTOFILE_NOPRE :
- case IDM_FILETODV_TYPE2 :
- case IDM_FILETODV_NOPRE_TYPE2 :
- case IDM_DVTOFILE_TYPE2 :
- case IDM_DVTOFILE_NOPRE_TYPE2 :
- DV_GraphModeCommand_WndProc (hwnd, iMsg, wParam, lParam);
- break;
-
- // Toolbar Button Commands
- // Transport State & Graph State Control
- case IDM_PLAY :
- case IDM_RECORD :
- case IDM_STOP :
- case IDM_PAUSE :
- case IDM_FF :
- case IDM_REW :
- case IDM_PLAY_FAST_FF :
- case IDM_PLAY_FAST_REV :
- case IDM_STEP_FWD :
- case IDM_STEP_REV :
- case IDM_SEEKTIMECODE :
- DV_TransportCommand_WndProc(hwnd, iMsg, wParam, lParam);
- break;
-
- // The Options Menu
- case IDM_DECODESIZE :
- DialogBox((HINSTANCE)GetWindowLongPtr(hwnd, GWLP_HINSTANCE), MAKEINTRESOURCE(IDD_DIALOG_DECODESIZE), hwnd, (DLGPROC)DV_ChangeDecodeSizeProc);
- break;
-
- case IDM_CHECKTAPE :
- if (S_OK != DV_GetTapeInfo())
- {
- MBOX(TEXT("Tape is not inserted, or has an improper format.\nReinsert the tape and select Options - Check Tape again"));
- }
- break;
-
- case IDM_REFRESHMODE :
- DV_RefreshMode();
- break;
-
- // Log Menu :: Set logging Priority & level
- case IDM_LEVEL_SUCCINCT :
- CheckMenuItem(hmenu, IDM_LEVEL_SUCCINCT, MF_CHECKED);
- CheckMenuItem(hmenu, IDM_LEVEL_MEDIUM, MF_UNCHECKED);
- CheckMenuItem(hmenu, IDM_LEVEL_VERBOSE, MF_UNCHECKED);
- g_iLogLevel = LOG_LEVEL_SUCCINCT;
- break;
- case IDM_LEVEL_MEDIUM :
- CheckMenuItem(hmenu, IDM_LEVEL_SUCCINCT, MF_UNCHECKED);
- CheckMenuItem(hmenu, IDM_LEVEL_MEDIUM, MF_CHECKED);
- CheckMenuItem(hmenu, IDM_LEVEL_VERBOSE, MF_UNCHECKED);
- g_iLogLevel = LOG_LEVEL_MEDIUM;
- break;
- case IDM_LEVEL_VERBOSE :
- CheckMenuItem(hmenu, IDM_LEVEL_SUCCINCT, MF_UNCHECKED);
- CheckMenuItem(hmenu, IDM_LEVEL_MEDIUM, MF_UNCHECKED);
- CheckMenuItem(hmenu, IDM_LEVEL_VERBOSE, MF_CHECKED);
- g_iLogLevel = LOG_LEVEL_VERBOSE;
- break;
-
- case IDM_PRIORITY_ERROR :
- CheckMenuItem(hmenu, IDM_PRIORITY_ERROR, MF_CHECKED);
- CheckMenuItem(hmenu, IDM_PRIORITY_WARN, MF_UNCHECKED);
- CheckMenuItem(hmenu, IDM_PRIORITY_INFO, MF_UNCHECKED);
- g_iLogPriority = LOG_PRIORITY_ERROR;
- break;
- case IDM_PRIORITY_WARN :
- CheckMenuItem(hmenu, IDM_PRIORITY_ERROR, MF_UNCHECKED);
- CheckMenuItem(hmenu, IDM_PRIORITY_WARN, MF_CHECKED);
- CheckMenuItem(hmenu, IDM_PRIORITY_INFO, MF_UNCHECKED);
- g_iLogPriority = LOG_PRIORITY_WARN;
- break;
- case IDM_PRIORITY_INFO :
- CheckMenuItem(hmenu, IDM_PRIORITY_ERROR, MF_UNCHECKED);
- CheckMenuItem(hmenu, IDM_PRIORITY_WARN, MF_UNCHECKED);
- CheckMenuItem(hmenu, IDM_PRIORITY_INFO, MF_CHECKED);
- g_iLogPriority = LOG_PRIORITY_INFO;
- break;
-
- } // switch (LOWORD(wParam))
-
-
- } // switch (iMsg)
- return DefWindowProc (hwnd, iMsg, wParam, lParam) ;
- }
-
-
- /*-------------------------------------------------------------------------
- Routine: DV_GraphModeCommand_WndProc
- Purpose: Message Handler for Graph Mode menu items
- Arguments: Usual message processing parameters
- Returns: Usual
- Notes: Builds the various kinds of Graph types preview/capture/transmit
- ------------------------------------------------------------------------*/
- void CALLBACK DV_GraphModeCommand_WndProc (HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
- {
- HMENU hmenu;
- switch (iMsg)
- {
- case WM_COMMAND :
- hmenu = GetMenu(hwnd);
- switch (LOWORD (wParam))
- {
- case IDM_PREVIEW :
- // Call the Special DV Graph Builder Method
- if (DV_MakeSpecialGraph(GRAPH_PREVIEW))
- {
- // update globals, log, toolbar, menu items
- g_iCurrentGraph = GRAPH_PREVIEW;
- DV_LogOut(LOG_PRIORITY_INFO, LOG_LEVEL_SUCCINCT, TEXT("Built Preview Graph"));
-
- SendMessage(g_hwndTBar, TB_SETSTATE, IDM_RECORD, MAKELONG(TBSTATE_INDETERMINATE, 0L));
- //re-enable everything else
- SendMessage(g_hwndTBar, TB_SETSTATE, IDM_STEP_REV, MAKELONG(TBSTATE_ENABLED, 0L));
- SendMessage(g_hwndTBar, TB_SETSTATE, IDM_REW, MAKELONG(TBSTATE_ENABLED, 0L));
- SendMessage(g_hwndTBar, TB_SETSTATE, IDM_PLAY_FAST_REV, MAKELONG(TBSTATE_ENABLED, 0L));
- SendMessage(g_hwndTBar, TB_SETSTATE, IDM_PLAY_FAST_FF, MAKELONG(TBSTATE_ENABLED, 0L));
- SendMessage(g_hwndTBar, TB_SETSTATE, IDM_FF, MAKELONG(TBSTATE_ENABLED, 0L));
- SendMessage(g_hwndTBar, TB_SETSTATE, IDM_STEP_FWD, MAKELONG(TBSTATE_ENABLED, 0L));
- SendMessage(g_hwndTBar, TB_SETSTATE, IDM_SEEKTIMECODE, MAKELONG(TBSTATE_ENABLED, 0L));
-
- CheckMenuItem(hmenu, IDM_PREVIEW, MF_CHECKED);
- CheckMenuItem(hmenu, IDM_FILETODV, MF_UNCHECKED);
- CheckMenuItem(hmenu, IDM_FILETODV_NOPRE, MF_UNCHECKED);
- CheckMenuItem(hmenu, IDM_DVTOFILE, MF_UNCHECKED);
- CheckMenuItem(hmenu, IDM_DVTOFILE_NOPRE, MF_UNCHECKED);
-
- CheckMenuItem(hmenu, IDM_FILETODV_TYPE2, MF_UNCHECKED);
- CheckMenuItem(hmenu, IDM_FILETODV_NOPRE_TYPE2, MF_UNCHECKED);
- CheckMenuItem(hmenu, IDM_DVTOFILE_TYPE2, MF_UNCHECKED);
- CheckMenuItem(hmenu, IDM_DVTOFILE_NOPRE_TYPE2, MF_UNCHECKED);
- }
- break;
-
- // Type 1 file (transmit & playback)
- case IDM_FILETODV :
- if (DV_MakeSpecialGraph(GRAPH_FILE_TO_DV))
- {
- // update globals, log, toolbar, menu items
- g_iCurrentGraph = GRAPH_FILE_TO_DV;
- DV_LogOut(LOG_PRIORITY_INFO, LOG_LEVEL_SUCCINCT, TEXT("Built File to DV Graph (Type1)"));
- SendMessage(g_hwndTBar, TB_SETSTATE, IDM_RECORD, MAKELONG(TBSTATE_ENABLED, 0L));
-
- //disable everything except for play, pause, and stop
- SendMessage(g_hwndTBar, TB_SETSTATE, IDM_STEP_REV, MAKELONG(TBSTATE_INDETERMINATE, 0L));
- SendMessage(g_hwndTBar, TB_SETSTATE, IDM_REW, MAKELONG(TBSTATE_INDETERMINATE, 0L));
- SendMessage(g_hwndTBar, TB_SETSTATE, IDM_PLAY_FAST_REV, MAKELONG(TBSTATE_INDETERMINATE, 0L));
- SendMessage(g_hwndTBar, TB_SETSTATE, IDM_PLAY_FAST_FF, MAKELONG(TBSTATE_INDETERMINATE, 0L));
- SendMessage(g_hwndTBar, TB_SETSTATE, IDM_FF, MAKELONG(TBSTATE_INDETERMINATE, 0L));
- SendMessage(g_hwndTBar, TB_SETSTATE, IDM_STEP_FWD, MAKELONG(TBSTATE_INDETERMINATE, 0L));
- SendMessage(g_hwndTBar, TB_SETSTATE, IDM_SEEKTIMECODE, MAKELONG(TBSTATE_INDETERMINATE, 0L));
-
- CheckMenuItem(hmenu, IDM_PREVIEW, MF_UNCHECKED);
- CheckMenuItem(hmenu, IDM_FILETODV, MF_CHECKED);
- CheckMenuItem(hmenu, IDM_FILETODV_NOPRE, MF_UNCHECKED);
- CheckMenuItem(hmenu, IDM_DVTOFILE, MF_UNCHECKED);
- CheckMenuItem(hmenu, IDM_DVTOFILE_NOPRE, MF_UNCHECKED);
-
- CheckMenuItem(hmenu, IDM_FILETODV_TYPE2, MF_UNCHECKED);
- CheckMenuItem(hmenu, IDM_FILETODV_NOPRE_TYPE2, MF_UNCHECKED);
- CheckMenuItem(hmenu, IDM_DVTOFILE_TYPE2, MF_UNCHECKED);
- CheckMenuItem(hmenu, IDM_DVTOFILE_NOPRE_TYPE2, MF_UNCHECKED);
- }
- break;
-
- // Type 1 file (transmit)
- case IDM_FILETODV_NOPRE :
- if (DV_MakeSpecialGraph(GRAPH_FILE_TO_DV_NOPRE))
- {
- // update globals, log, toolbar, menu items
- g_iCurrentGraph = GRAPH_FILE_TO_DV_NOPRE;
- DV_LogOut(LOG_PRIORITY_INFO, LOG_LEVEL_SUCCINCT, TEXT("Built File to DV Graph (Type1) without Preview"));
- SendMessage(g_hwndTBar, TB_SETSTATE, IDM_RECORD, MAKELONG(TBSTATE_ENABLED, 0L));
-
- //disable everything except for play, pause, and stop
- SendMessage(g_hwndTBar, TB_SETSTATE, IDM_STEP_REV, MAKELONG(TBSTATE_INDETERMINATE, 0L));
- SendMessage(g_hwndTBar, TB_SETSTATE, IDM_REW, MAKELONG(TBSTATE_INDETERMINATE, 0L));
- SendMessage(g_hwndTBar, TB_SETSTATE, IDM_PLAY_FAST_REV, MAKELONG(TBSTATE_INDETERMINATE, 0L));
- SendMessage(g_hwndTBar, TB_SETSTATE, IDM_PLAY_FAST_FF, MAKELONG(TBSTATE_INDETERMINATE, 0L));
- SendMessage(g_hwndTBar, TB_SETSTATE, IDM_FF, MAKELONG(TBSTATE_INDETERMINATE, 0L));
- SendMessage(g_hwndTBar, TB_SETSTATE, IDM_STEP_FWD, MAKELONG(TBSTATE_INDETERMINATE, 0L));
- SendMessage(g_hwndTBar, TB_SETSTATE, IDM_SEEKTIMECODE, MAKELONG(TBSTATE_INDETERMINATE, 0L));
-
- CheckMenuItem(hmenu, IDM_PREVIEW, MF_UNCHECKED);
- CheckMenuItem(hmenu, IDM_FILETODV, MF_UNCHECKED);
- CheckMenuItem(hmenu, IDM_DVTOFILE, MF_UNCHECKED);
- CheckMenuItem(hmenu, IDM_FILETODV_NOPRE, MF_CHECKED);
- CheckMenuItem(hmenu, IDM_DVTOFILE_NOPRE, MF_UNCHECKED);
-
- CheckMenuItem(hmenu, IDM_FILETODV_TYPE2, MF_UNCHECKED);
- CheckMenuItem(hmenu, IDM_FILETODV_NOPRE_TYPE2, MF_UNCHECKED);
- CheckMenuItem(hmenu, IDM_DVTOFILE_TYPE2, MF_UNCHECKED);
- CheckMenuItem(hmenu, IDM_DVTOFILE_NOPRE_TYPE2, MF_UNCHECKED);
-
- }
- break;
-
- // Type 1 file (capture & preview)
- case IDM_DVTOFILE :
- if (DV_MakeSpecialGraph(GRAPH_DV_TO_FILE))
- {
- // update globals, log, toolbar, menu items
- g_iCurrentGraph = GRAPH_DV_TO_FILE;
- DV_LogOut(LOG_PRIORITY_INFO, LOG_LEVEL_SUCCINCT, TEXT("Built DV to File Graph (Type1)"));
- SendMessage(g_hwndTBar, TB_SETSTATE, IDM_RECORD, MAKELONG(TBSTATE_ENABLED, 0L));
- CheckMenuItem(hmenu, IDM_PREVIEW, MF_UNCHECKED);
- CheckMenuItem(hmenu, IDM_FILETODV, MF_UNCHECKED);
- CheckMenuItem(hmenu, IDM_DVTOFILE, MF_CHECKED);
- CheckMenuItem(hmenu, IDM_FILETODV_NOPRE, MF_UNCHECKED);
- CheckMenuItem(hmenu, IDM_DVTOFILE_NOPRE, MF_UNCHECKED);
-
- CheckMenuItem(hmenu, IDM_FILETODV_TYPE2, MF_UNCHECKED);
- CheckMenuItem(hmenu, IDM_FILETODV_NOPRE_TYPE2, MF_UNCHECKED);
- CheckMenuItem(hmenu, IDM_DVTOFILE_TYPE2, MF_UNCHECKED);
- CheckMenuItem(hmenu, IDM_DVTOFILE_NOPRE_TYPE2, MF_UNCHECKED);
- //re-enable everything
- SendMessage(g_hwndTBar, TB_SETSTATE, IDM_STEP_REV, MAKELONG(TBSTATE_ENABLED, 0L));
- SendMessage(g_hwndTBar, TB_SETSTATE, IDM_REW, MAKELONG(TBSTATE_ENABLED, 0L));
- SendMessage(g_hwndTBar, TB_SETSTATE, IDM_PLAY_FAST_REV, MAKELONG(TBSTATE_ENABLED, 0L));
- SendMessage(g_hwndTBar, TB_SETSTATE, IDM_PLAY_FAST_FF, MAKELONG(TBSTATE_ENABLED, 0L));
- SendMessage(g_hwndTBar, TB_SETSTATE, IDM_FF, MAKELONG(TBSTATE_ENABLED, 0L));
- SendMessage(g_hwndTBar, TB_SETSTATE, IDM_STEP_FWD, MAKELONG(TBSTATE_ENABLED, 0L));
- SendMessage(g_hwndTBar, TB_SETSTATE, IDM_SEEKTIMECODE, MAKELONG(TBSTATE_ENABLED, 0L));
- SendMessage(g_hwndTBar, TB_SETSTATE, IDM_RECORD, MAKELONG(TBSTATE_ENABLED, 0L));
-
- }
- break;
-
- // Type 1 file (capture)
- case IDM_DVTOFILE_NOPRE :
- if (DV_MakeSpecialGraph(GRAPH_DV_TO_FILE_NOPRE))
- {
- // update globals, log, toolbar, menu items
- g_iCurrentGraph = GRAPH_DV_TO_FILE_NOPRE;
- DV_LogOut(LOG_PRIORITY_INFO, LOG_LEVEL_SUCCINCT, TEXT("Built DV to File Graph (Type1) without Preview"));
- SendMessage(g_hwndTBar, TB_SETSTATE, IDM_RECORD, MAKELONG(TBSTATE_ENABLED, 0L));
- CheckMenuItem(hmenu, IDM_PREVIEW, MF_UNCHECKED);
- CheckMenuItem(hmenu, IDM_FILETODV, MF_UNCHECKED);
- CheckMenuItem(hmenu, IDM_DVTOFILE, MF_UNCHECKED);
- CheckMenuItem(hmenu, IDM_FILETODV_NOPRE, MF_UNCHECKED);
- CheckMenuItem(hmenu, IDM_DVTOFILE_NOPRE, MF_CHECKED);
-
- CheckMenuItem(hmenu, IDM_FILETODV_TYPE2, MF_UNCHECKED);
- CheckMenuItem(hmenu, IDM_FILETODV_NOPRE_TYPE2, MF_UNCHECKED);
- CheckMenuItem(hmenu, IDM_DVTOFILE_TYPE2, MF_UNCHECKED);
- CheckMenuItem(hmenu, IDM_DVTOFILE_NOPRE_TYPE2, MF_UNCHECKED);
-
- //re-enable everything
- SendMessage(g_hwndTBar, TB_SETSTATE, IDM_STEP_REV, MAKELONG(TBSTATE_ENABLED, 0L));
- SendMessage(g_hwndTBar, TB_SETSTATE, IDM_REW, MAKELONG(TBSTATE_ENABLED, 0L));
- SendMessage(g_hwndTBar, TB_SETSTATE, IDM_PLAY_FAST_REV, MAKELONG(TBSTATE_ENABLED, 0L));
- SendMessage(g_hwndTBar, TB_SETSTATE, IDM_PLAY_FAST_FF, MAKELONG(TBSTATE_ENABLED, 0L));
- SendMessage(g_hwndTBar, TB_SETSTATE, IDM_FF, MAKELONG(TBSTATE_ENABLED, 0L));
- SendMessage(g_hwndTBar, TB_SETSTATE, IDM_STEP_FWD, MAKELONG(TBSTATE_ENABLED, 0L));
- SendMessage(g_hwndTBar, TB_SETSTATE, IDM_SEEKTIMECODE, MAKELONG(TBSTATE_ENABLED, 0L));
- SendMessage(g_hwndTBar, TB_SETSTATE, IDM_RECORD, MAKELONG(TBSTATE_ENABLED, 0L));
- }
- break;
-
- // Type 2 File (transmit & playback)
- case IDM_FILETODV_TYPE2 :
- if (DV_MakeSpecialGraph(GRAPH_FILE_TO_DV_TYPE2))
- {
- // update globals, log, toolbar, menu items
- g_iCurrentGraph = GRAPH_FILE_TO_DV_TYPE2;
- DV_LogOut(LOG_PRIORITY_INFO, LOG_LEVEL_SUCCINCT, TEXT("Built File to DV Graph (Type2)"));
- SendMessage(g_hwndTBar, TB_SETSTATE, IDM_RECORD, MAKELONG(TBSTATE_ENABLED, 0L));
-
- //disable everything except for play, pause, and stop
- SendMessage(g_hwndTBar, TB_SETSTATE, IDM_STEP_REV, MAKELONG(TBSTATE_INDETERMINATE, 0L));
- SendMessage(g_hwndTBar, TB_SETSTATE, IDM_REW, MAKELONG(TBSTATE_INDETERMINATE, 0L));
- SendMessage(g_hwndTBar, TB_SETSTATE, IDM_PLAY_FAST_REV, MAKELONG(TBSTATE_INDETERMINATE, 0L));
- SendMessage(g_hwndTBar, TB_SETSTATE, IDM_PLAY_FAST_FF, MAKELONG(TBSTATE_INDETERMINATE, 0L));
- SendMessage(g_hwndTBar, TB_SETSTATE, IDM_FF, MAKELONG(TBSTATE_INDETERMINATE, 0L));
- SendMessage(g_hwndTBar, TB_SETSTATE, IDM_STEP_FWD, MAKELONG(TBSTATE_INDETERMINATE, 0L));
- SendMessage(g_hwndTBar, TB_SETSTATE, IDM_SEEKTIMECODE, MAKELONG(TBSTATE_INDETERMINATE, 0L));
-
- CheckMenuItem(hmenu, IDM_PREVIEW, MF_UNCHECKED);
- CheckMenuItem(hmenu, IDM_FILETODV, MF_UNCHECKED);
- CheckMenuItem(hmenu, IDM_FILETODV_NOPRE, MF_UNCHECKED);
- CheckMenuItem(hmenu, IDM_DVTOFILE, MF_UNCHECKED);
- CheckMenuItem(hmenu, IDM_DVTOFILE_NOPRE, MF_UNCHECKED);
-
- CheckMenuItem(hmenu, IDM_FILETODV_TYPE2, MF_CHECKED);
- CheckMenuItem(hmenu, IDM_FILETODV_NOPRE_TYPE2, MF_UNCHECKED);
- CheckMenuItem(hmenu, IDM_DVTOFILE_TYPE2, MF_UNCHECKED);
- CheckMenuItem(hmenu, IDM_DVTOFILE_NOPRE_TYPE2, MF_UNCHECKED);
- }
- break;
-
- // Type 2 File (transmit)
- case IDM_FILETODV_NOPRE_TYPE2 :
- if (DV_MakeSpecialGraph(GRAPH_FILE_TO_DV_NOPRE_TYPE2))
- {
- // update globals, log, toolbar, menu items
- g_iCurrentGraph = GRAPH_FILE_TO_DV_NOPRE_TYPE2;
- DV_LogOut(LOG_PRIORITY_INFO, LOG_LEVEL_SUCCINCT, TEXT("Built File to DV Graph (Type2) without Preview"));
- SendMessage(g_hwndTBar, TB_SETSTATE, IDM_RECORD, MAKELONG(TBSTATE_ENABLED, 0L));
-
- //disable everything except for play, pause, and stop
- SendMessage(g_hwndTBar, TB_SETSTATE, IDM_STEP_REV, MAKELONG(TBSTATE_INDETERMINATE, 0L));
- SendMessage(g_hwndTBar, TB_SETSTATE, IDM_REW, MAKELONG(TBSTATE_INDETERMINATE, 0L));
- SendMessage(g_hwndTBar, TB_SETSTATE, IDM_PLAY_FAST_REV, MAKELONG(TBSTATE_INDETERMINATE, 0L));
- SendMessage(g_hwndTBar, TB_SETSTATE, IDM_PLAY_FAST_FF, MAKELONG(TBSTATE_INDETERMINATE, 0L));
- SendMessage(g_hwndTBar, TB_SETSTATE, IDM_FF, MAKELONG(TBSTATE_INDETERMINATE, 0L));
- SendMessage(g_hwndTBar, TB_SETSTATE, IDM_STEP_FWD, MAKELONG(TBSTATE_INDETERMINATE, 0L));
- SendMessage(g_hwndTBar, TB_SETSTATE, IDM_SEEKTIMECODE, MAKELONG(TBSTATE_INDETERMINATE, 0L));
-
- CheckMenuItem(hmenu, IDM_PREVIEW, MF_UNCHECKED);
- CheckMenuItem(hmenu, IDM_FILETODV, MF_UNCHECKED);
- CheckMenuItem(hmenu, IDM_DVTOFILE, MF_UNCHECKED);
- CheckMenuItem(hmenu, IDM_FILETODV_NOPRE, MF_UNCHECKED);
- CheckMenuItem(hmenu, IDM_DVTOFILE_NOPRE, MF_UNCHECKED);
-
- CheckMenuItem(hmenu, IDM_FILETODV_TYPE2, MF_UNCHECKED);
- CheckMenuItem(hmenu, IDM_FILETODV_NOPRE_TYPE2, MF_CHECKED);
- CheckMenuItem(hmenu, IDM_DVTOFILE_TYPE2, MF_UNCHECKED);
- CheckMenuItem(hmenu, IDM_DVTOFILE_NOPRE_TYPE2, MF_UNCHECKED);
- }
- break;
-
- // Type 2 File (capture & preview)
- case IDM_DVTOFILE_TYPE2 :
- if (DV_MakeSpecialGraph(GRAPH_DV_TO_FILE_TYPE2))
- {
- // update globals, log, toolbar, menu items
- g_iCurrentGraph = GRAPH_DV_TO_FILE_TYPE2;
- DV_LogOut(LOG_PRIORITY_INFO, LOG_LEVEL_SUCCINCT, TEXT("Built DV to File Graph (Type2)"));
- SendMessage(g_hwndTBar, TB_SETSTATE, IDM_RECORD, MAKELONG(TBSTATE_ENABLED, 0L));
- CheckMenuItem(hmenu, IDM_PREVIEW, MF_UNCHECKED);
- CheckMenuItem(hmenu, IDM_FILETODV, MF_UNCHECKED);
- CheckMenuItem(hmenu, IDM_DVTOFILE, MF_UNCHECKED);
- CheckMenuItem(hmenu, IDM_FILETODV_NOPRE, MF_UNCHECKED);
- CheckMenuItem(hmenu, IDM_DVTOFILE_NOPRE, MF_UNCHECKED);
-
- CheckMenuItem(hmenu, IDM_FILETODV_TYPE2, MF_UNCHECKED);
- CheckMenuItem(hmenu, IDM_FILETODV_NOPRE_TYPE2, MF_UNCHECKED);
- CheckMenuItem(hmenu, IDM_DVTOFILE_TYPE2, MF_CHECKED);
- CheckMenuItem(hmenu, IDM_DVTOFILE_NOPRE_TYPE2, MF_UNCHECKED);
- //re-enable everything
- SendMessage(g_hwndTBar, TB_SETSTATE, IDM_STEP_REV, MAKELONG(TBSTATE_ENABLED, 0L));
- SendMessage(g_hwndTBar, TB_SETSTATE, IDM_REW, MAKELONG(TBSTATE_ENABLED, 0L));
- SendMessage(g_hwndTBar, TB_SETSTATE, IDM_PLAY_FAST_REV, MAKELONG(TBSTATE_ENABLED, 0L));
- SendMessage(g_hwndTBar, TB_SETSTATE, IDM_PLAY_FAST_FF, MAKELONG(TBSTATE_ENABLED, 0L));
- SendMessage(g_hwndTBar, TB_SETSTATE, IDM_FF, MAKELONG(TBSTATE_ENABLED, 0L));
- SendMessage(g_hwndTBar, TB_SETSTATE, IDM_STEP_FWD, MAKELONG(TBSTATE_ENABLED, 0L));
- SendMessage(g_hwndTBar, TB_SETSTATE, IDM_SEEKTIMECODE, MAKELONG(TBSTATE_ENABLED, 0L));
- SendMessage(g_hwndTBar, TB_SETSTATE, IDM_RECORD, MAKELONG(TBSTATE_ENABLED, 0L));
-
- }
- break;
-
- // Type 2 File (capture)
- case IDM_DVTOFILE_NOPRE_TYPE2 :
- if (DV_MakeSpecialGraph(GRAPH_DV_TO_FILE_NOPRE_TYPE2))
- {
- // update globals, log, toolbar, menu items
- g_iCurrentGraph = GRAPH_DV_TO_FILE_NOPRE_TYPE2;
- DV_LogOut(LOG_PRIORITY_INFO, LOG_LEVEL_SUCCINCT, TEXT("Built DV to File Graph (Type2) without Preview"));
- SendMessage(g_hwndTBar, TB_SETSTATE, IDM_RECORD, MAKELONG(TBSTATE_ENABLED, 0L));
- CheckMenuItem(hmenu, IDM_PREVIEW, MF_UNCHECKED);
- CheckMenuItem(hmenu, IDM_FILETODV, MF_UNCHECKED);
- CheckMenuItem(hmenu, IDM_DVTOFILE, MF_UNCHECKED);
- CheckMenuItem(hmenu, IDM_FILETODV_NOPRE, MF_UNCHECKED);
- CheckMenuItem(hmenu, IDM_DVTOFILE_NOPRE, MF_UNCHECKED);
-
- CheckMenuItem(hmenu, IDM_FILETODV_TYPE2, MF_UNCHECKED);
- CheckMenuItem(hmenu, IDM_FILETODV_NOPRE_TYPE2, MF_UNCHECKED);
- CheckMenuItem(hmenu, IDM_DVTOFILE_TYPE2, MF_UNCHECKED);
- CheckMenuItem(hmenu, IDM_DVTOFILE_NOPRE_TYPE2, MF_CHECKED);
-
- //re-enable everything
- SendMessage(g_hwndTBar, TB_SETSTATE, IDM_STEP_REV, MAKELONG(TBSTATE_ENABLED, 0L));
- SendMessage(g_hwndTBar, TB_SETSTATE, IDM_REW, MAKELONG(TBSTATE_ENABLED, 0L));
- SendMessage(g_hwndTBar, TB_SETSTATE, IDM_PLAY_FAST_REV, MAKELONG(TBSTATE_ENABLED, 0L));
- SendMessage(g_hwndTBar, TB_SETSTATE, IDM_PLAY_FAST_FF, MAKELONG(TBSTATE_ENABLED, 0L));
- SendMessage(g_hwndTBar, TB_SETSTATE, IDM_FF, MAKELONG(TBSTATE_ENABLED, 0L));
- SendMessage(g_hwndTBar, TB_SETSTATE, IDM_STEP_FWD, MAKELONG(TBSTATE_ENABLED, 0L));
- SendMessage(g_hwndTBar, TB_SETSTATE, IDM_SEEKTIMECODE, MAKELONG(TBSTATE_ENABLED, 0L));
- SendMessage(g_hwndTBar, TB_SETSTATE, IDM_RECORD, MAKELONG(TBSTATE_ENABLED, 0L));
-
- }
- break;
- } // switch (LOWORD(wParam))
- } // switch (iMsg)
- }
-
- /*-------------------------------------------------------------------------
- Routine: DV_AppSetup
- Purpose: look for a DV device, initialize it, get its subunit mode, Create the filtergraph and instantiate the filters
- Arguments: None
- Returns: None
- Notes:
- ------------------------------------------------------------------------*/
- void DV_AppSetup(void)
- {
-
- // COM initialization
- CoInitialize(NULL);
-
- HMENU hmenu = GetMenu(g_hwndApp);
- /*
- look for a DV device and initialize it,
- or show an error if one does not exist
- */
- if (!DV_InitDevice())
- {
- g_bDeviceFound = FALSE;
- int iOption = MessageBox(g_hwndApp, TEXT("There are no DV Camcorder devices on this system\n\nDo you want to exit the app?"), APPNAME, MB_YESNO);
- if(iOption == IDYES)
- SendMessage(g_hwndApp, WM_DESTROY, 0,0);
- else
- {
- DV_CleanUp();
- ShowWindow(g_hwndTBar, SW_HIDE);
-
- EnableMenuItem(hmenu, IDM_REFRESHMODE, MF_GRAYED);
- EnableMenuItem(hmenu, IDM_CHECKTAPE, MF_GRAYED);
- EnableMenuItem(hmenu, IDM_DECODESIZE, MF_GRAYED);
- EnableMenuItem(hmenu, IDM_PREVIEW, MF_GRAYED);
-
- EnableMenuItem(hmenu, IDM_DVTOFILE, MF_GRAYED);
- EnableMenuItem(hmenu, IDM_DVTOFILE_NOPRE, MF_GRAYED);
- EnableMenuItem(hmenu, IDM_FILETODV, MF_GRAYED);
- EnableMenuItem(hmenu, IDM_FILETODV_NOPRE, MF_GRAYED);
-
- EnableMenuItem(hmenu, IDM_DVTOFILE_TYPE2, MF_GRAYED);
- EnableMenuItem(hmenu, IDM_DVTOFILE_NOPRE_TYPE2, MF_GRAYED);
- EnableMenuItem(hmenu, IDM_FILETODV_TYPE2, MF_GRAYED);
- EnableMenuItem(hmenu, IDM_FILETODV_NOPRE_TYPE2, MF_GRAYED);
- }
- }
- else
- {
- g_bDeviceFound = TRUE;
- ShowWindow(g_hwndTBar, SW_SHOWNORMAL);
- EnableMenuItem(hmenu, IDM_REFRESHMODE, MF_ENABLED);
- EnableMenuItem(hmenu, IDM_CHECKTAPE, MF_ENABLED);
- EnableMenuItem(hmenu, IDM_DECODESIZE, MF_ENABLED);
- EnableMenuItem(hmenu, IDM_PREVIEW, MF_ENABLED);
-
- EnableMenuItem(hmenu, IDM_DVTOFILE, MF_ENABLED);
- EnableMenuItem(hmenu, IDM_DVTOFILE_NOPRE, MF_ENABLED);
- EnableMenuItem(hmenu, IDM_FILETODV, MF_ENABLED);
- EnableMenuItem(hmenu, IDM_FILETODV_NOPRE, MF_ENABLED);
-
- EnableMenuItem(hmenu, IDM_DVTOFILE_TYPE2, MF_ENABLED);
- EnableMenuItem(hmenu, IDM_DVTOFILE_NOPRE_TYPE2, MF_ENABLED);
- EnableMenuItem(hmenu, IDM_FILETODV_TYPE2, MF_ENABLED);
- EnableMenuItem(hmenu, IDM_FILETODV_NOPRE_TYPE2, MF_ENABLED);
-
- //if we are here, all of our interfaces should be valid
- ASSERT(g_pBuilder);
- ASSERT(g_pGraphBuilder);
- ASSERT(g_pDVCamera);
-
- //get directshow interfaces for DV
- g_pBuilder->FindInterface(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video, g_pDVCamera, IID_IAMExtTransport, reinterpret_cast<PVOID*>(&g_pExtTrans));
- g_pBuilder->FindInterface(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video, g_pDVCamera, IID_IAMTimecodeReader, reinterpret_cast<PVOID*>(&g_pTimeReader));
-
- //determine if we are in camera mode or vcr mode and disable unavailable menu items
- // Use GetDVMode to *not* use AVC commands
-
- switch (DV_GetDVMode())
- {
- case CameraMode :
- EnableMenuItem(hmenu, IDM_FILETODV, MF_GRAYED);
- EnableMenuItem(hmenu, IDM_FILETODV_NOPRE, MF_GRAYED);
- EnableMenuItem(hmenu, IDM_FILETODV_TYPE2, MF_GRAYED);
- EnableMenuItem(hmenu, IDM_FILETODV_NOPRE_TYPE2, MF_GRAYED);
- EnableMenuItem(hmenu, IDM_CHECKTAPE, MF_GRAYED);
- DV_StatusText(TEXT("Camera Mode"), 2);
- break;
-
- case VcrMode :
- //check information about the tape
- if (S_OK != DV_GetTapeInfo())
- {
- MBOX(TEXT("Tape is not inserted, or has an improper format.\nReinsert the tape and select Options - Check Tape"));
- }
- break;
-
- case UnknownMode :
- MBOX(TEXT("Cannot determine camera / Vcr mode"));
- DV_StatusText(TEXT("Unknown Mode"), 2);
- break;
-
- default :
- DV_LogOut(LOG_PRIORITY_ERROR, LOG_LEVEL_SUCCINCT, TEXT("Bad return value from DV_GetDVMode"));
- break;
- }
-
- // initialize the video window
- if (!DV_InitWindow())
- {
- MBOX(TEXT("Could not initialize video window"));
- SendMessage(g_hwndApp, WM_DESTROY, 0,0);
- }
- else
- {
- //If we've gotten this far, all of these components should be available
- //DV Splitter, DV Muxer, DV Codec is part of QDV
- EXECUTE_ASSERT(S_OK == CoCreateInstance(CLSID_DVSplitter, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, reinterpret_cast<PVOID *>(&g_pDVSplitter)));
- EXECUTE_ASSERT(S_OK == CoCreateInstance(CLSID_DVMux, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, reinterpret_cast<PVOID *>(&g_pDVMux)));
- EXECUTE_ASSERT(S_OK == CoCreateInstance(CLSID_DVVideoCodec, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, reinterpret_cast<PVOID *>(&g_pDVCodec)));
- // Other filters to help in building the graphs
- EXECUTE_ASSERT(S_OK == CoCreateInstance(CLSID_AviSplitter, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, reinterpret_cast<PVOID *>(&g_pAviSplitter)));
- EXECUTE_ASSERT(S_OK == CoCreateInstance(CLSID_SmartTee, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, reinterpret_cast<PVOID *>(&g_pSmartTee)));
- EXECUTE_ASSERT(S_OK == CoCreateInstance(CLSID_InfTee, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, reinterpret_cast<PVOID *>(&g_pInfTee)));
- EXECUTE_ASSERT(S_OK == CoCreateInstance(CLSID_VideoRenderer, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, reinterpret_cast<PVOID *>(&g_pVideoRenderer)));
- // The user may not have a sound card installed , so if this fails, we just won't do sound.
- CoCreateInstance(CLSID_DSoundRender, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, reinterpret_cast<PVOID *>(&g_pDSound));
-
- IMediaEventEx *pMe = NULL;
- if (SUCCEEDED(g_pGraphBuilder->QueryInterface(IID_IMediaEventEx, reinterpret_cast<PVOID *>(&pMe))))
- {
- pMe->SetNotifyWindow((LONG_PTR) g_hwndApp, WM_FGNOTIFY, 0);
- SAFE_RELEASE(pMe);
- }
-
- SetWindowText(g_hwndApp, DV_APPTITLE);
- DV_StatusText(g_DeviceName, 0);
- }
- }
-
- }
-
-
- /*-------------------------------------------------------------------------
- Routine: DV_InitControls
- Purpose: Initializer for app window controls (toolbars, edit controls, etc.)
- Arguments: window handle and hinstance
- Returns: FALSE if creation of any of the controls fails.
- Notes:
- ------------------------------------------------------------------------*/
- BOOL DV_InitControls(HWND hwnd, HINSTANCE hInst)
- {
- HWND hwndEdit1 = NULL;
- HWND hwndEdit2 = NULL;
- HWND hwndEdit3 = NULL;
- HWND hwndEdit4 = NULL;
- HWND hwndTCCheck = NULL;
-
- RECT rect = {0};
-
- InitCommonControls();
- // create status bar windows
- g_hwndStatus = CreateWindowEx( 0,
- STATUSCLASSNAME,
- TEXT(""),
- WS_CHILD | WS_BORDER | WS_VISIBLE | WS_CLIPSIBLINGS,
- -100, -100,
- 10, 10,
- hwnd,
- HMENU(IDB_STATUS),
- hInst,
- NULL);
- SendMessage(g_hwndStatus, SB_GETRECT, 0, (LPARAM)(LPRECT)&rect);
- g_statusHeight = rect.bottom;
- //Set the initial size for the status bar parts. The WM_SIZE handler will take care of it from here
- DV_StatusParts(g_iAppWidth);
-
- // create toolbar window
- g_hwndTBar = CreateToolbarEx(hwnd,
- WS_CHILD | WS_VISIBLE | WS_BORDER | TBSTYLE_TOOLTIPS,
- ID_TOOLBAR,
- 10,
- hInst,
- IDB_TOOLBAR,
- g_rgTbButtons,
- sizeof(g_rgTbButtons) / sizeof(TBBUTTON),
- 16,16,16,16,
- sizeof(TBBUTTON));
-
- SendMessage(g_hwndTBar, TB_GETRECT, IDM_SEEKTIMECODE, (LPARAM)&rect);
-
- if (!rect.right)
- {
- DV_LogOut(LOG_PRIORITY_WARN, LOG_LEVEL_MEDIUM, TEXT("Could not get rect of Seek Time code button"));
- rect.right = 350;
- }
- // create timecode text boxes on the toolbar
- hwndEdit1 = CreateWindow(TEXT("edit"), TEXT("00"), WS_CHILD | WS_BORDER | WS_VISIBLE | WS_TABSTOP | ES_NUMBER,
- rect.right + 6, 4, 22, 18, g_hwndTBar, (HMENU)IDC_EDIT_HOUR, (HINSTANCE) hInst, NULL);
-
- hwndEdit2 = CreateWindow(TEXT("edit"), TEXT("00"), WS_CHILD | WS_BORDER | WS_VISIBLE | WS_TABSTOP | ES_NUMBER,
- rect.right + 30, 4, 22, 18, g_hwndTBar, (HMENU)IDC_EDIT_MINUTE, (HINSTANCE) hInst, NULL);
-
- hwndEdit3 = CreateWindow(TEXT("edit"), TEXT("00"), WS_CHILD | WS_BORDER | WS_VISIBLE | WS_TABSTOP | ES_NUMBER,
- rect.right + 54, 4, 22, 18, g_hwndTBar, (HMENU)IDC_EDIT_SECOND, (HINSTANCE) hInst, NULL);
-
- hwndEdit4 = CreateWindow(TEXT("edit"), TEXT("00"), WS_CHILD | WS_BORDER | WS_VISIBLE | WS_TABSTOP | ES_NUMBER,
- rect.right + 78, 4, 22, 18, g_hwndTBar, (HMENU)IDC_EDIT_FRAME, (HINSTANCE) hInst, NULL);
-
- hwndTCCheck = CreateWindow(TEXT("button"), TEXT("Display Timecodes"), WS_CHILD | BS_AUTOCHECKBOX | WS_VISIBLE | WS_TABSTOP,
- rect.right + 106, 5, 150, 18, g_hwndTBar, (HMENU)IDC_TCCHECKBOX, (HINSTANCE) hInst, NULL);
- Button_SetCheck (hwndTCCheck, BST_CHECKED) ;
-
- //finally, resize the main window so it maintains the proper height despite the toolbar and status bar
- MoveWindow(g_hwndApp, CW_USEDEFAULT, CW_USEDEFAULT,
- g_iAppWidth, g_iAppHeight + (rect.bottom - rect.top) +
- (g_statusHeight + (2 * GetSystemMetrics(SM_CYBORDER))), TRUE);
-
- return (!( !hwndEdit1) || (!hwndEdit2) || (!hwndEdit3) || (!hwndEdit4) || (!hwndTCCheck) || (!g_hwndStatus));
-
- }
-
-
- /*-------------------------------------------------------------------------
- Routine: DV_InitDevice
- Purpose: Enumerates all video devices, and determines if it is a DV device.
- We'll do this by querying for an interface specific to DV - in this
- case, IAMExtDevice.
- Arguments: None
- Returns: TRUE if a DV device is found
- Notes: Will this solution work all the time. No, but then all other solutions are equally unreliable
- like comparing friendlyname or signal mode or device type on the transport.
- May be the mediatype of the Source filter should solve the problem, but then maybe not.
- ------------------------------------------------------------------------*/
- BOOL DV_InitDevice(void)
- {
- BOOL bStatus = FALSE;
- HRESULT hr;
- UINT uIndex = 0;
- ICreateDevEnum *pCreateDevEnum = NULL;
- // Before we can QI for IAMExtDevice, we need to build a graph and add our filter.
-
- // Create Device Enumerator
- hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER, IID_ICreateDevEnum, reinterpret_cast<PVOID *>(&pCreateDevEnum));
- if (SUCCEEDED(hr) )
- {
- // get the enumerator for videoinput devices
- IEnumMoniker *pEm;
- hr = pCreateDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, &pEm, 0);
- if (SUCCEEDED(hr) && pEm)
- {
- pCreateDevEnum->Release();
- {
- pEm->Reset();
- ULONG cFetched;
- IMoniker *pM;
- //loop while we can still enumerate, the enumeration succeeds, and while we have'nt yet found a dv camera
- while ( S_OK == (hr = pEm->Next(1, &pM, &cFetched)) && FALSE == bStatus )
- {
- // getting the propert page to get the device name
- IPropertyBag *pBag;
- hr = pM->BindToStorage(0, 0, IID_IPropertyBag, reinterpret_cast<PVOID *>(&pBag));
- if ( SUCCEEDED(hr) )
- {
- VARIANT var;
- var.vt = VT_BSTR;
- hr = pBag->Read(L"FriendlyName", &var, NULL);
- if ( SUCCEEDED(hr) )
- {
- //here, we'll save the device name
- #ifndef UNICODE
- WideCharToMultiByte(CP_ACP, 0, var.bstrVal, -1, g_DeviceName, DEVICENAME_BUFSIZE, NULL, NULL);
- #else
- lstrcpyW(g_DeviceName, var.bstrVal);
- #endif //UNICODE
- DV_LogOut(LOG_PRIORITY_INFO, LOG_LEVEL_SUCCINCT, TEXT("Device Found:\t%s"), g_DeviceName);
- SysFreeString(var.bstrVal);
- // Get the filter of video input device
- hr = pM->BindToObject(0, 0, IID_IBaseFilter, reinterpret_cast<PVOID *>(&g_pDVCamera));
- if ( g_pDVCamera == NULL )
- {
- DV_LogOut(LOG_PRIORITY_ERROR, LOG_LEVEL_SUCCINCT, TEXT("Error %x: Cannot create video capture filter"), hr);
- return FALSE;
- }
- else
- { // get the graph builder & capture graph builder to QI
- if (DV_GetGraphBuilder())
- {
- hr = CoCreateInstance((REFCLSID)CLSID_CaptureGraphBuilder2,
- NULL, CLSCTX_INPROC, (REFIID)IID_ICaptureGraphBuilder2,
- reinterpret_cast<PVOID *>(&g_pBuilder));
-
- if (SUCCEEDED(hr))
- {
- hr = g_pBuilder->SetFiltergraph(g_pGraphBuilder);
- if (SUCCEEDED(hr))
- {
- //add the DV cam to the graph
- hr = g_pGraphBuilder->AddFilter(g_pDVCamera, var.bstrVal);
- if (SUCCEEDED(hr))
- { // QI for IAMExtDevice
- hr = g_pBuilder->FindInterface(&PIN_CATEGORY_CAPTURE,
- &MEDIATYPE_Video,
- g_pDVCamera,IID_IAMExtDevice,
- reinterpret_cast<PVOID*>(&g_pExtDev));
- if (SUCCEEDED(hr))
- {
- //we have a DV camera
- DV_LogOut(LOG_PRIORITY_INFO, LOG_LEVEL_SUCCINCT, TEXT("We Have a DV camera"));
- bStatus = TRUE;
- }
- else
- {
- DV_LogOut(LOG_PRIORITY_INFO, LOG_LEVEL_SUCCINCT, TEXT("This is not a DV camera"));
- //release our interfaces
- SAFE_RELEASE(g_pGraphBuilder);
- SAFE_RELEASE(g_pBuilder);
- SAFE_RELEASE(g_pDVCamera);
- }
- }
- else
- {
- DV_LogOut(LOG_PRIORITY_ERROR, LOG_LEVEL_SUCCINCT, TEXT("AddFilter failed hr. = 0x%x"), hr);
- }
- }
- else
- {
- DV_LogOut(LOG_PRIORITY_ERROR, LOG_LEVEL_SUCCINCT, TEXT("SetFilterGraph failed. hr = 0x%x"), hr);
- }
- }
- else
- {
- DV_LogOut(LOG_PRIORITY_ERROR, LOG_LEVEL_SUCCINCT, TEXT("CoCreateInstance failed (ICaptureGraphbuilder2). hr = 0x%x"), hr);
- }
- }
- else
- {
- DV_LogOut(LOG_PRIORITY_ERROR, LOG_LEVEL_SUCCINCT, TEXT("DV_GetGraphBuilder failed"));
- }
-
- } //end g_pDVCamera == NULL
-
- } //end SUCCEEDED(hr)
- pBag->Release();
- }
- pM->Release();
- uIndex++;
- }
- pEm->Release();
- }
- }
- else
- {
- // no interesting devices
- DV_LogOut(LOG_PRIORITY_ERROR, LOG_LEVEL_SUCCINCT, TEXT("CreateClassEnumerator failed or Enumerator was not initialized. hr = 0x%c"), hr);
- MBOX(TEXT("There are no video devices installed"));
- }
- }
- return bStatus;
- }
-
-
- /*-------------------------------------------------------------------------
- Routine: DV_GetGraphBuilder
- Purpose: wrapper to get IGraphBuilder interface pointer
- Arguments: None
- Returns: TRUE if successful
- Notes:
- ------------------------------------------------------------------------*/
- BOOL DV_GetGraphBuilder(void)
- {
- //if we have one, release it, and make a new one
- if (g_pGraphBuilder)
- {
- g_pGraphBuilder->Release();
- g_pGraphBuilder = NULL;
- }
- HRESULT hr = CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC, IID_IGraphBuilder, reinterpret_cast<PVOID *>(&g_pGraphBuilder));
- return (SUCCEEDED(hr)) ? TRUE : FALSE;
- }
-
- /*-------------------------------------------------------------------------
- Routine: DV_InitWindow
- Purpose: Window initialization routine. This does the following:
- - Renders the VideoStream
- - makes the app window the output window
- - Plays the graph (preview)
- Arguments: None
- Returns: TRUE if Everything works - FALSE otherwise
- Notes:
- ------------------------------------------------------------------------*/
- BOOL DV_InitWindow(void)
- {
- DV_LogOut(LOG_PRIORITY_INFO, LOG_LEVEL_MEDIUM, TEXT("Entering DV_InitWindow"));
- BOOL bStatus = FALSE;
- HRESULT hr;
- // QI for IAMStreamConfig to make sure
- hr = g_pBuilder->FindInterface(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Interleaved, g_pDVCamera, IID_IAMStreamConfig, reinterpret_cast<PVOID *>(&g_pStreamConf));
- if (SUCCEEDED(hr))
- {
- AM_MEDIA_TYPE *pmt;
- hr = g_pStreamConf->GetFormat(&pmt);
- if (SUCCEEDED(hr))
- {
- DeleteMediaType(pmt);
- // build the default preview graph
- bStatus = DV_MakeSpecialGraph(GRAPH_PREVIEW);
- if (bStatus)
- {
- // update globals, log, toolbar
- g_iCurrentGraph = GRAPH_PREVIEW;
- DV_LogOut(LOG_PRIORITY_INFO, LOG_LEVEL_SUCCINCT, TEXT("Built Preview Graph"));
-
- SendMessage(g_hwndTBar, TB_SETSTATE, IDM_RECORD, MAKELONG(TBSTATE_INDETERMINATE, 0L));
- //re-enable everything else
- SendMessage(g_hwndTBar, TB_SETSTATE, IDM_STEP_REV, MAKELONG(TBSTATE_ENABLED, 0L));
- SendMessage(g_hwndTBar, TB_SETSTATE, IDM_REW, MAKELONG(TBSTATE_ENABLED, 0L));
- SendMessage(g_hwndTBar, TB_SETSTATE, IDM_PLAY_FAST_REV, MAKELONG(TBSTATE_ENABLED, 0L));
- SendMessage(g_hwndTBar, TB_SETSTATE, IDM_PLAY_FAST_FF, MAKELONG(TBSTATE_ENABLED, 0L));
- SendMessage(g_hwndTBar, TB_SETSTATE, IDM_FF, MAKELONG(TBSTATE_ENABLED, 0L));
- SendMessage(g_hwndTBar, TB_SETSTATE, IDM_STEP_FWD, MAKELONG(TBSTATE_ENABLED, 0L));
- SendMessage(g_hwndTBar, TB_SETSTATE, IDM_SEEKTIMECODE, MAKELONG(TBSTATE_ENABLED, 0L));
- }
- }
- else
- {
- DV_LogOut(LOG_PRIORITY_ERROR, LOG_LEVEL_SUCCINCT, TEXT("IAMStreamConfig::GetFormat Failed. hr = 0x%x"), hr);
- }
- }
- else
- {
- DV_LogOut(LOG_PRIORITY_ERROR, LOG_LEVEL_SUCCINCT, TEXT("Could not get pointer to IAMStreamConfig. hr = 0x%x"), hr);
- }
-
- return bStatus;
-
- }
-
- /*-------------------------------------------------------------------------
- Routine: DV_MakeSpecialGraph
- Purpose: Makes any one of the special graphs needed for reading and writing to/from the DVCR
- Arguments: None
- Returns: BOOL as appropriate
- Notes:
- ------------------------------------------------------------------------*/
- BOOL DV_MakeSpecialGraph(GRAPH_TYPE iGraphType)
- {
- BOOL bStatus = FALSE;
- HRESULT hr;
-
- //track whether the base or source filter is a file or the camera
- static BOOL bBaseFilterIsFile = FALSE;
-
- // dont rebuild if the required graph already exists
- if(iGraphType == g_iCurrentGraph && g_pVideoRenderer != NULL)
- {
- bStatus = TRUE;
- return bStatus;
- }
-
- //stop the graph - this should never fail before rebuilding
- EXECUTE_ASSERT(SUCCEEDED(DV_StopGraph()));
-
- //let's look at the current graph
- //Disconnect everything
- if (bBaseFilterIsFile)
- {
- DV_LogOut(LOG_PRIORITY_INFO, LOG_LEVEL_MEDIUM, TEXT("disonnect downstream from the Filesource"));
- //DisconnectAll removes only the downstream filters - we need to remove the file filter by hand.
- DV_DisconnectAll(g_pInputFileFilter);
- if (g_pInputFileFilter)
- {
- hr = g_pGraphBuilder->RemoveFilter(g_pInputFileFilter);
- SAFE_RELEASE(g_pInputFileFilter);
- }
- }
- else
- {
- DV_LogOut(LOG_PRIORITY_INFO, LOG_LEVEL_MEDIUM, TEXT("disconnect downstream from the camera"));
- //DisconnectAll removes only the downstream filters - we need to remove the file filter by hand.
- DV_DisconnectAll(g_pDVCamera);
- }
- DV_LogOut(LOG_PRIORITY_INFO, LOG_LEVEL_VERBOSE, TEXT("Dumping Graph. Pins should be disconnected"));
-
- switch (iGraphType)
- {
- // preview
- case GRAPH_PREVIEW :
- DV_LogOut(LOG_PRIORITY_INFO, LOG_LEVEL_MEDIUM, TEXT("Building Preview Graph"));
- // Build the preview graph by rendering via ICaptureGraphBuilder
- hr = g_pBuilder->RenderStream(&PIN_CATEGORY_PREVIEW, &MEDIATYPE_Video, g_pDVCamera, NULL, NULL);
- if (SUCCEEDED(hr))
- {
- hr = DV_SetPreview();
- if (SUCCEEDED(hr))
- {
- bStatus = TRUE;
- bBaseFilterIsFile = FALSE;
- }
- }
- else
- {
- DV_LogOut(LOG_PRIORITY_ERROR, LOG_LEVEL_SUCCINCT, TEXT("RenderStream Failed. hr = 0x%x"), hr);
- }
- break;
- //
- // Each of these type 1 & type 2 capture, transmit graphs have their graph building functions
- //
- // Type 1 File (capture & preview)
- case GRAPH_DV_TO_FILE :
- {
- if (SUCCEEDED(DV_MakeDvToFileGraph()))
- {
- bStatus = TRUE;
- bBaseFilterIsFile = FALSE;
- }
- break;
- }
-
- // Type 1 File (capture)
- case GRAPH_DV_TO_FILE_NOPRE :
- {
- if (SUCCEEDED(DV_MakeDvToFileGraph_NoPre()))
- {
- bStatus = TRUE;
- bBaseFilterIsFile = FALSE;
- }
- break;
- }
-
- // Type 1 File (transmit & playback)
- case GRAPH_FILE_TO_DV :
- {
- DV_LogOut(LOG_PRIORITY_INFO, LOG_LEVEL_MEDIUM, TEXT("Building Type 1 File to DV with Preview Graph"));
- if (SUCCEEDED(DV_MakeFileToDvGraph()))
- {
- bBaseFilterIsFile = TRUE;
- bStatus = TRUE;
- }
- break;
- }
-
- // Type 1 File (transmit)
- case GRAPH_FILE_TO_DV_NOPRE :
- {
- DV_LogOut(LOG_PRIORITY_INFO, LOG_LEVEL_MEDIUM, TEXT("Building Type 1 File to DV without Preview Graph"));
- if (SUCCEEDED(DV_MakeFileToDvGraph_NoPre()))
- {
- bBaseFilterIsFile = TRUE;
- bStatus = TRUE;
- }
- break;
- }
-
- // Type 2 File (capture & preview)
- case GRAPH_DV_TO_FILE_TYPE2 :
- {
- if (SUCCEEDED(DV_MakeDvToFileGraph_Type2()))
- {
- bStatus = TRUE;
- bBaseFilterIsFile = FALSE;
-
- }
- break;
- }
-
- // Type 2 File (capture)
- case GRAPH_DV_TO_FILE_NOPRE_TYPE2 :
- {
- if (SUCCEEDED(DV_MakeDvToFileGraph_NoPre_Type2()))
- {
- bStatus = TRUE;
- bBaseFilterIsFile = FALSE;
- }
- break;
- }
-
- // Type 2 File (transmit & playback)
- case GRAPH_FILE_TO_DV_TYPE2 :
- {
- DV_LogOut(LOG_PRIORITY_INFO, LOG_LEVEL_MEDIUM, TEXT("Building Type 2 File to DV with Preview Graph"));
- if (SUCCEEDED(DV_MakeFileToDvGraph_Type2()))
- {
- bBaseFilterIsFile = TRUE;
- bStatus = TRUE;
- }
- break;
- }
-
- // Type 2 File (transmit)
- case GRAPH_FILE_TO_DV_NOPRE_TYPE2 :
- {
- DV_LogOut(LOG_PRIORITY_INFO, LOG_LEVEL_MEDIUM, TEXT("Building Type 2 File to DV without Preview Graph"));
- if (SUCCEEDED(DV_MakeFileToDvGraph_NoPre_Type2()))
- {
- bBaseFilterIsFile = TRUE;
- bStatus = TRUE;
- }
- break;
- }
-
- default :
- // wrong graph type
- DV_LogOut(LOG_PRIORITY_ERROR, LOG_LEVEL_SUCCINCT, TEXT("Invalid paramater passed to DV_MakeSpecialGraph"));
- return bStatus;
- }
-
- // make sure you select MSDV as the master clock and not any of the renderers
- hr = DV_SelectClock(g_pDVCamera);
- return bStatus;
- }
-
- /*-------------------------------------------------------------------------
- Routine: DV_SelectClock
- Purpose: Selects the Clock of the Filter sets it to be the clock of the Graph
- Arguments: Filter to be selected
- Returns: HResult as appropriate
- Notes:
- ------------------------------------------------------------------------*/
- HRESULT DV_SelectClock(IBaseFilter *pBaseFilter)
- {
- HRESULT hr = S_OK;
- IReferenceClock *pRefClock = NULL;
- IMediaFilter *pMediaFilter = NULL;
-
- if(pBaseFilter == NULL)
- return E_POINTER;
- // QI for IReferenceClock on the specified filter
- hr = pBaseFilter->QueryInterface(IID_IReferenceClock, reinterpret_cast<PVOID *> (&pRefClock));
- // QI for IMediaFilter from the graph builder
- hr = g_pGraphBuilder->QueryInterface(IID_IMediaFilter, reinterpret_cast<PVOID *> (&pMediaFilter));
- if(pMediaFilter != NULL && pRefClock != NULL)
- {
- // set the clock of the specified filter on the filtergraph builder
- hr = pMediaFilter->SetSyncSource(pRefClock);
- }
- else
- hr = E_POINTER;
-
- SAFE_RELEASE(pMediaFilter);
- SAFE_RELEASE(pRefClock);
- return hr;
- }
-
-
- /*-------------------------------------------------------------------------
- Routine: DV_StartGraph
- Purpose: Starts the Filter Graph
- Arguments: None
- Returns: HResult as appropriate
- Notes:
- ------------------------------------------------------------------------*/
- HRESULT DV_StartGraph(void)
- {
- HRESULT hr;
- IMediaControl *pMC = NULL;
-
- // QI for the media control
- if(!g_pGraphBuilder)
- return S_FALSE;
- hr = g_pGraphBuilder->QueryInterface(IID_IMediaControl, reinterpret_cast<PVOID *>(&pMC));
- if (SUCCEEDED(hr))
- {
- // start the graph
- hr = pMC->Run();
- if ( FAILED(hr))
- {
- DV_LogOut(LOG_PRIORITY_INFO, LOG_LEVEL_MEDIUM, TEXT("IMediaControl::Run failed (0x%x)"), hr);
- // stop parts that ran
- pMC->Stop();
- }
- SAFE_RELEASE(pMC);
- }
- return hr;
- }
-
- /*-------------------------------------------------------------------------
- Routine: DV_PauseGraph
- Purpose: Starts the Filter Graph
- Arguments: None
- Returns: HResult as appropriate
- Notes:
- ------------------------------------------------------------------------*/
- HRESULT DV_PauseGraph(void)
- {
- HRESULT hr;
- IMediaControl *pMC = NULL;
-
- if(!g_pGraphBuilder)
- return S_FALSE;
- // QI for the media control
- hr = g_pGraphBuilder->QueryInterface(IID_IMediaControl, reinterpret_cast<PVOID *>(&pMC));
- if (SUCCEEDED(hr))
- {
- // Pause the graph
- hr = pMC->Pause();
- if ( FAILED(hr))
- {
- DV_LogOut(LOG_PRIORITY_INFO, LOG_LEVEL_MEDIUM, TEXT("IMediaControl::Pause failed (0x%x)"), hr);
- // stop parts that ran
- pMC->Stop();
- }
- SAFE_RELEASE(pMC);
- }
- return hr;
- }
-
-
- /*-------------------------------------------------------------------------
- Routine: DV_StopGraph
- Purpose: Starts the Filter Graph
- Arguments: None
- Returns: HResult as appropriate
- Notes:
- ------------------------------------------------------------------------*/
- HRESULT DV_StopGraph(void)
- {
- HRESULT hr;
- IMediaControl *pMC = NULL;
-
- if(!g_pGraphBuilder)
- return S_FALSE;
- //stop the current graph
- hr = g_pGraphBuilder->QueryInterface(IID_IMediaControl, reinterpret_cast<PVOID *>(&pMC));
- if (SUCCEEDED(hr))
- {
- hr = pMC->Stop();
- SAFE_RELEASE(pMC);
- }
- return hr;
- }
-
- /*-------------------------------------------------------------------------
- Routine: DV_DisconnectAll
- Purpose: Disconnects all pins in a graph (downstream from pBF)
- Arguments: pointer to the filter to disconnect pins from (downstream only)
- Returns: None
- Notes: This is the recursive nuke downstream routine from amcap
- ------------------------------------------------------------------------*/
- void DV_DisconnectAll(IBaseFilter *pBF)
- {
- IPin *pP, *pTo;
- ULONG u;
- IEnumPins *pins = NULL;
- PIN_INFO pininfo;
-
- ASSERT(g_pGraphBuilder);
- DV_LogOut(LOG_PRIORITY_INFO, LOG_LEVEL_VERBOSE, TEXT("Disconnecting Pins..."));
-
- HRESULT hr = pBF->EnumPins(&pins);
- pins->Reset();
- while ( hr == NOERROR )
- {
- hr = pins->Next(1, &pP, &u);
- if ( hr == S_OK && pP )
- {
- pP->ConnectedTo(&pTo);
- if ( pTo )
- {
- hr = pTo->QueryPinInfo(&pininfo);
- if ( hr == NOERROR )
- {
- if ( pininfo.dir == PINDIR_INPUT )
- {
- DV_DisconnectAll(pininfo.pFilter);
- hr = g_pGraphBuilder->Disconnect(pTo);
- hr = g_pGraphBuilder->Disconnect(pP);
-
- //always leave the Camera filter in the graph
- //if the base filter is a file,the camera is downstream
- if (pininfo.pFilter != g_pDVCamera)
- {
- hr = g_pGraphBuilder->RemoveFilter(pininfo.pFilter);
- }
- }
- ASSERT(pininfo.pFilter);
- SAFE_RELEASE(pininfo.pFilter);
- }
- ASSERT(pTo);
- SAFE_RELEASE(pTo);
- }
- ASSERT(pP);
- SAFE_RELEASE(pP);
- }
- }
- if ( pins )
- SAFE_RELEASE(pins);
-
- }
-
- /*-------------------------------------------------------------------------
- Routine: DV_CleanUp
- Purpose: writes values to the registry, releases all used interfaces. Uninitializes com and the dshow debug stuff
- Arguments: None
- Returns: None
- Notes:
- ------------------------------------------------------------------------*/
- void DV_CleanUp(void)
- {
-
- DV_WriteRegKeys();
-
- // release helper dshow interfaces
- SAFE_RELEASE(g_pBuilder);
- SAFE_RELEASE(g_pExtDev);
- SAFE_RELEASE(g_pStreamConf);
- SAFE_RELEASE(g_pExtTrans);
- SAFE_RELEASE(g_pTimeReader);
- SAFE_RELEASE(g_pDroppedFrames);
- SAFE_RELEASE(g_pGraphBuilder);
-
- // release the filters of the graph
- SAFE_RELEASE(g_pDVCamera);
- SAFE_RELEASE(g_pVideoWindow);
- SAFE_RELEASE(g_pInputFileFilter);
- SAFE_RELEASE(g_pInfTee);
- SAFE_RELEASE(g_pVideoRenderer);
- SAFE_RELEASE(g_pAviSplitter);
- SAFE_RELEASE(g_pDVSplitter);
- SAFE_RELEASE(g_pDVCodec);
- SAFE_RELEASE(g_pDvDec);
- SAFE_RELEASE(g_pDVMux);
- SAFE_RELEASE(g_pSmartTee);
- SAFE_RELEASE(g_pDSound);
-
- CoUninitialize();
- }
-
-
- /*-------------------------------------------------------------------------
- Routine: DV_SetPreview
- Purpose: Hooks up stream *from camera* to preview window
- Note that the preview for the playback from the file is handled within DV_MakeFileToDvGraph() stuff
- Arguments: None
- Returns: HRESULT as appropriate
- Notes:
- ------------------------------------------------------------------------*/
- HRESULT DV_SetPreview(void)
- {
- HRESULT hr = S_OK;
-
- if (g_pVideoWindow)
- { // dismantle the current video window
- g_pVideoWindow->put_Owner(NULL);
- SAFE_RELEASE(g_pVideoWindow);
- }
-
- // get the video window and set it up for the preview
- hr = g_pBuilder->FindInterface(NULL, &MEDIATYPE_Video, g_pDVCamera, IID_IVideoWindow, reinterpret_cast<PVOID *>(&g_pVideoWindow));
- if (SUCCEEDED(hr))
- {
- RECT rc, rect;
- g_pVideoWindow->put_Owner((LONG_PTR)g_hwndApp); // We own the window now
- g_pVideoWindow->put_WindowStyle(WS_CHILD); // you are now a child
-
- // give the preview window all our space but where the tool bar and status bar are
- GetClientRect(g_hwndApp, &rc);
- GetWindowRect(g_hwndTBar, &rect);
-
- //g_pVideoWindow->SetWindowPosition(0, rect.bottom - rect.top, rc.right,
- // (rc.bottom - (g_statusHeight + GetSystemMetrics(SM_CYBORDER)) - (rect.bottom - rect.top)));
-
- g_pVideoWindow->SetWindowPosition(0, rect.bottom - rect.top, g_iVWWidth, g_iVWHeight);
- g_pVideoWindow->put_Visible(OATRUE);
- }
- else
- {
- DV_LogOut(LOG_PRIORITY_ERROR, LOG_LEVEL_SUCCINCT, TEXT("FindInterface (IVideoWindow) Failed. hr = 0x%x"), hr);
- }
-
- return hr;
- }
-
- /*-------------------------------------------------------------------------
- Routine: DV_GetDVMode
- Purpose: Determines camera mode using IAMExtDevice::GetCapability()
- Arguments: None
- Returns: Current mode of camera device
- Notes:
- ------------------------------------------------------------------------*/
- DV_MODE DV_GetDVMode(void)
- {
- HRESULT hr = S_OK;
- LONG lDeviceType = 0;
-
- ASSERT(g_pExtDev);
- // Query the Device Type Capability
- hr = g_pExtDev->GetCapability(ED_DEVCAP_DEVICE_TYPE, &lDeviceType, 0);
- if (SUCCEEDED(hr))
- {
- switch (lDeviceType)
- {
- case 0 :
- //device type is unknown
- g_CurrentMode = UnknownMode;
- break;
-
- case ED_DEVTYPE_VCR :
- g_CurrentMode = VcrMode;
- break;
-
- case ED_DEVTYPE_CAMERA :
- g_CurrentMode = CameraMode;
- break;
-
- default :
- DV_LogOut(LOG_PRIORITY_ERROR, LOG_LEVEL_SUCCINCT, TEXT("GetCapability returned an unknown device type - 0x%x"), lDeviceType);
- break;
- }
- }
- return g_CurrentMode;
- }
-
- /*-------------------------------------------------------------------------
- Routine: DV_TimecodeTimerProc
- Purpose: Callback function for the timer proc
- Arguments: Usual Timer Processing Parameters
- Returns: None
- Notes:
- ------------------------------------------------------------------------*/
- void CALLBACK DV_TimecodeTimerProc(HWND hwnd, UINT uMsg, UINT idEvent, DWORD dwTime)
- {
- DV_DisplayTimecode();
- }
-
- /*-------------------------------------------------------------------------
- Routine: DV_StopRecProc
- Purpose: Callback to stop recording after a specified time
- Arguments: Usual Timer Processing Parameters
- Returns: None
- Notes:
- ------------------------------------------------------------------------*/
- void CALLBACK DV_StopRecProc(HWND hwnd, UINT uMsg, UINT idEvent, DWORD dwTime)
- {
- SendMessage(g_hwndApp, WM_COMMAND, IDM_STOP, 0);
- }
-
-
- /*-------------------------------------------------------------------------
- Routine: DV_GetFinalDroppedFramesStats
- Purpose: Get Final dropped frames stats for status bar display
- Arguments: DWORD current time
- Returns: None
- Notes: For both Capture & Transmit graphs
- ------------------------------------------------------------------------*/
- void DV_GetFinalDroppedFramesStats(DWORD dwTime)
- {
- BOOL bIsModeTransmit = TRUE;
- // determine if the current graph is a transmit graph
- if (GRAPH_DV_TO_FILE_NOPRE == g_iCurrentGraph || GRAPH_DV_TO_FILE == g_iCurrentGraph ||
- GRAPH_DV_TO_FILE_TYPE2 == g_iCurrentGraph || GRAPH_DV_TO_FILE_NOPRE_TYPE2 == g_iCurrentGraph)
- bIsModeTransmit = FALSE;
-
- // make sure the interface exists ans can be queried the stats
- if (g_pDroppedFrames)
- {
- HRESULT hr = S_OK;
- long dropped = 0, notdropped = 0, lAvgFrameSize = 0;
- TCHAR buffer[128];
- DWORD time = dwTime - g_CapStartTime;
-
- // Get the required stats
- hr = g_pDroppedFrames->GetNumDropped(&dropped);
- hr = g_pDroppedFrames->GetNumNotDropped(¬dropped);
- hr = g_pDroppedFrames->GetAverageFrameSize(&lAvgFrameSize);
-
- if (SUCCEEDED(hr) && time != 0)
- {
- double framerate = 0; // acheived frame rate
- LONG lData = 0; // acheived data rate
- // Calculate other stats
- framerate = (double)(LONGLONG)notdropped * 1000. / (double)(LONGLONG)time;
- lData = (LONG)(LONGLONG)(notdropped / (double)(LONGLONG)time * 1000. * (double)(LONGLONG)lAvgFrameSize);
- if(bIsModeTransmit)
- wsprintf(buffer, TEXT("Transmitted %d frames (%d dropped) %d.%d sec. %d.%d fps %d.%d Meg/sec"),
- notdropped, dropped, time / 1000, time / 100 - time / 1000 * 10,
- (int)framerate, (int)(framerate * 10.) - (int)framerate * 10,
- lData / 1000000, lData / 1000 - (lData / 1000000 * 1000));
- else
- wsprintf(buffer, TEXT("Captured %d frames (%d dropped) %d.%d sec. %d.%d fps %d.%d Meg/sec"),
- notdropped, dropped, time / 1000, time / 100 - time / 1000 * 10,
- (int)framerate, (int)(framerate * 10.) - (int)framerate * 10,
- lData / 1000000, lData / 1000 - (lData / 1000000 * 1000));
- // update the status bar with the gathered info
- DV_StatusText(buffer, 1);
- }
- else
- {
- DV_StatusText(TEXT("Cannot report dropped frame information"), 1);
- }
- }
- }
-
- /*-------------------------------------------------------------------------
- Routine: DV_DroppedFrameProc
- Purpose: Callback proc to display dropped frame info
- Arguments: DWORD current time
- Returns: None
- Notes: For both Capture & Transmit graphs
- ------------------------------------------------------------------------*/
- void CALLBACK DV_DroppedFrameProc(HWND hwnd, UINT uMsg, UINT idEvent, DWORD dwTime)
- {
- HRESULT hr = S_OK;
- long dropped = 0, notdropped = 0;
- TCHAR buffer[128];
- DWORD time = dwTime - g_CapStartTime;
- BOOL bIsModeTransmit = TRUE;
-
- // if the dropped frames interface does not already exist, query now!
- if (NULL == g_pDroppedFrames) {
- if (GRAPH_DV_TO_FILE == g_iCurrentGraph || GRAPH_DV_TO_FILE_NOPRE == g_iCurrentGraph ||
- GRAPH_DV_TO_FILE_TYPE2 == g_iCurrentGraph || GRAPH_DV_TO_FILE_NOPRE_TYPE2 == g_iCurrentGraph)
- {
- hr = g_pBuilder->FindInterface(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Interleaved, g_pDVCamera, IID_IAMDroppedFrames, reinterpret_cast<PVOID *>(&g_pDroppedFrames));
- bIsModeTransmit = FALSE;
- }
- else if (GRAPH_FILE_TO_DV == g_iCurrentGraph || GRAPH_FILE_TO_DV_NOPRE == g_iCurrentGraph ||
- GRAPH_FILE_TO_DV_TYPE2 == g_iCurrentGraph || GRAPH_FILE_TO_DV_NOPRE_TYPE2 == g_iCurrentGraph)
- {
- IPin *pAVIn = NULL;
- hr = g_pBuilder->FindPin(g_pDVCamera, PINDIR_INPUT, NULL, NULL, FALSE, 0, &pAVIn);
- if(SUCCEEDED(hr) && pAVIn != NULL)
- hr = pAVIn->QueryInterface(IID_IAMDroppedFrames, reinterpret_cast<PVOID *>(&g_pDroppedFrames));
- else
- DV_LogOut(LOG_PRIORITY_ERROR, LOG_LEVEL_SUCCINCT, TEXT("Could not get Input Pin for obtaining Dropped Frames Statistics"));
- }
- else
- {
- //we shouldn't get here as we dont call for the dropped frames in preview graph
- DV_LogOut(LOG_PRIORITY_ERROR, LOG_LEVEL_SUCCINCT, TEXT("Undefined graph mode (maybe GRAPH_PREVIEW) while obtaining Dropped Frames"));
- }
- }
-
- if (SUCCEEDED(hr))
- {
- // Get the stats once the interface is successfully obtained
- hr = g_pDroppedFrames->GetNumDropped(&dropped);
- hr = g_pDroppedFrames->GetNumNotDropped(¬dropped);
- if (SUCCEEDED(hr))
- {
- if(bIsModeTransmit)
- wsprintf(buffer, TEXT("Transmitted %d frames (%d dropped) %d.%d sec."), notdropped, dropped, time / 1000, time / 100 - time / 1000 * 10);
- else
- wsprintf(buffer, TEXT("Captured %d frames (%d dropped) %d.%d sec."), notdropped, dropped, time / 1000, time / 100 - time / 1000 * 10);
- // update the status bar
- DV_StatusText(buffer, 1);
- }
- else
- {
- DV_StatusText(TEXT("Cannot report dropped frame information"), 1);
- }
- }
- else
- {
- DV_LogOut(LOG_PRIORITY_ERROR, LOG_LEVEL_SUCCINCT, TEXT("Could not get IAMDroppedFrames interface"));
- KillTimer(hwnd, DV_TIMER_FRAMES);
- }
-
- }
-
-
-
- /*-------------------------------------------------------------------------
- Routine: DV_DisplayTimecode
- Purpose: Routine to display timecodes
- Arguments: None
- Returns: None
- Notes: This is TimeCode Read not Absolute Track Number Read
- ------------------------------------------------------------------------*/
- void DV_DisplayTimecode(void)
- {
- TIMECODE_SAMPLE TimecodeSample;
- TimecodeSample.timecode.dwFrames = 0;
- static DWORD i1 = 0, i2 = 0, i3 = 0;
-
- TimecodeSample.dwFlags = ED_DEVCAP_TIMECODE_READ;
- // Query the TimeCode sample data
- HRESULT hr = g_pTimeReader->GetTimecode(&TimecodeSample);
- TCHAR szBuf[4];
-
- if (SUCCEEDED(hr))
- {
- // It's worth it to spend a few extra cycles, and to store the static variables
- // to avoid calling wsprintf and setwindowtext on every timer tick.
- if (i1 != (TimecodeSample.timecode.dwFrames & 0xff000000) >> 24)
- {
- wsprintf(szBuf, TEXT("%.2x"),((TimecodeSample.timecode.dwFrames & 0xff000000) >> 24));
- SetDlgItemText(g_hwndTBar, IDC_EDIT_HOUR, szBuf);
- }
- i1 = (TimecodeSample.timecode.dwFrames & 0xff000000) >> 24;
-
- if (i2 != (TimecodeSample.timecode.dwFrames & 0x00ff0000) >> 16)
- {
- wsprintf(szBuf, TEXT("%.2x"),((TimecodeSample.timecode.dwFrames & 0x00ff0000) >> 16));
- SetDlgItemText(g_hwndTBar, IDC_EDIT_MINUTE, szBuf);
- }
- i2 = (TimecodeSample.timecode.dwFrames & 0x00ff0000) >> 16;
-
- if (i3 != (TimecodeSample.timecode.dwFrames & 0x0000ff00) >> 8)
- {
- wsprintf(szBuf, TEXT("%.2x"),((TimecodeSample.timecode.dwFrames & 0x0000ff00) >> 8));
- SetDlgItemText(g_hwndTBar, IDC_EDIT_SECOND, szBuf);
- }
- i3 = (TimecodeSample.timecode.dwFrames & 0x0000ff00) >> 8;
-
- //always update the toolbar display
- wsprintf(szBuf, TEXT("%.2x"),(TimecodeSample.timecode.dwFrames & 0x000000ff));
- SetDlgItemText(g_hwndTBar, IDC_EDIT_FRAME, szBuf);
- }
- else
- {
- DV_LogOut(LOG_PRIORITY_WARN, LOG_LEVEL_MEDIUM, TEXT("Failed to get Timecodesample. hr = 0x%x"), hr);
- }
- }
-
-
- /*-------------------------------------------------------------------------
- Routine: DV_SeekATN
- Purpose: ATN Seek function - uses GetTransportBasicParameters to send RAW AVC command
- Arguments: None
- Returns: TRUE if successful
- Notes: This is Absolute Track Number Seek not TimeCode Seek but uses the timecode display as input
- ------------------------------------------------------------------------*/
- BOOL DV_SeekATN(void)
- {
- BOOL bStatus = FALSE;
- HRESULT hr = S_OK;
- int iHr, iMn, iSc, iFr;
- ULONG ulTrackNumToSearch;
- long iCnt = 8;
- // ATN Seek Raw AVC Command
- BYTE RawAVCPkt[8] = {0x00, 0x20, 0x52, 0x20, 0xff, 0xff, 0xff, 0xff};
-
- //get the values from the edit fields
- iHr = GetDlgItemInt(g_hwndTBar, IDC_EDIT_HOUR, &bStatus, FALSE);
- iMn = GetDlgItemInt(g_hwndTBar, IDC_EDIT_MINUTE, &bStatus, FALSE);
- iSc = GetDlgItemInt(g_hwndTBar, IDC_EDIT_SECOND, &bStatus, FALSE);
- iFr = GetDlgItemInt(g_hwndTBar, IDC_EDIT_FRAME, &bStatus, FALSE);
-
- if ((iHr < 60) && (iMn < 60) && (iSc < 60) && (iFr <=30))
- {
- //Calculate the ATN
- if (g_AvgTimePerFrame == 40)
- {
- ulTrackNumToSearch = ((iMn * 60 + iSc) * 25 + iFr) * 12 * 2;
- }
- else
- {
- // Drop two frame every minutes
- ulTrackNumToSearch = ((iMn * 60 + iSc) * 30 + iFr - ((iMn - (iMn / 10)) * 2)) * 10 * 2;
- }
- // Update the Raw AVC Command query
- RawAVCPkt[4] = (BYTE) (ulTrackNumToSearch & 0x000000ff);
- RawAVCPkt[5] = (BYTE) ((ulTrackNumToSearch & 0x0000ff00) >> 8);
- RawAVCPkt[6] = (BYTE) ((ulTrackNumToSearch & 0x00ff0000) >> 16);
-
- // RAW AVC Call
- hr = g_pExtTrans->GetTransportBasicParameters(ED_RAW_EXT_DEV_CMD, &iCnt, (LPOLESTR *)RawAVCPkt);
- Sleep(_MAX_SLEEP*6);
- if (SUCCEEDED(hr))
- {
- bStatus = TRUE;
- }
- else
- {
- DV_LogOut(LOG_PRIORITY_ERROR, LOG_LEVEL_SUCCINCT, TEXT("Seek to a TimeCode Location failed"));
- }
- }
- else
- {
- MBOX(TEXT("Invalid Parameter - Time entered should be:\nHour:Minute:Second:Frame"));
- }
- return bStatus;
- }
-
- /*---------------------------------------------------------------------------------------------------------
- Routine: DV_MakeDvToFileGraph
- Purpose: Builds and runs the DV to File graph
- Arguments: None
- Returns: HRESULT as apropriate
- Notes: This is a capture & preview graph for DV Type 1 AVI files
- This graph is a bit more complex. It looks like this:
- DV_Cam(AV Out)->SmartTee(capture)->AviMux->FileWriter
- SmartTee(preview)->DVSplitter(vid)->DVCodec->VideoWindow
- DVSplitter(aud)->Default DirectSound device
- ---------------------------------------------------------------------------------------------------------*/
- HRESULT DV_MakeDvToFileGraph(void)
- {
- HRESULT hr = S_OK;
- DV_LogOut(LOG_PRIORITY_INFO, LOG_LEVEL_MEDIUM, TEXT("Building DV to File Graph"));
- // making sure there is a output file selected
- if (!g_OutputFileName[0])
- {
- MBOX(TEXT("Please set up an output file name for recording"));
- hr = E_FAIL;
- }
- else
- {
- DV_LogOut(LOG_PRIORITY_INFO, LOG_LEVEL_VERBOSE, TEXT("This is the graph - everything should be disconnected"));
-
- #ifndef UNICODE
- // convert the output file name to wchar
- WCHAR wFileName[MAX_PATH];
- MultiByteToWideChar(CP_ACP, 0, g_OutputFileName, -1, wFileName, MAX_PATH);
- #endif
-
- //we need a lot of pins to make this work...
- IPin *pAVOut = NULL, *pTeeIn = NULL, *pTeeOut = NULL, *pMuxIn = NULL, *pTeePreOut = NULL, *pSplitIn = NULL;
- IPin *pSplitVout = NULL, *pSplitAout = NULL, *pAudIn = NULL, *pCodecIn = NULL, *pCodecOut = NULL, *pRenderIn = NULL;
-
- //get the camera output pin
- hr = g_pBuilder->FindPin(g_pDVCamera, PINDIR_OUTPUT, NULL, &MEDIATYPE_Interleaved, TRUE, 0, &pAVOut);
- //add the smart tee filter, get the smart tee input pin and connect it to the DV Cam AV out
- if (SUCCEEDED(hr))
- {
- g_pGraphBuilder->AddFilter(g_pSmartTee, L"Smart Tee");
- hr = g_pBuilder->FindPin(g_pSmartTee, PINDIR_INPUT, NULL, NULL, TRUE, 0, &pTeeIn);
- if (SUCCEEDED(hr))
- {
- hr = g_pGraphBuilder->ConnectDirect(pAVOut, pTeeIn, NULL);
- if (SUCCEEDED(hr))
- {
- // get the capture output pin of smart tee and connect it to avi muxer & file writer
- hr = g_pBuilder->FindPin(g_pSmartTee, PINDIR_OUTPUT, NULL, NULL, TRUE, 0, &pTeeOut);
- if (SUCCEEDED(hr))
- {
- //add the avimux, and file writer to the graph
- IBaseFilter *ppf = NULL;
- IFileSinkFilter *pSink = NULL;
- #ifndef UNICODE
- hr = g_pBuilder->SetOutputFileName(&MEDIASUBTYPE_Avi, wFileName, &ppf, &pSink);
- #else
- hr = g_pBuilder->SetOutputFileName(&MEDIASUBTYPE_Avi, g_OutputFileName, &ppf, &pSink);
- #endif //UNICODE
- if (SUCCEEDED(hr))
- {
- // Set the AVI Options like interleaving mode etc...
- DV_SetAviOptions(ppf, INTERLEAVE_NONE);
- //Now I need the input pin on the mux to connect to the file writer
- hr = g_pBuilder->FindPin(ppf, PINDIR_INPUT, NULL, NULL, TRUE, 0, &pMuxIn);
- if (SUCCEEDED(hr))
- {
- hr = g_pGraphBuilder->ConnectDirect(pTeeOut, pMuxIn, NULL);
- //
- //the capture graph is built,but we still need to build the preview graph
- //
- // get the preview output pin on the smart tee
- hr = g_pBuilder->FindPin(g_pSmartTee, PINDIR_OUTPUT, NULL, NULL, TRUE, 0, &pTeePreOut);
- if (SUCCEEDED(hr))
- {
- // Add the filters DV Splitter, DV Decoder, Video Renderer
- EXECUTE_ASSERT(S_OK == g_pGraphBuilder->AddFilter(g_pDVSplitter, L"DV Splitter"));
- EXECUTE_ASSERT(S_OK == g_pGraphBuilder->AddFilter(g_pDVCodec, L"DV Codec"));
- EXECUTE_ASSERT(S_OK == g_pGraphBuilder->AddFilter(g_pVideoRenderer, L"VideoRenderer"));
-
- // Find input pin of dvsplitter & connect smart tee and dvsplitter
- hr = g_pBuilder->FindPin(g_pDVSplitter, PINDIR_INPUT, NULL, NULL, TRUE, 0, &pSplitIn);
- if (SUCCEEDED(hr))
- {
- hr = g_pGraphBuilder->ConnectDirect(pTeePreOut, pSplitIn, NULL);
- if (SUCCEEDED(hr))
- {
- // find the vid & aud output pins on the dvsplitter
- hr = g_pBuilder->FindPin(g_pDVSplitter, PINDIR_OUTPUT, NULL , &MEDIATYPE_Video, TRUE, 0, &pSplitVout);
- if (SUCCEEDED(hr))
- {
- hr = g_pBuilder->FindPin(g_pDVSplitter, PINDIR_OUTPUT, NULL , &MEDIATYPE_Audio, TRUE, 0, &pSplitAout);
- if (SUCCEEDED(hr))
- {
- // find the input & output pins on the dv codec
- hr = g_pBuilder->FindPin(g_pDVCodec, PINDIR_INPUT, NULL , NULL, TRUE, 0, &pCodecIn);
- if (SUCCEEDED(hr))
- {
- hr = g_pBuilder->FindPin(g_pDVCodec, PINDIR_OUTPUT, NULL , NULL, TRUE, 0, &pCodecOut);
- if (SUCCEEDED(hr))
- {
- // connect the dvsplitter(vid) & dvcodec
- hr = g_pGraphBuilder->ConnectDirect(pSplitVout, pCodecIn, NULL);
- if (SUCCEEDED(hr))
- {
- //if we have audio, add the filter to the graph connect it to the dvsplitter(aud)
- if (g_pDSound)
- {
- EXECUTE_ASSERT(S_OK == g_pGraphBuilder->AddFilter(g_pDSound, L"DSound"));
- hr = g_pBuilder->FindPin(g_pDSound, PINDIR_INPUT, NULL , NULL, TRUE, 0, &pAudIn);
- if (SUCCEEDED(hr))
- {
- hr = g_pGraphBuilder->ConnectDirect(pSplitAout, pAudIn, NULL);
- SAFE_RELEASE(pAudIn);
- }
- }
- if (SUCCEEDED(hr)) //this verifies success of the audio connection when audio exists
- {
- // get the input pin on the video renderer and connect it to the dvcodec
- hr = g_pBuilder->FindPin(g_pVideoRenderer, PINDIR_INPUT, NULL , NULL, TRUE, 0, &pRenderIn);
- if (SUCCEEDED(hr))
- {
- hr = g_pGraphBuilder->ConnectDirect(pCodecOut, pRenderIn, NULL);
- if (SUCCEEDED(hr))
- {
- // Woohoo! succeeded all the way
- // Set the Filter Graph to Preview State (Run in this case)
- DV_SetPreview();
- }
- SAFE_RELEASE(pRenderIn);
- }
- }
- }
- SAFE_RELEASE(pCodecOut);
- }
- SAFE_RELEASE(pCodecIn);
- }
- SAFE_RELEASE(pSplitAout);
- }
- SAFE_RELEASE(pSplitVout);
- }
- }
- SAFE_RELEASE(pSplitIn);
- }
- SAFE_RELEASE(pTeePreOut);
- }
- SAFE_RELEASE(pMuxIn);
- }
- SAFE_RELEASE(ppf);
- SAFE_RELEASE(pSink);
- }
- SAFE_RELEASE(pTeeOut);
- }
- } // Release interfaces appropriately
- else
- {
- DV_LogOut(LOG_PRIORITY_ERROR, LOG_LEVEL_SUCCINCT, TEXT("Could not connect ouput pin from camera (0x%x)"), hr);
- }
- SAFE_RELEASE(pTeeIn);
- }
- SAFE_RELEASE(pAVOut);
- }
- }
- return hr;
- }
-
- /*---------------------------------------------------------------------------------------------------------
- Routine: DV_MakeDvToFileGraph_NoPre
- Purpose: Builds and runs the DV to File graph with no preview
- Arguments: None
- Returns: HRESULT as apropriate
- Notes: This is a capture only graph for DV Type 1 AVI files
- This graph is not too complex. It looks like this:
- DV_Cam(AV Out)->AviMux->FileWriter
- ---------------------------------------------------------------------------------------------------------*/
- HRESULT DV_MakeDvToFileGraph_NoPre(void)
- {
- HRESULT hr = S_OK;
- DV_LogOut(LOG_PRIORITY_INFO, LOG_LEVEL_MEDIUM, TEXT("Building DV to File Graph (No Preview)"));
- // making sure there is a output file selected
- if (!g_OutputFileName[0])
- {
- MBOX(TEXT("Please set up an output file name for recording"));
- hr = E_FAIL;
- }
- else
- {
- DV_LogOut(LOG_PRIORITY_INFO, LOG_LEVEL_VERBOSE, TEXT("This is the graph - everything should be disconnected"));
- #ifndef UNICODE
- // convert the output file name to wchar
- WCHAR wFileName[MAX_PATH];
- MultiByteToWideChar(CP_ACP, 0, g_OutputFileName, -1, wFileName, MAX_PATH);
- #endif
-
- //we'll need a few pins...
- IPin *pAVOut = NULL, *pMuxIn = NULL;
-
- // get the capture output pin of dvcamera and connect it to avi muxer & file writer
- hr = g_pBuilder->FindPin(g_pDVCamera, PINDIR_OUTPUT, NULL, &MEDIATYPE_Interleaved, TRUE, 0, &pAVOut);
- if (SUCCEEDED(hr))
- {
- //add the avimux, and file writer to the graph
- IBaseFilter *ppf = NULL;
- IFileSinkFilter *pSink = NULL;
- #ifndef UNICODE
- hr = g_pBuilder->SetOutputFileName(&MEDIASUBTYPE_Avi, wFileName, &ppf, &pSink);
- #else
- hr = g_pBuilder->SetOutputFileName(&MEDIASUBTYPE_Avi, g_OutputFileName, &ppf, &pSink);
- #endif //UNICODE
- if (SUCCEEDED(hr))
- {
- // Set the AVI Options like interleaving mode etc...
- DV_SetAviOptions(ppf, INTERLEAVE_NONE);
- //Now I need the input pin on the mux to connect to the file writer
- hr = g_pBuilder->FindPin(ppf, PINDIR_INPUT, NULL, NULL, TRUE, 0, &pMuxIn);
- if (SUCCEEDED(hr))
- {
- hr = g_pGraphBuilder->ConnectDirect(pAVOut, pMuxIn, NULL);
- //
- //the capture graph is built
- //
- if (FAILED(hr))
- {
- DV_LogOut(LOG_PRIORITY_ERROR, LOG_LEVEL_SUCCINCT, TEXT("Could not connect ouput pin from camera (0x%x)"), hr);
- }
-
- SAFE_RELEASE(pMuxIn);
- }
- SAFE_RELEASE(ppf);
- SAFE_RELEASE(pSink);
- }
-
- }
- SAFE_RELEASE(pAVOut);
- } // Release interfaces appropriately
- return hr;
- }
-
- /*---------------------------------------------------------------------------------------------------------
- Routine: DV_MakeFileToDvGraph
- Purpose: Builds and runs the File to DV graph
- Arguments: None
- Returns: HRESULT as apropriate
- Notes: This is a transmit & playback graph for DV Type 1 AVI files
- This graph is a bit more complex. It looks like this:
- FileSource->AVI_Splitter->InfPinTee->DV_Camera
- InfPinTee->DVSplitter(vid)->DVDecoder->VideoWIndow
- DVSplitter(aud)->Default DirectSound device
- ---------------------------------------------------------------------------------------------------------*/
- HRESULT DV_MakeFileToDvGraph(void)
- {
- HRESULT hr = S_OK;
- // making sure there is a input file selected
- if (NULL == g_InputFileName[0])
- {
- MBOX(TEXT("Please set an input file for rendering"));
- hr = E_FAIL;
- }
- else
- {
- //if we are compiling ANSI, the file name needs to be converted to UNICODE
- // Add the file as source filter to the graph
- #ifndef UNICODE
- WCHAR wFileName[MAX_PATH];
- MultiByteToWideChar(CP_ACP, 0, g_InputFileName, -1, wFileName, MAX_PATH);
- EXECUTE_ASSERT(S_OK == g_pGraphBuilder->AddSourceFilter(wFileName, wFileName, &g_pInputFileFilter));
- #else
- EXECUTE_ASSERT(S_OK == g_pGraphBuilder->AddSourceFilter(g_InputFileName, g_InputFileName, &g_pInputFileFilter));
- #endif
- //making sure the file source exists
- if(g_pInputFileFilter == NULL)
- {
- MBOX(TEXT("Please set a correct input file for rendering"));
- hr = E_FAIL;
- return hr;
- }
- // Also add the AVI Splitter
- EXECUTE_ASSERT(S_OK == g_pGraphBuilder->AddFilter(g_pAviSplitter, L"AVI Splitter"));
-
- // now we need to connect the pins
- IPin *pFileOut = NULL, *pSplitterIn = NULL, *pSplitterOut = NULL, *pDvIn = NULL;
- IPin *pInfTeeIn = NULL, *pInfTeeOut1 = NULL, *pInfTeeOut2 = NULL, *pSplitIn = NULL, *pRenderIn = NULL;
- IPin *pSplitVout = NULL, *pSplitAout = NULL, *pCodecIn = NULL, *pCodecOut = NULL, *pAudIn = NULL;
-
- // obtain the output pin of the source filter and connect it to avi splitter
- hr = g_pBuilder->FindPin(g_pInputFileFilter, PINDIR_OUTPUT, NULL, NULL, TRUE, 0, &pFileOut);
- if (SUCCEEDED(hr))
- {
- ASSERT(pFileOut);
- //now get the input pin of the splitter
- hr = g_pBuilder->FindPin(g_pAviSplitter, PINDIR_INPUT, NULL, NULL, TRUE, 0, &pSplitterIn);
- if (SUCCEEDED(hr))
- {
- ASSERT(pSplitterIn);
- //connect the file output pin to the AVI splitter in
- //until we do this, the output pin on the splitter won't appear
- hr = g_pGraphBuilder->ConnectDirect(pFileOut, pSplitterIn, NULL);
- if (SUCCEEDED(hr))
- {
- //now we can connect the AVISplitterOut to the InfTee IN, then connect that to the camera
- hr = g_pBuilder->FindPin(g_pAviSplitter, PINDIR_OUTPUT, NULL, NULL, TRUE, 0, &pSplitterOut);
- if (SUCCEEDED(hr))
- {
- ASSERT(pSplitterOut);
- //add the the infinite pin tee filter to the graph
- EXECUTE_ASSERT(S_OK == g_pGraphBuilder->AddFilter(g_pInfTee, L"Infinite Tee"));
- hr = g_pBuilder->FindPin(g_pInfTee, PINDIR_INPUT, NULL, NULL, TRUE, 0, &pInfTeeIn);
- if (SUCCEEDED(hr))
- {
- ASSERT(pInfTeeIn);
- hr = g_pGraphBuilder->ConnectDirect(pSplitterOut, pInfTeeIn, NULL);
- if (SUCCEEDED(hr))
- {
- //get the inftee output pin, and the DV Camera input pin
- hr = g_pBuilder->FindPin(g_pInfTee, PINDIR_OUTPUT, NULL, NULL, TRUE, 0, &pInfTeeOut1);
- if (SUCCEEDED(hr))
- {
- ASSERT(pInfTeeOut1);
- hr = g_pBuilder->FindPin(g_pDVCamera, PINDIR_INPUT, NULL, NULL, TRUE, 0, &pDvIn);
- if (SUCCEEDED(hr))
- {
- ASSERT(pDvIn);
- hr = g_pGraphBuilder->ConnectDirect(pInfTeeOut1, pDvIn, NULL);
- //
- //the capture portion of the graph is built, now lets do the preview
- //
- //get another output pin on the inftee
- hr = g_pBuilder->FindPin(g_pInfTee, PINDIR_OUTPUT, NULL, NULL, TRUE, 0, &pInfTeeOut2);
- if (SUCCEEDED(hr))
- {
- // Add the filters DV Splitter, DV Decoder, Video Renderer
- EXECUTE_ASSERT(S_OK == g_pGraphBuilder->AddFilter(g_pDVSplitter, L"DV Splitter"));
- EXECUTE_ASSERT(S_OK == g_pGraphBuilder->AddFilter(g_pDVCodec, L"DV Codec"));
- EXECUTE_ASSERT(S_OK == g_pGraphBuilder->AddFilter(g_pVideoRenderer, L"VideoRenderer"));
-
- // Find input pin of dvsplitter & connect inf tee and dvsplitter
- hr = g_pBuilder->FindPin(g_pDVSplitter, PINDIR_INPUT, NULL, NULL, TRUE, 0, &pSplitIn);
- if (SUCCEEDED(hr))
- {
- hr = g_pGraphBuilder->ConnectDirect(pInfTeeOut2, pSplitIn, NULL);
- if (SUCCEEDED(hr))
- {
- // find the vid & aud output pins on the dvsplitter
- hr = g_pBuilder->FindPin(g_pDVSplitter, PINDIR_OUTPUT, NULL , &MEDIATYPE_Video, TRUE, 0, &pSplitVout);
- if (SUCCEEDED(hr))
- {
- hr = g_pBuilder->FindPin(g_pDVSplitter, PINDIR_OUTPUT, NULL , &MEDIATYPE_Audio, TRUE, 0, &pSplitAout);
- if (SUCCEEDED(hr))
- {
- // find the input & output pins on the dv codec
- hr = g_pBuilder->FindPin(g_pDVCodec, PINDIR_INPUT, NULL , NULL, TRUE, 0, &pCodecIn);
- if (SUCCEEDED(hr))
- {
- hr = g_pBuilder->FindPin(g_pDVCodec, PINDIR_OUTPUT, NULL , NULL, TRUE, 0, &pCodecOut);
- if (SUCCEEDED(hr))
- {
- // connect the dvsplitter(vid) & dvcodec
- hr = g_pGraphBuilder->ConnectDirect(pSplitVout, pCodecIn, NULL);
- if (SUCCEEDED(hr))
- {
- //if we have audio, add the filter to the graph connect it to the dvsplitter(aud)
- if (g_pDSound)
- {
- EXECUTE_ASSERT(S_OK == g_pGraphBuilder->AddFilter(g_pDSound, L"DSound"));
- hr = g_pBuilder->FindPin(g_pDSound, PINDIR_INPUT, NULL , NULL, TRUE, 0, &pAudIn);
- if (SUCCEEDED(hr))
- {
- hr = g_pGraphBuilder->ConnectDirect(pSplitAout, pAudIn, NULL);
- }
- }
- if (SUCCEEDED(hr)) //verifies audio connection when audio exists
- {
- // get the input pin on the video renderer and connect it to the dvcodec
- hr = g_pBuilder->FindPin(g_pVideoRenderer, PINDIR_INPUT, NULL , NULL, TRUE, 0, &pRenderIn);
- if (SUCCEEDED(hr))
- {
- hr = g_pGraphBuilder->ConnectDirect(pCodecOut, pRenderIn, NULL);
- if (SUCCEEDED(hr))
- {
- // Woohoo! succeeded all the way
- // Set up the Video Window
- if (g_pVideoWindow)
- {
- g_pVideoWindow->put_Owner(NULL);
- SAFE_RELEASE(g_pVideoWindow);
- }
- hr = g_pBuilder->FindInterface(NULL, &MEDIATYPE_Video, g_pInputFileFilter, IID_IVideoWindow, reinterpret_cast<PVOID *>(&g_pVideoWindow));
- if (SUCCEEDED(hr))
- {
-
- RECT rc, rect;
- g_pVideoWindow->put_Owner((LONG_PTR)g_hwndApp); // We own the window now
- g_pVideoWindow->put_WindowStyle(WS_CHILD); // you are now a child
- GetClientRect(g_hwndApp, &rc);
- GetWindowRect(g_hwndTBar, &rect);
- g_pVideoWindow->SetWindowPosition(0, rect.bottom - rect.top, g_iVWWidth, g_iVWHeight);
- g_pVideoWindow->put_Visible(OATRUE);
- }
- else
- {
- DV_LogOut(LOG_PRIORITY_ERROR, LOG_LEVEL_SUCCINCT, TEXT("FindInterface (IVideoWindow) Failed. hr = 0x%x"), hr);
- }
- }
- SAFE_RELEASE(pRenderIn);
- }
- SAFE_RELEASE(pAudIn);
- }
- }
- SAFE_RELEASE(pCodecOut);
- }
- SAFE_RELEASE(pCodecIn);
- }
- SAFE_RELEASE(pSplitAout);
- }
- SAFE_RELEASE(pSplitVout);
- }
- }
- SAFE_RELEASE(pSplitIn);
- }
- SAFE_RELEASE(pInfTeeOut2);
- }
- SAFE_RELEASE(pDvIn);
- }
- SAFE_RELEASE(pInfTeeOut1);
- }
- }
- SAFE_RELEASE(pInfTeeIn);
- }
- SAFE_RELEASE(pSplitterOut);
- }
- } // Release interfaces appropriately
- else
- {
- // Handler for invalid source file format
- if (VFW_E_INVALID_FILE_FORMAT == hr)
- {
- MBOX(TEXT("The File format is invalid for the input file"));
- DV_LogOut(LOG_PRIORITY_ERROR, LOG_LEVEL_SUCCINCT, TEXT("The File format is invalid for the input file"));
- }
- else
- {
- DV_LogOut(LOG_PRIORITY_ERROR, LOG_LEVEL_SUCCINCT, TEXT("Could not connect ouput pin from file (0x%x)"), hr);
- }
- }
- SAFE_RELEASE(pSplitterIn);
- }
- SAFE_RELEASE(pFileOut);
- }
- }
-
- //if something failed, remove all of the filters we could have added here,
- //because DV_DisconnectAll only removes connected filters
- if (FAILED(hr))
- {
- if (g_pAviSplitter)
- g_pGraphBuilder->RemoveFilter(g_pAviSplitter);
- if (g_pInfTee)
- g_pGraphBuilder->RemoveFilter(g_pInfTee);
- if (g_pDVSplitter)
- g_pGraphBuilder->RemoveFilter(g_pDVSplitter);
- if (g_pDVCodec)
- g_pGraphBuilder->RemoveFilter(g_pDVCodec);
- if (g_pVideoRenderer)
- g_pGraphBuilder->RemoveFilter(g_pVideoRenderer);
- if (g_pDSound)
- g_pGraphBuilder->RemoveFilter(g_pDSound);
- if (g_pInputFileFilter)
- g_pGraphBuilder->RemoveFilter(g_pInputFileFilter);
- }
-
- return hr;
- }
-
-
- /*---------------------------------------------------------------------------------------------------------
- Routine: DV_MakeFileToDvGraph_NoPre
- Purpose: Builds and runs the File to DV graph without preview
- Arguments: None
- Returns: HRESULT as apropriate
- Notes: This is a transmit only graph for DV Type 1 AVI files
- This graph is a bit simplex. It looks like this:
- FileSource->AVI_Splitter->DV_Camera
- ---------------------------------------------------------------------------------------------------------*/
- HRESULT DV_MakeFileToDvGraph_NoPre(void)
- {
- HRESULT hr = S_OK;
- // making sure there is a input file selected
- if (NULL == g_InputFileName[0])
- {
- MBOX(TEXT("Please set an input file for rendering"));
- hr = E_FAIL;
- }
- else
- {
- //if we are compiling ANSI, the file name needs to be converted to UNICODE
- // Add the file as source filter to the graph
- #ifndef UNICODE
- WCHAR wFileName[MAX_PATH];
- MultiByteToWideChar(CP_ACP, 0, g_InputFileName, -1, wFileName, MAX_PATH);
- EXECUTE_ASSERT(S_OK == g_pGraphBuilder->AddSourceFilter(wFileName, wFileName, &g_pInputFileFilter));
- #else
- EXECUTE_ASSERT(S_OK == g_pGraphBuilder->AddSourceFilter(g_InputFileName, g_InputFileName, &g_pInputFileFilter));
- #endif
- //making sure the file source exists
- if(g_pInputFileFilter == NULL)
- {
- MBOX(TEXT("Please set a correct input file for rendering"));
- hr = E_FAIL;
- return hr;
- }
- // Also add the AVI Splitter
- EXECUTE_ASSERT(S_OK == g_pGraphBuilder->AddFilter(g_pAviSplitter, L"AVI Splitter"));
-
- // now we need to connect the pins
- IPin *pFileOut = NULL, *pSplitterIn = NULL, *pSplitterOut = NULL, *pDvIn = NULL;
-
- // obtain the output pin of the source filter and connect it to avi splitter
- hr = g_pBuilder->FindPin(g_pInputFileFilter, PINDIR_OUTPUT, NULL, NULL, TRUE, 0, &pFileOut);
- if (SUCCEEDED(hr))
- {
- ASSERT(pFileOut);
- //now get the input pin of the splitter
- hr = g_pBuilder->FindPin(g_pAviSplitter, PINDIR_INPUT, NULL, NULL, TRUE, 0, &pSplitterIn);
- if (SUCCEEDED(hr))
- {
- ASSERT(pSplitterIn);
- //connect the file output pin to the AVI splitter in
- //until we do this, the output pin on the splitter won't appear
- hr = g_pGraphBuilder->ConnectDirect(pFileOut, pSplitterIn, NULL);
- if (SUCCEEDED(hr))
- {
- //get the AVI Splitter output pin, and the DV Camera input pin and connect them
- hr = g_pBuilder->FindPin(g_pAviSplitter, PINDIR_OUTPUT, NULL, NULL, TRUE, 0, &pSplitterOut);
- if (SUCCEEDED(hr))
- {
- hr = g_pBuilder->FindPin(g_pDVCamera, PINDIR_INPUT, NULL, NULL, TRUE, 0, &pDvIn);
- if (SUCCEEDED(hr))
- {
- ASSERT(pDvIn);
- hr = g_pGraphBuilder->ConnectDirect(pSplitterOut, pDvIn, NULL);
- //
- //the capture portion of the graph is built
- //
- if (FAILED(hr))
- {
- DV_LogOut(LOG_PRIORITY_ERROR, LOG_LEVEL_MEDIUM, TEXT("Could not connect the AviSplitter to the DV Camera"));
- }
- SAFE_RELEASE(pDvIn);
- }
- SAFE_RELEASE(pSplitterOut);
- }
- } // Release interfaces appropriately
- else
- {
- // Handler for invalid source file format
- if (VFW_E_INVALID_FILE_FORMAT == hr)
- {
- MBOX(TEXT("The File format is invalid for the input file"));
- DV_LogOut(LOG_PRIORITY_ERROR, LOG_LEVEL_SUCCINCT, TEXT("The File format is invalid for the input file"));
- }
- else
- {
- DV_LogOut(LOG_PRIORITY_ERROR, LOG_LEVEL_SUCCINCT, TEXT("Could not connect ouput pin from file (0x%x)"), hr);
- }
- }
- SAFE_RELEASE(pSplitterIn);
- }
- SAFE_RELEASE(pFileOut);
- }
- }
- //if something failed, remove all of the filters we could have added here,
- //because DisconnectAll only removes connected filters
- if (FAILED(hr))
- {
- if (g_pAviSplitter)
- g_pGraphBuilder->RemoveFilter(g_pAviSplitter);
- if (g_pInputFileFilter)
- g_pGraphBuilder->RemoveFilter(g_pInputFileFilter);
- }
- return hr;
- }
-
- /*---------------------------------------------------------------------------------------------------------
- Routine: DV_MakeDvToFileGraph_Type2
- Purpose: Builds and runs the DV to File graph
- Arguments: None
- Returns: HRESULT as apropriate
- Notes: This is a capture & preview graph for DV Type 2 AVI files
- This graph is a bit more complex. It looks like this:
- DV_Cam(AV Out)->DVSplitter(vid)->SmartTee(capture)->AviMux->FileWriter
- SmartTee(preview)->DVCodec->VideoWindow
- DVSplitter(aud)->InfinitePinTee->AviMux->FileWriter
- InfinitePinTee->Default DirectSound device
- ---------------------------------------------------------------------------------------------------------*/
- HRESULT DV_MakeDvToFileGraph_Type2(void)
- {
- HRESULT hr = S_OK;
- DV_LogOut(LOG_PRIORITY_INFO, LOG_LEVEL_MEDIUM, TEXT("Building DV to File Graph (Adobe)"));
- // making sure there is a output file selected
- if (!g_OutputFileName[0])
- {
- MBOX(TEXT("Please set up an output file name for recording"));
- hr = E_FAIL;
- }
- else
- {
- DV_LogOut(LOG_PRIORITY_INFO, LOG_LEVEL_VERBOSE, TEXT("This is the graph - everything should be disconnected"));
- #ifndef UNICODE
- // convert the output file name to wchar
- WCHAR wFileName[MAX_PATH];
- MultiByteToWideChar(CP_ACP, 0, g_OutputFileName, -1, wFileName, MAX_PATH);
- #endif
-
- //we need a lot of pins to make this work...
- IPin *pAVOut = NULL, *pMuxAIn = NULL, *pMuxVIn = NULL;
- IPin *pDVSplitterIn = NULL, *pDVSplitterVOut = NULL, *pDVSplitterAOut = NULL;
- IPin *pTeeIn = NULL, *pTeeOut = NULL, *pTeePreOut = NULL;
- IPin *pInfTeeIn = NULL, *pInfTeeOut = NULL, *pInfTeePreOut = NULL;
- IPin *pAudIn = NULL, *pCodecIn = NULL, *pCodecOut = NULL, *pRenderIn = NULL;
-
- //get the camera output pin
- hr = g_pBuilder->FindPin(g_pDVCamera, PINDIR_OUTPUT, NULL, &MEDIATYPE_Interleaved, TRUE, 0, &pAVOut);
- // add the dv splitter, get the input pin of dvsplitter and connect it to the dvcamera
- if (SUCCEEDED(hr))
- {
- EXECUTE_ASSERT(S_OK == g_pGraphBuilder->AddFilter(g_pDVSplitter, L"DV Splitter"));
- hr = g_pBuilder->FindPin(g_pDVSplitter, PINDIR_INPUT, NULL, NULL, TRUE, 0, &pDVSplitterIn);
- if(SUCCEEDED(hr))
- {
- hr = g_pGraphBuilder->ConnectDirect(pAVOut, pDVSplitterIn, NULL);
- if(SUCCEEDED(hr))
- {
- // get the vid & aud output pins of the dvsplitter
- hr = g_pBuilder->FindPin(g_pDVSplitter, PINDIR_OUTPUT, NULL, &MEDIATYPE_Video, TRUE, 0, &pDVSplitterVOut);
- hr = g_pBuilder->FindPin(g_pDVSplitter, PINDIR_OUTPUT, NULL, &MEDIATYPE_Audio, TRUE, 0, &pDVSplitterAOut);
-
- if (SUCCEEDED(hr))
- {
- ASSERT(pDVSplitterVOut);
- ASSERT(pDVSplitterAOut);
- //add the smart tee, infinite tee filters to the graph
- EXECUTE_ASSERT(S_OK == g_pGraphBuilder->AddFilter(g_pSmartTee, L"Smart Tee"));
- EXECUTE_ASSERT(S_OK == g_pGraphBuilder->AddFilter(g_pInfTee, L"Infinite Tee"));
-
- // get the input pin of infinite pin tee and connect it to dvsplitter (aud) output pin
- hr = g_pBuilder->FindPin(g_pInfTee, PINDIR_INPUT, NULL, NULL, TRUE, 0, &pInfTeeIn);
- if (SUCCEEDED(hr))
- {
- hr = g_pGraphBuilder->ConnectDirect(pDVSplitterAOut, pInfTeeIn, NULL);
- if (SUCCEEDED(hr))
- {
- // get the outpin of infinite pin tee
- hr = g_pBuilder->FindPin(g_pInfTee, PINDIR_OUTPUT, NULL, NULL, TRUE, 0, &pInfTeeOut);
- if(SUCCEEDED(hr))
- {
- // get the input pin of smart tee and connect it to dvsplitter (vid) output pin
- hr = g_pBuilder->FindPin(g_pSmartTee, PINDIR_INPUT, NULL, NULL, TRUE, 0, &pTeeIn);
- if (SUCCEEDED(hr))
- {
- hr = g_pGraphBuilder->ConnectDirect(pDVSplitterVOut, pTeeIn, NULL);
- if (SUCCEEDED(hr))
- {
- // get the capture outpin of smart tee filter and connect it to avi muxer & file writer
- hr = g_pBuilder->FindPin(g_pSmartTee, PINDIR_OUTPUT, NULL, NULL, TRUE, 0, &pTeeOut);
- if(SUCCEEDED(hr))
- {
- //add the avimux, and file writer to the graph
- IBaseFilter *ppf = NULL;
- IFileSinkFilter *pSink = NULL;
- #ifndef UNICODE
- hr = g_pBuilder->SetOutputFileName(&MEDIASUBTYPE_Avi, wFileName, &ppf, &pSink);
- #else
- hr = g_pBuilder->SetOutputFileName(&MEDIASUBTYPE_Avi, g_OutputFileName, &ppf, &pSink);
- #endif //UNICODE
- if (SUCCEEDED(hr))
- {
- // Set the AVI Options like interleaving mode etc...
- DV_SetAviOptions(ppf, INTERLEAVE_NONE);
- //Now I need the input video pin on the mux to connect to the file writer
- hr = g_pBuilder->FindPin(ppf, PINDIR_INPUT, NULL, NULL, TRUE, 0, &pMuxVIn);
- if (SUCCEEDED(hr))
- {
- hr = g_pGraphBuilder->ConnectDirect(pTeeOut, pMuxVIn, NULL);
- if (SUCCEEDED(hr))
- {
- //Now I need the input audio pin on the mux
- hr = g_pBuilder->FindPin(ppf, PINDIR_INPUT, NULL, NULL, TRUE, 0, &pMuxAIn);
- if (SUCCEEDED(hr))
- {
- hr = g_pGraphBuilder->ConnectDirect(pInfTeeOut, pMuxAIn, NULL);
- //
- //the capture graph is built,but we still need to build the preview graph
- //
- // get the preview output pin on the smart tee
- hr = g_pBuilder->FindPin(g_pSmartTee, PINDIR_OUTPUT, NULL, NULL, TRUE, 0, &pTeePreOut);
- if (SUCCEEDED(hr))
- {
- // Add the filters DV Decoder, Video Renderer
- EXECUTE_ASSERT(S_OK == g_pGraphBuilder->AddFilter(g_pDVCodec, L"DV Codec"));
- EXECUTE_ASSERT(S_OK == g_pGraphBuilder->AddFilter(g_pVideoRenderer, L"VideoRenderer"));
-
- // get the output pin of Infinite pin tee filter
- hr = g_pBuilder->FindPin(g_pInfTee, PINDIR_OUTPUT, NULL , NULL, TRUE, 0, &pInfTeePreOut);
- if (SUCCEEDED(hr))
- {
- // find the input & output pins on the dv codec
- hr = g_pBuilder->FindPin(g_pDVCodec, PINDIR_INPUT, NULL , NULL, TRUE, 0, &pCodecIn);
- if (SUCCEEDED(hr))
- {
- hr = g_pBuilder->FindPin(g_pDVCodec, PINDIR_OUTPUT, NULL , NULL, TRUE, 0, &pCodecOut);
- if (SUCCEEDED(hr))
- {
- // connect the infinite pin tee to dvcodec
- hr = g_pGraphBuilder->ConnectDirect(pTeePreOut, pCodecIn, NULL);
- if (SUCCEEDED(hr))
- {
- //if we have audio, add the filter to the graph connect it to the infinite pin tee
- if (g_pDSound)
- {
- EXECUTE_ASSERT(S_OK == g_pGraphBuilder->AddFilter(g_pDSound, L"DSound"));
- hr = g_pBuilder->FindPin(g_pDSound, PINDIR_INPUT, NULL , NULL, TRUE, 0, &pAudIn);
- if (SUCCEEDED(hr))
- {
- hr = g_pGraphBuilder->ConnectDirect(pInfTeePreOut, pAudIn, NULL);
- SAFE_RELEASE(pAudIn);
- }
- }
- if (SUCCEEDED(hr)) //this verifies success of the audio connection when audio exists
- {
- // get the input pin ont he video renderer and connect it to the dvcodec
- hr = g_pBuilder->FindPin(g_pVideoRenderer, PINDIR_INPUT, NULL , NULL, TRUE, 0, &pRenderIn);
- if (SUCCEEDED(hr))
- {
- hr = g_pGraphBuilder->ConnectDirect(pCodecOut, pRenderIn, NULL);
- if (SUCCEEDED(hr))
- {
- // Woohoo! succeeded all the way
- // Set the Filter Graph to Preview State (Run in this case)
- DV_SetPreview();
- }
- }
- SAFE_RELEASE(pRenderIn);
- }
- }
- }
- SAFE_RELEASE(pCodecOut);
- }
- SAFE_RELEASE(pCodecIn);
- }
- SAFE_RELEASE(pInfTeePreOut);
- }
- SAFE_RELEASE(pTeePreOut);
- }
- SAFE_RELEASE(pMuxAIn);
- }
- }
- SAFE_RELEASE(pMuxVIn);
- }
- SAFE_RELEASE(ppf);
- SAFE_RELEASE(pSink);
- }
- SAFE_RELEASE(pTeeOut);
- }
- }
- SAFE_RELEASE(pTeeIn);
- }
- SAFE_RELEASE(pInfTeeOut);
- }
- }
- SAFE_RELEASE(pInfTeeIn);
- }
- SAFE_RELEASE(pDVSplitterVOut);
- SAFE_RELEASE(pDVSplitterAOut);
- } // Release interfaces appropriately
- else
- {
- DV_LogOut(LOG_PRIORITY_ERROR, LOG_LEVEL_SUCCINCT, TEXT("Could not connect output pin from camera (0x%x)"), hr);
- }
- }
- SAFE_RELEASE(pDVSplitterIn);
- }
- SAFE_RELEASE(pAVOut);
- }
- return hr;
- }
-
- /*---------------------------------------------------------------------------------------------------------
- Routine: DV_MakeDvToFileGraph_NoPre_Type2
- Purpose: Builds and runs the DV to File graph
- Arguments: None
- Returns: HRESULT as apropriate
- Notes: This is a capture only graph for DV Type 2 AVI files
- This graph is a bit simplex . It looks like this:
- DV_Cam(AV Out)->DVSplitter(vid)->AviMux->FileWriter
- DVSplitter(aud)->AviMux->FileWriter
- ---------------------------------------------------------------------------------------------------------*/
- HRESULT DV_MakeDvToFileGraph_NoPre_Type2(void)
- {
- HRESULT hr = S_OK;
- DV_LogOut(LOG_PRIORITY_INFO, LOG_LEVEL_MEDIUM, TEXT("Building DV to File Graph (No Preview)"));
- // making sure there is a output file selected
- if (!g_OutputFileName[0])
- {
- MBOX(TEXT("Please set up an output file name for recording"));
- hr = E_FAIL;
- }
- else
- {
- DV_LogOut(LOG_PRIORITY_INFO, LOG_LEVEL_VERBOSE, TEXT("This is the graph - everything should be disconnected"));
- #ifndef UNICODE
- // convert the output file name to wchar
- WCHAR wFileName[MAX_PATH];
- MultiByteToWideChar(CP_ACP, 0, g_OutputFileName, -1, wFileName, MAX_PATH);
- #endif
-
- //we'll need a few pins...
- IPin *pAVOut = NULL, *pDVSplitterIn=NULL, *pDVSplitterVOut=NULL, *pDVSplitterAOut=NULL, *pMuxVIn = NULL, *pMuxAIn = NULL;
-
- //get the camera output pin
- hr = g_pBuilder->FindPin(g_pDVCamera, PINDIR_OUTPUT, NULL, &MEDIATYPE_Interleaved, TRUE, 0, &pAVOut);
- // add the dv splitter, get the input pin of dvsplitter and connect it to the dvcamera
- if(SUCCEEDED(hr))
- {
- EXECUTE_ASSERT(S_OK == g_pGraphBuilder->AddFilter(g_pDVSplitter, L"DV Splitter"));
- hr = g_pBuilder->FindPin(g_pDVSplitter, PINDIR_INPUT, NULL, NULL, TRUE, 0, &pDVSplitterIn);
- if(SUCCEEDED(hr))
- {
- hr = g_pGraphBuilder->ConnectDirect(pAVOut, pDVSplitterIn, NULL);
- if(SUCCEEDED(hr))
- {
- // get the vid & aud output pins of the dvsplitter
- hr = g_pBuilder->FindPin(g_pDVSplitter, PINDIR_OUTPUT, NULL, &MEDIATYPE_Video, TRUE, 0, &pDVSplitterVOut);
- hr = g_pBuilder->FindPin(g_pDVSplitter, PINDIR_OUTPUT, NULL, &MEDIATYPE_Audio, TRUE, 0, &pDVSplitterAOut);
- if (SUCCEEDED(hr))
- {
- ASSERT(pDVSplitterVOut);
- ASSERT(pDVSplitterAOut);
- //add the avimux, and file writer to the graph
- IBaseFilter *ppf = NULL;
- IFileSinkFilter *pSink = NULL;
- #ifndef UNICODE
- hr = g_pBuilder->SetOutputFileName(&MEDIASUBTYPE_Avi, wFileName, &ppf, &pSink);
- #else
- hr = g_pBuilder->SetOutputFileName(&MEDIASUBTYPE_Avi, g_OutputFileName, &ppf, &pSink);
- #endif //UNICODE
- if (SUCCEEDED(hr))
- {
- // Set the AVI Options like interleaving mode etc...
- DV_SetAviOptions(ppf, INTERLEAVE_NONE);
- //Now I need the input pin on the mux to connect to the file writer
- hr = g_pBuilder->FindPin(ppf, PINDIR_INPUT, NULL, NULL, TRUE, 0, &pMuxVIn);
- // connect the video & audio paths between dvsplitter & avi muxer
- if (SUCCEEDED(hr))
- {
- hr = g_pGraphBuilder->ConnectDirect(pDVSplitterVOut, pMuxVIn, NULL);
- if(SUCCEEDED(hr))
- {
- hr = g_pBuilder->FindPin(ppf, PINDIR_INPUT, NULL, NULL, TRUE, 0, &pMuxAIn);
- if(SUCCEEDED(hr))
- {
- hr = g_pGraphBuilder->ConnectDirect(pDVSplitterAOut, pMuxAIn, NULL);
- //
- //the capture graph is built
- //
- if (FAILED(hr))
- {
- DV_LogOut(LOG_PRIORITY_ERROR, LOG_LEVEL_SUCCINCT, TEXT("Could not connect ouput pin from camera (0x%x)"), hr);
- }
-
- SAFE_RELEASE(pMuxAIn);
- }
- }
- SAFE_RELEASE(pMuxVIn);
- }
- SAFE_RELEASE(ppf);
- SAFE_RELEASE(pSink);
- }
-
- }
- SAFE_RELEASE(pDVSplitterVOut);
- SAFE_RELEASE(pDVSplitterAOut);
- }
- }
- SAFE_RELEASE(pDVSplitterIn);
- }
- SAFE_RELEASE(pAVOut);
- } // Release interfaces appropriately
- return hr;
- }
-
- /*---------------------------------------------------------------------------------------------------------
- Routine: DV_MakeFileToDvGraph_Type2
- Purpose: Builds and runs the File to DV graph
- Arguments: None
- Returns: HRESULT as apropriate
- Notes: This is a transmit & playback graph for DV Type 2 AVI files
- This graph is a bit complex. It looks like this:
- FileSource->AVI_Splitter(vid) ->DVMuxer(vid)---------->InfPinTee->DV_Camera
- AVI_Splitter(aud)->DVMuxer(aud) InfPinTee->DVSplitter(vid)->DVDecoder->VideoWIndow
- DVSplitter(aud)->DSoundDevice
- ---------------------------------------------------------------------------------------------------------*/
- HRESULT DV_MakeFileToDvGraph_Type2(void)
- {
- HRESULT hr = S_OK;
- // making sure there is a input file selected
- if (NULL == g_InputFileName[0])
- {
- MBOX(TEXT("Please set an input file for rendering"));
- hr = E_FAIL;
- }
- else
- {
- //if we are compiling ANSI, the file name needs to be converted to UNICODE
- // Add the file as source filter to the graph
- #ifndef UNICODE
- WCHAR wFileName[MAX_PATH];
- MultiByteToWideChar(CP_ACP, 0, g_InputFileName, -1, wFileName, MAX_PATH);
- EXECUTE_ASSERT(S_OK == g_pGraphBuilder->AddSourceFilter(wFileName, wFileName, &g_pInputFileFilter));
- #else
- EXECUTE_ASSERT(S_OK == g_pGraphBuilder->AddSourceFilter(g_InputFileName, g_InputFileName, &g_pInputFileFilter));
- #endif
- //making sure the file source exists
- if(g_pInputFileFilter == NULL)
- {
- MBOX(TEXT("Please set a correct input file for rendering"));
- hr = E_FAIL;
- return hr;
- }
- // Also add the AVI Splitter
- EXECUTE_ASSERT(S_OK == g_pGraphBuilder->AddFilter(g_pAviSplitter, L"AVI Splitter"));
-
- // now we need to connect the pins
- IPin *pFileOut = NULL, *pSplitterIn = NULL, *pSplitterVOut = NULL, *pSplitterAOut = NULL, *pDvIn = NULL;
- IPin *pInfTeeIn = NULL, *pInfTeeOut1 = NULL, *pInfTeeOut2 = NULL, *pSplitIn = NULL, *pRenderIn = NULL;
- IPin *pSplitVout = NULL, *pSplitAout = NULL, *pCodecIn = NULL, *pCodecOut = NULL, *pAudIn = NULL;
- IPin *pMuxerVIn = NULL, *pMuxerAIn = NULL, *pMuxerOut = NULL;
-
- // obtain the output pin of the source filter and connect it to avi splitter
- hr = g_pBuilder->FindPin(g_pInputFileFilter, PINDIR_OUTPUT, NULL, NULL, TRUE, 0, &pFileOut);
- if (SUCCEEDED(hr))
- {
- ASSERT(pFileOut);
- //now get the input pin of the splitter
- hr = g_pBuilder->FindPin(g_pAviSplitter, PINDIR_INPUT, NULL, NULL, TRUE, 0, &pSplitterIn);
- if (SUCCEEDED(hr))
- {
- ASSERT(pSplitterIn);
- //connect the file output pin to the AVI splitter in
- //until we do this, the output pin on the splitter won't appear
- hr = g_pGraphBuilder->ConnectDirect(pFileOut, pSplitterIn, NULL);
- if (SUCCEEDED(hr))
- {
- // get the video & audio output pins of the avi splitter
- hr = g_pBuilder->FindPin(g_pAviSplitter, PINDIR_OUTPUT, NULL, &MEDIATYPE_Video, TRUE, 0, &pSplitterVOut);
- hr = g_pBuilder->FindPin(g_pAviSplitter, PINDIR_OUTPUT, NULL, &MEDIATYPE_Audio, TRUE, 0, &pSplitterAOut);
- if(SUCCEEDED(hr))
- {
- ASSERT(pSplitterVOut);
- ASSERT(pSplitterAOut);
- // Add the DVMuxer to the graph
- EXECUTE_ASSERT(S_OK == g_pGraphBuilder->AddFilter(g_pDVMux, L"DV Muxer"));
- // get the video & audio input pins on the dvmuxer and connect it to the corressponding output pins of avi splitter
- hr = g_pBuilder->FindPin(g_pDVMux, PINDIR_INPUT, NULL, NULL, TRUE, 0, &pMuxerVIn);
- if(SUCCEEDED(hr))
- {
- hr = g_pGraphBuilder->ConnectDirect(pSplitterVOut, pMuxerVIn, NULL);
- if(SUCCEEDED(hr))
- {
- hr = g_pBuilder->FindPin(g_pDVMux, PINDIR_INPUT, NULL, NULL, TRUE, 0, &pMuxerAIn);
- if(SUCCEEDED(hr))
- {
- hr = g_pGraphBuilder->ConnectDirect(pSplitterAOut, pMuxerAIn, NULL);
- // get the ouput pin of the dv muxer
- if(SUCCEEDED(hr))
- {
- hr = g_pBuilder->FindPin(g_pDVMux, PINDIR_OUTPUT, NULL, NULL, TRUE, 0, &pMuxerOut);
- if (SUCCEEDED(hr))
- {
- //Add the infinite pin tee filter to the graph and connect it downstream to the dv muxer
- EXECUTE_ASSERT(S_OK == g_pGraphBuilder->AddFilter(g_pInfTee, L"Infinite Tee"));
- hr = g_pBuilder->FindPin(g_pInfTee, PINDIR_INPUT, NULL, NULL, TRUE, 0, &pInfTeeIn);
- if (SUCCEEDED(hr))
- {
- ASSERT(pInfTeeIn);
- hr = g_pGraphBuilder->ConnectDirect(pMuxerOut, pInfTeeIn, NULL);
- if (SUCCEEDED(hr))
- {
- //get the inftee output pin, and the DV Camera input pin and connect them
- hr = g_pBuilder->FindPin(g_pInfTee, PINDIR_OUTPUT, NULL, NULL, TRUE, 0, &pInfTeeOut1);
- if (SUCCEEDED(hr))
- {
- ASSERT(pInfTeeOut1);
- hr = g_pBuilder->FindPin(g_pDVCamera, PINDIR_INPUT, NULL, NULL, TRUE, 0, &pDvIn);
- if (SUCCEEDED(hr))
- {
- ASSERT(pDvIn);
- hr = g_pGraphBuilder->ConnectDirect(pInfTeeOut1, pDvIn, NULL);
- //
- //the capture portion of the graph should be done now, lets do the preview segment
- //
- //get another output pin on the inftee
- hr = g_pBuilder->FindPin(g_pInfTee, PINDIR_OUTPUT, NULL, NULL, TRUE, 0, &pInfTeeOut2);
- if (SUCCEEDED(hr))
- {
- // Add the filters DV Splitter, DV Decoder, Video Renderer
- EXECUTE_ASSERT(S_OK == g_pGraphBuilder->AddFilter(g_pDVSplitter, L"DV Splitter"));
- EXECUTE_ASSERT(S_OK == g_pGraphBuilder->AddFilter(g_pDVCodec, L"DV Codec"));
- EXECUTE_ASSERT(S_OK == g_pGraphBuilder->AddFilter(g_pVideoRenderer, L"VideoRenderer"));
-
- // Find input pin of dvsplitter & connect inf tee and dvsplitter
- hr = g_pBuilder->FindPin(g_pDVSplitter, PINDIR_INPUT, NULL, NULL, TRUE, 0, &pSplitIn);
- if (SUCCEEDED(hr))
- {
- hr = g_pGraphBuilder->ConnectDirect(pInfTeeOut2, pSplitIn, NULL);
- if (SUCCEEDED(hr))
- {
- // find the vid & aud output pins on the dvsplitter
- hr = g_pBuilder->FindPin(g_pDVSplitter, PINDIR_OUTPUT, NULL , &MEDIATYPE_Video, TRUE, 0, &pSplitVout);
- if (SUCCEEDED(hr))
- {
- hr = g_pBuilder->FindPin(g_pDVSplitter, PINDIR_OUTPUT, NULL , &MEDIATYPE_Audio, TRUE, 0, &pSplitAout);
- if (SUCCEEDED(hr))
- {
- // find the input & output pins on the dv codec
- hr = g_pBuilder->FindPin(g_pDVCodec, PINDIR_INPUT, NULL , NULL, TRUE, 0, &pCodecIn);
- if (SUCCEEDED(hr))
- {
- hr = g_pBuilder->FindPin(g_pDVCodec, PINDIR_OUTPUT, NULL , NULL, TRUE, 0, &pCodecOut);
- if (SUCCEEDED(hr))
- {
- // connect the dvsplitter(vid) & dvcodec
- hr = g_pGraphBuilder->ConnectDirect(pSplitVout, pCodecIn, NULL);
- if (SUCCEEDED(hr))
- {
- //if we have audio, add the filter to the graph connect it to the dvsplitter(aud)
- if (g_pDSound)
- {
- EXECUTE_ASSERT(S_OK == g_pGraphBuilder->AddFilter(g_pDSound, L"DSound"));
- hr = g_pBuilder->FindPin(g_pDSound, PINDIR_INPUT, NULL , NULL, TRUE, 0, &pAudIn);
- if (SUCCEEDED(hr))
- {
- hr = g_pGraphBuilder->ConnectDirect(pSplitAout, pAudIn, NULL);
- }
- }
- if (SUCCEEDED(hr)) //verifies audio connection when audio exists
- {
- // get the input pin on the video renderer and connect it to the dvcodec
- hr = g_pBuilder->FindPin(g_pVideoRenderer, PINDIR_INPUT, NULL , NULL, TRUE, 0, &pRenderIn);
- if (SUCCEEDED(hr))
- {
- hr = g_pGraphBuilder->ConnectDirect(pCodecOut, pRenderIn, NULL);
- if (SUCCEEDED(hr))
- {
- // Woohoo! succeeded all the way
- // Set up the Video Window
- if (g_pVideoWindow)
- {
- g_pVideoWindow->put_Owner(NULL);
- SAFE_RELEASE(g_pVideoWindow);
- }
- hr = g_pBuilder->FindInterface(NULL, &MEDIATYPE_Video, g_pInputFileFilter, IID_IVideoWindow, reinterpret_cast<PVOID *>(&g_pVideoWindow));
- if (SUCCEEDED(hr))
- {
-
- RECT rc, rect;
- g_pVideoWindow->put_Owner((LONG_PTR)g_hwndApp); // We own the window now
- g_pVideoWindow->put_WindowStyle(WS_CHILD); // you are now a child
- GetClientRect(g_hwndApp, &rc);
- GetWindowRect(g_hwndTBar, &rect);
- g_pVideoWindow->SetWindowPosition(0, rect.bottom - rect.top, g_iVWWidth, g_iVWHeight);
- g_pVideoWindow->put_Visible(OATRUE);
- }
- else
- {
- DV_LogOut(LOG_PRIORITY_ERROR, LOG_LEVEL_SUCCINCT, TEXT("FindInterface (IVideoWindow) Failed. hr = 0x%x"), hr);
- }
- }
- SAFE_RELEASE(pRenderIn);
- }
- SAFE_RELEASE(pAudIn);
- }
- }
- SAFE_RELEASE(pCodecOut);
- }
- SAFE_RELEASE(pCodecIn);
- }
- SAFE_RELEASE(pSplitAout);
- }
- SAFE_RELEASE(pSplitVout);
- }
- }
- SAFE_RELEASE(pSplitIn);
- }
- SAFE_RELEASE(pInfTeeOut2);
- }
- SAFE_RELEASE(pDvIn);
- }
- SAFE_RELEASE(pInfTeeOut1);
- }
- }
- SAFE_RELEASE(pInfTeeIn);
- }
- SAFE_RELEASE(pMuxerOut);
- }
- }
- SAFE_RELEASE(pMuxerAIn);
- }
- }
- SAFE_RELEASE(pMuxerVIn);
- }
- SAFE_RELEASE(pSplitterVOut);
- SAFE_RELEASE(pSplitterAOut);
- }
- } // Release interfaces appropriately
- else
- {
- // Handler for invalid source file format
- if (VFW_E_INVALID_FILE_FORMAT == hr)
- {
- MBOX(TEXT("The File format is invalid for the input file"));
- DV_LogOut(LOG_PRIORITY_ERROR, LOG_LEVEL_SUCCINCT, TEXT("The File format is invalid for the input file"));
- }
- else
- {
- DV_LogOut(LOG_PRIORITY_ERROR, LOG_LEVEL_SUCCINCT, TEXT("Could not connect ouput pin from file (0x%x)"), hr);
- }
- }
- SAFE_RELEASE(pSplitterIn);
- }
- SAFE_RELEASE(pFileOut);
- }
- }
- //if something failed, remove all of the filters we could have added here,
- //because DV_DisconnectAll only removes connected filters
- if (FAILED(hr))
- {
- if (g_pAviSplitter)
- g_pGraphBuilder->RemoveFilter(g_pAviSplitter);
- if (g_pInfTee)
- g_pGraphBuilder->RemoveFilter(g_pInfTee);
- if (g_pDVSplitter)
- g_pGraphBuilder->RemoveFilter(g_pDVSplitter);
- if (g_pDVCodec)
- g_pGraphBuilder->RemoveFilter(g_pDVCodec);
- if (g_pVideoRenderer)
- g_pGraphBuilder->RemoveFilter(g_pVideoRenderer);
- if (g_pDSound)
- g_pGraphBuilder->RemoveFilter(g_pDSound);
- if (g_pInputFileFilter)
- g_pGraphBuilder->RemoveFilter(g_pInputFileFilter);
- }
-
- return hr;
- }
-
-
- /*---------------------------------------------------------------------------------------------------------
- Routine: DV_MakeFileToDvGraph_NoPre_Type2
- Purpose: Builds and runs the File to DV graph
- Arguments: None
- Returns: HRESULT as apropriate
- Notes: This is a transmit only graph for DV Type 2 AVI files
- This graph looks like this:
- FileSource->AVI_Splitter(vid) ->DVMuxer(vid)----->DV_Camera
- AVI_Splitter(aud)->DVMuxer(aud)
- ---------------------------------------------------------------------------------------------------------*/
- HRESULT DV_MakeFileToDvGraph_NoPre_Type2(void)
- {
- HRESULT hr = S_OK;
- // making sure there is a input file selected
- if (NULL == g_InputFileName[0])
- {
- MBOX(TEXT("Please set an input file for rendering"));
- hr = E_FAIL;
- }
- else
- {
- //if we are compiling ANSI, the file name needs to be converted to UNICODE
- // Add the file as source filter to the graph
- #ifndef UNICODE
- WCHAR wFileName[MAX_PATH];
- MultiByteToWideChar(CP_ACP, 0, g_InputFileName, -1, wFileName, MAX_PATH);
- EXECUTE_ASSERT(S_OK == g_pGraphBuilder->AddSourceFilter(wFileName, wFileName, &g_pInputFileFilter));
- #else
- EXECUTE_ASSERT(S_OK == g_pGraphBuilder->AddSourceFilter(g_InputFileName, g_InputFileName, &g_pInputFileFilter));
- #endif
- //making sure the file source exists
- if(g_pInputFileFilter == NULL)
- {
- MBOX(TEXT("Please set a correct input file for rendering"));
- hr = E_FAIL;
- return hr;
- }
- // Also add the AVI Splitter
- EXECUTE_ASSERT(S_OK == g_pGraphBuilder->AddFilter(g_pAviSplitter, L"AVI Splitter"));
-
- // now we need to connect the pins
- IPin *pFileOut = NULL, *pSplitterIn = NULL, *pSplitterVOut = NULL, *pSplitterAOut = NULL, *pMuxerVIn=NULL, *pMuxerAIn=NULL, *pMuxerOut=NULL, *pDvIn = NULL;
-
- // obtain the output pin of the source filter and connect it to avi splitter
- hr = g_pBuilder->FindPin(g_pInputFileFilter, PINDIR_OUTPUT, NULL, NULL, TRUE, 0, &pFileOut);
- if (SUCCEEDED(hr))
- {
- ASSERT(pFileOut);
- //now get the input pin of the splitter
- hr = g_pBuilder->FindPin(g_pAviSplitter, PINDIR_INPUT, NULL, NULL, TRUE, 0, &pSplitterIn);
- if (SUCCEEDED(hr))
- {
- ASSERT(pSplitterIn);
- //connect the file output pin to the AVI splitter in
- //until we do this, the output pin on the splitter won't appear
- hr = g_pGraphBuilder->ConnectDirect(pFileOut, pSplitterIn, NULL);
- if (SUCCEEDED(hr))
- {
- // get the video & audio output pins of the avi splitter
- hr = g_pBuilder->FindPin(g_pAviSplitter, PINDIR_OUTPUT, NULL, &MEDIATYPE_Video, TRUE, 0, &pSplitterVOut);
- hr = g_pBuilder->FindPin(g_pAviSplitter, PINDIR_OUTPUT, NULL, &MEDIATYPE_Audio, TRUE, 0, &pSplitterAOut);
- if(SUCCEEDED(hr))
- {
- ASSERT(pSplitterVOut);
- ASSERT(pSplitterAOut);
- // Add the DVMuxer to the graph
- EXECUTE_ASSERT(S_OK == g_pGraphBuilder->AddFilter(g_pDVMux, L"DV Muxer"));
- // get the video & audio input pins on the dvmuxer and connect it to the corressponding output pins of avi splitter
- hr = g_pBuilder->FindPin(g_pDVMux, PINDIR_INPUT, NULL, NULL, TRUE, 0, &pMuxerVIn);
- if(SUCCEEDED(hr))
- {
- hr = g_pGraphBuilder->ConnectDirect(pSplitterVOut, pMuxerVIn, NULL);
- if(SUCCEEDED(hr))
- {
- hr = g_pBuilder->FindPin(g_pDVMux, PINDIR_INPUT, NULL, NULL, TRUE, 0, &pMuxerAIn);
- if(SUCCEEDED(hr))
- {
- hr = g_pGraphBuilder->ConnectDirect(pSplitterAOut, pMuxerAIn, NULL);
- // get the ouput pin of the dv muxer and the dv camera input pin and connect them
- if(SUCCEEDED(hr))
- {
- hr = g_pBuilder->FindPin(g_pDVMux, PINDIR_OUTPUT, NULL, NULL, TRUE, 0, &pMuxerOut);
- if(SUCCEEDED(hr))
- {
- hr = g_pBuilder->FindPin(g_pDVCamera, PINDIR_INPUT, NULL, NULL, TRUE, 0, &pDvIn);
- if (SUCCEEDED(hr))
- {
- ASSERT(pDvIn);
- hr = g_pGraphBuilder->ConnectDirect(pMuxerOut, pDvIn, NULL);
- //
- //the capture portion of the graph should be done now, lets do the preview segment
- //
- if (FAILED(hr))
- {
- DV_LogOut(LOG_PRIORITY_ERROR, LOG_LEVEL_MEDIUM, TEXT("Could not connect the DV Muxer to the DV Camera"));
- }
- SAFE_RELEASE(pDvIn);
- }
- }
- SAFE_RELEASE(pMuxerOut);
- }
- }
- SAFE_RELEASE(pMuxerAIn);
- }
- }
- SAFE_RELEASE(pMuxerVIn);
- }
- SAFE_RELEASE(pSplitterVOut);
- SAFE_RELEASE(pSplitterAOut);
- } // Release interfaces appropriately
- else
- {
- // Handler for invalid source file format
- if (VFW_E_INVALID_FILE_FORMAT == hr)
- {
- MBOX(TEXT("The File format is invalid for the input file"));
- DV_LogOut(LOG_PRIORITY_ERROR, LOG_LEVEL_SUCCINCT, TEXT("The File format is invalid for the input file"));
- }
- else
- {
- DV_LogOut(LOG_PRIORITY_ERROR, LOG_LEVEL_SUCCINCT, TEXT("Could not connect ouput pin from file (0x%x)"), hr);
- }
- }
- SAFE_RELEASE(pSplitterIn);
- }
- SAFE_RELEASE(pFileOut);
- }
- }
- //if something failed, remove all of the filters we could have added here,
- //because DisconnectAll only removes connected filters
- if (FAILED(hr))
- {
- if (g_pAviSplitter)
- g_pGraphBuilder->RemoveFilter(g_pAviSplitter);
- if (g_pInputFileFilter)
- g_pGraphBuilder->RemoveFilter(g_pInputFileFilter);
-
- }
- return hr;
- }
-
- /*-------------------------------------------------------------------------
- Routine: DV_SetAviOptions
- Purpose: Routine for changing AVI Mux properties. In this sample, we just set a few options.
- These options could be set through the Avi Mux property sheet, or through a separate dialog
- Arguments: pointer to the AVI renderer (from SetOutputFileName())
- Returns: HRESULT as appropriate
- Notes:
- ------------------------------------------------------------------------*/
- HRESULT DV_SetAviOptions(IBaseFilter *ppf, InterleavingMode INTERLEAVE_MODE)
- {
- HRESULT hr;
- ASSERT(ppf);
- IConfigAviMux *pMux = NULL;
- IConfigInterleaving *pInterleaving = NULL;
-
- // QI for interface AVI Muxer
- hr = ppf->QueryInterface(IID_IConfigAviMux, reinterpret_cast<PVOID *>(&pMux));
- if (SUCCEEDED(hr))
- {
- pMux->SetOutputCompatibilityIndex(TRUE);
- // QI for interface Interleaving
- hr = ppf->QueryInterface(IID_IConfigInterleaving, reinterpret_cast<PVOID *>(&pInterleaving));
- if (SUCCEEDED(hr))
- {
- // put the interleaving mode (full, none, half)
- pInterleaving->put_Mode(INTERLEAVE_MODE);
- SAFE_RELEASE(pInterleaving);
- }
- SAFE_RELEASE(pMux);
- }
- return hr;
- }
-
-
- /*-------------------------------------------------------------------------
- Routine: DV_AboutDlgProc
- Purpose: simple standard about dialog box proc
- Arguments: Usual Dialog Processing parameters
- Returns: BOOL
- Notes:
- ------------------------------------------------------------------------*/
- BOOL CALLBACK DV_AboutDlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
- {
- switch ( msg )
- {
- //the only command we process are those that close the dialog
- case WM_COMMAND:
- EndDialog(hwnd, TRUE);
- return TRUE;
- case WM_INITDIALOG:
- return TRUE;
- }
- return FALSE;
- }
-
- /*-------------------------------------------------------------------------
- Routine: DV_ChooseModeDlgProc
- Purpose: dialog proc to select camera/vcr mode on devices that do not respond to the queries
- Arguments: Usual Dialog Processing parameters
- Returns: BOOL
- Notes:
- ------------------------------------------------------------------------*/
- BOOL CALLBACK DV_ChooseModeDlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
- {
- switch ( msg )
- {
- case WM_COMMAND:
- // Choose whether the camera or vcr unit is selected manually
- switch LOWORD(wParam)
- {
- case IDC_BUTTON_CAMERA :
- g_CurrentMode = CameraMode;
- EndDialog(hwnd, TRUE);
- break;
- case IDC_BUTTON_VCR :
- g_CurrentMode = VcrMode;
- EndDialog(hwnd, TRUE);
- break;
- default :
- break;
- }
- break;
- case WM_INITDIALOG:
- return TRUE;
- }
- return FALSE;
- }
-
- /*-------------------------------------------------------------------------
- Routine: DV_ChangeDecodeSizeProc
- Purpose: UI wrapper to change DV Decode size
- Arguments: Usual Dialog Processing parameters
- Returns: BOOL
- Notes:
- ------------------------------------------------------------------------*/
- BOOL CALLBACK DV_ChangeDecodeSizeProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
- {
- int iDisplayPix = 0;
- HRESULT hr;
-
- switch ( msg )
- {
- case WM_COMMAND:
- // Select which DV format resolution you would like to navigate to
- switch LOWORD(wParam)
- {
- case IDOK :
- //get selected size, and set size accordingly
- if (Button_GetCheck(GetDlgItem(hwnd, IDC_RADIO_88x60)))
- {
- g_pDvDec->put_IPDisplay(DVRESOLUTION_DC);
- g_iVWWidth = 88; g_iVWHeight = 60;
- g_iAppWidth = g_iVWWidth+5; g_iAppHeight = g_iVWHeight+135;
- SendMessage(g_hwndApp, WM_SIZE, SIZE_RESTORED, MAKELONG(g_iAppWidth, g_iAppHeight));
- }
- else if (Button_GetCheck(GetDlgItem(hwnd, IDC_RADIO_180x120)))
- {
- g_pDvDec->put_IPDisplay(DVRESOLUTION_QUARTER);
- g_iVWWidth = 160; g_iVWHeight = 120;
- g_iAppWidth = g_iVWWidth+5; g_iAppHeight = g_iVWHeight+115;
- SendMessage(g_hwndApp, WM_SIZE, SIZE_RESTORED, MAKELONG(g_iAppWidth, g_iAppHeight));
- }
- else if (Button_GetCheck(GetDlgItem(hwnd, IDC_RADIO_360x240)))
- {
- g_pDvDec->put_IPDisplay(DVRESOLUTION_HALF);
- g_iVWWidth = 360; g_iVWHeight = 240;
- g_iAppWidth = g_iVWWidth+5; g_iAppHeight = g_iVWHeight+95;
- SendMessage(g_hwndApp, WM_SIZE, SIZE_RESTORED, MAKELONG(g_iAppWidth, g_iAppHeight));
- }
- else if (Button_GetCheck(GetDlgItem(hwnd, IDC_RADIO_720x480)))
- {
- g_pDvDec->put_IPDisplay(DVRESOLUTION_FULL);
- g_iVWWidth = 720; g_iVWHeight = 480;
- g_iAppWidth = g_iVWWidth+5; g_iAppHeight = g_iVWHeight+95;
- SendMessage(g_hwndApp, WM_SIZE, SIZE_RESTORED, MAKELONG(g_iAppWidth, g_iAppHeight));
- }
- else
- {
- DV_LogOut(LOG_PRIORITY_ERROR, LOG_LEVEL_SUCCINCT, TEXT("Invalid selection in DecodeSize Dialog"));
- }
- //safely fall through
-
- case IDCANCEL :
- //if it's the preview graph - restart it - otherwise leave it stopped
- if (GRAPH_PREVIEW == g_iCurrentGraph)
- {
- DV_StartGraph();
- }
- SAFE_RELEASE(g_pDvDec);
- EndDialog(hwnd, TRUE);
- break;
-
- default :
- break;
- }
- break;
-
- case WM_INITDIALOG:
- /*
- can't set the decode size if the graph is running - so we'll stop it.
- there are other options, such as graying out the menu item whil the graph is
- playing that could be implemented. For this simple application, this methos
- will suffice.
- */
- if (SUCCEEDED(DV_StopGraph()))
- {
- hr = g_pDVCodec->QueryInterface(IID_IIPDVDec, reinterpret_cast<PVOID *>(&g_pDvDec));
- if (SUCCEEDED(hr))
- {
- hr = g_pDvDec->get_IPDisplay(&iDisplayPix);
- //set button check appropriately
- switch (iDisplayPix)
- {
- case DVRESOLUTION_DC :
- Button_SetCheck(GetDlgItem(hwnd, IDC_RADIO_88x60), TRUE);
- break;
-
- case DVRESOLUTION_QUARTER :
- Button_SetCheck(GetDlgItem(hwnd, IDC_RADIO_180x120), TRUE);
- break;
-
- case DVRESOLUTION_HALF :
- Button_SetCheck(GetDlgItem(hwnd, IDC_RADIO_360x240), TRUE);
- break;
-
- case DVRESOLUTION_FULL :
- Button_SetCheck(GetDlgItem(hwnd, IDC_RADIO_720x480), TRUE);
- break;
-
- default :
- DV_LogOut(LOG_PRIORITY_ERROR, LOG_LEVEL_SUCCINCT, TEXT("Invalid return from get_IPDisplay"));
- break;
- }
- }
- else
- {
- MBOX(TEXT("Cannot determine current Decode size"));
- EndDialog(hwnd, FALSE);
- DV_LogOut(LOG_PRIORITY_ERROR, LOG_LEVEL_SUCCINCT, TEXT("Could not get IIPDVDec interface. hr = 0x%x"), hr);
- }
- }
- else
- {
- MBOX(TEXT("Could not stop graph"));
- EndDialog(hwnd, FALSE);
- }
- return TRUE;
- }
- return FALSE;
- }
-
- /*-------------------------------------------------------------------------
- Routine: DV_CapSizeDlgProc
- Purpose: Dialog proc for cap size dialog
- Arguments: Usual Dialog Processing parameters
- Returns: BOOL
- Notes:
- ------------------------------------------------------------------------*/
- BOOL CALLBACK DV_CapSizeDlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
- {
-
- switch ( msg )
- {
- case WM_INITDIALOG:
- {
- TCHAR capDisk[8];
- ULARGE_INTEGER ulFreeBytes;
- ULARGE_INTEGER ulTotalBytes;
- ULARGE_INTEGER ulAvailBytes;
-
- // make sure output file name has been input for capture
- if (!g_OutputFileName[0])
- {
- MBOX(TEXT("Please set up an output file name for recording"));
- EndDialog(hwnd, FALSE);
- return FALSE;
- }
-
- //need to determine disk space and init the dialog appropriately
- lstrcpyn(capDisk, g_OutputFileName, 3);
- capDisk[4] = '\0';
- GetDiskFreeSpaceEx(capDisk, &ulFreeBytes, &ulTotalBytes, &ulAvailBytes);
- DV_LogOut(LOG_PRIORITY_INFO, LOG_LEVEL_SUCCINCT, TEXT("Available MB on drive %s is %d MB"), capDisk, ulAvailBytes.QuadPart / (1024 * 1024));
-
- //let's see what our top limits are, and set our limits appropriately
- if ((ulAvailBytes.QuadPart / DV_BYTES_IN_MEG) < 120)
- {
- //less than 120 MB available - subtract 10 MB at a time until we get a usable amount
- UINT i = 110;
- while ((ulAvailBytes.QuadPart / DV_BYTES_IN_MEG) < i)
- {
- i -= 10;
- }
- SendMessage(GetDlgItem(hwnd, IDC_SPIN_TIME), UDM_SETRANGE, 0, MAKELONG(i / 4, 1));
- SendMessage(GetDlgItem(hwnd, IDC_SPIN_SIZE), UDM_SETRANGE, 0, MAKELONG(i, 1));
- }
- else
- {
- SendMessage(GetDlgItem(hwnd, IDC_SPIN_TIME), UDM_SETRANGE, 0, MAKELONG( ((ulAvailBytes.QuadPart / (1024 * 1024) ) - 10) / 4, 1));
- SendMessage(GetDlgItem(hwnd, IDC_SPIN_SIZE), UDM_SETRANGE, 0, MAKELONG( (ulAvailBytes.QuadPart / (1024 * 1024) ) - 10, 1));
- }
-
- //enable / disable the controls as appropriate
- switch (g_dwCaptureLimit)
- {
- case DV_CAPLIMIT_NONE :
- Button_SetCheck(GetDlgItem(hwnd, IDC_RADIO_NOLIMIT), TRUE);
- EnableWindow(GetDlgItem(hwnd, IDC_EDIT_SIZE), FALSE);
- EnableWindow(GetDlgItem(hwnd, IDC_SPIN_SIZE), FALSE);
- EnableWindow(GetDlgItem(hwnd, IDC_EDIT_TIME), FALSE);
- EnableWindow(GetDlgItem(hwnd, IDC_SPIN_TIME), FALSE);
- break;
-
- case DV_CAPLIMIT_TIME :
- {
- /*check the radio button, disable the size based controls */
- Button_SetCheck(GetDlgItem(hwnd, IDC_RADIO_TIME), TRUE);
- EnableWindow(GetDlgItem(hwnd, IDC_EDIT_SIZE), FALSE);
- EnableWindow(GetDlgItem(hwnd, IDC_SPIN_SIZE), FALSE);
-
- break;
- }
- case DV_CAPLIMIT_SIZE :
- {
- /*check the radio button, disable the time based controls */
- Button_SetCheck(GetDlgItem(hwnd, IDC_RADIO_SIZE), TRUE);
- EnableWindow(GetDlgItem(hwnd, IDC_EDIT_TIME), FALSE);
- EnableWindow(GetDlgItem(hwnd, IDC_SPIN_TIME), FALSE);
-
- break;
- }
- }
- SetDlgItemInt(hwnd, IDC_EDIT_TIME, g_dwTimeLimit, FALSE);
- SetDlgItemInt(hwnd, IDC_EDIT_SIZE, g_dwDiskSpace, FALSE);
- break;
- }
- case WM_COMMAND :
- switch LOWORD(wParam)
- {
- // Update the controls ui according to the choices made
- case IDC_RADIO_NOLIMIT :
- {
- Button_SetCheck(GetDlgItem(hwnd, IDC_RADIO_NOLIMIT), TRUE);
- EnableWindow(GetDlgItem(hwnd, IDC_EDIT_SIZE), FALSE);
- EnableWindow(GetDlgItem(hwnd, IDC_SPIN_SIZE), FALSE);
- EnableWindow(GetDlgItem(hwnd, IDC_EDIT_TIME), FALSE);
- EnableWindow(GetDlgItem(hwnd, IDC_SPIN_TIME), FALSE);
- break;
- }
-
- case IDC_RADIO_TIME :
- {
- Button_SetCheck(GetDlgItem(hwnd, IDC_RADIO_TIME), TRUE);
- EnableWindow(GetDlgItem(hwnd, IDC_EDIT_SIZE), FALSE);
- EnableWindow(GetDlgItem(hwnd, IDC_SPIN_SIZE), FALSE);
- EnableWindow(GetDlgItem(hwnd, IDC_EDIT_TIME), TRUE);
- EnableWindow(GetDlgItem(hwnd, IDC_SPIN_TIME), TRUE);
- break;
- }
-
- case IDC_RADIO_SIZE :
- {
- Button_SetCheck(GetDlgItem(hwnd, IDC_RADIO_SIZE), TRUE);
- EnableWindow(GetDlgItem(hwnd, IDC_EDIT_TIME), FALSE);
- EnableWindow(GetDlgItem(hwnd, IDC_SPIN_TIME), FALSE);
- EnableWindow(GetDlgItem(hwnd, IDC_EDIT_SIZE), TRUE);
- EnableWindow(GetDlgItem(hwnd, IDC_SPIN_SIZE), TRUE);
- break;
- }
-
- case IDOK :
- {
- BOOL bTranslated = FALSE;
- // The selections are made
- // update the new global capture flag
- if (Button_GetCheck(GetDlgItem(hwnd, IDC_RADIO_NOLIMIT)))
- {
- g_dwCaptureLimit = DV_CAPLIMIT_NONE;
- DV_LogOut(LOG_PRIORITY_INFO, LOG_LEVEL_MEDIUM, TEXT("No capture size limit"));
- }
- else if (Button_GetCheck(GetDlgItem(hwnd, IDC_RADIO_TIME)))
- {
- g_dwTimeLimit = GetDlgItemInt(hwnd, IDC_EDIT_TIME, &bTranslated, FALSE);
- g_dwCaptureLimit = DV_CAPLIMIT_TIME;
- DV_LogOut(LOG_PRIORITY_INFO, LOG_LEVEL_MEDIUM, TEXT("Time based limit - %d"), g_dwTimeLimit);
- }
- else if (Button_GetCheck(GetDlgItem(hwnd, IDC_RADIO_SIZE)))
- {
- g_dwDiskSpace = GetDlgItemInt(hwnd, IDC_EDIT_SIZE, &bTranslated, FALSE);
- g_dwCaptureLimit = DV_CAPLIMIT_SIZE;
- DV_LogOut(LOG_PRIORITY_INFO, LOG_LEVEL_MEDIUM, TEXT("Disk based limit - %d MB"), g_dwDiskSpace);
- }
- EndDialog(hwnd, TRUE);
- return TRUE;
- }
-
- case IDCANCEL :
- // update nothing much
- EndDialog(hwnd, FALSE);
- return FALSE;
- default :
- return FALSE;
- }
- return TRUE;
- }
- return FALSE;
- }
-
- /*-------------------------------------------------------------------------
- Routine: DV_GetTapeInfo
- Purpose: Get Frame rate and availability of dvcr tape
- Arguments: None
- Returns: HRESULT as appropriate
- Notes:
- ------------------------------------------------------------------------*/
- HRESULT DV_GetTapeInfo(void)
- {
- HRESULT hr;
- LONG lMediaType = 0;
- LONG lInSignalMode = 0;
-
- // Query Media Type of the transport
- hr = g_pExtTrans->GetStatus(ED_MEDIA_TYPE, &lMediaType);
- if (SUCCEEDED(hr))
- {
- if (ED_MEDIA_NOT_PRESENT == lMediaType)
- {
- // Update the log & Status Window
- DV_LogOut(LOG_PRIORITY_INFO, LOG_LEVEL_SUCCINCT, TEXT("No tape is inserted"));
- DV_StatusText(TEXT("VCR Mode - No tape, or unknown format"), 2);
- //we want to return failure if there is no tape installed
- hr = S_FALSE;
- }
- else
- {
- //tape type should always be DVC
- ASSERT(ED_MEDIA_DVC == lMediaType);
-
- // Now lets query for the signal mode of the tape.
- g_pExtTrans->GetTransportBasicParameters(ED_TRANSBASIC_INPUT_SIGNAL, &lInSignalMode, NULL);
- Sleep(_MAX_SLEEP);
- if (SUCCEEDED(hr))
- { // determine whether the camcorder supports ntsc or pal
- switch (lInSignalMode)
- {
- case ED_TRANSBASIC_SIGNAL_525_60_SD :
- g_AvgTimePerFrame = 33; // 33 milli-sec (29.97 FPS)
- DV_StatusText(TEXT("VCR Mode - NTSC"), 2);
- break;
-
- case ED_TRANSBASIC_SIGNAL_525_60_SDL :
- g_AvgTimePerFrame = 33; // 33 milli-sec (29.97 FPS)
- DV_StatusText(TEXT("VCR Mode - NTSC"), 2);
- break;
-
- case ED_TRANSBASIC_SIGNAL_625_50_SD :
- g_AvgTimePerFrame = 40; // 40 milli-sec (25FPS)
- DV_StatusText(TEXT("VCR Mode - PAL"), 2);
- break;
-
- case ED_TRANSBASIC_SIGNAL_625_50_SDL :
- g_AvgTimePerFrame = 40; // 40 milli-sec (25FPS)
- DV_StatusText(TEXT("VCR Mode - PAL"), 2);
- break;
-
- default :
- DV_LogOut(LOG_PRIORITY_ERROR, LOG_LEVEL_SUCCINCT, TEXT("Unsupported or unrecognized tape format type"));
- g_AvgTimePerFrame = 33; // 33 milli-sec (29.97 FPS); default
- break;
- }
-
- DV_LogOut(LOG_PRIORITY_INFO, LOG_LEVEL_MEDIUM, TEXT("Avg time per frame is %d FPS"), g_AvgTimePerFrame);
- }
- else
- {
- DV_LogOut(LOG_PRIORITY_ERROR, LOG_LEVEL_SUCCINCT, TEXT("GetTransportBasicParameters Failed (0x%x)"), hr);
- }
- }
- }
- else
- {
- DV_LogOut(LOG_PRIORITY_ERROR, LOG_LEVEL_SUCCINCT, TEXT("GetStatus Failed (0x%x)"), hr);
- }
- return hr;
- }
-
- /*-------------------------------------------------------------------------
- Routine: DV_RefreshMode
- Purpose: Use this to rebuild the necessary stuff to switch between VCR and camera mode
- Arguments: None
- Returns: TRUE if successful
- Notes:
- ------------------------------------------------------------------------*/
- BOOL DV_RefreshMode(void)
- {
- BOOL bStatus = FALSE;
- // Query the current device type
- switch(DV_GetDVMode())
- {
- case CameraMode :
- // update the Graph Mode menu items & status window
- EnableMenuItem(GetMenu(g_hwndApp), IDM_FILETODV, MF_GRAYED);
- EnableMenuItem(GetMenu(g_hwndApp), IDM_FILETODV_NOPRE, MF_GRAYED);
- EnableMenuItem(GetMenu(g_hwndApp), IDM_FILETODV_TYPE2, MF_GRAYED);
- EnableMenuItem(GetMenu(g_hwndApp), IDM_FILETODV_NOPRE_TYPE2, MF_GRAYED);
- EnableMenuItem(GetMenu(g_hwndApp), IDM_CHECKTAPE, MF_GRAYED);
- DV_StatusText(TEXT("Camera Mode"), 2);
- bStatus = TRUE;
- break;
-
- case VcrMode :
- // Query the tape info & update the status bar
- DV_GetTapeInfo();
- // update the Graph Mode menu items & status window
- EnableMenuItem(GetMenu(g_hwndApp), IDM_CHECKTAPE, MF_ENABLED);
- EnableMenuItem(GetMenu(g_hwndApp), IDM_FILETODV, MF_ENABLED);
- EnableMenuItem(GetMenu(g_hwndApp), IDM_FILETODV_NOPRE, MF_ENABLED);
- EnableMenuItem(GetMenu(g_hwndApp), IDM_FILETODV_TYPE2, MF_ENABLED);
- EnableMenuItem(GetMenu(g_hwndApp), IDM_FILETODV_NOPRE_TYPE2, MF_ENABLED);
- EnableMenuItem(GetMenu(g_hwndApp), IDM_CHECKTAPE, MF_ENABLED);
- bStatus = TRUE;
- break;
-
- case UnknownMode :
- DV_LogOut(LOG_PRIORITY_ERROR, LOG_LEVEL_SUCCINCT, TEXT("Should not have reached unknown mode handler"));
- break;
-
- default :
- DV_LogOut(LOG_PRIORITY_ERROR, LOG_LEVEL_SUCCINCT, TEXT("Could not determine Camera/Vcr Mode"));
- break;
- }
- return bStatus;
- }
-
- /*-------------------------------------------------------------------------
- Routine: DV_WriteRegKeys
- Purpose: Save the input and output file names to the registry
- Arguments: None
- Returns: None
- Notes:
- ------------------------------------------------------------------------*/
- void DV_WriteRegKeys(void)
- {
- HKEY hKey;
- LONG lResult;
- DWORD dwDisp = 0;
- // Create DVApp's registry keys
- lResult = RegCreateKeyEx(HKEY_CURRENT_USER,
- TEXT("Software\\Microsoft\\DVApp"),
- NULL,
- NULL,
- REG_OPTION_NON_VOLATILE,
- KEY_ALL_ACCESS,
- NULL,
- &hKey,
- &dwDisp);
-
- // Write the input & output filenames
- if (REG_OPENED_EXISTING_KEY == dwDisp || REG_CREATED_NEW_KEY == dwDisp)
- {
- //note that the sizeof parameter expects BYTES (not characters)
- RegSetValueEx(hKey, TEXT("InputFile"), NULL, REG_SZ, (PBYTE)g_InputFileName, (lstrlen(g_InputFileName) * sizeof(TCHAR)) + sizeof(TCHAR));
- RegSetValueEx(hKey, TEXT("OutputFile"), NULL, REG_SZ, (PBYTE)g_OutputFileName, (lstrlen(g_OutputFileName) * sizeof(TCHAR)) + sizeof(TCHAR));
- RegCloseKey(hKey);
- }
- }
-
-
- /*-------------------------------------------------------------------------
- Routine: DV_ReadRegKeys
- Purpose: Save the input and output file names to the registry
- Arguments: None
- Returns: None
- Notes:
- ------------------------------------------------------------------------*/
- void DV_ReadRegKeys(void)
- {
- HKEY hKey;
- LONG lResult;
- DWORD dwType;
- DWORD a = MAX_PATH * sizeof(TCHAR), b = MAX_PATH * sizeof(TCHAR);
- // Read the DVApp's registry keys
- lResult = RegOpenKeyEx(HKEY_CURRENT_USER, TEXT("Software\\Microsoft\\DVApp"), NULL, KEY_ALL_ACCESS, &hKey);
-
- // Load the input & output filenames
- if (ERROR_SUCCESS == lResult)
- {
- RegQueryValueEx(hKey, TEXT("InputFile"), NULL, &dwType, (PBYTE)g_InputFileName, &a);
- RegQueryValueEx(hKey, TEXT("OutputFile"), NULL, &dwType, (PBYTE)g_OutputFileName, &b);
- RegCloseKey(hKey);
- }
-
- }
-
-
- /*-------------------------------------------------------------------------
- Routine: DV_SaveGraph
- Purpose: Save the filter graph into a *.grf file
- Arguments: FileName
- Returns: HRESULT as appropriate
- Notes:
- ------------------------------------------------------------------------*/
- HRESULT DV_SaveGraph(TCHAR* sGraphFile)
- {
- IStorage * pStorage = NULL;
- IStream * pStream = NULL;
- IPersistStream * pPersistStream = NULL;
- HRESULT hr = S_OK;
-
- if(g_pGraphBuilder == NULL || sGraphFile == NULL)
- return E_FAIL;
-
- #ifndef UNICODE
- WCHAR swGraphFile[MAX_PATH];
- MultiByteToWideChar(CP_ACP, 0, sGraphFile, -1, swGraphFile, MAX_PATH);
-
- // Either Open or Create the *.GRF file
- hr = StgOpenStorage( swGraphFile, NULL, STGM_TRANSACTED | STGM_READWRITE | STGM_SHARE_DENY_WRITE, NULL, NULL, &pStorage );
- if ( STG_E_FILENOTFOUND == hr )
- hr = StgCreateDocfile( swGraphFile, STGM_CREATE | STGM_TRANSACTED | STGM_READWRITE | STGM_SHARE_EXCLUSIVE , NULL , &pStorage);
- #else
- // Either Open or Create the *.GRF file
- hr = StgOpenStorage( sGraphFile, NULL, STGM_TRANSACTED | STGM_READWRITE | STGM_SHARE_DENY_WRITE, NULL, NULL, &pStorage );
- if ( STG_E_FILENOTFOUND == hr )
- hr = StgCreateDocfile( sGraphFile, STGM_CREATE | STGM_TRANSACTED | STGM_2READWRITE | STGM_SHARE_EXCLUSIVE , NULL , &pStorage);
-
- #endif
-
- if ( SUCCEEDED(hr) )
- hr = pStorage->CreateStream( L"ActiveMovieGraph", STGM_WRITE | STGM_CREATE | STGM_SHARE_EXCLUSIVE, NULL, NULL, &pStream );
-
- // Persist the stream, save & commit to disk
- if ( SUCCEEDED(hr) )
- hr = g_pGraphBuilder->QueryInterface( IID_IPersistStream, (void **) &pPersistStream );
- if ( SUCCEEDED(hr) )
- hr = pPersistStream->Save(pStream, TRUE);
- if ( SUCCEEDED(hr) )
- hr = pStorage->Commit( STGC_DEFAULT );
-
- if ( SUCCEEDED(hr) )
- DV_LogOut(LOG_PRIORITY_INFO, LOG_LEVEL_MEDIUM, TEXT("Save current Filter Graph to GRF file succeded"));
- else
- {
- MessageBox( NULL, "Save GRF file failed", "DVApp", MB_ICONEXCLAMATION | MB_OK );
- DV_LogOut(LOG_PRIORITY_ERROR, LOG_LEVEL_SUCCINCT, TEXT("Save current Filter Graph to GRF file failed"));
- }
- SAFE_RELEASE(pStorage);
- SAFE_RELEASE(pStream);
- SAFE_RELEASE(pPersistStream);
-
- return hr;
- }
-
- /*-------------------------------------------------------------------------
- Routine: DV_LogOut
- Purpose: Show the Message Window with the Log string
- Arguments: logging priority, logging level & the message
- Returns: None
- Notes: Logs according to the current logging priority & level set
- ------------------------------------------------------------------------*/
- void __cdecl DV_LogOut (LOG_PRIORITY iPriority, LOG_LEVEL ilevel, TCHAR *szFormat, ... )
- {
- static TCHAR msg[1024];
- va_list va;
- va_start(va, szFormat);
- wvsprintf (msg, szFormat, va);
- va_end(va);
-
- if ( ilevel > g_iLogLevel ) // we can skip this message
- return;
- if ( iPriority > g_iLogPriority ) // we can skip this message
- return;
-
- MBOX(msg);
- return;
- }
-
-