home *** CD-ROM | disk | FTP | other *** search
/ Visual Basic Game Programming for Teens / VBGPFT.cdr / DirectX8 / dx8a_sdk.exe / samples / multimedia / directshow / capture / dvapp / dvapp.cpp next >
Encoding:
C/C++ Source or Header  |  2000-10-09  |  204.8 KB  |  4,098 lines

  1. //------------------------------------------------------------------------------
  2. // File: DVApp.cpp
  3. //
  4. // Desc: DirectShow sample code - DV control/capture example.
  5. //
  6. // Copyright (c) 1993 - 2000, Microsoft Corporation.  All rights reserved.
  7. //------------------------------------------------------------------------------
  8.  
  9.  
  10. #include "dvapp.h"
  11.  
  12. /*-------------------------------------------------------------------------
  13. Routine:        WinMain
  14. Purpose:        Program entry point      
  15. Arguments:    Usual
  16. Returns:        Usual
  17. Notes:          Sets up window capabilities, initializes & creates the required DirectShow interface & filters.
  18. ------------------------------------------------------------------------*/
  19. int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
  20.                     PSTR szCmdLine, int iCmdShow)
  21. {
  22.     static TCHAR    szAppName[] = APPNAME ;
  23.     MSG                 msg ;
  24.     WNDCLASSEX wndclass ;
  25.     HMENU           hmenu;
  26.  
  27.     // Set the Window Parameters   
  28.     wndclass.cbSize        = sizeof (wndclass) ;
  29.     wndclass.style         = CS_HREDRAW | CS_VREDRAW ;
  30.     wndclass.lpfnWndProc   = DV_WndProc ;
  31.     wndclass.cbClsExtra    = 0 ;
  32.     wndclass.cbWndExtra    = 0 ;
  33.     wndclass.hInstance     = hInstance ;
  34.     wndclass.hIcon         = LoadIcon (hInstance, TEXT("DVICON")) ;
  35.     wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW) ;
  36.     wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ;
  37.     wndclass.lpszMenuName  = NULL ;
  38.     wndclass.lpszClassName = szAppName ;
  39.     wndclass.hIconSm       = LoadIcon(hInstance, TEXT("DVICON"));
  40.     // create & setup the window
  41.     RegisterClassEx (&wndclass) ;
  42.     hmenu = LoadMenu(hInstance, MAKEINTRESOURCE(IDR_MENU1));
  43.     g_hwndApp = CreateWindow  (szAppName,            // window class name
  44.                             DV_APPTITLE,             // window caption
  45.                             WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX | WS_MAXIMIZEBOX,     // window style
  46.                             CW_USEDEFAULT,           // initial x position
  47.                             CW_USEDEFAULT,           // initial y position
  48.                             g_iAppWidth,             // initial x size
  49.                             g_iAppHeight,            // initial y size
  50.                             NULL,                    // parent window handle
  51.                             hmenu,                   // window menu handle
  52.                             hInstance,               // program instance handle
  53.                             NULL) ;                   // creation parameters
  54.     
  55.     ShowWindow (g_hwndApp, iCmdShow) ;
  56.     UpdateWindow (g_hwndApp) ;
  57.  
  58.     // Initialize UI & Logging levels
  59.     SetWindowText(g_hwndApp, TEXT("Initializing..."));
  60.     CheckMenuItem(hmenu, IDM_LEVEL_SUCCINCT, MF_CHECKED);
  61.     CheckMenuItem(hmenu, IDM_PRIORITY_ERROR, MF_CHECKED);
  62.  
  63.     // Register for device add/remove notifications.
  64.     DEV_BROADCAST_DEVICEINTERFACE filterData;
  65.     ZeroMemory(&filterData, sizeof(DEV_BROADCAST_DEVICEINTERFACE));
  66.     
  67.     filterData.dbcc_size = sizeof(DEV_BROADCAST_DEVICEINTERFACE);
  68.     filterData.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
  69.     filterData.dbcc_classguid = AM_KSCATEGORY_CAPTURE;
  70.  
  71.     g_pUnregisterDeviceNotification = NULL;
  72.     g_pRegisterDeviceNotification = NULL;
  73.     // dynload device removal APIs
  74.     {
  75.         HMODULE hmodUser = GetModuleHandle(TEXT("user32.dll"));
  76.         ASSERT(hmodUser);       // we link to user32
  77.         g_pUnregisterDeviceNotification = (PUnregisterDeviceNotification)
  78.             GetProcAddress(hmodUser, "UnregisterDeviceNotification");
  79.  
  80.         // m_pRegisterDeviceNotification is prototyped differently in unicode
  81.         g_pRegisterDeviceNotification = (PRegisterDeviceNotification)
  82.             GetProcAddress(hmodUser,
  83. #ifdef UNICODE
  84.                            "RegisterDeviceNotificationW"
  85. #else
  86.                            "RegisterDeviceNotificationA"
  87. #endif
  88.                            );
  89.         // failures expected on older platforms.
  90.         ASSERT(g_pRegisterDeviceNotification && g_pUnregisterDeviceNotification ||
  91.                !g_pRegisterDeviceNotification && !g_pUnregisterDeviceNotification);
  92.     }
  93.  
  94.     g_hDevNotify = NULL;
  95.  
  96.     if (g_pRegisterDeviceNotification)
  97.     {
  98.         g_hDevNotify = g_pRegisterDeviceNotification(g_hwndApp, &filterData, DEVICE_NOTIFY_WINDOW_HANDLE);
  99.         ASSERT(g_hDevNotify != NULL);
  100.     }
  101.  
  102.     // Setup & Initialize the device & filtergraph
  103.     DV_AppSetup();
  104.  
  105.     // Message processing loop
  106.     while (GetMessage (&msg, NULL, 0, 0))
  107.     {
  108.         TranslateMessage (&msg) ;
  109.         DispatchMessage (&msg) ;
  110.     }
  111.     return (int) msg.wParam;
  112. }
  113.  
  114.  
  115. /*-------------------------------------------------------------------------
  116. Routine:        DV_TransportCommand_WndProc 
  117. Purpose:        Message Handler to control transport state of the device & the filtergraph state
  118. Arguments:    Usual message processing parameters
  119. Returns:        Usual
  120. Notes:          Handles for the Toolbar button controls
  121. ------------------------------------------------------------------------*/
  122. void CALLBACK DV_TransportCommand_WndProc (HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
  123. {
  124.     HMENU       hmenu;   
  125.     switch (iMsg)
  126.     {
  127.     case WM_COMMAND :
  128.         hmenu = GetMenu(hwnd);
  129.         switch (LOWORD (wParam))
  130.         {
  131.     /*
  132.         The VCR Tool bar commands need to behave differently depending on the 
  133.         current graph.  
  134.  
  135.         In Preview (default) mode, the VCR commands should simply
  136.         control the VCR functions on the vcr device.
  137.  
  138.         In DV To File mode, or File To DV mode the commands should start and stop the graph, 
  139.         as  well as control the vcr mode (although we will disable some buttons to avoid confusion)
  140.     */
  141.         case IDM_PLAY :
  142.         {
  143.             //check if the current graph is a transmit graph
  144.             if (GRAPH_FILE_TO_DV == g_iCurrentGraph || GRAPH_FILE_TO_DV_NOPRE == g_iCurrentGraph || 
  145.                 GRAPH_FILE_TO_DV_TYPE2 == g_iCurrentGraph || GRAPH_FILE_TO_DV_NOPRE_TYPE2 == g_iCurrentGraph)
  146.             {
  147.                 // update the toolbar accordingly
  148.                 SendMessage(g_hwndTBar, TB_SETSTATE, IDM_PLAY, MAKELONG(TBSTATE_INDETERMINATE, 0L));
  149.                 //update the status bar with the dropped frames information
  150.                 g_CapStartTime = GetTickCount();
  151.                 SetTimer(hwnd, DV_TIMER_FRAMES,  DV_TIMERFREQ, (TIMERPROC) DV_DroppedFrameProc);
  152.                 // run the filter graph & wait for dshow events
  153.                 DV_StartGraph();
  154.                 IMediaEventEx *pMe = NULL;
  155.                 if (SUCCEEDED(g_pGraphBuilder->QueryInterface(IID_IMediaEventEx, reinterpret_cast<PVOID *>(&pMe))))
  156.                 {
  157.                     pMe->SetNotifyWindow((LONG_PTR) g_hwndApp, WM_FGNOTIFY, 0);
  158.                     SAFE_RELEASE(pMe);
  159.                 } 
  160.             } 
  161.             else
  162.             {
  163.                 // play the tape for the capture or preview graph
  164.                 DV_PutVcrMode(ED_MODE_PLAY);
  165.  
  166.                 // run the filter graph too if it is preview
  167.                 if(GRAPH_PREVIEW == g_iCurrentGraph)
  168.                     DV_StartGraph();
  169.                 //do we want to display timecodes?
  170.                 if (IsDlgButtonChecked(g_hwndTBar, IDC_TCCHECKBOX))
  171.                 {
  172.                     SetTimer(hwnd, DV_TIMER_ATN,  DV_TIMERFREQ, (TIMERPROC) DV_TimecodeTimerProc);
  173.                     g_bUseAtnTimer = TRUE;
  174.                 } 
  175.             } 
  176.             break;
  177.         }
  178.  
  179.         /*
  180.             The record button starts the *entire* graph, so preview (if selected), won't
  181.             start until the recording starts.  
  182.         */
  183.         case IDM_RECORD :
  184.             // update the toolbar accordingly
  185.             SendMessage(g_hwndTBar, TB_SETSTATE, IDM_STEP_FWD, MAKELONG(TBSTATE_INDETERMINATE, 0L));
  186.             SendMessage(g_hwndTBar, TB_SETSTATE, IDM_STEP_REV, MAKELONG(TBSTATE_INDETERMINATE, 0L));
  187.  
  188.             // check to see if it is a capture graph
  189.             if (GRAPH_DV_TO_FILE == g_iCurrentGraph || GRAPH_DV_TO_FILE_NOPRE == g_iCurrentGraph ||
  190.                 GRAPH_DV_TO_FILE_TYPE2 == g_iCurrentGraph || GRAPH_DV_TO_FILE_NOPRE_TYPE2 == g_iCurrentGraph)
  191.             {
  192.                 //do something here to record to an avi file on the disk - or to start recording on the vcr.
  193.                 switch (g_dwCaptureLimit)
  194.                 {
  195.                     case DV_CAPLIMIT_NONE :
  196.                         break;
  197.                     case DV_CAPLIMIT_TIME :
  198.                         SetTimer(hwnd, DV_TIMER_CAPLIMIT, g_dwTimeLimit * 1000, (TIMERPROC) DV_StopRecProc);
  199.                         break;
  200.                     case DV_CAPLIMIT_SIZE :
  201.                         //rather than monitor disk usage, we'll just do the math and set a timer
  202.                         SetTimer(hwnd, DV_TIMER_CAPLIMIT, ((g_dwDiskSpace * 100000) / DV_BYTESPERMSEC), (TIMERPROC) DV_StopRecProc);
  203.                         break;
  204.                     default :
  205.                         DV_LogOut(LOG_PRIORITY_ERROR, LOG_LEVEL_SUCCINCT, TEXT("Bad value for g_dwCaptureLimit (%d)"), g_dwCaptureLimit);
  206.                         break;
  207.                 }
  208.                 //update the status bar with the dropped frames information
  209.                 g_CapStartTime = GetTickCount();
  210.                 SetTimer(hwnd, DV_TIMER_FRAMES,  DV_TIMERFREQ, (TIMERPROC) DV_DroppedFrameProc);
  211.                 //run the graph - assume that the camera is already playing if in Vcr mode
  212.                 DV_StartGraph();             
  213.             } 
  214.             else if (GRAPH_FILE_TO_DV == g_iCurrentGraph || GRAPH_FILE_TO_DV_NOPRE == g_iCurrentGraph ||
  215.                      GRAPH_FILE_TO_DV_TYPE2 == g_iCurrentGraph || GRAPH_FILE_TO_DV_NOPRE_TYPE2 == g_iCurrentGraph)
  216.             {
  217.                 // if transmit graph then record on tape of the device
  218.                 DV_PutVcrMode(ED_MODE_RECORD);
  219.             } 
  220.             else
  221.             {
  222.                 //we shouldn't get here
  223.                 DV_LogOut(LOG_PRIORITY_ERROR, LOG_LEVEL_SUCCINCT, TEXT("Undefined graph mode (maybe GRAPH_PREVIEW) in IDM_RECORD message"));
  224.             } 
  225.             break;
  226.  
  227.         case IDM_STOP :
  228.             if (GRAPH_PREVIEW != g_iCurrentGraph)
  229.             {   // for transmit & capture graphs we need stats if any
  230.                 DV_GetFinalDroppedFramesStats(GetTickCount());
  231.             } 
  232.     
  233.             // handle the timers accordingly
  234.             if (g_bUseAtnTimer)
  235.                 KillTimer(hwnd, DV_TIMER_ATN);
  236.             //if we're here, these timers were set
  237.             KillTimer(hwnd, DV_TIMER_CAPLIMIT);
  238.             KillTimer(hwnd, DV_TIMER_FRAMES);
  239.  
  240.             if (GRAPH_PREVIEW != g_iCurrentGraph)
  241.             {   // for transmit & capture graphs we need stop the graph, preview graph is running all the time
  242.                 DV_StopGraph();
  243.             } 
  244.             // Stop the transport on the device
  245.             DV_PutVcrMode(ED_MODE_STOP);
  246.             // update the toolbar 
  247.             SendMessage(g_hwndTBar, TB_SETSTATE, IDM_PLAY, MAKELONG(TBSTATE_ENABLED, 0L));
  248.             SendMessage(g_hwndTBar, TB_SETSTATE, IDM_STEP_FWD, MAKELONG(TBSTATE_INDETERMINATE, 0L));
  249.             SendMessage(g_hwndTBar, TB_SETSTATE, IDM_STEP_REV, MAKELONG(TBSTATE_INDETERMINATE, 0L));
  250.             break;
  251.  
  252.         case IDM_PAUSE :
  253.             if (GRAPH_FILE_TO_DV == g_iCurrentGraph || GRAPH_FILE_TO_DV_NOPRE == g_iCurrentGraph ||
  254.                 GRAPH_FILE_TO_DV_TYPE2 == g_iCurrentGraph || GRAPH_FILE_TO_DV_NOPRE_TYPE2 == g_iCurrentGraph)
  255.             {   // transmit graph
  256.                 DV_PauseGraph();
  257.             } 
  258.             else
  259.             {   // capture or preview graph
  260.                 DV_PutVcrMode(ED_MODE_FREEZE);
  261.                 SendMessage(g_hwndTBar, TB_SETSTATE, IDM_STEP_FWD, MAKELONG(TBSTATE_ENABLED, 0L));
  262.                 SendMessage(g_hwndTBar, TB_SETSTATE, IDM_STEP_REV, MAKELONG(TBSTATE_ENABLED, 0L));
  263.             } 
  264.             SendMessage(g_hwndTBar, TB_SETSTATE, IDM_PLAY, MAKELONG(TBSTATE_ENABLED, 0L));
  265.             break;    
  266.  
  267.         case IDM_FF :
  268.             // all graphs just forward the tape & update the toolbar
  269.             DV_PutVcrMode(ED_MODE_FF);
  270.             SendMessage(g_hwndTBar, TB_SETSTATE, IDM_STEP_FWD, MAKELONG(TBSTATE_INDETERMINATE, 0L));
  271.             SendMessage(g_hwndTBar, TB_SETSTATE, IDM_STEP_REV, MAKELONG(TBSTATE_INDETERMINATE, 0L));
  272.             break;
  273.  
  274.         case IDM_REW :
  275.             // all graphs just rewind the tape & update the toolbar
  276.             DV_PutVcrMode(ED_MODE_REW);
  277.             SendMessage(g_hwndTBar, TB_SETSTATE, IDM_STEP_FWD, MAKELONG(TBSTATE_INDETERMINATE, 0L));
  278.             SendMessage(g_hwndTBar, TB_SETSTATE, IDM_STEP_REV, MAKELONG(TBSTATE_INDETERMINATE, 0L));
  279.             break;
  280.  
  281.         case IDM_PLAY_FAST_FF :
  282.             // all graphs just forward the tape & update the toolbar
  283.             DV_PutVcrMode(ED_MODE_PLAY_FASTEST_FWD);
  284.             SendMessage(g_hwndTBar, TB_SETSTATE, IDM_STEP_FWD, MAKELONG(TBSTATE_INDETERMINATE, 0L));
  285.             SendMessage(g_hwndTBar, TB_SETSTATE, IDM_STEP_REV, MAKELONG(TBSTATE_INDETERMINATE, 0L));
  286.             break;
  287.  
  288.         case IDM_PLAY_FAST_REV :
  289.             // all graphs just rewind the tape & update the toolbar
  290.             DV_PutVcrMode(ED_MODE_PLAY_FASTEST_REV);
  291.             SendMessage(g_hwndTBar, TB_SETSTATE, IDM_STEP_FWD, MAKELONG(TBSTATE_INDETERMINATE, 0L));
  292.             SendMessage(g_hwndTBar, TB_SETSTATE, IDM_STEP_REV, MAKELONG(TBSTATE_INDETERMINATE, 0L));
  293.             break;            
  294.  
  295.         case IDM_STEP_FWD :
  296.             // all graphs just forward the tape & update the toolbar
  297.             DV_PutVcrMode(ED_MODE_STEP_FWD);
  298.             g_bUseAtnTimer = FALSE;
  299.             DV_DisplayTimecode();
  300.             break;
  301.  
  302.         case IDM_STEP_REV :
  303.             // all graphs just rewind the tape & update the toolbar
  304.             DV_PutVcrMode(ED_MODE_STEP_REV);
  305.             g_bUseAtnTimer = FALSE;
  306.             DV_DisplayTimecode();
  307.             break;
  308.  
  309.         case IDM_SEEKTIMECODE :
  310.             // ATN Seek & display on the toolbar
  311.              DV_SeekATN();
  312.              DV_DisplayTimecode();
  313.              break;
  314.  
  315.         } // switch (LOWORD(wParam))
  316.     } // switch (iMsg)
  317. }
  318.  
  319.  
  320.  
  321.  
  322. /*-------------------------------------------------------------------------
  323. Routine:        DV_WndProc
  324. Purpose:        Message Handler
  325. Arguments:    Usual
  326. Returns:        Usual
  327. Notes:          Handles Windows UI & Command Messages, Menu Messages et al
  328. ------------------------------------------------------------------------*/
  329. LRESULT CALLBACK DV_WndProc (HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
  330. {
  331.     HDC         hdc ;
  332.     PAINTSTRUCT ps ;
  333.     RECT        rect;
  334.     HMENU       hmenu;
  335.     static HWND hWndTT;
  336.     
  337.     switch (iMsg)
  338.     {
  339.     case WM_CREATE :
  340.         // Initializes & loads the Controls like toolbar buttons etc
  341.         if (!DV_InitControls(hwnd, (HINSTANCE)GetWindowLongPtr(hwnd, GWLP_HINSTANCE)))
  342.         {
  343.             DV_LogOut(LOG_PRIORITY_ERROR, LOG_LEVEL_SUCCINCT, TEXT("DV_InitControls failed to create one of the control windows"));
  344.         }
  345.         break;
  346.  
  347.     case WM_PAINT :
  348.         hdc = BeginPaint (hwnd, &ps) ;
  349.         GetClientRect (hwnd, &rect) ;
  350.         EndPaint (hwnd, &ps) ;
  351.         // not calling default message handler
  352.         return 0;
  353.  
  354.     case WM_SIZE:
  355.     {
  356.         RECT  rcAppWin, rcClient, rcTB;
  357.         //re-size the App window
  358.         int cxBorder = GetSystemMetrics(SM_CXBORDER);
  359.         int cyBorder = GetSystemMetrics(SM_CYBORDER);
  360.         GetWindowRect(g_hwndApp, &rcAppWin);
  361.         GetWindowRect(g_hwndTBar, &rcTB);
  362.         MoveWindow(g_hwndApp, rcAppWin.left, rcAppWin.top, g_iAppWidth, g_iAppHeight, TRUE);
  363.  
  364.         // Tell the toolbar to resize itself to fill the top of the window.
  365.         SendMessage(g_hwndTBar, TB_AUTOSIZE, 0L, 0L);
  366.  
  367.         //handle the status bar height
  368.         GetClientRect(g_hwndApp, &rcClient);
  369.         cxBorder = GetSystemMetrics(SM_CXBORDER);
  370.         cyBorder = GetSystemMetrics(SM_CYBORDER);
  371.         MoveWindow(g_hwndStatus, -cxBorder, rcClient.bottom - (g_statusHeight + cyBorder), 
  372.                    rcClient.right + (2 * cxBorder), (g_statusHeight + (2 * cyBorder)), TRUE);  
  373.         DV_StatusParts(rcClient.right);
  374.         
  375.         //re-size the video window
  376.         GetWindowRect(g_hwndTBar, &rcTB);
  377.         if (g_pVideoWindow)
  378.         {
  379.             g_pVideoWindow->SetWindowPosition(0, rcTB.bottom - rcTB.top, g_iVWWidth, g_iVWHeight);
  380.         }
  381.         break;
  382.     }
  383.  
  384.     case WM_CLOSE:
  385.         return SendMessage(hwnd, WM_DESTROY, 0,0);
  386.  
  387.     case WM_DESTROY :
  388.         // Unregister device notifications
  389.         if (g_hDevNotify != NULL)
  390.         {
  391.             ASSERT(g_pUnregisterDeviceNotification);
  392.             g_pUnregisterDeviceNotification(g_hDevNotify);
  393.             g_hDevNotify = NULL;
  394.         }
  395.         // Time to Kill All
  396.         DV_CleanUp();
  397.         hmenu = GetMenu(hwnd);
  398.         DestroyMenu(hmenu);
  399.         DestroyWindow(g_hwndTBar);
  400.         DestroyWindow(g_hwndStatus);
  401.         PostQuitMessage (0) ;
  402.         // not calling default message handler
  403.         return 0;     
  404.  
  405.     case WM_NOTIFY :
  406.     {   
  407.         //Windows Events Notify Message handler
  408.         switch (((LPNMHDR)lParam)->code)
  409.         {
  410.             case TTN_NEEDTEXT :
  411.                 LPTOOLTIPTEXT lpttt;
  412.                 TCHAR         ttBuff[128];
  413.                 lpttt = (LPTOOLTIPTEXT) lParam; 
  414.                 LoadString ((HINSTANCE)GetWindowLongPtr(hwnd, GWLP_HINSTANCE), (UINT) lpttt->hdr.idFrom, ttBuff, 128);
  415.                 lpttt->lpszText = ttBuff;           
  416.                 break;
  417.         } 
  418.         break;   
  419.     } 
  420.  
  421.     case WM_DEVICECHANGE:
  422.     {
  423.         // We are interested in only device arrival events
  424.         if (DBT_DEVICEARRIVAL != wParam)
  425.             break;
  426.         PDEV_BROADCAST_HDR pdbh = (PDEV_BROADCAST_HDR) lParam;
  427.         if (pdbh->dbch_devicetype != DBT_DEVTYP_DEVICEINTERFACE)
  428.             break;
  429.  
  430.         // Check for capture devices.
  431.         PDEV_BROADCAST_DEVICEINTERFACE pdbi = (PDEV_BROADCAST_DEVICEINTERFACE) lParam;
  432.         if (pdbi->dbcc_classguid != AM_KSCATEGORY_CAPTURE)
  433.             break;
  434.  
  435.         // Check for device arrival.
  436.         if (g_bDeviceFound == FALSE)
  437.         {
  438.             MessageBox(g_hwndApp, TEXT("There is a new capture device on this system..."), APPNAME, MB_OK);
  439.             DV_CleanUp();
  440.             DV_AppSetup();
  441.         }
  442.         break;
  443.     }
  444.     
  445.     case WM_FGNOTIFY :
  446.     {
  447.         //Filter Graph Events Notify Message handler
  448.         IMediaEventEx *pMe = NULL;
  449.         if(g_pGraphBuilder == NULL)
  450.             break;
  451.         else if (SUCCEEDED(g_pGraphBuilder->QueryInterface(IID_IMediaEventEx, reinterpret_cast<PVOID *>(&pMe))))
  452.         {
  453.             long event;
  454.             LONG_PTR l1, l2;
  455.             // Get the corresponding filtergraph directshow media event to handle
  456.             while (SUCCEEDED(pMe->GetEvent(&event, &l1, &l2, 0L)))
  457.             {
  458.                 switch (event)
  459.                 {
  460.                     case EC_USERABORT :
  461.                     case EC_COMPLETE :
  462.                         // filtergraph is done, time to stop the filtergraph or transport state
  463.                         SendMessage(g_hwndApp, WM_COMMAND, IDM_STOP, 0);  
  464.                         break;
  465.                     
  466.                     case EC_ERRORABORT :
  467.                         //something bad happened during capture
  468.                         MBOX(TEXT("Error during preview, capture or transmit"));
  469.                         break;
  470.                     case EC_DEVICE_LOST :
  471.                         // Check if we have lost a capture filter being used.
  472.                         // lParam2 of EC_DEVICE_LOST event == 0 indicates device removed
  473.                         // lParam2 of EC_DEVICE_LOST event == 1 indicates removed device added again
  474.                         if (l2 == 0)
  475.                         {
  476.                             IBaseFilter *pf;
  477.                             IUnknown *punk = (IUnknown *) l1;
  478.                             if (S_OK == punk->QueryInterface(IID_IBaseFilter, (void **) &pf))
  479.                             {
  480.                                 if (::IsEqualObject(g_pDVCamera, pf))
  481.                                 {
  482.                                     pMe->FreeEventParams(event, l1, l2);
  483.  
  484.                                     // handle the timers accordingly
  485.                                     if (g_bUseAtnTimer)
  486.                                         KillTimer(hwnd, DV_TIMER_ATN);
  487.                                     KillTimer(hwnd, DV_TIMER_CAPLIMIT);
  488.                                     KillTimer(hwnd, DV_TIMER_FRAMES);
  489.                                     // Cleanup the old device's filtergraph & 
  490.                                     // Search for other DV camcorders or the same DV camcorder being plugged in again, 
  491.                                     // if found set it up else exit the app
  492.                                     MBOX("DV Camcorder Device in use was removed");
  493.                                     g_bDeviceFound = FALSE;
  494.                                     DV_CleanUp();
  495.                                     DV_AppSetup();
  496.                                 }
  497.                                 pf->Release();
  498.                             }
  499.                         }
  500.                         break;
  501.  
  502.                     default :
  503.                         DV_LogOut(LOG_PRIORITY_INFO, LOG_LEVEL_VERBOSE, TEXT("Unhandled Event Code (0x%x)"), event);
  504.                         break;
  505.                 }
  506.                 pMe->FreeEventParams(event, l1, l2);
  507.             } 
  508.             SAFE_RELEASE(pMe);
  509.         } 
  510.         SAFE_RELEASE(pMe);       
  511.         break;
  512.     }
  513.  
  514.     
  515.     case WM_COMMAND :
  516.         // Handle menu commands
  517.         hmenu = GetMenu(hwnd);
  518.         switch (LOWORD (wParam))
  519.         {
  520.             // Help Menu
  521.         case IDM_ABOUT:
  522.             DialogBox((HINSTANCE)GetWindowLongPtr(hwnd, GWLP_HINSTANCE), MAKEINTRESOURCE(IDD_ABOUT), hwnd, (DLGPROC)DV_AboutDlgProc);
  523.             break;
  524.  
  525.         // The File Menu 
  526.         /*  
  527.             The globals for input file and output file are TCHAR.  When compiled ANSI,
  528.             GetOpenFileName (obviously) return ANSI buffers.  DShow functions use Unicode
  529.             names exclusively, so these are converted to Unicode within the functions 
  530.             that need to use these variables (DV_Make...To... functions).
  531.         */
  532.         case IDM_SETINPUT :    //fall through
  533.         case IDM_SETOUTPUT :
  534.         case IDM_OPTIONS_SAVEGRAPH :
  535.         {
  536.             OPENFILENAME ofn = {0};
  537.             OSVERSIONINFO osi = {0};
  538.             //need to adjust the ofn struct size if we are running on win98 vs. nt5
  539.             osi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
  540.             GetVersionEx(&osi);
  541.             if (osi.dwMajorVersion >=5 && osi.dwPlatformId == VER_PLATFORM_WIN32_NT)
  542.             {
  543.                 ofn.lStructSize = sizeof (OPENFILENAME);
  544.             } 
  545.             else
  546.             {
  547.                 ofn.lStructSize = sizeof(OPENFILENAME);
  548.             }   
  549.             
  550.             ofn.hwndOwner = g_hwndApp;
  551.             ofn.nMaxFile = _MAX_PATH;
  552.             if (IDM_OPTIONS_SAVEGRAPH == LOWORD (wParam))
  553.             {
  554.                 ofn.lpstrFilter = TEXT("Filter Graph\0*.grf\0\0");
  555.                 ofn.lpstrTitle = TEXT("Set FilterGraph File Name");
  556.                 ofn.lpstrFile = g_FilterGraphFileName;
  557.             } 
  558.             else if (IDM_SETOUTPUT == LOWORD (wParam))
  559.             {
  560.                 ofn.lpstrFilter = TEXT("Microsoft AVI\0*.avi\0\0");
  561.                 ofn.lpstrTitle = TEXT("Set output File Name");
  562.                 ofn.lpstrFile = g_OutputFileName;
  563.             } 
  564.             else
  565.             {
  566.                 ofn.lpstrFilter = TEXT("Microsoft AVI\0*.avi\0\0");
  567.                 ofn.lpstrTitle = TEXT("Set input File Name");
  568.                 ofn.lpstrFile = g_InputFileName;
  569.             } 
  570.  
  571.             if (GetOpenFileName(&ofn))
  572.             {
  573.                 if (IDM_OPTIONS_SAVEGRAPH == LOWORD (wParam))
  574.                 {
  575.                     lstrcpy(g_FilterGraphFileName, ofn.lpstrFile);
  576.                     // Save the current built filter graph to a *.grf file
  577.                     DV_SaveGraph(g_FilterGraphFileName);
  578.                 } 
  579.                 else if (IDM_SETOUTPUT == LOWORD (wParam))
  580.                 {
  581.                     lstrcpy(g_OutputFileName, ofn.lpstrFile);
  582.                 } 
  583.                 else
  584.                 {
  585.                     lstrcpy(g_InputFileName, ofn.lpstrFile);
  586.                 } 
  587.             }
  588.             break;    
  589.         } 
  590.  
  591.         case IDM_CAPSIZE:
  592.             DialogBox((HINSTANCE)GetWindowLongPtr(hwnd, GWLP_HINSTANCE), MAKEINTRESOURCE(IDD_DIALOG_CAPSIZE), hwnd, (DLGPROC)DV_CapSizeDlgProc);
  593.             break;
  594.  
  595.         case IDM_EXIT :
  596.             return SendMessage(hwnd, WM_DESTROY, 0,0);
  597.  
  598.         // Graph Mode Menu
  599.         //Change the Current Graph Mode
  600.         case IDM_PREVIEW :
  601.         case IDM_FILETODV :
  602.         case IDM_FILETODV_NOPRE :
  603.         case IDM_DVTOFILE :
  604.         case IDM_DVTOFILE_NOPRE :
  605.         case IDM_FILETODV_TYPE2 :
  606.         case IDM_FILETODV_NOPRE_TYPE2 :
  607.         case IDM_DVTOFILE_TYPE2 :
  608.         case IDM_DVTOFILE_NOPRE_TYPE2 :
  609.             DV_GraphModeCommand_WndProc (hwnd, iMsg, wParam, lParam);
  610.             break;
  611.  
  612.         // Toolbar Button Commands
  613.         // Transport State & Graph State Control
  614.         case IDM_PLAY :
  615.         case IDM_RECORD :
  616.         case IDM_STOP :
  617.         case IDM_PAUSE :
  618.         case IDM_FF :
  619.         case IDM_REW :
  620.         case IDM_PLAY_FAST_FF :
  621.         case IDM_PLAY_FAST_REV :
  622.         case IDM_STEP_FWD :
  623.         case IDM_STEP_REV :
  624.         case IDM_SEEKTIMECODE :
  625.             DV_TransportCommand_WndProc(hwnd, iMsg, wParam, lParam);
  626.             break;
  627.  
  628.         // The Options Menu
  629.         case IDM_DECODESIZE :
  630.             DialogBox((HINSTANCE)GetWindowLongPtr(hwnd, GWLP_HINSTANCE), MAKEINTRESOURCE(IDD_DIALOG_DECODESIZE), hwnd, (DLGPROC)DV_ChangeDecodeSizeProc);
  631.             break;
  632.             
  633.         case IDM_CHECKTAPE :
  634.             if (S_OK != DV_GetTapeInfo())
  635.             {
  636.                 MBOX(TEXT("Tape is not inserted, or has an improper format.\nReinsert the tape and select Options - Check Tape again"));
  637.             } 
  638.             break;
  639.  
  640.         case IDM_REFRESHMODE :
  641.             DV_RefreshMode();
  642.             break;
  643.                 
  644.         // Log Menu :: Set logging Priority & level 
  645.         case IDM_LEVEL_SUCCINCT :
  646.              CheckMenuItem(hmenu, IDM_LEVEL_SUCCINCT, MF_CHECKED);
  647.              CheckMenuItem(hmenu, IDM_LEVEL_MEDIUM, MF_UNCHECKED);
  648.              CheckMenuItem(hmenu, IDM_LEVEL_VERBOSE, MF_UNCHECKED);
  649.              g_iLogLevel = LOG_LEVEL_SUCCINCT;
  650.              break;
  651.         case IDM_LEVEL_MEDIUM :
  652.              CheckMenuItem(hmenu, IDM_LEVEL_SUCCINCT, MF_UNCHECKED);
  653.              CheckMenuItem(hmenu, IDM_LEVEL_MEDIUM, MF_CHECKED);
  654.              CheckMenuItem(hmenu, IDM_LEVEL_VERBOSE, MF_UNCHECKED);
  655.              g_iLogLevel = LOG_LEVEL_MEDIUM;
  656.              break;
  657.         case IDM_LEVEL_VERBOSE :
  658.              CheckMenuItem(hmenu, IDM_LEVEL_SUCCINCT, MF_UNCHECKED);
  659.              CheckMenuItem(hmenu, IDM_LEVEL_MEDIUM, MF_UNCHECKED);
  660.              CheckMenuItem(hmenu, IDM_LEVEL_VERBOSE, MF_CHECKED);
  661.              g_iLogLevel = LOG_LEVEL_VERBOSE;
  662.              break;
  663.  
  664.         case IDM_PRIORITY_ERROR :
  665.              CheckMenuItem(hmenu, IDM_PRIORITY_ERROR, MF_CHECKED);
  666.              CheckMenuItem(hmenu, IDM_PRIORITY_WARN, MF_UNCHECKED);
  667.              CheckMenuItem(hmenu, IDM_PRIORITY_INFO, MF_UNCHECKED);
  668.              g_iLogPriority = LOG_PRIORITY_ERROR;
  669.              break;
  670.         case IDM_PRIORITY_WARN :
  671.              CheckMenuItem(hmenu, IDM_PRIORITY_ERROR, MF_UNCHECKED);
  672.              CheckMenuItem(hmenu, IDM_PRIORITY_WARN, MF_CHECKED);
  673.              CheckMenuItem(hmenu, IDM_PRIORITY_INFO, MF_UNCHECKED);
  674.              g_iLogPriority = LOG_PRIORITY_WARN;
  675.              break;
  676.         case IDM_PRIORITY_INFO :
  677.              CheckMenuItem(hmenu, IDM_PRIORITY_ERROR, MF_UNCHECKED);
  678.              CheckMenuItem(hmenu, IDM_PRIORITY_WARN, MF_UNCHECKED);
  679.              CheckMenuItem(hmenu, IDM_PRIORITY_INFO, MF_CHECKED);
  680.              g_iLogPriority = LOG_PRIORITY_INFO;
  681.              break;
  682.  
  683.         } // switch (LOWORD(wParam))
  684.         
  685.                
  686.     } // switch (iMsg)
  687.     return DefWindowProc (hwnd, iMsg, wParam, lParam) ;
  688. }
  689.  
  690.  
  691. /*-------------------------------------------------------------------------
  692. Routine:        DV_GraphModeCommand_WndProc
  693. Purpose:        Message Handler for Graph Mode menu items
  694. Arguments:    Usual message processing parameters
  695. Returns:        Usual
  696. Notes:          Builds the various kinds of Graph types preview/capture/transmit
  697. ------------------------------------------------------------------------*/
  698. void CALLBACK DV_GraphModeCommand_WndProc (HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
  699. {
  700.     HMENU       hmenu;    
  701.     switch (iMsg)
  702.     {
  703.     case WM_COMMAND :
  704.         hmenu = GetMenu(hwnd);
  705.         switch (LOWORD (wParam))
  706.         {   
  707.         case IDM_PREVIEW :
  708.             // Call the Special DV Graph Builder Method 
  709.             if (DV_MakeSpecialGraph(GRAPH_PREVIEW))
  710.             {
  711.                 // update globals, log, toolbar, menu items
  712.                 g_iCurrentGraph = GRAPH_PREVIEW;
  713.                 DV_LogOut(LOG_PRIORITY_INFO, LOG_LEVEL_SUCCINCT, TEXT("Built Preview Graph"));
  714.  
  715.                 SendMessage(g_hwndTBar, TB_SETSTATE, IDM_RECORD, MAKELONG(TBSTATE_INDETERMINATE, 0L));
  716.                 //re-enable everything else
  717.                 SendMessage(g_hwndTBar, TB_SETSTATE, IDM_STEP_REV, MAKELONG(TBSTATE_ENABLED, 0L));
  718.                 SendMessage(g_hwndTBar, TB_SETSTATE, IDM_REW, MAKELONG(TBSTATE_ENABLED, 0L));
  719.                 SendMessage(g_hwndTBar, TB_SETSTATE, IDM_PLAY_FAST_REV, MAKELONG(TBSTATE_ENABLED, 0L));
  720.                 SendMessage(g_hwndTBar, TB_SETSTATE, IDM_PLAY_FAST_FF, MAKELONG(TBSTATE_ENABLED, 0L));
  721.                 SendMessage(g_hwndTBar, TB_SETSTATE, IDM_FF, MAKELONG(TBSTATE_ENABLED, 0L));
  722.                 SendMessage(g_hwndTBar, TB_SETSTATE, IDM_STEP_FWD, MAKELONG(TBSTATE_ENABLED, 0L));
  723.                 SendMessage(g_hwndTBar, TB_SETSTATE, IDM_SEEKTIMECODE, MAKELONG(TBSTATE_ENABLED, 0L));
  724.                 
  725.                 CheckMenuItem(hmenu, IDM_PREVIEW, MF_CHECKED);
  726.                 CheckMenuItem(hmenu, IDM_FILETODV, MF_UNCHECKED);
  727.                 CheckMenuItem(hmenu, IDM_FILETODV_NOPRE, MF_UNCHECKED);
  728.                 CheckMenuItem(hmenu, IDM_DVTOFILE, MF_UNCHECKED);
  729.                 CheckMenuItem(hmenu, IDM_DVTOFILE_NOPRE, MF_UNCHECKED);
  730.  
  731.                 CheckMenuItem(hmenu, IDM_FILETODV_TYPE2, MF_UNCHECKED);
  732.                 CheckMenuItem(hmenu, IDM_FILETODV_NOPRE_TYPE2, MF_UNCHECKED);
  733.                 CheckMenuItem(hmenu, IDM_DVTOFILE_TYPE2, MF_UNCHECKED);
  734.                 CheckMenuItem(hmenu, IDM_DVTOFILE_NOPRE_TYPE2, MF_UNCHECKED);
  735.             } 
  736.             break;
  737.  
  738.         // Type 1 file (transmit & playback)    
  739.         case IDM_FILETODV :
  740.             if (DV_MakeSpecialGraph(GRAPH_FILE_TO_DV))
  741.             {
  742.                 // update globals, log, toolbar, menu items
  743.                 g_iCurrentGraph = GRAPH_FILE_TO_DV;
  744.                 DV_LogOut(LOG_PRIORITY_INFO, LOG_LEVEL_SUCCINCT, TEXT("Built File to DV Graph (Type1)"));
  745.                 SendMessage(g_hwndTBar, TB_SETSTATE, IDM_RECORD, MAKELONG(TBSTATE_ENABLED, 0L));
  746.  
  747.                 //disable everything except for play, pause, and stop
  748.                 SendMessage(g_hwndTBar, TB_SETSTATE, IDM_STEP_REV, MAKELONG(TBSTATE_INDETERMINATE, 0L));
  749.                 SendMessage(g_hwndTBar, TB_SETSTATE, IDM_REW, MAKELONG(TBSTATE_INDETERMINATE, 0L));
  750.                 SendMessage(g_hwndTBar, TB_SETSTATE, IDM_PLAY_FAST_REV, MAKELONG(TBSTATE_INDETERMINATE, 0L));
  751.                 SendMessage(g_hwndTBar, TB_SETSTATE, IDM_PLAY_FAST_FF, MAKELONG(TBSTATE_INDETERMINATE, 0L));
  752.                 SendMessage(g_hwndTBar, TB_SETSTATE, IDM_FF, MAKELONG(TBSTATE_INDETERMINATE, 0L));
  753.                 SendMessage(g_hwndTBar, TB_SETSTATE, IDM_STEP_FWD, MAKELONG(TBSTATE_INDETERMINATE, 0L));
  754.                 SendMessage(g_hwndTBar, TB_SETSTATE, IDM_SEEKTIMECODE, MAKELONG(TBSTATE_INDETERMINATE, 0L));
  755.  
  756.                 CheckMenuItem(hmenu, IDM_PREVIEW, MF_UNCHECKED);
  757.                 CheckMenuItem(hmenu, IDM_FILETODV, MF_CHECKED);
  758.                 CheckMenuItem(hmenu, IDM_FILETODV_NOPRE, MF_UNCHECKED);
  759.                 CheckMenuItem(hmenu, IDM_DVTOFILE, MF_UNCHECKED);
  760.                 CheckMenuItem(hmenu, IDM_DVTOFILE_NOPRE, MF_UNCHECKED);
  761.  
  762.                 CheckMenuItem(hmenu, IDM_FILETODV_TYPE2, MF_UNCHECKED);
  763.                 CheckMenuItem(hmenu, IDM_FILETODV_NOPRE_TYPE2, MF_UNCHECKED);
  764.                 CheckMenuItem(hmenu, IDM_DVTOFILE_TYPE2, MF_UNCHECKED);
  765.                 CheckMenuItem(hmenu, IDM_DVTOFILE_NOPRE_TYPE2, MF_UNCHECKED);
  766.             } 
  767.             break;
  768.  
  769.         // Type 1 file (transmit)   
  770.         case IDM_FILETODV_NOPRE :
  771.             if (DV_MakeSpecialGraph(GRAPH_FILE_TO_DV_NOPRE))
  772.             {
  773.                 // update globals, log, toolbar, menu items
  774.                 g_iCurrentGraph = GRAPH_FILE_TO_DV_NOPRE;
  775.                 DV_LogOut(LOG_PRIORITY_INFO, LOG_LEVEL_SUCCINCT, TEXT("Built File to DV Graph (Type1) without Preview"));
  776.                 SendMessage(g_hwndTBar, TB_SETSTATE, IDM_RECORD, MAKELONG(TBSTATE_ENABLED, 0L));
  777.  
  778.                 //disable everything except for play, pause, and stop
  779.                 SendMessage(g_hwndTBar, TB_SETSTATE, IDM_STEP_REV, MAKELONG(TBSTATE_INDETERMINATE, 0L));
  780.                 SendMessage(g_hwndTBar, TB_SETSTATE, IDM_REW, MAKELONG(TBSTATE_INDETERMINATE, 0L));
  781.                 SendMessage(g_hwndTBar, TB_SETSTATE, IDM_PLAY_FAST_REV, MAKELONG(TBSTATE_INDETERMINATE, 0L));
  782.                 SendMessage(g_hwndTBar, TB_SETSTATE, IDM_PLAY_FAST_FF, MAKELONG(TBSTATE_INDETERMINATE, 0L));
  783.                 SendMessage(g_hwndTBar, TB_SETSTATE, IDM_FF, MAKELONG(TBSTATE_INDETERMINATE, 0L));
  784.                 SendMessage(g_hwndTBar, TB_SETSTATE, IDM_STEP_FWD, MAKELONG(TBSTATE_INDETERMINATE, 0L));
  785.                 SendMessage(g_hwndTBar, TB_SETSTATE, IDM_SEEKTIMECODE, MAKELONG(TBSTATE_INDETERMINATE, 0L));
  786.  
  787.                 CheckMenuItem(hmenu, IDM_PREVIEW, MF_UNCHECKED);
  788.                 CheckMenuItem(hmenu, IDM_FILETODV, MF_UNCHECKED);
  789.                 CheckMenuItem(hmenu, IDM_DVTOFILE, MF_UNCHECKED);
  790.                 CheckMenuItem(hmenu, IDM_FILETODV_NOPRE, MF_CHECKED);
  791.                 CheckMenuItem(hmenu, IDM_DVTOFILE_NOPRE, MF_UNCHECKED);
  792.  
  793.                 CheckMenuItem(hmenu, IDM_FILETODV_TYPE2, MF_UNCHECKED);
  794.                 CheckMenuItem(hmenu, IDM_FILETODV_NOPRE_TYPE2, MF_UNCHECKED);
  795.                 CheckMenuItem(hmenu, IDM_DVTOFILE_TYPE2, MF_UNCHECKED);
  796.                 CheckMenuItem(hmenu, IDM_DVTOFILE_NOPRE_TYPE2, MF_UNCHECKED);
  797.  
  798.             } 
  799.             break;
  800.             
  801.         // Type 1 file (capture & preview)  
  802.         case IDM_DVTOFILE :
  803.             if (DV_MakeSpecialGraph(GRAPH_DV_TO_FILE))
  804.             {
  805.                 // update globals, log, toolbar, menu items
  806.                 g_iCurrentGraph = GRAPH_DV_TO_FILE;
  807.                 DV_LogOut(LOG_PRIORITY_INFO, LOG_LEVEL_SUCCINCT, TEXT("Built DV to File Graph (Type1)"));
  808.                 SendMessage(g_hwndTBar, TB_SETSTATE, IDM_RECORD, MAKELONG(TBSTATE_ENABLED, 0L));
  809.                 CheckMenuItem(hmenu, IDM_PREVIEW, MF_UNCHECKED);
  810.                 CheckMenuItem(hmenu, IDM_FILETODV, MF_UNCHECKED);
  811.                 CheckMenuItem(hmenu, IDM_DVTOFILE, MF_CHECKED);
  812.                 CheckMenuItem(hmenu, IDM_FILETODV_NOPRE, MF_UNCHECKED);
  813.                 CheckMenuItem(hmenu, IDM_DVTOFILE_NOPRE, MF_UNCHECKED);
  814.  
  815.                 CheckMenuItem(hmenu, IDM_FILETODV_TYPE2, MF_UNCHECKED);
  816.                 CheckMenuItem(hmenu, IDM_FILETODV_NOPRE_TYPE2, MF_UNCHECKED);
  817.                 CheckMenuItem(hmenu, IDM_DVTOFILE_TYPE2, MF_UNCHECKED);
  818.                 CheckMenuItem(hmenu, IDM_DVTOFILE_NOPRE_TYPE2, MF_UNCHECKED);
  819.                 //re-enable everything 
  820.                 SendMessage(g_hwndTBar, TB_SETSTATE, IDM_STEP_REV, MAKELONG(TBSTATE_ENABLED, 0L));
  821.                 SendMessage(g_hwndTBar, TB_SETSTATE, IDM_REW, MAKELONG(TBSTATE_ENABLED, 0L));
  822.                 SendMessage(g_hwndTBar, TB_SETSTATE, IDM_PLAY_FAST_REV, MAKELONG(TBSTATE_ENABLED, 0L));
  823.                 SendMessage(g_hwndTBar, TB_SETSTATE, IDM_PLAY_FAST_FF, MAKELONG(TBSTATE_ENABLED, 0L));
  824.                 SendMessage(g_hwndTBar, TB_SETSTATE, IDM_FF, MAKELONG(TBSTATE_ENABLED, 0L));
  825.                 SendMessage(g_hwndTBar, TB_SETSTATE, IDM_STEP_FWD, MAKELONG(TBSTATE_ENABLED, 0L));
  826.                 SendMessage(g_hwndTBar, TB_SETSTATE, IDM_SEEKTIMECODE, MAKELONG(TBSTATE_ENABLED, 0L));
  827.                 SendMessage(g_hwndTBar, TB_SETSTATE, IDM_RECORD, MAKELONG(TBSTATE_ENABLED, 0L));
  828.  
  829.             } 
  830.             break;
  831.  
  832.         // Type 1 file (capture)    
  833.         case IDM_DVTOFILE_NOPRE :
  834.             if (DV_MakeSpecialGraph(GRAPH_DV_TO_FILE_NOPRE))
  835.             {
  836.                 // update globals, log, toolbar, menu items
  837.                 g_iCurrentGraph = GRAPH_DV_TO_FILE_NOPRE;
  838.                 DV_LogOut(LOG_PRIORITY_INFO, LOG_LEVEL_SUCCINCT, TEXT("Built DV to File Graph (Type1) without Preview"));
  839.                 SendMessage(g_hwndTBar, TB_SETSTATE, IDM_RECORD, MAKELONG(TBSTATE_ENABLED, 0L));
  840.                 CheckMenuItem(hmenu, IDM_PREVIEW, MF_UNCHECKED);
  841.                 CheckMenuItem(hmenu, IDM_FILETODV, MF_UNCHECKED);
  842.                 CheckMenuItem(hmenu, IDM_DVTOFILE, MF_UNCHECKED);
  843.                 CheckMenuItem(hmenu, IDM_FILETODV_NOPRE, MF_UNCHECKED);
  844.                 CheckMenuItem(hmenu, IDM_DVTOFILE_NOPRE, MF_CHECKED);
  845.  
  846.                 CheckMenuItem(hmenu, IDM_FILETODV_TYPE2, MF_UNCHECKED);
  847.                 CheckMenuItem(hmenu, IDM_FILETODV_NOPRE_TYPE2, MF_UNCHECKED);
  848.                 CheckMenuItem(hmenu, IDM_DVTOFILE_TYPE2, MF_UNCHECKED);
  849.                 CheckMenuItem(hmenu, IDM_DVTOFILE_NOPRE_TYPE2, MF_UNCHECKED);
  850.  
  851.                 //re-enable everything 
  852.                 SendMessage(g_hwndTBar, TB_SETSTATE, IDM_STEP_REV, MAKELONG(TBSTATE_ENABLED, 0L));
  853.                 SendMessage(g_hwndTBar, TB_SETSTATE, IDM_REW, MAKELONG(TBSTATE_ENABLED, 0L));
  854.                 SendMessage(g_hwndTBar, TB_SETSTATE, IDM_PLAY_FAST_REV, MAKELONG(TBSTATE_ENABLED, 0L));
  855.                 SendMessage(g_hwndTBar, TB_SETSTATE, IDM_PLAY_FAST_FF, MAKELONG(TBSTATE_ENABLED, 0L));
  856.                 SendMessage(g_hwndTBar, TB_SETSTATE, IDM_FF, MAKELONG(TBSTATE_ENABLED, 0L));
  857.                 SendMessage(g_hwndTBar, TB_SETSTATE, IDM_STEP_FWD, MAKELONG(TBSTATE_ENABLED, 0L));
  858.                 SendMessage(g_hwndTBar, TB_SETSTATE, IDM_SEEKTIMECODE, MAKELONG(TBSTATE_ENABLED, 0L));
  859.                 SendMessage(g_hwndTBar, TB_SETSTATE, IDM_RECORD, MAKELONG(TBSTATE_ENABLED, 0L));
  860.             } 
  861.             break;
  862.  
  863.         // Type 2 File (transmit & playback)
  864.         case IDM_FILETODV_TYPE2 :
  865.             if (DV_MakeSpecialGraph(GRAPH_FILE_TO_DV_TYPE2))
  866.             {
  867.                 // update globals, log, toolbar, menu items
  868.                 g_iCurrentGraph = GRAPH_FILE_TO_DV_TYPE2;
  869.                 DV_LogOut(LOG_PRIORITY_INFO, LOG_LEVEL_SUCCINCT, TEXT("Built File to DV Graph (Type2)"));
  870.                 SendMessage(g_hwndTBar, TB_SETSTATE, IDM_RECORD, MAKELONG(TBSTATE_ENABLED, 0L));
  871.  
  872.                 //disable everything except for play, pause, and stop
  873.                 SendMessage(g_hwndTBar, TB_SETSTATE, IDM_STEP_REV, MAKELONG(TBSTATE_INDETERMINATE, 0L));
  874.                 SendMessage(g_hwndTBar, TB_SETSTATE, IDM_REW, MAKELONG(TBSTATE_INDETERMINATE, 0L));
  875.                 SendMessage(g_hwndTBar, TB_SETSTATE, IDM_PLAY_FAST_REV, MAKELONG(TBSTATE_INDETERMINATE, 0L));
  876.                 SendMessage(g_hwndTBar, TB_SETSTATE, IDM_PLAY_FAST_FF, MAKELONG(TBSTATE_INDETERMINATE, 0L));
  877.                 SendMessage(g_hwndTBar, TB_SETSTATE, IDM_FF, MAKELONG(TBSTATE_INDETERMINATE, 0L));
  878.                 SendMessage(g_hwndTBar, TB_SETSTATE, IDM_STEP_FWD, MAKELONG(TBSTATE_INDETERMINATE, 0L));
  879.                 SendMessage(g_hwndTBar, TB_SETSTATE, IDM_SEEKTIMECODE, MAKELONG(TBSTATE_INDETERMINATE, 0L));
  880.  
  881.                 CheckMenuItem(hmenu, IDM_PREVIEW, MF_UNCHECKED);
  882.                 CheckMenuItem(hmenu, IDM_FILETODV, MF_UNCHECKED);
  883.                 CheckMenuItem(hmenu, IDM_FILETODV_NOPRE, MF_UNCHECKED);
  884.                 CheckMenuItem(hmenu, IDM_DVTOFILE, MF_UNCHECKED);
  885.                 CheckMenuItem(hmenu, IDM_DVTOFILE_NOPRE, MF_UNCHECKED);
  886.  
  887.                 CheckMenuItem(hmenu, IDM_FILETODV_TYPE2, MF_CHECKED);
  888.                 CheckMenuItem(hmenu, IDM_FILETODV_NOPRE_TYPE2, MF_UNCHECKED);
  889.                 CheckMenuItem(hmenu, IDM_DVTOFILE_TYPE2, MF_UNCHECKED);
  890.                 CheckMenuItem(hmenu, IDM_DVTOFILE_NOPRE_TYPE2, MF_UNCHECKED);
  891.             } 
  892.             break;
  893.  
  894.         // Type 2 File (transmit)
  895.         case IDM_FILETODV_NOPRE_TYPE2 :
  896.             if (DV_MakeSpecialGraph(GRAPH_FILE_TO_DV_NOPRE_TYPE2))
  897.             {
  898.                 // update globals, log, toolbar, menu items
  899.                 g_iCurrentGraph = GRAPH_FILE_TO_DV_NOPRE_TYPE2;
  900.                 DV_LogOut(LOG_PRIORITY_INFO, LOG_LEVEL_SUCCINCT, TEXT("Built File to DV Graph (Type2) without Preview"));
  901.                 SendMessage(g_hwndTBar, TB_SETSTATE, IDM_RECORD, MAKELONG(TBSTATE_ENABLED, 0L));
  902.  
  903.                 //disable everything except for play, pause, and stop
  904.                 SendMessage(g_hwndTBar, TB_SETSTATE, IDM_STEP_REV, MAKELONG(TBSTATE_INDETERMINATE, 0L));
  905.                 SendMessage(g_hwndTBar, TB_SETSTATE, IDM_REW, MAKELONG(TBSTATE_INDETERMINATE, 0L));
  906.                 SendMessage(g_hwndTBar, TB_SETSTATE, IDM_PLAY_FAST_REV, MAKELONG(TBSTATE_INDETERMINATE, 0L));
  907.                 SendMessage(g_hwndTBar, TB_SETSTATE, IDM_PLAY_FAST_FF, MAKELONG(TBSTATE_INDETERMINATE, 0L));
  908.                 SendMessage(g_hwndTBar, TB_SETSTATE, IDM_FF, MAKELONG(TBSTATE_INDETERMINATE, 0L));
  909.                 SendMessage(g_hwndTBar, TB_SETSTATE, IDM_STEP_FWD, MAKELONG(TBSTATE_INDETERMINATE, 0L));
  910.                 SendMessage(g_hwndTBar, TB_SETSTATE, IDM_SEEKTIMECODE, MAKELONG(TBSTATE_INDETERMINATE, 0L));
  911.  
  912.                 CheckMenuItem(hmenu, IDM_PREVIEW, MF_UNCHECKED);
  913.                 CheckMenuItem(hmenu, IDM_FILETODV, MF_UNCHECKED);
  914.                 CheckMenuItem(hmenu, IDM_DVTOFILE, MF_UNCHECKED);
  915.                 CheckMenuItem(hmenu, IDM_FILETODV_NOPRE, MF_UNCHECKED);
  916.                 CheckMenuItem(hmenu, IDM_DVTOFILE_NOPRE, MF_UNCHECKED);
  917.  
  918.                 CheckMenuItem(hmenu, IDM_FILETODV_TYPE2, MF_UNCHECKED);
  919.                 CheckMenuItem(hmenu, IDM_FILETODV_NOPRE_TYPE2, MF_CHECKED);
  920.                 CheckMenuItem(hmenu, IDM_DVTOFILE_TYPE2, MF_UNCHECKED);
  921.                 CheckMenuItem(hmenu, IDM_DVTOFILE_NOPRE_TYPE2, MF_UNCHECKED);               
  922.             } 
  923.             break;
  924.             
  925.         // Type 2 File (capture & preview)
  926.         case IDM_DVTOFILE_TYPE2 :
  927.             if (DV_MakeSpecialGraph(GRAPH_DV_TO_FILE_TYPE2))
  928.             {
  929.                 // update globals, log, toolbar, menu items
  930.                 g_iCurrentGraph = GRAPH_DV_TO_FILE_TYPE2;
  931.                 DV_LogOut(LOG_PRIORITY_INFO, LOG_LEVEL_SUCCINCT, TEXT("Built DV to File Graph (Type2)"));
  932.                 SendMessage(g_hwndTBar, TB_SETSTATE, IDM_RECORD, MAKELONG(TBSTATE_ENABLED, 0L));
  933.                 CheckMenuItem(hmenu, IDM_PREVIEW, MF_UNCHECKED);
  934.                 CheckMenuItem(hmenu, IDM_FILETODV, MF_UNCHECKED);
  935.                 CheckMenuItem(hmenu, IDM_DVTOFILE, MF_UNCHECKED);
  936.                 CheckMenuItem(hmenu, IDM_FILETODV_NOPRE, MF_UNCHECKED);
  937.                 CheckMenuItem(hmenu, IDM_DVTOFILE_NOPRE, MF_UNCHECKED);
  938.  
  939.                 CheckMenuItem(hmenu, IDM_FILETODV_TYPE2, MF_UNCHECKED);
  940.                 CheckMenuItem(hmenu, IDM_FILETODV_NOPRE_TYPE2, MF_UNCHECKED);
  941.                 CheckMenuItem(hmenu, IDM_DVTOFILE_TYPE2, MF_CHECKED);
  942.                 CheckMenuItem(hmenu, IDM_DVTOFILE_NOPRE_TYPE2, MF_UNCHECKED);
  943.                 //re-enable everything 
  944.                 SendMessage(g_hwndTBar, TB_SETSTATE, IDM_STEP_REV, MAKELONG(TBSTATE_ENABLED, 0L));
  945.                 SendMessage(g_hwndTBar, TB_SETSTATE, IDM_REW, MAKELONG(TBSTATE_ENABLED, 0L));
  946.                 SendMessage(g_hwndTBar, TB_SETSTATE, IDM_PLAY_FAST_REV, MAKELONG(TBSTATE_ENABLED, 0L));
  947.                 SendMessage(g_hwndTBar, TB_SETSTATE, IDM_PLAY_FAST_FF, MAKELONG(TBSTATE_ENABLED, 0L));
  948.                 SendMessage(g_hwndTBar, TB_SETSTATE, IDM_FF, MAKELONG(TBSTATE_ENABLED, 0L));
  949.                 SendMessage(g_hwndTBar, TB_SETSTATE, IDM_STEP_FWD, MAKELONG(TBSTATE_ENABLED, 0L));
  950.                 SendMessage(g_hwndTBar, TB_SETSTATE, IDM_SEEKTIMECODE, MAKELONG(TBSTATE_ENABLED, 0L));
  951.                 SendMessage(g_hwndTBar, TB_SETSTATE, IDM_RECORD, MAKELONG(TBSTATE_ENABLED, 0L));
  952.  
  953.             } 
  954.             break;
  955.  
  956.         // Type 2 File (capture)
  957.         case IDM_DVTOFILE_NOPRE_TYPE2 :
  958.             if (DV_MakeSpecialGraph(GRAPH_DV_TO_FILE_NOPRE_TYPE2))
  959.             {
  960.                 // update globals, log, toolbar, menu items
  961.                 g_iCurrentGraph = GRAPH_DV_TO_FILE_NOPRE_TYPE2;
  962.                 DV_LogOut(LOG_PRIORITY_INFO, LOG_LEVEL_SUCCINCT, TEXT("Built DV to File Graph (Type2) without Preview"));
  963.                 SendMessage(g_hwndTBar, TB_SETSTATE, IDM_RECORD, MAKELONG(TBSTATE_ENABLED, 0L));
  964.                 CheckMenuItem(hmenu, IDM_PREVIEW, MF_UNCHECKED);
  965.                 CheckMenuItem(hmenu, IDM_FILETODV, MF_UNCHECKED);
  966.                 CheckMenuItem(hmenu, IDM_DVTOFILE, MF_UNCHECKED);
  967.                 CheckMenuItem(hmenu, IDM_FILETODV_NOPRE, MF_UNCHECKED);
  968.                 CheckMenuItem(hmenu, IDM_DVTOFILE_NOPRE, MF_UNCHECKED);
  969.  
  970.                 CheckMenuItem(hmenu, IDM_FILETODV_TYPE2, MF_UNCHECKED);
  971.                 CheckMenuItem(hmenu, IDM_FILETODV_NOPRE_TYPE2, MF_UNCHECKED);
  972.                 CheckMenuItem(hmenu, IDM_DVTOFILE_TYPE2, MF_UNCHECKED);
  973.                 CheckMenuItem(hmenu, IDM_DVTOFILE_NOPRE_TYPE2, MF_CHECKED);
  974.  
  975.                 //re-enable everything 
  976.                 SendMessage(g_hwndTBar, TB_SETSTATE, IDM_STEP_REV, MAKELONG(TBSTATE_ENABLED, 0L));
  977.                 SendMessage(g_hwndTBar, TB_SETSTATE, IDM_REW, MAKELONG(TBSTATE_ENABLED, 0L));
  978.                 SendMessage(g_hwndTBar, TB_SETSTATE, IDM_PLAY_FAST_REV, MAKELONG(TBSTATE_ENABLED, 0L));
  979.                 SendMessage(g_hwndTBar, TB_SETSTATE, IDM_PLAY_FAST_FF, MAKELONG(TBSTATE_ENABLED, 0L));
  980.                 SendMessage(g_hwndTBar, TB_SETSTATE, IDM_FF, MAKELONG(TBSTATE_ENABLED, 0L));
  981.                 SendMessage(g_hwndTBar, TB_SETSTATE, IDM_STEP_FWD, MAKELONG(TBSTATE_ENABLED, 0L));
  982.                 SendMessage(g_hwndTBar, TB_SETSTATE, IDM_SEEKTIMECODE, MAKELONG(TBSTATE_ENABLED, 0L));
  983.                 SendMessage(g_hwndTBar, TB_SETSTATE, IDM_RECORD, MAKELONG(TBSTATE_ENABLED, 0L));
  984.  
  985.             } 
  986.             break;
  987.         } // switch (LOWORD(wParam))
  988.     } // switch (iMsg)
  989. }
  990.  
  991. /*-------------------------------------------------------------------------
  992. Routine:        DV_AppSetup
  993. Purpose:        look for a DV device, initialize it, get its subunit mode, Create the filtergraph and instantiate the filters
  994. Arguments:    None
  995. Returns:        None
  996. Notes:          
  997. ------------------------------------------------------------------------*/
  998. void DV_AppSetup(void)
  999. {
  1000.     
  1001.     // COM initialization
  1002.     CoInitialize(NULL);
  1003.  
  1004.     HMENU hmenu = GetMenu(g_hwndApp);   
  1005.     /*
  1006.         look for a DV device and initialize it,
  1007.         or show an error if one does not exist
  1008.     */  
  1009.     if (!DV_InitDevice())
  1010.     {
  1011.         g_bDeviceFound = FALSE;
  1012.         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);
  1013.         if(iOption == IDYES) 
  1014.             SendMessage(g_hwndApp, WM_DESTROY, 0,0);
  1015.         else
  1016.         {
  1017.             DV_CleanUp();
  1018.             ShowWindow(g_hwndTBar, SW_HIDE);
  1019.  
  1020.             EnableMenuItem(hmenu, IDM_REFRESHMODE, MF_GRAYED);
  1021.             EnableMenuItem(hmenu, IDM_CHECKTAPE, MF_GRAYED);
  1022.             EnableMenuItem(hmenu, IDM_DECODESIZE, MF_GRAYED);
  1023.             EnableMenuItem(hmenu, IDM_PREVIEW, MF_GRAYED);
  1024.  
  1025.             EnableMenuItem(hmenu, IDM_DVTOFILE, MF_GRAYED);
  1026.             EnableMenuItem(hmenu, IDM_DVTOFILE_NOPRE, MF_GRAYED);
  1027.             EnableMenuItem(hmenu, IDM_FILETODV, MF_GRAYED);
  1028.             EnableMenuItem(hmenu, IDM_FILETODV_NOPRE, MF_GRAYED);
  1029.  
  1030.             EnableMenuItem(hmenu, IDM_DVTOFILE_TYPE2, MF_GRAYED);
  1031.             EnableMenuItem(hmenu, IDM_DVTOFILE_NOPRE_TYPE2, MF_GRAYED);
  1032.             EnableMenuItem(hmenu, IDM_FILETODV_TYPE2, MF_GRAYED);
  1033.             EnableMenuItem(hmenu, IDM_FILETODV_NOPRE_TYPE2, MF_GRAYED);
  1034.         }
  1035.     }
  1036.     else
  1037.     {
  1038.             g_bDeviceFound = TRUE;
  1039.             ShowWindow(g_hwndTBar, SW_SHOWNORMAL);
  1040.             EnableMenuItem(hmenu, IDM_REFRESHMODE, MF_ENABLED);
  1041.             EnableMenuItem(hmenu, IDM_CHECKTAPE, MF_ENABLED);
  1042.             EnableMenuItem(hmenu, IDM_DECODESIZE, MF_ENABLED);
  1043.             EnableMenuItem(hmenu, IDM_PREVIEW, MF_ENABLED);
  1044.  
  1045.             EnableMenuItem(hmenu, IDM_DVTOFILE, MF_ENABLED);
  1046.             EnableMenuItem(hmenu, IDM_DVTOFILE_NOPRE, MF_ENABLED);
  1047.             EnableMenuItem(hmenu, IDM_FILETODV, MF_ENABLED);
  1048.             EnableMenuItem(hmenu, IDM_FILETODV_NOPRE, MF_ENABLED);
  1049.  
  1050.             EnableMenuItem(hmenu, IDM_DVTOFILE_TYPE2, MF_ENABLED);
  1051.             EnableMenuItem(hmenu, IDM_DVTOFILE_NOPRE_TYPE2, MF_ENABLED);
  1052.             EnableMenuItem(hmenu, IDM_FILETODV_TYPE2, MF_ENABLED);
  1053.             EnableMenuItem(hmenu, IDM_FILETODV_NOPRE_TYPE2, MF_ENABLED);
  1054.  
  1055.         //if we are here, all of our interfaces should be valid
  1056.         ASSERT(g_pBuilder);
  1057.         ASSERT(g_pGraphBuilder);
  1058.         ASSERT(g_pDVCamera);
  1059.  
  1060.         //get directshow interfaces for DV
  1061.         g_pBuilder->FindInterface(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video, g_pDVCamera, IID_IAMExtTransport, reinterpret_cast<PVOID*>(&g_pExtTrans));
  1062.         g_pBuilder->FindInterface(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video, g_pDVCamera, IID_IAMTimecodeReader, reinterpret_cast<PVOID*>(&g_pTimeReader));
  1063.  
  1064.         //determine if we are in camera mode or vcr mode and disable unavailable menu items
  1065.         //  Use GetDVMode to *not* use AVC commands
  1066.  
  1067.         switch (DV_GetDVMode())
  1068.         {
  1069.             case CameraMode :          
  1070.                 EnableMenuItem(hmenu, IDM_FILETODV, MF_GRAYED);
  1071.                 EnableMenuItem(hmenu, IDM_FILETODV_NOPRE, MF_GRAYED);
  1072.                 EnableMenuItem(hmenu, IDM_FILETODV_TYPE2, MF_GRAYED);
  1073.                 EnableMenuItem(hmenu, IDM_FILETODV_NOPRE_TYPE2, MF_GRAYED);
  1074.                 EnableMenuItem(hmenu, IDM_CHECKTAPE, MF_GRAYED);
  1075.                 DV_StatusText(TEXT("Camera Mode"), 2);
  1076.                 break;                
  1077.  
  1078.             case VcrMode :
  1079.                //check information about the tape
  1080.                 if (S_OK != DV_GetTapeInfo())
  1081.                 {
  1082.                     MBOX(TEXT("Tape is not inserted, or has an improper format.\nReinsert the tape and select Options - Check Tape"));
  1083.                 } 
  1084.                 break;
  1085.  
  1086.             case UnknownMode :
  1087.                 MBOX(TEXT("Cannot determine camera / Vcr mode"));
  1088.                 DV_StatusText(TEXT("Unknown Mode"), 2);
  1089.                 break;
  1090.  
  1091.             default :
  1092.                 DV_LogOut(LOG_PRIORITY_ERROR, LOG_LEVEL_SUCCINCT, TEXT("Bad return value from DV_GetDVMode"));
  1093.                 break;
  1094.         } 
  1095.         
  1096.         // initialize the video window
  1097.         if (!DV_InitWindow())
  1098.         {
  1099.             MBOX(TEXT("Could not initialize video window"));
  1100.             SendMessage(g_hwndApp, WM_DESTROY, 0,0);
  1101.         } 
  1102.         else
  1103.         {
  1104.             //If we've gotten this far, all of these components should be available
  1105.             //DV Splitter, DV Muxer, DV Codec is part of QDV
  1106.             EXECUTE_ASSERT(S_OK == CoCreateInstance(CLSID_DVSplitter, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, reinterpret_cast<PVOID *>(&g_pDVSplitter)));
  1107.             EXECUTE_ASSERT(S_OK == CoCreateInstance(CLSID_DVMux, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, reinterpret_cast<PVOID *>(&g_pDVMux)));
  1108.             EXECUTE_ASSERT(S_OK == CoCreateInstance(CLSID_DVVideoCodec, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, reinterpret_cast<PVOID *>(&g_pDVCodec)));
  1109.             // Other filters to help in building the graphs
  1110.             EXECUTE_ASSERT(S_OK == CoCreateInstance(CLSID_AviSplitter, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, reinterpret_cast<PVOID *>(&g_pAviSplitter)));
  1111.             EXECUTE_ASSERT(S_OK == CoCreateInstance(CLSID_SmartTee, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, reinterpret_cast<PVOID *>(&g_pSmartTee)));
  1112.             EXECUTE_ASSERT(S_OK == CoCreateInstance(CLSID_InfTee, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, reinterpret_cast<PVOID *>(&g_pInfTee)));
  1113.             EXECUTE_ASSERT(S_OK == CoCreateInstance(CLSID_VideoRenderer, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, reinterpret_cast<PVOID *>(&g_pVideoRenderer)));
  1114.             // The user may not have a sound card installed , so if this fails, we just won't do sound.
  1115.             CoCreateInstance(CLSID_DSoundRender, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, reinterpret_cast<PVOID *>(&g_pDSound));
  1116.  
  1117.             IMediaEventEx *pMe = NULL;
  1118.             if (SUCCEEDED(g_pGraphBuilder->QueryInterface(IID_IMediaEventEx, reinterpret_cast<PVOID *>(&pMe))))
  1119.             {
  1120.                 pMe->SetNotifyWindow((LONG_PTR) g_hwndApp, WM_FGNOTIFY, 0);
  1121.                 SAFE_RELEASE(pMe);
  1122.             } 
  1123.  
  1124.             SetWindowText(g_hwndApp, DV_APPTITLE);
  1125.             DV_StatusText(g_DeviceName, 0);
  1126.         } 
  1127.     }
  1128.  
  1129. }
  1130.  
  1131.  
  1132. /*-------------------------------------------------------------------------
  1133. Routine:        DV_InitControls
  1134. Purpose:        Initializer for app window controls (toolbars, edit controls, etc.)
  1135. Arguments:    window handle and hinstance
  1136. Returns:        FALSE if creation of any of the controls fails.
  1137. Notes:          
  1138. ------------------------------------------------------------------------*/
  1139. BOOL DV_InitControls(HWND hwnd, HINSTANCE hInst)
  1140. {
  1141.     HWND hwndEdit1 = NULL;
  1142.     HWND hwndEdit2 = NULL;
  1143.     HWND hwndEdit3 = NULL;
  1144.     HWND hwndEdit4 = NULL;
  1145.     HWND hwndTCCheck = NULL;
  1146.  
  1147.     RECT rect = {0};
  1148.         
  1149.     InitCommonControls();
  1150.     // create status bar windows
  1151.     g_hwndStatus = CreateWindowEx( 0,
  1152.                                    STATUSCLASSNAME,
  1153.                                    TEXT(""),
  1154.                                    WS_CHILD | WS_BORDER | WS_VISIBLE | WS_CLIPSIBLINGS,
  1155.                                    -100, -100,
  1156.                                    10, 10,
  1157.                                    hwnd,
  1158.                                    HMENU(IDB_STATUS),
  1159.                                    hInst,
  1160.                                    NULL);
  1161.     SendMessage(g_hwndStatus, SB_GETRECT, 0, (LPARAM)(LPRECT)&rect);          
  1162.     g_statusHeight = rect.bottom;
  1163.     //Set the initial size for the status bar parts.  The WM_SIZE handler will take care of it from here
  1164.     DV_StatusParts(g_iAppWidth);
  1165.  
  1166.     // create toolbar window
  1167.     g_hwndTBar = CreateToolbarEx(hwnd, 
  1168.                                    WS_CHILD | WS_VISIBLE | WS_BORDER | TBSTYLE_TOOLTIPS, 
  1169.                                    ID_TOOLBAR, 
  1170.                                    10, 
  1171.                                    hInst, 
  1172.                                    IDB_TOOLBAR, 
  1173.                                    g_rgTbButtons, 
  1174.                                    sizeof(g_rgTbButtons) / sizeof(TBBUTTON), 
  1175.                                    16,16,16,16, 
  1176.                                    sizeof(TBBUTTON)); 
  1177.  
  1178.     SendMessage(g_hwndTBar, TB_GETRECT, IDM_SEEKTIMECODE, (LPARAM)&rect);
  1179.  
  1180.     if (!rect.right)
  1181.     {
  1182.         DV_LogOut(LOG_PRIORITY_WARN, LOG_LEVEL_MEDIUM, TEXT("Could not get rect of Seek Time code button"));
  1183.         rect.right = 350;
  1184.     } 
  1185.     // create timecode text boxes on the toolbar            
  1186.     hwndEdit1 = CreateWindow(TEXT("edit"), TEXT("00"), WS_CHILD | WS_BORDER | WS_VISIBLE | WS_TABSTOP | ES_NUMBER, 
  1187.                     rect.right + 6, 4, 22, 18, g_hwndTBar, (HMENU)IDC_EDIT_HOUR, (HINSTANCE) hInst, NULL);
  1188.     
  1189.     hwndEdit2 = CreateWindow(TEXT("edit"), TEXT("00"), WS_CHILD | WS_BORDER | WS_VISIBLE | WS_TABSTOP | ES_NUMBER,  
  1190.                     rect.right + 30, 4, 22, 18, g_hwndTBar, (HMENU)IDC_EDIT_MINUTE, (HINSTANCE) hInst, NULL);
  1191.     
  1192.     hwndEdit3 = CreateWindow(TEXT("edit"), TEXT("00"), WS_CHILD | WS_BORDER | WS_VISIBLE | WS_TABSTOP | ES_NUMBER, 
  1193.                     rect.right + 54, 4, 22, 18, g_hwndTBar, (HMENU)IDC_EDIT_SECOND, (HINSTANCE) hInst, NULL);
  1194.  
  1195.     hwndEdit4 = CreateWindow(TEXT("edit"), TEXT("00"), WS_CHILD | WS_BORDER | WS_VISIBLE | WS_TABSTOP | ES_NUMBER, 
  1196.                     rect.right + 78, 4, 22, 18, g_hwndTBar, (HMENU)IDC_EDIT_FRAME, (HINSTANCE) hInst, NULL);
  1197.  
  1198.     hwndTCCheck = CreateWindow(TEXT("button"), TEXT("Display Timecodes"), WS_CHILD | BS_AUTOCHECKBOX | WS_VISIBLE | WS_TABSTOP, 
  1199.                     rect.right + 106, 5, 150, 18, g_hwndTBar, (HMENU)IDC_TCCHECKBOX, (HINSTANCE) hInst, NULL); 
  1200.     Button_SetCheck (hwndTCCheck, BST_CHECKED) ;                    
  1201.  
  1202.     //finally, resize the main window so it maintains the proper height despite the toolbar and status bar
  1203.     MoveWindow(g_hwndApp, CW_USEDEFAULT, CW_USEDEFAULT, 
  1204.                g_iAppWidth, g_iAppHeight + (rect.bottom - rect.top) + 
  1205.                (g_statusHeight + (2 * GetSystemMetrics(SM_CYBORDER))), TRUE);
  1206.     
  1207.     return (!( !hwndEdit1) || (!hwndEdit2) || (!hwndEdit3) || (!hwndEdit4) || (!hwndTCCheck) || (!g_hwndStatus));
  1208.  
  1209.  
  1210.  
  1211. /*-------------------------------------------------------------------------
  1212. Routine:        DV_InitDevice
  1213. Purpose:        Enumerates all video devices, and determines if it is a DV device.  
  1214.                     We'll do this by querying for an interface specific to DV - in this
  1215.                     case, IAMExtDevice.
  1216. Arguments:    None
  1217. Returns:        TRUE if a DV device is found
  1218. Notes:          Will this solution work all the time. No, but then all other solutions are equally unreliable 
  1219.                     like comparing friendlyname or signal mode or device type on the transport. 
  1220.                     May be the mediatype of the Source filter should solve the problem, but then maybe not.
  1221. ------------------------------------------------------------------------*/
  1222. BOOL DV_InitDevice(void)
  1223. {
  1224.     BOOL bStatus = FALSE;
  1225.     HRESULT hr;
  1226.     UINT uIndex = 0;
  1227.     ICreateDevEnum *pCreateDevEnum = NULL;
  1228.     // Before we can QI for IAMExtDevice, we need to build a graph and add our filter.
  1229.     
  1230.     // Create Device Enumerator
  1231.     hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER, IID_ICreateDevEnum, reinterpret_cast<PVOID *>(&pCreateDevEnum));
  1232.     if (SUCCEEDED(hr) )
  1233.     {
  1234.         // get the enumerator for videoinput devices
  1235.         IEnumMoniker *pEm;
  1236.         hr = pCreateDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, &pEm, 0);
  1237.         if (SUCCEEDED(hr) && pEm)
  1238.         {
  1239.             pCreateDevEnum->Release();
  1240.             {
  1241.                 pEm->Reset();
  1242.                 ULONG cFetched;
  1243.                 IMoniker *pM;
  1244.                 //loop while we can still enumerate, the enumeration succeeds, and while we have'nt yet found a dv camera
  1245.                 while ( S_OK == (hr = pEm->Next(1, &pM, &cFetched)) && FALSE == bStatus )
  1246.                 {
  1247.                     // getting the propert page to get the device name
  1248.                     IPropertyBag *pBag;
  1249.                     hr = pM->BindToStorage(0, 0, IID_IPropertyBag, reinterpret_cast<PVOID *>(&pBag));
  1250.                     if ( SUCCEEDED(hr) )
  1251.                     {
  1252.                         VARIANT var;
  1253.                         var.vt = VT_BSTR;
  1254.                         hr = pBag->Read(L"FriendlyName", &var, NULL);
  1255.                         if ( SUCCEEDED(hr) )
  1256.                         {
  1257.     //here, we'll save the device name
  1258. #ifndef UNICODE
  1259.                             WideCharToMultiByte(CP_ACP, 0, var.bstrVal, -1, g_DeviceName, DEVICENAME_BUFSIZE,  NULL, NULL);
  1260. #else
  1261.                             lstrcpyW(g_DeviceName, var.bstrVal);
  1262. #endif //UNICODE                        
  1263.                             DV_LogOut(LOG_PRIORITY_INFO, LOG_LEVEL_SUCCINCT, TEXT("Device Found:\t%s"), g_DeviceName);
  1264.                             SysFreeString(var.bstrVal);
  1265.                             // Get the filter of video input device
  1266.                             hr = pM->BindToObject(0, 0, IID_IBaseFilter, reinterpret_cast<PVOID *>(&g_pDVCamera));
  1267.                             if ( g_pDVCamera == NULL )
  1268.                             {
  1269.                                 DV_LogOut(LOG_PRIORITY_ERROR, LOG_LEVEL_SUCCINCT, TEXT("Error %x: Cannot create video capture filter"), hr);
  1270.                                 return FALSE;
  1271.                             }
  1272.                             else
  1273.                             {   // get the graph builder & capture graph builder to QI
  1274.                                 if (DV_GetGraphBuilder())
  1275.                                 {
  1276.                                     hr = CoCreateInstance((REFCLSID)CLSID_CaptureGraphBuilder2,
  1277.                                                 NULL, CLSCTX_INPROC, (REFIID)IID_ICaptureGraphBuilder2,
  1278.                                                 reinterpret_cast<PVOID *>(&g_pBuilder));
  1279.  
  1280.                                     if (SUCCEEDED(hr))
  1281.                                     {
  1282.                                         hr = g_pBuilder->SetFiltergraph(g_pGraphBuilder);
  1283.                                         if (SUCCEEDED(hr))
  1284.                                         {
  1285.                                             //add the DV cam to the graph
  1286.                                             hr = g_pGraphBuilder->AddFilter(g_pDVCamera, var.bstrVal);
  1287.                                             if (SUCCEEDED(hr))
  1288.                                             {   // QI for IAMExtDevice
  1289.                                                 hr = g_pBuilder->FindInterface(&PIN_CATEGORY_CAPTURE,
  1290.                                                                   &MEDIATYPE_Video,  
  1291.                                                                   g_pDVCamera,IID_IAMExtDevice, 
  1292.                                                                   reinterpret_cast<PVOID*>(&g_pExtDev));
  1293.                                                 if (SUCCEEDED(hr))
  1294.                                                 {
  1295.                                                     //we have a DV camera
  1296.                                                     DV_LogOut(LOG_PRIORITY_INFO, LOG_LEVEL_SUCCINCT, TEXT("We Have a DV camera"));
  1297.                                                     bStatus = TRUE;
  1298.                                                 } 
  1299.                                                 else
  1300.                                                 {
  1301.                                                     DV_LogOut(LOG_PRIORITY_INFO, LOG_LEVEL_SUCCINCT, TEXT("This is not a DV camera"));
  1302.                                                     //release our interfaces
  1303.                                                     SAFE_RELEASE(g_pGraphBuilder);
  1304.                                                     SAFE_RELEASE(g_pBuilder);
  1305.                                                     SAFE_RELEASE(g_pDVCamera);
  1306.                                                 }                                                               
  1307.                                             } 
  1308.                                             else
  1309.                                             {
  1310.                                                 DV_LogOut(LOG_PRIORITY_ERROR, LOG_LEVEL_SUCCINCT, TEXT("AddFilter failed hr. = 0x%x"), hr);
  1311.                                             }
  1312.                                         } 
  1313.                                         else
  1314.                                         {
  1315.                                             DV_LogOut(LOG_PRIORITY_ERROR, LOG_LEVEL_SUCCINCT, TEXT("SetFilterGraph failed. hr = 0x%x"), hr);
  1316.                                         }
  1317.                                     }
  1318.                                     else
  1319.                                     {
  1320.                                         DV_LogOut(LOG_PRIORITY_ERROR, LOG_LEVEL_SUCCINCT, TEXT("CoCreateInstance failed (ICaptureGraphbuilder2). hr = 0x%x"), hr);
  1321.                                     } 
  1322.                                 }
  1323.                                 else
  1324.                                 {
  1325.                                     DV_LogOut(LOG_PRIORITY_ERROR, LOG_LEVEL_SUCCINCT, TEXT("DV_GetGraphBuilder failed"));
  1326.                                 } 
  1327.                                 
  1328.                             } //end g_pDVCamera == NULL
  1329.                             
  1330.                         } //end SUCCEEDED(hr)
  1331.                         pBag->Release();
  1332.                     }
  1333.                     pM->Release();
  1334.                     uIndex++;
  1335.                 }
  1336.                 pEm->Release();
  1337.             }
  1338.         }
  1339.         else
  1340.         {
  1341.             // no interesting devices
  1342.             DV_LogOut(LOG_PRIORITY_ERROR, LOG_LEVEL_SUCCINCT, TEXT("CreateClassEnumerator failed or Enumerator was not initialized. hr = 0x%c"), hr);
  1343.             MBOX(TEXT("There are no video devices installed"));
  1344.         } 
  1345.     }
  1346.     return bStatus;
  1347.  
  1348.  
  1349. /*-------------------------------------------------------------------------
  1350. Routine:        DV_GetGraphBuilder
  1351. Purpose:        wrapper to get IGraphBuilder interface pointer
  1352. Arguments:    None
  1353. Returns:        TRUE if successful
  1354. Notes:          
  1355. ------------------------------------------------------------------------*/
  1356. BOOL DV_GetGraphBuilder(void)
  1357. {
  1358.     //if we have one, release it, and make a new one
  1359.     if (g_pGraphBuilder)
  1360.     {
  1361.         g_pGraphBuilder->Release();
  1362.         g_pGraphBuilder = NULL;
  1363.     } 
  1364.     HRESULT hr = CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC, IID_IGraphBuilder, reinterpret_cast<PVOID *>(&g_pGraphBuilder));
  1365.     return (SUCCEEDED(hr)) ? TRUE : FALSE;
  1366. }
  1367.  
  1368. /*-------------------------------------------------------------------------
  1369. Routine:        DV_InitWindow
  1370. Purpose:       Window initialization routine.  This does the following:
  1371.                     - Renders the VideoStream
  1372.                     - makes the app window the output window
  1373.                     - Plays the graph (preview)
  1374. Arguments:    None
  1375. Returns:        TRUE if Everything works - FALSE otherwise
  1376. Notes:          
  1377. ------------------------------------------------------------------------*/
  1378. BOOL DV_InitWindow(void)
  1379. {
  1380.     DV_LogOut(LOG_PRIORITY_INFO, LOG_LEVEL_MEDIUM, TEXT("Entering DV_InitWindow"));
  1381.     BOOL        bStatus = FALSE;
  1382.     HRESULT     hr;
  1383.     // QI for IAMStreamConfig to make sure
  1384.     hr = g_pBuilder->FindInterface(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Interleaved, g_pDVCamera, IID_IAMStreamConfig, reinterpret_cast<PVOID *>(&g_pStreamConf));
  1385.     if (SUCCEEDED(hr))
  1386.     {
  1387.         AM_MEDIA_TYPE *pmt;
  1388.         hr = g_pStreamConf->GetFormat(&pmt); 
  1389.         if (SUCCEEDED(hr))
  1390.         {
  1391.             DeleteMediaType(pmt);
  1392.             // build the default preview graph
  1393.             bStatus = DV_MakeSpecialGraph(GRAPH_PREVIEW);            
  1394.             if (bStatus)
  1395.             {
  1396.                 // update globals, log, toolbar
  1397.                 g_iCurrentGraph = GRAPH_PREVIEW;
  1398.                 DV_LogOut(LOG_PRIORITY_INFO, LOG_LEVEL_SUCCINCT, TEXT("Built Preview Graph"));
  1399.  
  1400.                 SendMessage(g_hwndTBar, TB_SETSTATE, IDM_RECORD, MAKELONG(TBSTATE_INDETERMINATE, 0L));
  1401.                 //re-enable everything else
  1402.                 SendMessage(g_hwndTBar, TB_SETSTATE, IDM_STEP_REV, MAKELONG(TBSTATE_ENABLED, 0L));
  1403.                 SendMessage(g_hwndTBar, TB_SETSTATE, IDM_REW, MAKELONG(TBSTATE_ENABLED, 0L));
  1404.                 SendMessage(g_hwndTBar, TB_SETSTATE, IDM_PLAY_FAST_REV, MAKELONG(TBSTATE_ENABLED, 0L));
  1405.                 SendMessage(g_hwndTBar, TB_SETSTATE, IDM_PLAY_FAST_FF, MAKELONG(TBSTATE_ENABLED, 0L));
  1406.                 SendMessage(g_hwndTBar, TB_SETSTATE, IDM_FF, MAKELONG(TBSTATE_ENABLED, 0L));
  1407.                 SendMessage(g_hwndTBar, TB_SETSTATE, IDM_STEP_FWD, MAKELONG(TBSTATE_ENABLED, 0L));
  1408.                 SendMessage(g_hwndTBar, TB_SETSTATE, IDM_SEEKTIMECODE, MAKELONG(TBSTATE_ENABLED, 0L));              
  1409.             } 
  1410.         }
  1411.         else
  1412.         {
  1413.             DV_LogOut(LOG_PRIORITY_ERROR, LOG_LEVEL_SUCCINCT, TEXT("IAMStreamConfig::GetFormat Failed. hr = 0x%x"), hr);
  1414.         } 
  1415.     }
  1416.     else    
  1417.     {
  1418.         DV_LogOut(LOG_PRIORITY_ERROR, LOG_LEVEL_SUCCINCT, TEXT("Could not get pointer to IAMStreamConfig. hr = 0x%x"), hr);
  1419.     }
  1420.  
  1421.     return bStatus;      
  1422.     
  1423.  
  1424. /*-------------------------------------------------------------------------
  1425. Routine:        DV_MakeSpecialGraph
  1426. Purpose:        Makes any one of the special graphs needed for reading and writing to/from the DVCR
  1427. Arguments:    None
  1428. Returns:        BOOL as appropriate
  1429. Notes:          
  1430. ------------------------------------------------------------------------*/
  1431. BOOL DV_MakeSpecialGraph(GRAPH_TYPE iGraphType)
  1432. {
  1433.     BOOL bStatus = FALSE;
  1434.     HRESULT hr;
  1435.  
  1436.     //track whether the base or source filter is a file or the camera
  1437.     static BOOL bBaseFilterIsFile = FALSE;  
  1438.  
  1439.     // dont rebuild if the required graph already exists
  1440.     if(iGraphType == g_iCurrentGraph && g_pVideoRenderer != NULL)
  1441.     {
  1442.         bStatus = TRUE;
  1443.         return bStatus;
  1444.     }
  1445.  
  1446.     //stop the graph - this should never fail before rebuilding
  1447.     EXECUTE_ASSERT(SUCCEEDED(DV_StopGraph()));
  1448.  
  1449.     //let's look at the current graph
  1450.     //Disconnect everything
  1451.     if (bBaseFilterIsFile)
  1452.     {
  1453.         DV_LogOut(LOG_PRIORITY_INFO, LOG_LEVEL_MEDIUM, TEXT("disonnect downstream from the Filesource"));
  1454.         //DisconnectAll removes only the downstream filters - we need to remove the file filter by hand.
  1455.         DV_DisconnectAll(g_pInputFileFilter);
  1456.         if (g_pInputFileFilter)
  1457.         {
  1458.             hr = g_pGraphBuilder->RemoveFilter(g_pInputFileFilter);
  1459.             SAFE_RELEASE(g_pInputFileFilter);        
  1460.         }
  1461.     } 
  1462.     else
  1463.     {
  1464.         DV_LogOut(LOG_PRIORITY_INFO, LOG_LEVEL_MEDIUM, TEXT("disconnect downstream from the camera"));
  1465.         //DisconnectAll removes only the downstream filters - we need to remove the file filter by hand.
  1466.         DV_DisconnectAll(g_pDVCamera);
  1467.     }
  1468.     DV_LogOut(LOG_PRIORITY_INFO, LOG_LEVEL_VERBOSE, TEXT("Dumping Graph.  Pins should be disconnected"));
  1469.  
  1470.     switch (iGraphType)
  1471.     {
  1472.         // preview
  1473.         case GRAPH_PREVIEW :
  1474.             DV_LogOut(LOG_PRIORITY_INFO, LOG_LEVEL_MEDIUM, TEXT("Building Preview Graph"));
  1475.             // Build the preview graph by rendering via ICaptureGraphBuilder
  1476.             hr = g_pBuilder->RenderStream(&PIN_CATEGORY_PREVIEW, &MEDIATYPE_Video, g_pDVCamera,  NULL, NULL);
  1477.             if (SUCCEEDED(hr))
  1478.             {
  1479.                 hr = DV_SetPreview();
  1480.                 if (SUCCEEDED(hr))
  1481.                 {
  1482.                     bStatus = TRUE;
  1483.                     bBaseFilterIsFile = FALSE;
  1484.                 }
  1485.             } 
  1486.             else
  1487.             {
  1488.                 DV_LogOut(LOG_PRIORITY_ERROR, LOG_LEVEL_SUCCINCT, TEXT("RenderStream Failed. hr = 0x%x"), hr);
  1489.             }               
  1490.             break;
  1491.         //
  1492.         // Each of these type 1 & type 2 capture, transmit graphs have their graph building functions
  1493.         //
  1494.         // Type 1 File (capture & preview)
  1495.         case GRAPH_DV_TO_FILE :
  1496.         {
  1497.             if (SUCCEEDED(DV_MakeDvToFileGraph()))
  1498.             {
  1499.                 bStatus = TRUE;
  1500.                 bBaseFilterIsFile = FALSE;
  1501.             } 
  1502.             break;
  1503.         }
  1504.  
  1505.         // Type 1 File (capture)
  1506.         case GRAPH_DV_TO_FILE_NOPRE :
  1507.         {
  1508.             if (SUCCEEDED(DV_MakeDvToFileGraph_NoPre()))
  1509.             {
  1510.                 bStatus = TRUE;
  1511.                 bBaseFilterIsFile = FALSE;
  1512.             } 
  1513.             break;
  1514.         }
  1515.  
  1516.         // Type 1 File (transmit & playback)
  1517.         case GRAPH_FILE_TO_DV :
  1518.         {
  1519.             DV_LogOut(LOG_PRIORITY_INFO, LOG_LEVEL_MEDIUM, TEXT("Building Type 1 File to DV with Preview Graph"));
  1520.             if (SUCCEEDED(DV_MakeFileToDvGraph()))
  1521.             {
  1522.                 bBaseFilterIsFile = TRUE;  
  1523.                 bStatus = TRUE;
  1524.             } 
  1525.             break;
  1526.         }
  1527.         
  1528.         // Type 1 File (transmit)
  1529.         case GRAPH_FILE_TO_DV_NOPRE :
  1530.         {
  1531.             DV_LogOut(LOG_PRIORITY_INFO, LOG_LEVEL_MEDIUM, TEXT("Building Type 1 File to DV without Preview Graph"));
  1532.             if (SUCCEEDED(DV_MakeFileToDvGraph_NoPre()))
  1533.             {
  1534.                 bBaseFilterIsFile = TRUE;  
  1535.                 bStatus = TRUE;
  1536.             } 
  1537.             break;
  1538.         }
  1539.         
  1540.         // Type 2 File (capture & preview)
  1541.         case GRAPH_DV_TO_FILE_TYPE2 :
  1542.         {
  1543.             if (SUCCEEDED(DV_MakeDvToFileGraph_Type2()))
  1544.             {
  1545.                 bStatus = TRUE;
  1546.                 bBaseFilterIsFile = FALSE;
  1547.  
  1548.             } 
  1549.             break;
  1550.         }
  1551.  
  1552.         // Type 2 File (capture)
  1553.         case GRAPH_DV_TO_FILE_NOPRE_TYPE2 :
  1554.         {
  1555.             if (SUCCEEDED(DV_MakeDvToFileGraph_NoPre_Type2()))
  1556.             {
  1557.                 bStatus = TRUE;
  1558.                 bBaseFilterIsFile = FALSE;
  1559.             } 
  1560.             break;
  1561.         }
  1562.  
  1563.         // Type 2 File (transmit & playback)
  1564.         case GRAPH_FILE_TO_DV_TYPE2 :
  1565.         {
  1566.             DV_LogOut(LOG_PRIORITY_INFO, LOG_LEVEL_MEDIUM, TEXT("Building Type 2 File to DV with Preview Graph"));
  1567.             if (SUCCEEDED(DV_MakeFileToDvGraph_Type2()))
  1568.             {
  1569.                 bBaseFilterIsFile = TRUE;  
  1570.                 bStatus = TRUE;
  1571.             } 
  1572.             break;
  1573.         }
  1574.  
  1575.         // Type 2 File (transmit)
  1576.         case GRAPH_FILE_TO_DV_NOPRE_TYPE2 :
  1577.         {
  1578.             DV_LogOut(LOG_PRIORITY_INFO, LOG_LEVEL_MEDIUM, TEXT("Building Type 2 File to DV without Preview Graph"));
  1579.             if (SUCCEEDED(DV_MakeFileToDvGraph_NoPre_Type2()))
  1580.             {
  1581.                 bBaseFilterIsFile = TRUE;  
  1582.                 bStatus = TRUE;
  1583.             } 
  1584.             break;
  1585.         }
  1586.         
  1587.         default :
  1588.             // wrong graph type
  1589.             DV_LogOut(LOG_PRIORITY_ERROR, LOG_LEVEL_SUCCINCT, TEXT("Invalid paramater passed to DV_MakeSpecialGraph"));
  1590.             return bStatus;
  1591.     } 
  1592.  
  1593.     // make sure you select MSDV as the master clock and not any of the renderers
  1594.     hr = DV_SelectClock(g_pDVCamera);
  1595.     return bStatus;
  1596.  
  1597. /*-------------------------------------------------------------------------
  1598. Routine:        DV_SelectClock
  1599. Purpose:        Selects the Clock of the Filter sets it to be the clock of the Graph
  1600. Arguments:    Filter to be selected
  1601. Returns:        HResult as appropriate
  1602. Notes:          
  1603. ------------------------------------------------------------------------*/
  1604. HRESULT DV_SelectClock(IBaseFilter *pBaseFilter)
  1605. {
  1606.     HRESULT hr = S_OK;
  1607.     IReferenceClock *pRefClock      = NULL;
  1608.     IMediaFilter *pMediaFilter      = NULL;
  1609.  
  1610.     if(pBaseFilter == NULL)
  1611.         return E_POINTER;
  1612.     // QI for IReferenceClock on the specified filter
  1613.     hr = pBaseFilter->QueryInterface(IID_IReferenceClock, reinterpret_cast<PVOID *> (&pRefClock));
  1614.     // QI for IMediaFilter from the graph builder
  1615.     hr = g_pGraphBuilder->QueryInterface(IID_IMediaFilter, reinterpret_cast<PVOID *> (&pMediaFilter));
  1616.     if(pMediaFilter != NULL && pRefClock != NULL)
  1617.     {
  1618.         // set the clock of the specified filter on the filtergraph builder
  1619.         hr = pMediaFilter->SetSyncSource(pRefClock);
  1620.     }
  1621.     else
  1622.         hr = E_POINTER;
  1623.  
  1624.     SAFE_RELEASE(pMediaFilter);
  1625.     SAFE_RELEASE(pRefClock);
  1626.     return hr;
  1627. }       
  1628.  
  1629.  
  1630. /*-------------------------------------------------------------------------
  1631. Routine:        DV_StartGraph
  1632. Purpose:        Starts the Filter Graph 
  1633. Arguments:    None
  1634. Returns:        HResult as appropriate
  1635. Notes:          
  1636. ------------------------------------------------------------------------*/
  1637. HRESULT DV_StartGraph(void)
  1638. {
  1639.     HRESULT hr;
  1640.     IMediaControl *pMC = NULL;
  1641.  
  1642.     // QI for the media control 
  1643.     if(!g_pGraphBuilder)
  1644.         return S_FALSE;
  1645.     hr = g_pGraphBuilder->QueryInterface(IID_IMediaControl, reinterpret_cast<PVOID *>(&pMC));
  1646.     if (SUCCEEDED(hr))
  1647.     {
  1648.         // start the graph
  1649.         hr = pMC->Run();
  1650.         if ( FAILED(hr))
  1651.         {
  1652.             DV_LogOut(LOG_PRIORITY_INFO, LOG_LEVEL_MEDIUM, TEXT("IMediaControl::Run failed (0x%x)"), hr);
  1653.             // stop parts that ran
  1654.             pMC->Stop();
  1655.         }
  1656.         SAFE_RELEASE(pMC);
  1657.     }
  1658.     return hr;
  1659. }
  1660.  
  1661. /*-------------------------------------------------------------------------
  1662. Routine:        DV_PauseGraph
  1663. Purpose:        Starts the Filter Graph 
  1664. Arguments:    None
  1665. Returns:        HResult as appropriate
  1666. Notes:          
  1667. ------------------------------------------------------------------------*/
  1668. HRESULT DV_PauseGraph(void)
  1669. {
  1670.     HRESULT hr;
  1671.     IMediaControl *pMC = NULL;
  1672.     
  1673.     if(!g_pGraphBuilder)
  1674.         return S_FALSE;
  1675.     // QI for the media control 
  1676.     hr = g_pGraphBuilder->QueryInterface(IID_IMediaControl, reinterpret_cast<PVOID *>(&pMC));
  1677.     if (SUCCEEDED(hr))
  1678.     {
  1679.         // Pause the graph
  1680.         hr = pMC->Pause();
  1681.         if ( FAILED(hr))
  1682.         {
  1683.             DV_LogOut(LOG_PRIORITY_INFO, LOG_LEVEL_MEDIUM, TEXT("IMediaControl::Pause failed (0x%x)"), hr);
  1684.             // stop parts that ran
  1685.             pMC->Stop();
  1686.         }
  1687.         SAFE_RELEASE(pMC);
  1688.     }
  1689.     return hr;
  1690. }
  1691.  
  1692.  
  1693. /*-------------------------------------------------------------------------
  1694. Routine:        DV_StopGraph
  1695. Purpose:        Starts the Filter Graph 
  1696. Arguments:    None
  1697. Returns:        HResult as appropriate
  1698. Notes:          
  1699. ------------------------------------------------------------------------*/
  1700. HRESULT DV_StopGraph(void)
  1701. {
  1702.     HRESULT hr;
  1703.     IMediaControl *pMC = NULL;
  1704.  
  1705.     if(!g_pGraphBuilder)
  1706.         return S_FALSE;
  1707.     //stop the current graph
  1708.     hr = g_pGraphBuilder->QueryInterface(IID_IMediaControl, reinterpret_cast<PVOID *>(&pMC));
  1709.     if (SUCCEEDED(hr))
  1710.     {
  1711.         hr = pMC->Stop();
  1712.         SAFE_RELEASE(pMC);
  1713.     }
  1714.     return hr;
  1715. }
  1716.  
  1717. /*-------------------------------------------------------------------------
  1718. Routine:        DV_DisconnectAll
  1719. Purpose:        Disconnects all pins in a graph (downstream from pBF)   
  1720. Arguments:    pointer to the filter to disconnect pins from (downstream only)
  1721. Returns:        None
  1722. Notes:          This is the recursive nuke downstream routine from amcap
  1723. ------------------------------------------------------------------------*/
  1724. void DV_DisconnectAll(IBaseFilter *pBF)
  1725. {
  1726.     IPin *pP, *pTo;
  1727.     ULONG u;
  1728.     IEnumPins *pins = NULL;
  1729.     PIN_INFO pininfo;
  1730.  
  1731.     ASSERT(g_pGraphBuilder);
  1732.     DV_LogOut(LOG_PRIORITY_INFO, LOG_LEVEL_VERBOSE, TEXT("Disconnecting Pins..."));
  1733.    
  1734.     HRESULT hr = pBF->EnumPins(&pins);
  1735.     pins->Reset();
  1736.     while ( hr == NOERROR )
  1737.     {
  1738.         hr = pins->Next(1, &pP, &u);
  1739.         if ( hr == S_OK && pP )
  1740.         {
  1741.             pP->ConnectedTo(&pTo);
  1742.             if ( pTo )
  1743.             {
  1744.                 hr = pTo->QueryPinInfo(&pininfo);
  1745.                 if ( hr == NOERROR )
  1746.                 {
  1747.                     if ( pininfo.dir == PINDIR_INPUT )
  1748.                     {
  1749.                         DV_DisconnectAll(pininfo.pFilter);
  1750.                         hr = g_pGraphBuilder->Disconnect(pTo);
  1751.                         hr = g_pGraphBuilder->Disconnect(pP);
  1752.  
  1753.                         //always leave the Camera filter in the graph
  1754.                         //if the base filter is a file,the camera is downstream
  1755.                         if (pininfo.pFilter != g_pDVCamera)
  1756.                         {
  1757.                             hr = g_pGraphBuilder->RemoveFilter(pininfo.pFilter);
  1758.                         }
  1759.                     }
  1760.                     ASSERT(pininfo.pFilter);
  1761.                     SAFE_RELEASE(pininfo.pFilter);
  1762.                 }
  1763.                 ASSERT(pTo);
  1764.                 SAFE_RELEASE(pTo);
  1765.             }
  1766.             ASSERT(pP);
  1767.             SAFE_RELEASE(pP);
  1768.         }
  1769.     }
  1770.     if ( pins )
  1771.         SAFE_RELEASE(pins);
  1772.  
  1773.  
  1774. /*-------------------------------------------------------------------------
  1775. Routine:        DV_CleanUp
  1776. Purpose:        writes values to the registry, releases all used interfaces. Uninitializes com and the dshow debug stuff
  1777. Arguments:    None
  1778. Returns:        None
  1779. Notes:          
  1780. ------------------------------------------------------------------------*/
  1781. void DV_CleanUp(void)
  1782. {
  1783.  
  1784.     DV_WriteRegKeys();
  1785.  
  1786.     // release helper dshow interfaces
  1787.     SAFE_RELEASE(g_pBuilder);
  1788.     SAFE_RELEASE(g_pExtDev);
  1789.     SAFE_RELEASE(g_pStreamConf);
  1790.     SAFE_RELEASE(g_pExtTrans);
  1791.     SAFE_RELEASE(g_pTimeReader);
  1792.     SAFE_RELEASE(g_pDroppedFrames);
  1793.     SAFE_RELEASE(g_pGraphBuilder);
  1794.  
  1795.     // release the filters of the graph    
  1796.     SAFE_RELEASE(g_pDVCamera);    
  1797.     SAFE_RELEASE(g_pVideoWindow);
  1798.     SAFE_RELEASE(g_pInputFileFilter);
  1799.     SAFE_RELEASE(g_pInfTee);
  1800.     SAFE_RELEASE(g_pVideoRenderer);
  1801.     SAFE_RELEASE(g_pAviSplitter);
  1802.     SAFE_RELEASE(g_pDVSplitter); 
  1803.     SAFE_RELEASE(g_pDVCodec);
  1804.     SAFE_RELEASE(g_pDvDec);
  1805.     SAFE_RELEASE(g_pDVMux);
  1806.     SAFE_RELEASE(g_pSmartTee);     
  1807.     SAFE_RELEASE(g_pDSound);
  1808.  
  1809.     CoUninitialize();
  1810.  
  1811.  
  1812. /*-------------------------------------------------------------------------
  1813. Routine:        DV_SetPreview
  1814. Purpose:        Hooks up stream  *from camera* to preview window
  1815.                     Note that the preview for the playback from the file is handled within DV_MakeFileToDvGraph() stuff
  1816. Arguments:    None
  1817. Returns:        HRESULT as appropriate
  1818. Notes:          
  1819. ------------------------------------------------------------------------*/
  1820. HRESULT DV_SetPreview(void)
  1821. {
  1822.     HRESULT hr = S_OK;
  1823.  
  1824.     if (g_pVideoWindow)
  1825.     {   // dismantle the current video window
  1826.         g_pVideoWindow->put_Owner(NULL);
  1827.         SAFE_RELEASE(g_pVideoWindow);
  1828.     } 
  1829.  
  1830.     // get the video window and set it up for the preview
  1831.     hr = g_pBuilder->FindInterface(NULL, &MEDIATYPE_Video, g_pDVCamera, IID_IVideoWindow, reinterpret_cast<PVOID *>(&g_pVideoWindow));
  1832.     if (SUCCEEDED(hr))
  1833.     {        
  1834.         RECT rc, rect;
  1835.         g_pVideoWindow->put_Owner((LONG_PTR)g_hwndApp);     // We own the window now
  1836.         g_pVideoWindow->put_WindowStyle(WS_CHILD);     // you are now a child
  1837.  
  1838.         // give the preview window all our space but where the tool bar and status bar are        
  1839.         GetClientRect(g_hwndApp, &rc);
  1840.         GetWindowRect(g_hwndTBar, &rect);
  1841.  
  1842.         //g_pVideoWindow->SetWindowPosition(0, rect.bottom - rect.top, rc.right, 
  1843.         //      (rc.bottom - (g_statusHeight + GetSystemMetrics(SM_CYBORDER)) - (rect.bottom - rect.top)));
  1844.  
  1845.         g_pVideoWindow->SetWindowPosition(0, rect.bottom - rect.top, g_iVWWidth, g_iVWHeight);
  1846.         g_pVideoWindow->put_Visible(OATRUE);
  1847.     }
  1848.     else
  1849.     {
  1850.         DV_LogOut(LOG_PRIORITY_ERROR, LOG_LEVEL_SUCCINCT, TEXT("FindInterface (IVideoWindow) Failed. hr = 0x%x"), hr);
  1851.     }
  1852.  
  1853.     return hr;
  1854.  
  1855. /*-------------------------------------------------------------------------
  1856. Routine:        DV_GetDVMode
  1857. Purpose:        Determines camera mode using IAMExtDevice::GetCapability()
  1858. Arguments:    None
  1859. Returns:        Current mode of camera device
  1860. Notes:          
  1861. ------------------------------------------------------------------------*/
  1862. DV_MODE DV_GetDVMode(void)
  1863. {
  1864.     HRESULT hr = S_OK;
  1865.     LONG    lDeviceType = 0;
  1866.  
  1867.     ASSERT(g_pExtDev);
  1868.     //  Query the Device Type Capability
  1869.     hr = g_pExtDev->GetCapability(ED_DEVCAP_DEVICE_TYPE, &lDeviceType, 0);
  1870.     if (SUCCEEDED(hr))
  1871.     {
  1872.         switch (lDeviceType)
  1873.         {
  1874.             case 0 :
  1875.                 //device type is unknown
  1876.                 g_CurrentMode = UnknownMode;
  1877.                 break;
  1878.  
  1879.             case ED_DEVTYPE_VCR :
  1880.                 g_CurrentMode = VcrMode;
  1881.                 break;
  1882.  
  1883.             case ED_DEVTYPE_CAMERA :
  1884.                 g_CurrentMode = CameraMode;
  1885.                 break;
  1886.  
  1887.             default :
  1888.                 DV_LogOut(LOG_PRIORITY_ERROR, LOG_LEVEL_SUCCINCT, TEXT("GetCapability returned an unknown device type - 0x%x"), lDeviceType);
  1889.                 break;
  1890.         } 
  1891.     }
  1892.     return g_CurrentMode;
  1893.  
  1894. /*-------------------------------------------------------------------------
  1895. Routine:        DV_TimecodeTimerProc
  1896. Purpose:        Callback function for the timer proc
  1897. Arguments:    Usual Timer Processing Parameters
  1898. Returns:        None
  1899. Notes:          
  1900. ------------------------------------------------------------------------*/
  1901. void CALLBACK DV_TimecodeTimerProc(HWND hwnd, UINT uMsg, UINT idEvent, DWORD dwTime)
  1902. {
  1903.     DV_DisplayTimecode();
  1904.  
  1905. /*-------------------------------------------------------------------------
  1906. Routine:        DV_StopRecProc
  1907. Purpose:        Callback to stop recording after a specified time
  1908. Arguments:    Usual Timer Processing Parameters
  1909. Returns:        None
  1910. Notes:          
  1911. ------------------------------------------------------------------------*/
  1912. void CALLBACK DV_StopRecProc(HWND hwnd, UINT uMsg, UINT idEvent, DWORD dwTime)
  1913. {
  1914.     SendMessage(g_hwndApp, WM_COMMAND, IDM_STOP, 0);
  1915.  
  1916.  
  1917. /*-------------------------------------------------------------------------
  1918. Routine:        DV_GetFinalDroppedFramesStats
  1919. Purpose:        Get Final dropped frames stats for status bar display
  1920. Arguments:    DWORD current time
  1921. Returns:        None
  1922. Notes:          For both Capture & Transmit graphs
  1923. ------------------------------------------------------------------------*/
  1924. void DV_GetFinalDroppedFramesStats(DWORD dwTime)
  1925. {
  1926.     BOOL bIsModeTransmit = TRUE;
  1927.     // determine if the current graph is a transmit graph
  1928.     if (GRAPH_DV_TO_FILE_NOPRE == g_iCurrentGraph || GRAPH_DV_TO_FILE == g_iCurrentGraph ||
  1929.                 GRAPH_DV_TO_FILE_TYPE2 == g_iCurrentGraph || GRAPH_DV_TO_FILE_NOPRE_TYPE2 == g_iCurrentGraph)
  1930.         bIsModeTransmit = FALSE;
  1931.  
  1932.     // make sure the interface exists ans can be queried the stats
  1933.     if (g_pDroppedFrames)
  1934.     {
  1935.         HRESULT hr = S_OK;
  1936.         long dropped = 0, notdropped = 0, lAvgFrameSize = 0;
  1937.         TCHAR buffer[128];
  1938.         DWORD time = dwTime - g_CapStartTime;
  1939.  
  1940.         // Get the required stats
  1941.         hr = g_pDroppedFrames->GetNumDropped(&dropped);
  1942.         hr = g_pDroppedFrames->GetNumNotDropped(¬dropped);
  1943.         hr = g_pDroppedFrames->GetAverageFrameSize(&lAvgFrameSize);
  1944.         
  1945.         if (SUCCEEDED(hr) && time != 0)
  1946.         {   
  1947.             double  framerate = 0;      // acheived frame rate
  1948.             LONG    lData     = 0;      // acheived data rate
  1949.             // Calculate other stats
  1950.             framerate = (double)(LONGLONG)notdropped * 1000. / (double)(LONGLONG)time;
  1951.             lData = (LONG)(LONGLONG)(notdropped / (double)(LONGLONG)time * 1000. * (double)(LONGLONG)lAvgFrameSize);
  1952.             if(bIsModeTransmit)
  1953.                 wsprintf(buffer, TEXT("Transmitted %d frames (%d dropped) %d.%d sec. %d.%d fps %d.%d Meg/sec"), 
  1954.                              notdropped, dropped, time / 1000, time / 100 - time / 1000 * 10,
  1955.                              (int)framerate, (int)(framerate * 10.) - (int)framerate * 10, 
  1956.                              lData / 1000000, lData / 1000 - (lData / 1000000 * 1000));
  1957.             else
  1958.                 wsprintf(buffer, TEXT("Captured %d frames (%d dropped) %d.%d sec. %d.%d fps %d.%d Meg/sec"), 
  1959.                              notdropped, dropped, time / 1000, time / 100 - time / 1000 * 10,
  1960.                              (int)framerate, (int)(framerate * 10.) - (int)framerate * 10, 
  1961.                              lData / 1000000, lData / 1000 - (lData / 1000000 * 1000));
  1962.             // update the status bar with the gathered info        
  1963.             DV_StatusText(buffer, 1);
  1964.         }
  1965.         else
  1966.            {
  1967.                DV_StatusText(TEXT("Cannot report dropped frame information"), 1);
  1968.         } 
  1969.     }
  1970. }    
  1971.  
  1972. /*-------------------------------------------------------------------------
  1973. Routine:        DV_DroppedFrameProc
  1974. Purpose:        Callback proc to display dropped frame info
  1975. Arguments:    DWORD current time
  1976. Returns:        None
  1977. Notes:          For both Capture & Transmit graphs
  1978. ------------------------------------------------------------------------*/
  1979. void CALLBACK DV_DroppedFrameProc(HWND hwnd, UINT uMsg, UINT idEvent, DWORD dwTime)
  1980. {
  1981.     HRESULT hr = S_OK;
  1982.     long dropped = 0, notdropped = 0;
  1983.     TCHAR buffer[128];
  1984.     DWORD time = dwTime - g_CapStartTime;
  1985.     BOOL bIsModeTransmit = TRUE;
  1986.  
  1987.     // if the dropped frames interface does not already exist, query now!
  1988.     if (NULL == g_pDroppedFrames) {
  1989.         if (GRAPH_DV_TO_FILE == g_iCurrentGraph || GRAPH_DV_TO_FILE_NOPRE == g_iCurrentGraph ||
  1990.             GRAPH_DV_TO_FILE_TYPE2 == g_iCurrentGraph || GRAPH_DV_TO_FILE_NOPRE_TYPE2 == g_iCurrentGraph)
  1991.         {
  1992.             hr = g_pBuilder->FindInterface(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Interleaved, g_pDVCamera, IID_IAMDroppedFrames, reinterpret_cast<PVOID *>(&g_pDroppedFrames));
  1993.             bIsModeTransmit = FALSE;
  1994.         }
  1995.         else if (GRAPH_FILE_TO_DV == g_iCurrentGraph || GRAPH_FILE_TO_DV_NOPRE == g_iCurrentGraph ||
  1996.             GRAPH_FILE_TO_DV_TYPE2 == g_iCurrentGraph || GRAPH_FILE_TO_DV_NOPRE_TYPE2 == g_iCurrentGraph)
  1997.         {
  1998.             IPin *pAVIn = NULL;
  1999.              hr = g_pBuilder->FindPin(g_pDVCamera, PINDIR_INPUT, NULL, NULL, FALSE, 0, &pAVIn);
  2000.             if(SUCCEEDED(hr) && pAVIn != NULL)
  2001.                 hr = pAVIn->QueryInterface(IID_IAMDroppedFrames, reinterpret_cast<PVOID *>(&g_pDroppedFrames));
  2002.             else 
  2003.                 DV_LogOut(LOG_PRIORITY_ERROR, LOG_LEVEL_SUCCINCT, TEXT("Could not get Input Pin for obtaining Dropped Frames Statistics"));
  2004.         }
  2005.         else
  2006.         {
  2007.             //we shouldn't get here as we dont call for the dropped frames in preview graph
  2008.             DV_LogOut(LOG_PRIORITY_ERROR, LOG_LEVEL_SUCCINCT, TEXT("Undefined graph mode (maybe GRAPH_PREVIEW) while obtaining Dropped Frames"));
  2009.         } 
  2010.     }
  2011.  
  2012.     if (SUCCEEDED(hr))
  2013.     {
  2014.         // Get the stats once the interface is successfully obtained
  2015.         hr = g_pDroppedFrames->GetNumDropped(&dropped);
  2016.         hr = g_pDroppedFrames->GetNumNotDropped(¬dropped);
  2017.         if (SUCCEEDED(hr))
  2018.         {          
  2019.             if(bIsModeTransmit)
  2020.                 wsprintf(buffer, TEXT("Transmitted %d frames (%d dropped) %d.%d sec."), notdropped, dropped, time / 1000, time / 100 - time / 1000 * 10);
  2021.             else
  2022.                    wsprintf(buffer, TEXT("Captured %d frames (%d dropped) %d.%d sec."), notdropped, dropped, time / 1000, time / 100 - time / 1000 * 10);
  2023.             // update the status bar
  2024.             DV_StatusText(buffer, 1);
  2025.         }
  2026.         else
  2027.         {
  2028.             DV_StatusText(TEXT("Cannot report dropped frame information"), 1);
  2029.         } 
  2030.     } 
  2031.     else
  2032.     {
  2033.            DV_LogOut(LOG_PRIORITY_ERROR, LOG_LEVEL_SUCCINCT, TEXT("Could not get IAMDroppedFrames interface"));
  2034.         KillTimer(hwnd, DV_TIMER_FRAMES);
  2035.     } 
  2036.  
  2037.  
  2038.  
  2039.  
  2040. /*-------------------------------------------------------------------------
  2041. Routine:        DV_DisplayTimecode
  2042. Purpose:        Routine to display timecodes
  2043. Arguments:    None
  2044. Returns:        None
  2045. Notes:          This is TimeCode Read not Absolute Track Number Read
  2046. ------------------------------------------------------------------------*/
  2047. void DV_DisplayTimecode(void)
  2048. {
  2049.     TIMECODE_SAMPLE TimecodeSample;
  2050.     TimecodeSample.timecode.dwFrames = 0;
  2051.     static DWORD i1 = 0, i2 = 0, i3 = 0;
  2052.  
  2053.     TimecodeSample.dwFlags = ED_DEVCAP_TIMECODE_READ;
  2054.     // Query the TimeCode sample data
  2055.     HRESULT hr = g_pTimeReader->GetTimecode(&TimecodeSample);
  2056.     TCHAR szBuf[4];
  2057.  
  2058.     if (SUCCEEDED(hr))
  2059.     {
  2060.         // It's worth it to spend a few extra cycles, and to store the static variables
  2061.         // to avoid calling wsprintf and setwindowtext on every timer tick.
  2062.         if (i1 != (TimecodeSample.timecode.dwFrames & 0xff000000) >> 24)
  2063.         {
  2064.             wsprintf(szBuf, TEXT("%.2x"),((TimecodeSample.timecode.dwFrames & 0xff000000) >> 24));
  2065.             SetDlgItemText(g_hwndTBar, IDC_EDIT_HOUR, szBuf);
  2066.         } 
  2067.         i1 = (TimecodeSample.timecode.dwFrames & 0xff000000) >> 24;
  2068.  
  2069.         if (i2 != (TimecodeSample.timecode.dwFrames & 0x00ff0000) >> 16)
  2070.         {
  2071.             wsprintf(szBuf, TEXT("%.2x"),((TimecodeSample.timecode.dwFrames & 0x00ff0000) >> 16));
  2072.             SetDlgItemText(g_hwndTBar, IDC_EDIT_MINUTE, szBuf);
  2073.         } 
  2074.         i2 = (TimecodeSample.timecode.dwFrames & 0x00ff0000) >> 16;
  2075.         
  2076.         if (i3 != (TimecodeSample.timecode.dwFrames & 0x0000ff00) >>  8)
  2077.         {
  2078.             wsprintf(szBuf, TEXT("%.2x"),((TimecodeSample.timecode.dwFrames & 0x0000ff00) >>  8));
  2079.             SetDlgItemText(g_hwndTBar, IDC_EDIT_SECOND, szBuf);
  2080.         } 
  2081.         i3 = (TimecodeSample.timecode.dwFrames & 0x0000ff00) >>  8;
  2082.  
  2083.         //always update the toolbar display
  2084.         wsprintf(szBuf, TEXT("%.2x"),(TimecodeSample.timecode.dwFrames & 0x000000ff));
  2085.         SetDlgItemText(g_hwndTBar, IDC_EDIT_FRAME, szBuf);
  2086.     }
  2087.     else
  2088.     {
  2089.         DV_LogOut(LOG_PRIORITY_WARN, LOG_LEVEL_MEDIUM, TEXT("Failed to get Timecodesample.  hr = 0x%x"), hr);
  2090.     } 
  2091.  
  2092.  
  2093. /*-------------------------------------------------------------------------
  2094. Routine:        DV_SeekATN
  2095. Purpose:        ATN Seek function - uses GetTransportBasicParameters to send RAW AVC command 
  2096. Arguments:    None
  2097. Returns:        TRUE if successful
  2098. Notes:          This is Absolute Track Number Seek not TimeCode Seek but uses the timecode display as input
  2099. ------------------------------------------------------------------------*/
  2100. BOOL DV_SeekATN(void)
  2101. {
  2102.     BOOL bStatus = FALSE;
  2103.     HRESULT hr = S_OK;
  2104.     int iHr, iMn, iSc, iFr;
  2105.     ULONG ulTrackNumToSearch;
  2106.     long iCnt = 8;
  2107.     // ATN Seek Raw AVC Command 
  2108.     BYTE RawAVCPkt[8] = {0x00, 0x20, 0x52, 0x20, 0xff, 0xff, 0xff, 0xff};
  2109.  
  2110.     //get the values from the edit fields
  2111.     iHr = GetDlgItemInt(g_hwndTBar, IDC_EDIT_HOUR,   &bStatus, FALSE);
  2112.     iMn = GetDlgItemInt(g_hwndTBar, IDC_EDIT_MINUTE, &bStatus, FALSE);
  2113.     iSc = GetDlgItemInt(g_hwndTBar, IDC_EDIT_SECOND, &bStatus, FALSE);
  2114.     iFr = GetDlgItemInt(g_hwndTBar, IDC_EDIT_FRAME,  &bStatus, FALSE);
  2115.  
  2116.     if ((iHr < 60) && (iMn < 60) && (iSc < 60) && (iFr <=30))
  2117.     {
  2118.         //Calculate the ATN
  2119.         if (g_AvgTimePerFrame == 40) 
  2120.         {
  2121.             ulTrackNumToSearch = ((iMn * 60 + iSc) * 25 + iFr) * 12 * 2;
  2122.         } 
  2123.         else 
  2124.         {
  2125.             // Drop two frame every minutes
  2126.             ulTrackNumToSearch = ((iMn * 60 + iSc) * 30 + iFr - ((iMn - (iMn / 10)) * 2)) * 10 * 2;
  2127.         }
  2128.         // Update the Raw AVC Command query
  2129.         RawAVCPkt[4] = (BYTE)  (ulTrackNumToSearch & 0x000000ff);
  2130.         RawAVCPkt[5] = (BYTE) ((ulTrackNumToSearch & 0x0000ff00) >> 8);
  2131.         RawAVCPkt[6] = (BYTE) ((ulTrackNumToSearch & 0x00ff0000) >> 16);
  2132.         
  2133.         // RAW AVC Call
  2134.         hr = g_pExtTrans->GetTransportBasicParameters(ED_RAW_EXT_DEV_CMD, &iCnt, (LPOLESTR *)RawAVCPkt);
  2135.         Sleep(_MAX_SLEEP*6);
  2136.         if (SUCCEEDED(hr))
  2137.         {
  2138.             bStatus = TRUE;
  2139.         }
  2140.         else
  2141.         {
  2142.             DV_LogOut(LOG_PRIORITY_ERROR, LOG_LEVEL_SUCCINCT, TEXT("Seek to a TimeCode Location failed"));
  2143.         }
  2144.     }
  2145.     else
  2146.     {
  2147.         MBOX(TEXT("Invalid Parameter - Time entered should be:\nHour:Minute:Second:Frame"));
  2148.     } 
  2149.     return bStatus;
  2150.  
  2151. /*---------------------------------------------------------------------------------------------------------
  2152. Routine:        DV_MakeDvToFileGraph
  2153. Purpose:        Builds and runs the DV to File graph
  2154. Arguments:    None
  2155. Returns:        HRESULT as apropriate
  2156. Notes:          This is a capture & preview graph for DV Type 1 AVI files           
  2157.                     This graph is a bit more complex.  It looks like this:
  2158.                     DV_Cam(AV Out)->SmartTee(capture)->AviMux->FileWriter
  2159.                                                 SmartTee(preview)->DVSplitter(vid)->DVCodec->VideoWindow
  2160.                                                                                 DVSplitter(aud)->Default DirectSound device
  2161. ---------------------------------------------------------------------------------------------------------*/
  2162. HRESULT DV_MakeDvToFileGraph(void)
  2163. {
  2164.     HRESULT hr = S_OK;
  2165.     DV_LogOut(LOG_PRIORITY_INFO, LOG_LEVEL_MEDIUM, TEXT("Building DV to File Graph"));
  2166.     // making sure there is a output file selected
  2167.     if (!g_OutputFileName[0])
  2168.     {
  2169.         MBOX(TEXT("Please set up an output file name for recording"));
  2170.         hr = E_FAIL;
  2171.     } 
  2172.     else
  2173.     {
  2174.         DV_LogOut(LOG_PRIORITY_INFO, LOG_LEVEL_VERBOSE, TEXT("This is the graph - everything should be disconnected"));
  2175.  
  2176. #ifndef UNICODE        
  2177.         // convert the output file name to wchar
  2178.         WCHAR wFileName[MAX_PATH];
  2179.         MultiByteToWideChar(CP_ACP, 0, g_OutputFileName, -1, wFileName, MAX_PATH);
  2180. #endif
  2181.  
  2182.         //we need a lot of pins to make this work...
  2183.         IPin *pAVOut = NULL, *pTeeIn = NULL, *pTeeOut = NULL, *pMuxIn = NULL, *pTeePreOut = NULL, *pSplitIn = NULL;
  2184.         IPin *pSplitVout = NULL, *pSplitAout = NULL, *pAudIn = NULL, *pCodecIn = NULL, *pCodecOut = NULL, *pRenderIn = NULL;
  2185.  
  2186.         //get the camera output pin
  2187.         hr = g_pBuilder->FindPin(g_pDVCamera, PINDIR_OUTPUT, NULL, &MEDIATYPE_Interleaved, TRUE, 0, &pAVOut);
  2188.         //add the smart tee filter, get the smart tee input pin and connect it to the DV Cam AV out
  2189.         if (SUCCEEDED(hr))
  2190.         {
  2191.             g_pGraphBuilder->AddFilter(g_pSmartTee, L"Smart Tee");           
  2192.             hr = g_pBuilder->FindPin(g_pSmartTee, PINDIR_INPUT, NULL, NULL, TRUE, 0, &pTeeIn);
  2193.             if (SUCCEEDED(hr))
  2194.             {
  2195.                 hr = g_pGraphBuilder->ConnectDirect(pAVOut, pTeeIn, NULL);
  2196.                 if (SUCCEEDED(hr))
  2197.                 {
  2198.                     // get the capture output pin of smart tee and connect it to avi muxer & file writer
  2199.                     hr = g_pBuilder->FindPin(g_pSmartTee, PINDIR_OUTPUT, NULL, NULL, TRUE, 0, &pTeeOut);
  2200.                     if (SUCCEEDED(hr))
  2201.                     {
  2202.                         //add the avimux, and file writer to the graph 
  2203.                         IBaseFilter *ppf = NULL;
  2204.                         IFileSinkFilter *pSink = NULL;
  2205. #ifndef UNICODE
  2206.                         hr = g_pBuilder->SetOutputFileName(&MEDIASUBTYPE_Avi, wFileName, &ppf, &pSink);
  2207. #else
  2208.                         hr = g_pBuilder->SetOutputFileName(&MEDIASUBTYPE_Avi, g_OutputFileName, &ppf, &pSink);
  2209. #endif //UNICODE
  2210.                         if (SUCCEEDED(hr))
  2211.                         {
  2212.                             // Set the AVI Options like interleaving mode etc...
  2213.                             DV_SetAviOptions(ppf, INTERLEAVE_NONE);
  2214.                             //Now I need the input pin on the mux to connect to the file writer
  2215.                             hr = g_pBuilder->FindPin(ppf, PINDIR_INPUT, NULL, NULL, TRUE, 0, &pMuxIn);
  2216.                             if (SUCCEEDED(hr))
  2217.                             {
  2218.                                 hr = g_pGraphBuilder->ConnectDirect(pTeeOut, pMuxIn, NULL);
  2219.                                 //
  2220.                                 //the capture graph is built,but we still need to build the preview graph
  2221.                                 //
  2222.                                 // get the preview output pin on the smart tee
  2223.                                 hr = g_pBuilder->FindPin(g_pSmartTee, PINDIR_OUTPUT, NULL, NULL, TRUE, 0, &pTeePreOut);
  2224.                                  if (SUCCEEDED(hr))
  2225.                                 {
  2226.                                     // Add the filters DV Splitter, DV Decoder, Video Renderer 
  2227.                                     EXECUTE_ASSERT(S_OK == g_pGraphBuilder->AddFilter(g_pDVSplitter, L"DV Splitter"));
  2228.                                     EXECUTE_ASSERT(S_OK == g_pGraphBuilder->AddFilter(g_pDVCodec, L"DV Codec"));
  2229.                                     EXECUTE_ASSERT(S_OK == g_pGraphBuilder->AddFilter(g_pVideoRenderer, L"VideoRenderer"));
  2230.  
  2231.                                     // Find input pin of dvsplitter & connect smart tee and dvsplitter
  2232.                                     hr = g_pBuilder->FindPin(g_pDVSplitter, PINDIR_INPUT, NULL, NULL, TRUE, 0, &pSplitIn);
  2233.                                     if (SUCCEEDED(hr))
  2234.                                     {
  2235.                                         hr = g_pGraphBuilder->ConnectDirect(pTeePreOut, pSplitIn, NULL);
  2236.                                         if (SUCCEEDED(hr))
  2237.                                         {
  2238.                                             // find the vid & aud output pins on the dvsplitter
  2239.                                             hr = g_pBuilder->FindPin(g_pDVSplitter, PINDIR_OUTPUT, NULL , &MEDIATYPE_Video, TRUE, 0, &pSplitVout);
  2240.                                             if (SUCCEEDED(hr))
  2241.                                             {
  2242.                                                 hr = g_pBuilder->FindPin(g_pDVSplitter, PINDIR_OUTPUT, NULL , &MEDIATYPE_Audio, TRUE, 0, &pSplitAout);
  2243.                                                 if (SUCCEEDED(hr))
  2244.                                                 {
  2245.                                                     // find the input & output pins on the dv codec
  2246.                                                     hr = g_pBuilder->FindPin(g_pDVCodec, PINDIR_INPUT, NULL , NULL, TRUE, 0, &pCodecIn);
  2247.                                                     if (SUCCEEDED(hr))
  2248.                                                     {
  2249.                                                         hr = g_pBuilder->FindPin(g_pDVCodec, PINDIR_OUTPUT, NULL , NULL, TRUE, 0, &pCodecOut);
  2250.                                                         if (SUCCEEDED(hr))
  2251.                                                         {
  2252.                                                             // connect the dvsplitter(vid) & dvcodec
  2253.                                                             hr = g_pGraphBuilder->ConnectDirect(pSplitVout, pCodecIn, NULL);
  2254.                                                             if (SUCCEEDED(hr))
  2255.                                                             {
  2256.                                                                 //if we have audio, add the filter to the graph connect it to the dvsplitter(aud)
  2257.                                                                 if (g_pDSound)
  2258.                                                                 {
  2259.                                                                     EXECUTE_ASSERT(S_OK == g_pGraphBuilder->AddFilter(g_pDSound, L"DSound"));
  2260.                                                                     hr = g_pBuilder->FindPin(g_pDSound, PINDIR_INPUT, NULL , NULL, TRUE, 0, &pAudIn);
  2261.                                                                     if (SUCCEEDED(hr))
  2262.                                                                     {
  2263.                                                                         hr = g_pGraphBuilder->ConnectDirect(pSplitAout, pAudIn, NULL);
  2264.                                                                         SAFE_RELEASE(pAudIn);
  2265.                                                                     }
  2266.                                                                 }   
  2267.                                                                 if (SUCCEEDED(hr))  //this verifies success of the audio connection when audio exists
  2268.                                                                 {
  2269.                                                                     // get the input pin on the video renderer and connect it to the dvcodec
  2270.                                                                     hr = g_pBuilder->FindPin(g_pVideoRenderer, PINDIR_INPUT, NULL , NULL, TRUE, 0, &pRenderIn);
  2271.                                                                     if (SUCCEEDED(hr))
  2272.                                                                     {
  2273.                                                                         hr = g_pGraphBuilder->ConnectDirect(pCodecOut, pRenderIn, NULL);
  2274.                                                                         if (SUCCEEDED(hr))
  2275.                                                                         {
  2276.                                                                             // Woohoo! succeeded all the way
  2277.                                                                             // Set the Filter Graph to Preview State (Run in this case)
  2278.                                                                             DV_SetPreview();
  2279.                                                                         } 
  2280.                                                                         SAFE_RELEASE(pRenderIn);
  2281.                                                                     } 
  2282.                                                                 } 
  2283.                                                             } 
  2284.                                                             SAFE_RELEASE(pCodecOut);
  2285.                                                         } 
  2286.                                                         SAFE_RELEASE(pCodecIn);
  2287.                                                     } 
  2288.                                                     SAFE_RELEASE(pSplitAout);
  2289.                                                 } 
  2290.                                                 SAFE_RELEASE(pSplitVout);
  2291.                                             } 
  2292.                                         } 
  2293.                                         SAFE_RELEASE(pSplitIn);
  2294.                                     } 
  2295.                                     SAFE_RELEASE(pTeePreOut);
  2296.                                 } 
  2297.                                 SAFE_RELEASE(pMuxIn);
  2298.                             } 
  2299.                             SAFE_RELEASE(ppf);
  2300.                             SAFE_RELEASE(pSink);
  2301.                         } 
  2302.                         SAFE_RELEASE(pTeeOut);
  2303.                     } 
  2304.                 } // Release interfaces appropriately
  2305.                 else
  2306.                 {
  2307.                     DV_LogOut(LOG_PRIORITY_ERROR, LOG_LEVEL_SUCCINCT, TEXT("Could not connect ouput pin from camera (0x%x)"), hr);
  2308.                 } 
  2309.                 SAFE_RELEASE(pTeeIn);
  2310.             } 
  2311.             SAFE_RELEASE(pAVOut);
  2312.         } 
  2313.     }
  2314.     return hr;
  2315. }
  2316.  
  2317. /*---------------------------------------------------------------------------------------------------------
  2318. Routine:        DV_MakeDvToFileGraph_NoPre
  2319. Purpose:        Builds and runs the DV to File graph with no preview
  2320. Arguments:    None
  2321. Returns:        HRESULT as apropriate
  2322. Notes:          This is a capture only graph for DV Type 1 AVI files            
  2323.                     This graph is not too complex.  It looks like this:
  2324.                     DV_Cam(AV Out)->AviMux->FileWriter
  2325. ---------------------------------------------------------------------------------------------------------*/
  2326. HRESULT  DV_MakeDvToFileGraph_NoPre(void)
  2327. {
  2328.     HRESULT hr = S_OK;
  2329.     DV_LogOut(LOG_PRIORITY_INFO, LOG_LEVEL_MEDIUM, TEXT("Building DV to File Graph (No Preview)"));
  2330.     // making sure there is a output file selected
  2331.     if (!g_OutputFileName[0])
  2332.     {
  2333.         MBOX(TEXT("Please set up an output file name for recording"));
  2334.         hr = E_FAIL;
  2335.     } 
  2336.     else
  2337.     {
  2338.         DV_LogOut(LOG_PRIORITY_INFO, LOG_LEVEL_VERBOSE, TEXT("This is the graph - everything should be disconnected"));
  2339. #ifndef UNICODE        
  2340.         // convert the output file name to wchar
  2341.         WCHAR wFileName[MAX_PATH];
  2342.         MultiByteToWideChar(CP_ACP, 0, g_OutputFileName, -1, wFileName, MAX_PATH);
  2343. #endif
  2344.  
  2345.         //we'll need a few pins...
  2346.         IPin *pAVOut = NULL, *pMuxIn = NULL;
  2347.  
  2348.         // get the capture output pin of dvcamera and connect it to avi muxer & file writer
  2349.         hr = g_pBuilder->FindPin(g_pDVCamera, PINDIR_OUTPUT, NULL, &MEDIATYPE_Interleaved, TRUE, 0, &pAVOut);
  2350.         if (SUCCEEDED(hr))
  2351.         {
  2352.             //add the avimux, and file writer to the graph 
  2353.             IBaseFilter *ppf = NULL;
  2354.             IFileSinkFilter *pSink = NULL;
  2355. #ifndef UNICODE
  2356.             hr = g_pBuilder->SetOutputFileName(&MEDIASUBTYPE_Avi, wFileName, &ppf, &pSink);
  2357. #else
  2358.             hr = g_pBuilder->SetOutputFileName(&MEDIASUBTYPE_Avi, g_OutputFileName, &ppf, &pSink);
  2359. #endif //UNICODE
  2360.             if (SUCCEEDED(hr))
  2361.             {
  2362.                 // Set the AVI Options like interleaving mode etc...
  2363.                 DV_SetAviOptions(ppf, INTERLEAVE_NONE);
  2364.                 //Now I need the input pin on the mux to connect to the file writer
  2365.                 hr = g_pBuilder->FindPin(ppf, PINDIR_INPUT, NULL, NULL, TRUE, 0, &pMuxIn);
  2366.                 if (SUCCEEDED(hr))
  2367.                 {
  2368.                     hr = g_pGraphBuilder->ConnectDirect(pAVOut, pMuxIn, NULL);
  2369.                     //
  2370.                     //the capture graph is built
  2371.                     //
  2372.                     if (FAILED(hr))
  2373.                     {
  2374.                         DV_LogOut(LOG_PRIORITY_ERROR, LOG_LEVEL_SUCCINCT, TEXT("Could not connect ouput pin from camera (0x%x)"), hr);
  2375.                     } 
  2376.                                                             
  2377.                     SAFE_RELEASE(pMuxIn);
  2378.                 } 
  2379.                 SAFE_RELEASE(ppf);
  2380.                 SAFE_RELEASE(pSink);
  2381.             } 
  2382.             
  2383.         } 
  2384.         SAFE_RELEASE(pAVOut);
  2385.     } // Release interfaces appropriately
  2386.     return hr;
  2387. }
  2388.  
  2389. /*---------------------------------------------------------------------------------------------------------
  2390. Routine:        DV_MakeFileToDvGraph
  2391. Purpose:        Builds and runs the File to DV graph
  2392. Arguments:    None
  2393. Returns:        HRESULT as apropriate
  2394. Notes:          This is a transmit & playback graph for DV Type 1 AVI files         
  2395.                     This graph is a bit more complex.  It looks like this:
  2396.                      FileSource->AVI_Splitter->InfPinTee->DV_Camera
  2397.                                                                InfPinTee->DVSplitter(vid)->DVDecoder->VideoWIndow
  2398.                                                                                 DVSplitter(aud)->Default DirectSound device
  2399. ---------------------------------------------------------------------------------------------------------*/
  2400. HRESULT DV_MakeFileToDvGraph(void)
  2401. {
  2402.     HRESULT hr = S_OK;
  2403.     // making sure there is a input file selected
  2404.     if (NULL == g_InputFileName[0])
  2405.     {
  2406.         MBOX(TEXT("Please set an input file for rendering"));
  2407.         hr = E_FAIL;
  2408.     } 
  2409.     else
  2410.     {
  2411.          //if we are compiling ANSI, the file name needs to be converted to UNICODE
  2412.         // Add the file as source filter to the graph
  2413.  #ifndef UNICODE
  2414.        WCHAR wFileName[MAX_PATH];
  2415.         MultiByteToWideChar(CP_ACP, 0, g_InputFileName, -1, wFileName, MAX_PATH);
  2416.         EXECUTE_ASSERT(S_OK == g_pGraphBuilder->AddSourceFilter(wFileName, wFileName, &g_pInputFileFilter));
  2417. #else
  2418.         EXECUTE_ASSERT(S_OK == g_pGraphBuilder->AddSourceFilter(g_InputFileName, g_InputFileName, &g_pInputFileFilter));
  2419. #endif
  2420.         //making sure the file source exists
  2421.         if(g_pInputFileFilter == NULL)
  2422.         {
  2423.             MBOX(TEXT("Please set a correct input file for rendering"));
  2424.             hr = E_FAIL;
  2425.             return hr;
  2426.         } 
  2427.         // Also add the AVI Splitter
  2428.         EXECUTE_ASSERT(S_OK == g_pGraphBuilder->AddFilter(g_pAviSplitter, L"AVI Splitter"));
  2429.  
  2430.         // now we need to connect the pins
  2431.         IPin *pFileOut = NULL, *pSplitterIn = NULL, *pSplitterOut = NULL, *pDvIn = NULL;
  2432.         IPin *pInfTeeIn = NULL, *pInfTeeOut1 = NULL, *pInfTeeOut2 = NULL, *pSplitIn = NULL, *pRenderIn = NULL;
  2433.         IPin *pSplitVout = NULL, *pSplitAout = NULL, *pCodecIn = NULL, *pCodecOut = NULL, *pAudIn = NULL;
  2434.  
  2435.         // obtain the output pin of the source filter and connect it to avi splitter
  2436.         hr = g_pBuilder->FindPin(g_pInputFileFilter, PINDIR_OUTPUT, NULL, NULL, TRUE, 0, &pFileOut);
  2437.         if (SUCCEEDED(hr))
  2438.         {
  2439.             ASSERT(pFileOut);
  2440.             //now get the input pin of the splitter
  2441.             hr = g_pBuilder->FindPin(g_pAviSplitter, PINDIR_INPUT, NULL, NULL, TRUE, 0, &pSplitterIn);
  2442.             if (SUCCEEDED(hr))
  2443.             {
  2444.                 ASSERT(pSplitterIn);
  2445.                 //connect the file output pin to the AVI splitter in
  2446.                 //until we do this, the output pin on the splitter won't appear
  2447.                 hr = g_pGraphBuilder->ConnectDirect(pFileOut, pSplitterIn, NULL);
  2448.                 if (SUCCEEDED(hr))
  2449.                 {
  2450.                     //now we can connect the AVISplitterOut to the InfTee IN, then connect that to the camera
  2451.                     hr = g_pBuilder->FindPin(g_pAviSplitter, PINDIR_OUTPUT, NULL, NULL, TRUE, 0, &pSplitterOut);
  2452.                     if (SUCCEEDED(hr))
  2453.                     {
  2454.                         ASSERT(pSplitterOut);
  2455.                         //add the the infinite pin tee filter to the graph
  2456.                         EXECUTE_ASSERT(S_OK == g_pGraphBuilder->AddFilter(g_pInfTee, L"Infinite Tee")); 
  2457.                         hr = g_pBuilder->FindPin(g_pInfTee, PINDIR_INPUT, NULL, NULL, TRUE, 0, &pInfTeeIn);
  2458.                         if (SUCCEEDED(hr))
  2459.                         {
  2460.                             ASSERT(pInfTeeIn);
  2461.                             hr = g_pGraphBuilder->ConnectDirect(pSplitterOut, pInfTeeIn, NULL);
  2462.                             if (SUCCEEDED(hr))
  2463.                             {
  2464.                                 //get the inftee output pin, and the DV Camera input pin
  2465.                                 hr = g_pBuilder->FindPin(g_pInfTee, PINDIR_OUTPUT, NULL, NULL, TRUE, 0, &pInfTeeOut1);
  2466.                                 if (SUCCEEDED(hr))
  2467.                                 {
  2468.                                     ASSERT(pInfTeeOut1);
  2469.                                     hr = g_pBuilder->FindPin(g_pDVCamera, PINDIR_INPUT, NULL, NULL, TRUE, 0, &pDvIn);
  2470.                                     if (SUCCEEDED(hr))
  2471.                                     {
  2472.                                         ASSERT(pDvIn);
  2473.                                         hr = g_pGraphBuilder->ConnectDirect(pInfTeeOut1, pDvIn, NULL);
  2474.                                         //
  2475.                                         //the capture portion of the graph is built, now lets do the preview
  2476.                                         //
  2477.                                         //get another output pin on the inftee
  2478.                                         hr = g_pBuilder->FindPin(g_pInfTee, PINDIR_OUTPUT, NULL, NULL, TRUE, 0, &pInfTeeOut2);
  2479.                                         if (SUCCEEDED(hr))
  2480.                                         {
  2481.                                             // Add the filters DV Splitter, DV Decoder, Video Renderer 
  2482.                                             EXECUTE_ASSERT(S_OK == g_pGraphBuilder->AddFilter(g_pDVSplitter, L"DV Splitter"));
  2483.                                             EXECUTE_ASSERT(S_OK == g_pGraphBuilder->AddFilter(g_pDVCodec, L"DV Codec"));
  2484.                                             EXECUTE_ASSERT(S_OK == g_pGraphBuilder->AddFilter(g_pVideoRenderer, L"VideoRenderer"));
  2485.  
  2486.                                             // Find input pin of dvsplitter & connect inf tee and dvsplitter
  2487.                                             hr = g_pBuilder->FindPin(g_pDVSplitter, PINDIR_INPUT, NULL, NULL, TRUE, 0, &pSplitIn);
  2488.                                             if (SUCCEEDED(hr))
  2489.                                             {
  2490.                                                 hr = g_pGraphBuilder->ConnectDirect(pInfTeeOut2, pSplitIn, NULL);
  2491.                                                 if (SUCCEEDED(hr))
  2492.                                                 {
  2493.                                                     // find the vid & aud output pins on the dvsplitter
  2494.                                                     hr = g_pBuilder->FindPin(g_pDVSplitter, PINDIR_OUTPUT, NULL , &MEDIATYPE_Video, TRUE, 0, &pSplitVout);
  2495.                                                     if (SUCCEEDED(hr))
  2496.                                                     {
  2497.                                                         hr = g_pBuilder->FindPin(g_pDVSplitter, PINDIR_OUTPUT, NULL , &MEDIATYPE_Audio, TRUE, 0, &pSplitAout);
  2498.                                                         if (SUCCEEDED(hr))
  2499.                                                         {
  2500.                                                             // find the input & output pins on the dv codec
  2501.                                                             hr = g_pBuilder->FindPin(g_pDVCodec, PINDIR_INPUT, NULL , NULL, TRUE, 0, &pCodecIn);
  2502.                                                             if (SUCCEEDED(hr))
  2503.                                                             {
  2504.                                                                 hr = g_pBuilder->FindPin(g_pDVCodec, PINDIR_OUTPUT, NULL , NULL, TRUE, 0, &pCodecOut);
  2505.                                                                 if (SUCCEEDED(hr))
  2506.                                                                 {
  2507.                                                                     // connect the dvsplitter(vid) & dvcodec
  2508.                                                                     hr = g_pGraphBuilder->ConnectDirect(pSplitVout, pCodecIn, NULL);
  2509.                                                                     if (SUCCEEDED(hr))
  2510.                                                                     {
  2511.                                                                         //if we have audio, add the filter to the graph connect it to the dvsplitter(aud)
  2512.                                                                         if (g_pDSound)
  2513.                                                                         {
  2514.                                                                             EXECUTE_ASSERT(S_OK == g_pGraphBuilder->AddFilter(g_pDSound, L"DSound"));
  2515.                                                                             hr = g_pBuilder->FindPin(g_pDSound, PINDIR_INPUT, NULL , NULL, TRUE, 0, &pAudIn);
  2516.                                                                             if (SUCCEEDED(hr))
  2517.                                                                             {
  2518.                                                                                 hr = g_pGraphBuilder->ConnectDirect(pSplitAout, pAudIn, NULL);
  2519.                                                                             } 
  2520.                                                                         } 
  2521.                                                                         if (SUCCEEDED(hr)) //verifies audio connection when audio exists
  2522.                                                                         {
  2523.                                                                             // get the input pin on the video renderer and connect it to the dvcodec
  2524.                                                                             hr = g_pBuilder->FindPin(g_pVideoRenderer, PINDIR_INPUT, NULL , NULL, TRUE, 0, &pRenderIn);
  2525.                                                                             if (SUCCEEDED(hr))
  2526.                                                                             {
  2527.                                                                                 hr = g_pGraphBuilder->ConnectDirect(pCodecOut, pRenderIn, NULL);
  2528.                                                                                 if (SUCCEEDED(hr))
  2529.                                                                                 {
  2530.                                                                                     // Woohoo! succeeded all the way
  2531.                                                                                     // Set up the Video Window
  2532.                                                                                     if (g_pVideoWindow)
  2533.                                                                                     {
  2534.                                                                                         g_pVideoWindow->put_Owner(NULL);
  2535.                                                                                         SAFE_RELEASE(g_pVideoWindow);
  2536.                                                                                     } 
  2537.                                                                                     hr = g_pBuilder->FindInterface(NULL, &MEDIATYPE_Video, g_pInputFileFilter, IID_IVideoWindow, reinterpret_cast<PVOID *>(&g_pVideoWindow));
  2538.                                                                                     if (SUCCEEDED(hr))
  2539.                                                                                     {
  2540.                                                                                        
  2541.                                                                                         RECT rc, rect;
  2542.                                                                                         g_pVideoWindow->put_Owner((LONG_PTR)g_hwndApp);     // We own the window now
  2543.                                                                                         g_pVideoWindow->put_WindowStyle(WS_CHILD);     // you are now a child
  2544.                                                                                         GetClientRect(g_hwndApp, &rc);
  2545.                                                                                         GetWindowRect(g_hwndTBar, &rect);
  2546.                                                                                         g_pVideoWindow->SetWindowPosition(0, rect.bottom - rect.top, g_iVWWidth, g_iVWHeight);
  2547.                                                                                         g_pVideoWindow->put_Visible(OATRUE);
  2548.                                                                                     }
  2549.                                                                                     else
  2550.                                                                                     {
  2551.                                                                                         DV_LogOut(LOG_PRIORITY_ERROR, LOG_LEVEL_SUCCINCT, TEXT("FindInterface (IVideoWindow) Failed. hr = 0x%x"), hr);
  2552.                                                                                     }
  2553.                                                                                 } 
  2554.                                                                                 SAFE_RELEASE(pRenderIn);
  2555.                                                                             } 
  2556.                                                                             SAFE_RELEASE(pAudIn);
  2557.                                                                         } 
  2558.                                                                     } 
  2559.                                                                     SAFE_RELEASE(pCodecOut);
  2560.                                                                 } 
  2561.                                                                 SAFE_RELEASE(pCodecIn);
  2562.                                                             } 
  2563.                                                             SAFE_RELEASE(pSplitAout);
  2564.                                                         } 
  2565.                                                         SAFE_RELEASE(pSplitVout);
  2566.                                                     } 
  2567.                                                 } 
  2568.                                                 SAFE_RELEASE(pSplitIn);
  2569.                                             } 
  2570.                                             SAFE_RELEASE(pInfTeeOut2);
  2571.                                         }   
  2572.                                         SAFE_RELEASE(pDvIn);
  2573.                                     }
  2574.                                     SAFE_RELEASE(pInfTeeOut1);
  2575.                                 }
  2576.                             }
  2577.                             SAFE_RELEASE(pInfTeeIn);
  2578.                         } 
  2579.                         SAFE_RELEASE(pSplitterOut);
  2580.                     } 
  2581.                 } // Release interfaces appropriately
  2582.                 else
  2583.                 {
  2584.                     // Handler for invalid source file format
  2585.                     if (VFW_E_INVALID_FILE_FORMAT == hr)
  2586.                     {
  2587.                         MBOX(TEXT("The File format is invalid for the input file"));
  2588.                         DV_LogOut(LOG_PRIORITY_ERROR, LOG_LEVEL_SUCCINCT, TEXT("The File format is invalid for the input file"));
  2589.                     } 
  2590.                     else
  2591.                     {
  2592.                         DV_LogOut(LOG_PRIORITY_ERROR, LOG_LEVEL_SUCCINCT, TEXT("Could not connect ouput pin from file (0x%x)"), hr);
  2593.                     } 
  2594.                 }
  2595.                 SAFE_RELEASE(pSplitterIn);
  2596.             } 
  2597.             SAFE_RELEASE(pFileOut);
  2598.         } 
  2599.     }
  2600.  
  2601.     //if something failed, remove all of the filters we could have added here, 
  2602.     //because DV_DisconnectAll only removes connected filters
  2603.     if (FAILED(hr))
  2604.     {
  2605.         if (g_pAviSplitter)
  2606.             g_pGraphBuilder->RemoveFilter(g_pAviSplitter);
  2607.         if (g_pInfTee)
  2608.             g_pGraphBuilder->RemoveFilter(g_pInfTee);
  2609.         if (g_pDVSplitter)
  2610.             g_pGraphBuilder->RemoveFilter(g_pDVSplitter);
  2611.         if (g_pDVCodec)
  2612.             g_pGraphBuilder->RemoveFilter(g_pDVCodec);
  2613.         if (g_pVideoRenderer)
  2614.             g_pGraphBuilder->RemoveFilter(g_pVideoRenderer);
  2615.         if (g_pDSound)
  2616.             g_pGraphBuilder->RemoveFilter(g_pDSound);
  2617.         if (g_pInputFileFilter)
  2618.             g_pGraphBuilder->RemoveFilter(g_pInputFileFilter);
  2619.     } 
  2620.     
  2621.     return hr;
  2622.  
  2623.   
  2624. /*---------------------------------------------------------------------------------------------------------
  2625. Routine:        DV_MakeFileToDvGraph_NoPre
  2626. Purpose:        Builds and runs the File to DV graph without preview
  2627. Arguments:    None
  2628. Returns:        HRESULT as apropriate
  2629. Notes:          This is a transmit only graph for DV Type 1 AVI files           
  2630.                     This graph is a bit simplex.  It looks like this:
  2631.                     FileSource->AVI_Splitter->DV_Camera
  2632. ---------------------------------------------------------------------------------------------------------*/
  2633. HRESULT DV_MakeFileToDvGraph_NoPre(void)
  2634. {
  2635.     HRESULT hr = S_OK;
  2636.     // making sure there is a input file selected
  2637.     if (NULL == g_InputFileName[0])
  2638.     {
  2639.         MBOX(TEXT("Please set an input file for rendering"));
  2640.         hr = E_FAIL;
  2641.     } 
  2642.     else
  2643.     {
  2644.         //if we are compiling ANSI, the file name needs to be converted to UNICODE
  2645.         // Add the file as source filter to the graph
  2646. #ifndef UNICODE
  2647.         WCHAR wFileName[MAX_PATH];
  2648.         MultiByteToWideChar(CP_ACP, 0, g_InputFileName, -1, wFileName, MAX_PATH);
  2649.         EXECUTE_ASSERT(S_OK == g_pGraphBuilder->AddSourceFilter(wFileName, wFileName, &g_pInputFileFilter));
  2650. #else
  2651.         EXECUTE_ASSERT(S_OK == g_pGraphBuilder->AddSourceFilter(g_InputFileName, g_InputFileName, &g_pInputFileFilter));
  2652. #endif
  2653.         //making sure the file source exists
  2654.         if(g_pInputFileFilter == NULL)
  2655.         {
  2656.             MBOX(TEXT("Please set a correct input file for rendering"));
  2657.             hr = E_FAIL;
  2658.             return hr;
  2659.         } 
  2660.         // Also add the AVI Splitter
  2661.         EXECUTE_ASSERT(S_OK == g_pGraphBuilder->AddFilter(g_pAviSplitter, L"AVI Splitter"));
  2662.  
  2663.         // now we need to connect the pins
  2664.         IPin *pFileOut = NULL, *pSplitterIn = NULL, *pSplitterOut = NULL, *pDvIn = NULL;
  2665.  
  2666.         // obtain the output pin of the source filter and connect it to avi splitter
  2667.         hr = g_pBuilder->FindPin(g_pInputFileFilter, PINDIR_OUTPUT, NULL, NULL, TRUE, 0, &pFileOut);
  2668.         if (SUCCEEDED(hr))
  2669.         {
  2670.             ASSERT(pFileOut);
  2671.             //now get the input pin of the splitter
  2672.             hr = g_pBuilder->FindPin(g_pAviSplitter, PINDIR_INPUT, NULL, NULL, TRUE, 0, &pSplitterIn);
  2673.             if (SUCCEEDED(hr))
  2674.             {
  2675.                 ASSERT(pSplitterIn);
  2676.                 //connect the file output pin to the AVI splitter in
  2677.                 //until we do this, the output pin on the splitter won't appear
  2678.                 hr = g_pGraphBuilder->ConnectDirect(pFileOut, pSplitterIn, NULL);
  2679.                 if (SUCCEEDED(hr))
  2680.                 {
  2681.                     //get the AVI Splitter output pin, and the DV Camera input pin and connect them
  2682.                     hr = g_pBuilder->FindPin(g_pAviSplitter, PINDIR_OUTPUT, NULL, NULL, TRUE, 0, &pSplitterOut);
  2683.                     if (SUCCEEDED(hr))
  2684.                     {
  2685.                         hr = g_pBuilder->FindPin(g_pDVCamera, PINDIR_INPUT, NULL, NULL, TRUE, 0, &pDvIn);
  2686.                         if (SUCCEEDED(hr))
  2687.                         {
  2688.                             ASSERT(pDvIn);
  2689.                             hr = g_pGraphBuilder->ConnectDirect(pSplitterOut, pDvIn, NULL);
  2690.                             //
  2691.                             //the capture portion of the graph is built
  2692.                             //
  2693.                             if (FAILED(hr))
  2694.                             {
  2695.                                 DV_LogOut(LOG_PRIORITY_ERROR, LOG_LEVEL_MEDIUM, TEXT("Could not connect the AviSplitter to the DV Camera"));
  2696.                             } 
  2697.                             SAFE_RELEASE(pDvIn);
  2698.                         } 
  2699.                     SAFE_RELEASE(pSplitterOut);
  2700.                     }
  2701.                 } // Release interfaces appropriately
  2702.                 else
  2703.                 {
  2704.                     // Handler for invalid source file format
  2705.                     if (VFW_E_INVALID_FILE_FORMAT == hr)
  2706.                     {
  2707.                         MBOX(TEXT("The File format is invalid for the input file"));
  2708.                         DV_LogOut(LOG_PRIORITY_ERROR, LOG_LEVEL_SUCCINCT, TEXT("The File format is invalid for the input file"));
  2709.                     } 
  2710.                     else
  2711.                     {
  2712.                         DV_LogOut(LOG_PRIORITY_ERROR, LOG_LEVEL_SUCCINCT, TEXT("Could not connect ouput pin from file (0x%x)"), hr);
  2713.                     } 
  2714.                 }
  2715.                 SAFE_RELEASE(pSplitterIn);
  2716.             } 
  2717.             SAFE_RELEASE(pFileOut);
  2718.         } 
  2719.     }
  2720.     //if something failed, remove all of the filters we could have added here, 
  2721.     //because DisconnectAll only removes connected filters
  2722.     if (FAILED(hr))
  2723.     {
  2724.         if (g_pAviSplitter)
  2725.             g_pGraphBuilder->RemoveFilter(g_pAviSplitter);
  2726.         if (g_pInputFileFilter)
  2727.             g_pGraphBuilder->RemoveFilter(g_pInputFileFilter);
  2728.     } 
  2729.     return hr;
  2730.  
  2731. /*---------------------------------------------------------------------------------------------------------
  2732. Routine:        DV_MakeDvToFileGraph_Type2
  2733. Purpose:        Builds and runs the DV to File graph
  2734. Arguments:    None
  2735. Returns:        HRESULT as apropriate
  2736. Notes:          This is a capture & preview graph for DV Type 2 AVI files           
  2737.                     This graph is a bit more complex.  It looks like this:
  2738.                     DV_Cam(AV Out)->DVSplitter(vid)->SmartTee(capture)->AviMux->FileWriter
  2739.                                                                           SmartTee(preview)->DVCodec->VideoWindow
  2740.                                                 DVSplitter(aud)->InfinitePinTee->AviMux->FileWriter
  2741.                                                                            InfinitePinTee->Default DirectSound device
  2742. ---------------------------------------------------------------------------------------------------------*/
  2743. HRESULT DV_MakeDvToFileGraph_Type2(void)
  2744. {
  2745.     HRESULT hr = S_OK;
  2746.     DV_LogOut(LOG_PRIORITY_INFO, LOG_LEVEL_MEDIUM, TEXT("Building DV to File Graph (Adobe)"));
  2747.     // making sure there is a output file selected
  2748.     if (!g_OutputFileName[0])
  2749.     {
  2750.         MBOX(TEXT("Please set up an output file name for recording"));
  2751.         hr = E_FAIL;
  2752.     } 
  2753.     else
  2754.     {
  2755.         DV_LogOut(LOG_PRIORITY_INFO, LOG_LEVEL_VERBOSE, TEXT("This is the graph - everything should be disconnected"));
  2756. #ifndef UNICODE        
  2757.         // convert the output file name to wchar
  2758.         WCHAR wFileName[MAX_PATH];
  2759.         MultiByteToWideChar(CP_ACP, 0, g_OutputFileName, -1, wFileName, MAX_PATH);
  2760. #endif
  2761.  
  2762.         //we need a lot of pins to make this work...
  2763.         IPin *pAVOut = NULL, *pMuxAIn = NULL, *pMuxVIn = NULL;
  2764.         IPin *pDVSplitterIn = NULL, *pDVSplitterVOut = NULL, *pDVSplitterAOut = NULL;
  2765.         IPin *pTeeIn = NULL, *pTeeOut = NULL, *pTeePreOut = NULL;
  2766.         IPin *pInfTeeIn = NULL, *pInfTeeOut = NULL, *pInfTeePreOut = NULL;
  2767.         IPin *pAudIn = NULL, *pCodecIn = NULL, *pCodecOut = NULL, *pRenderIn = NULL;
  2768.  
  2769.         //get the camera output pin
  2770.         hr = g_pBuilder->FindPin(g_pDVCamera, PINDIR_OUTPUT, NULL, &MEDIATYPE_Interleaved, TRUE, 0, &pAVOut);
  2771.         // add the dv splitter, get the input pin of dvsplitter and connect it to the dvcamera
  2772.         if (SUCCEEDED(hr))
  2773.         {
  2774.             EXECUTE_ASSERT(S_OK == g_pGraphBuilder->AddFilter(g_pDVSplitter, L"DV Splitter"));
  2775.             hr = g_pBuilder->FindPin(g_pDVSplitter, PINDIR_INPUT, NULL, NULL, TRUE, 0, &pDVSplitterIn);
  2776.             if(SUCCEEDED(hr))
  2777.             {
  2778.                 hr = g_pGraphBuilder->ConnectDirect(pAVOut, pDVSplitterIn, NULL);
  2779.                 if(SUCCEEDED(hr))
  2780.                 {
  2781.                     // get the vid & aud output pins of the dvsplitter
  2782.                     hr = g_pBuilder->FindPin(g_pDVSplitter, PINDIR_OUTPUT, NULL, &MEDIATYPE_Video, TRUE, 0, &pDVSplitterVOut);
  2783.                     hr = g_pBuilder->FindPin(g_pDVSplitter, PINDIR_OUTPUT, NULL, &MEDIATYPE_Audio, TRUE, 0, &pDVSplitterAOut);
  2784.  
  2785.                     if (SUCCEEDED(hr))
  2786.                     {
  2787.                         ASSERT(pDVSplitterVOut);
  2788.                         ASSERT(pDVSplitterAOut);
  2789.                         //add the smart tee, infinite tee filters to the graph
  2790.                         EXECUTE_ASSERT(S_OK == g_pGraphBuilder->AddFilter(g_pSmartTee, L"Smart Tee"));
  2791.                         EXECUTE_ASSERT(S_OK == g_pGraphBuilder->AddFilter(g_pInfTee, L"Infinite Tee"));
  2792.  
  2793.                         // get the input pin of infinite pin tee and connect it to dvsplitter (aud) output pin
  2794.                         hr = g_pBuilder->FindPin(g_pInfTee, PINDIR_INPUT, NULL, NULL, TRUE, 0, &pInfTeeIn);
  2795.                         if (SUCCEEDED(hr))
  2796.                         {
  2797.                             hr = g_pGraphBuilder->ConnectDirect(pDVSplitterAOut, pInfTeeIn, NULL);
  2798.                             if (SUCCEEDED(hr))
  2799.                             {
  2800.                                 // get the outpin of infinite pin tee
  2801.                                 hr = g_pBuilder->FindPin(g_pInfTee, PINDIR_OUTPUT, NULL, NULL, TRUE, 0, &pInfTeeOut);
  2802.                                 if(SUCCEEDED(hr))
  2803.                                 {          
  2804.                                     // get the input pin of smart tee and connect it to dvsplitter (vid) output pin
  2805.                                     hr = g_pBuilder->FindPin(g_pSmartTee, PINDIR_INPUT, NULL, NULL, TRUE, 0, &pTeeIn);
  2806.                                     if (SUCCEEDED(hr))
  2807.                                     {
  2808.                                         hr = g_pGraphBuilder->ConnectDirect(pDVSplitterVOut, pTeeIn, NULL);
  2809.                                         if (SUCCEEDED(hr))
  2810.                                         {
  2811.                                             // get the capture outpin of smart tee filter and connect it to avi muxer & file writer
  2812.                                             hr = g_pBuilder->FindPin(g_pSmartTee, PINDIR_OUTPUT, NULL, NULL, TRUE, 0, &pTeeOut);
  2813.                                             if(SUCCEEDED(hr))
  2814.                                             {
  2815.                                                 //add the avimux, and file writer to the graph 
  2816.                                                 IBaseFilter *ppf = NULL;
  2817.                                                 IFileSinkFilter *pSink = NULL;
  2818. #ifndef UNICODE
  2819.                                                 hr = g_pBuilder->SetOutputFileName(&MEDIASUBTYPE_Avi, wFileName, &ppf, &pSink);
  2820. #else
  2821.                                                 hr = g_pBuilder->SetOutputFileName(&MEDIASUBTYPE_Avi, g_OutputFileName, &ppf, &pSink);
  2822. #endif //UNICODE
  2823.                                                 if (SUCCEEDED(hr))
  2824.                                                 {
  2825.                                                     // Set the AVI Options like interleaving mode etc...
  2826.                                                     DV_SetAviOptions(ppf, INTERLEAVE_NONE);
  2827.                                                     //Now I need the input video pin on the mux to connect to the file writer
  2828.                                                     hr = g_pBuilder->FindPin(ppf, PINDIR_INPUT, NULL, NULL, TRUE, 0, &pMuxVIn);
  2829.                                                     if (SUCCEEDED(hr))
  2830.                                                     {
  2831.                                                         hr = g_pGraphBuilder->ConnectDirect(pTeeOut, pMuxVIn, NULL);
  2832.                                                         if (SUCCEEDED(hr))
  2833.                                                         {
  2834.                                                             //Now I need the input audio pin on the mux
  2835.                                                             hr = g_pBuilder->FindPin(ppf, PINDIR_INPUT, NULL, NULL, TRUE, 0, &pMuxAIn);
  2836.                                                             if (SUCCEEDED(hr))
  2837.                                                             {
  2838.                                                                 hr = g_pGraphBuilder->ConnectDirect(pInfTeeOut, pMuxAIn, NULL);
  2839.                                                                 //  
  2840.                                                                 //the capture graph is built,but we still need to build the preview graph
  2841.                                                                 //
  2842.                                                                 // get the preview output pin on the smart tee
  2843.                                                                 hr = g_pBuilder->FindPin(g_pSmartTee, PINDIR_OUTPUT, NULL, NULL, TRUE, 0, &pTeePreOut);
  2844.                                                                 if (SUCCEEDED(hr))
  2845.                                                                 {
  2846.                                                                     // Add the filters DV Decoder, Video Renderer 
  2847.                                                                     EXECUTE_ASSERT(S_OK == g_pGraphBuilder->AddFilter(g_pDVCodec, L"DV Codec"));
  2848.                                                                     EXECUTE_ASSERT(S_OK == g_pGraphBuilder->AddFilter(g_pVideoRenderer, L"VideoRenderer"));
  2849.  
  2850.                                                                     // get the output pin of Infinite pin tee filter
  2851.                                                                     hr = g_pBuilder->FindPin(g_pInfTee, PINDIR_OUTPUT, NULL , NULL, TRUE, 0, &pInfTeePreOut);
  2852.                                                                     if (SUCCEEDED(hr))
  2853.                                                                     {
  2854.                                                                         // find the input & output pins on the dv codec
  2855.                                                                         hr = g_pBuilder->FindPin(g_pDVCodec, PINDIR_INPUT, NULL , NULL, TRUE, 0, &pCodecIn);
  2856.                                                                         if (SUCCEEDED(hr))
  2857.                                                                         {
  2858.                                                                             hr = g_pBuilder->FindPin(g_pDVCodec, PINDIR_OUTPUT, NULL , NULL, TRUE, 0, &pCodecOut);
  2859.                                                                             if (SUCCEEDED(hr))
  2860.                                                                             {
  2861.                                                                                 // connect the infinite pin tee to dvcodec 
  2862.                                                                                 hr = g_pGraphBuilder->ConnectDirect(pTeePreOut, pCodecIn, NULL);
  2863.                                                                                 if (SUCCEEDED(hr))
  2864.                                                                                 {
  2865.                                                                                     //if we have audio, add the filter to the graph connect it to the infinite pin tee
  2866.                                                                                     if (g_pDSound)
  2867.                                                                                     {
  2868.                                                                                         EXECUTE_ASSERT(S_OK == g_pGraphBuilder->AddFilter(g_pDSound, L"DSound"));
  2869.                                                                                         hr = g_pBuilder->FindPin(g_pDSound, PINDIR_INPUT, NULL , NULL, TRUE, 0, &pAudIn);
  2870.                                                                                         if (SUCCEEDED(hr))
  2871.                                                                                         {
  2872.                                                                                             hr = g_pGraphBuilder->ConnectDirect(pInfTeePreOut, pAudIn, NULL);
  2873.                                                                                             SAFE_RELEASE(pAudIn);
  2874.                                                                                         }
  2875.                                                                                     }   
  2876.                                                                                     if (SUCCEEDED(hr))  //this verifies success of the audio connection when audio exists
  2877.                                                                                     {
  2878.                                                                                         // get the input pin ont he video renderer and connect it to the dvcodec
  2879.                                                                                         hr = g_pBuilder->FindPin(g_pVideoRenderer, PINDIR_INPUT, NULL , NULL, TRUE, 0, &pRenderIn);
  2880.                                                                                         if (SUCCEEDED(hr))
  2881.                                                                                         {
  2882.                                                                                             hr = g_pGraphBuilder->ConnectDirect(pCodecOut, pRenderIn, NULL);
  2883.                                                                                             if (SUCCEEDED(hr))
  2884.                                                                                             {
  2885.                                                                                                 // Woohoo! succeeded all the way
  2886.                                                                                                 // Set the Filter Graph to Preview State (Run in this case)
  2887.                                                                                                 DV_SetPreview();
  2888.                                                                                             } 
  2889.                                                                                         } 
  2890.                                                                                         SAFE_RELEASE(pRenderIn);
  2891.                                                                                     } 
  2892.                                                                                 } 
  2893.                                                                             } 
  2894.                                                                             SAFE_RELEASE(pCodecOut);
  2895.                                                                         } 
  2896.                                                                         SAFE_RELEASE(pCodecIn);
  2897.                                                                     } 
  2898.                                                                     SAFE_RELEASE(pInfTeePreOut);
  2899.                                                                 } 
  2900.                                                                 SAFE_RELEASE(pTeePreOut);
  2901.                                                             } 
  2902.                                                             SAFE_RELEASE(pMuxAIn);
  2903.                                                         } 
  2904.                                                     } 
  2905.                                                     SAFE_RELEASE(pMuxVIn);
  2906.                                                 }
  2907.                                                 SAFE_RELEASE(ppf);
  2908.                                                 SAFE_RELEASE(pSink);
  2909.                                             }
  2910.                                             SAFE_RELEASE(pTeeOut);
  2911.                                         } 
  2912.                                     }
  2913.                                     SAFE_RELEASE(pTeeIn);
  2914.                                 }
  2915.                                 SAFE_RELEASE(pInfTeeOut);
  2916.                             }
  2917.                         }
  2918.                         SAFE_RELEASE(pInfTeeIn);
  2919.                     }
  2920.                     SAFE_RELEASE(pDVSplitterVOut);
  2921.                     SAFE_RELEASE(pDVSplitterAOut);
  2922.                 } // Release interfaces appropriately
  2923.                 else
  2924.                 {
  2925.                     DV_LogOut(LOG_PRIORITY_ERROR, LOG_LEVEL_SUCCINCT, TEXT("Could not connect output pin from camera (0x%x)"), hr);
  2926.                 } 
  2927.             } 
  2928.             SAFE_RELEASE(pDVSplitterIn);
  2929.         } 
  2930.         SAFE_RELEASE(pAVOut);
  2931.     }
  2932.     return hr;
  2933. }
  2934.  
  2935. /*---------------------------------------------------------------------------------------------------------
  2936. Routine:        DV_MakeDvToFileGraph_NoPre_Type2
  2937. Purpose:        Builds and runs the DV to File graph
  2938. Arguments:    None
  2939. Returns:        HRESULT as apropriate
  2940. Notes:          This is a capture only graph for DV Type 2 AVI files            
  2941.                     This graph is a bit simplex .  It looks like this:
  2942.                     DV_Cam(AV Out)->DVSplitter(vid)->AviMux->FileWriter
  2943.                                                 DVSplitter(aud)->AviMux->FileWriter
  2944. ---------------------------------------------------------------------------------------------------------*/
  2945. HRESULT DV_MakeDvToFileGraph_NoPre_Type2(void)
  2946. {
  2947.     HRESULT hr = S_OK;
  2948.     DV_LogOut(LOG_PRIORITY_INFO, LOG_LEVEL_MEDIUM, TEXT("Building DV to File Graph (No Preview)"));
  2949.     // making sure there is a output file selected
  2950.     if (!g_OutputFileName[0])
  2951.     {
  2952.         MBOX(TEXT("Please set up an output file name for recording"));
  2953.         hr = E_FAIL;
  2954.     } 
  2955.     else
  2956.     {
  2957.         DV_LogOut(LOG_PRIORITY_INFO, LOG_LEVEL_VERBOSE, TEXT("This is the graph - everything should be disconnected"));
  2958. #ifndef UNICODE        
  2959.         // convert the output file name to wchar
  2960.         WCHAR wFileName[MAX_PATH];
  2961.         MultiByteToWideChar(CP_ACP, 0, g_OutputFileName, -1, wFileName, MAX_PATH);
  2962. #endif
  2963.  
  2964.         //we'll need a few pins...
  2965.         IPin *pAVOut = NULL, *pDVSplitterIn=NULL, *pDVSplitterVOut=NULL, *pDVSplitterAOut=NULL, *pMuxVIn = NULL, *pMuxAIn = NULL;
  2966.  
  2967.         //get the camera output pin
  2968.         hr = g_pBuilder->FindPin(g_pDVCamera, PINDIR_OUTPUT, NULL, &MEDIATYPE_Interleaved, TRUE, 0, &pAVOut);
  2969.         // add the dv splitter, get the input pin of dvsplitter and connect it to the dvcamera
  2970.         if(SUCCEEDED(hr))
  2971.         {
  2972.             EXECUTE_ASSERT(S_OK == g_pGraphBuilder->AddFilter(g_pDVSplitter, L"DV Splitter"));
  2973.             hr = g_pBuilder->FindPin(g_pDVSplitter, PINDIR_INPUT, NULL, NULL, TRUE, 0, &pDVSplitterIn);
  2974.             if(SUCCEEDED(hr))
  2975.             {
  2976.                 hr = g_pGraphBuilder->ConnectDirect(pAVOut, pDVSplitterIn, NULL);
  2977.                 if(SUCCEEDED(hr))
  2978.                 {
  2979.                     // get the vid & aud output pins of the dvsplitter
  2980.                     hr = g_pBuilder->FindPin(g_pDVSplitter, PINDIR_OUTPUT, NULL, &MEDIATYPE_Video, TRUE, 0, &pDVSplitterVOut);
  2981.                     hr = g_pBuilder->FindPin(g_pDVSplitter, PINDIR_OUTPUT, NULL, &MEDIATYPE_Audio, TRUE, 0, &pDVSplitterAOut);
  2982.                     if (SUCCEEDED(hr))
  2983.                     {
  2984.                         ASSERT(pDVSplitterVOut);
  2985.                         ASSERT(pDVSplitterAOut);
  2986.                         //add the avimux, and file writer to the graph 
  2987.                         IBaseFilter *ppf = NULL;
  2988.                         IFileSinkFilter *pSink = NULL;
  2989. #ifndef UNICODE
  2990.                         hr = g_pBuilder->SetOutputFileName(&MEDIASUBTYPE_Avi, wFileName, &ppf, &pSink);
  2991. #else
  2992.                         hr = g_pBuilder->SetOutputFileName(&MEDIASUBTYPE_Avi, g_OutputFileName, &ppf, &pSink);
  2993. #endif //UNICODE
  2994.                         if (SUCCEEDED(hr))
  2995.                         {
  2996.                             // Set the AVI Options like interleaving mode etc...
  2997.                             DV_SetAviOptions(ppf, INTERLEAVE_NONE);
  2998.                             //Now I need the input pin on the mux to connect to the file writer
  2999.                             hr = g_pBuilder->FindPin(ppf, PINDIR_INPUT, NULL, NULL, TRUE, 0, &pMuxVIn);
  3000.                             // connect the video & audio paths between dvsplitter & avi muxer
  3001.                             if (SUCCEEDED(hr))
  3002.                             {
  3003.                                 hr = g_pGraphBuilder->ConnectDirect(pDVSplitterVOut, pMuxVIn, NULL);
  3004.                                 if(SUCCEEDED(hr))
  3005.                                 {
  3006.                                     hr = g_pBuilder->FindPin(ppf, PINDIR_INPUT, NULL, NULL, TRUE, 0, &pMuxAIn);
  3007.                                     if(SUCCEEDED(hr))
  3008.                                     {
  3009.                                         hr = g_pGraphBuilder->ConnectDirect(pDVSplitterAOut, pMuxAIn, NULL);
  3010.                                         //  
  3011.                                         //the capture graph is built
  3012.                                         //
  3013.                                         if (FAILED(hr))
  3014.                                         {
  3015.                                             DV_LogOut(LOG_PRIORITY_ERROR, LOG_LEVEL_SUCCINCT, TEXT("Could not connect ouput pin from camera (0x%x)"), hr);
  3016.                                         }                                       
  3017.                                                             
  3018.                                         SAFE_RELEASE(pMuxAIn);
  3019.                                     }
  3020.                                 }
  3021.                                 SAFE_RELEASE(pMuxVIn);
  3022.                             }
  3023.                             SAFE_RELEASE(ppf);
  3024.                             SAFE_RELEASE(pSink);
  3025.                         } 
  3026.             
  3027.                     }
  3028.                     SAFE_RELEASE(pDVSplitterVOut);
  3029.                     SAFE_RELEASE(pDVSplitterAOut);
  3030.                 }
  3031.             }
  3032.             SAFE_RELEASE(pDVSplitterIn);
  3033.         }
  3034.         SAFE_RELEASE(pAVOut);
  3035.     } // Release interfaces appropriately
  3036.     return hr;
  3037.  
  3038. /*---------------------------------------------------------------------------------------------------------
  3039. Routine:        DV_MakeFileToDvGraph_Type2
  3040. Purpose:        Builds and runs the File to DV graph 
  3041. Arguments:    None
  3042. Returns:        HRESULT as apropriate
  3043. Notes:          This is a transmit & playback graph for DV Type 2 AVI files         
  3044.                     This graph is a bit complex.  It looks like this:
  3045.                      FileSource->AVI_Splitter(vid) ->DVMuxer(vid)---------->InfPinTee->DV_Camera
  3046.                                         AVI_Splitter(aud)->DVMuxer(aud)                 InfPinTee->DVSplitter(vid)->DVDecoder->VideoWIndow
  3047.                                                                                                                                             DVSplitter(aud)->DSoundDevice
  3048. ---------------------------------------------------------------------------------------------------------*/
  3049. HRESULT DV_MakeFileToDvGraph_Type2(void)
  3050. {
  3051.     HRESULT hr = S_OK;
  3052.     // making sure there is a input file selected
  3053.     if (NULL == g_InputFileName[0])
  3054.     {
  3055.         MBOX(TEXT("Please set an input file for rendering"));
  3056.         hr = E_FAIL;
  3057.     } 
  3058.     else
  3059.     {
  3060.         //if we are compiling ANSI, the file name needs to be converted to UNICODE
  3061.         // Add the file as source filter to the graph
  3062. #ifndef UNICODE
  3063.         WCHAR wFileName[MAX_PATH];
  3064.         MultiByteToWideChar(CP_ACP, 0, g_InputFileName, -1, wFileName, MAX_PATH);
  3065.         EXECUTE_ASSERT(S_OK == g_pGraphBuilder->AddSourceFilter(wFileName, wFileName, &g_pInputFileFilter));
  3066. #else
  3067.         EXECUTE_ASSERT(S_OK == g_pGraphBuilder->AddSourceFilter(g_InputFileName, g_InputFileName, &g_pInputFileFilter));
  3068. #endif
  3069.         //making sure the file source exists
  3070.         if(g_pInputFileFilter == NULL)
  3071.         {
  3072.             MBOX(TEXT("Please set a correct input file for rendering"));
  3073.             hr = E_FAIL;
  3074.             return hr;
  3075.         } 
  3076.         // Also add the AVI Splitter
  3077.         EXECUTE_ASSERT(S_OK == g_pGraphBuilder->AddFilter(g_pAviSplitter, L"AVI Splitter"));
  3078.  
  3079.         // now we need to connect the pins
  3080.         IPin *pFileOut = NULL, *pSplitterIn = NULL, *pSplitterVOut = NULL, *pSplitterAOut = NULL, *pDvIn = NULL;
  3081.         IPin *pInfTeeIn = NULL, *pInfTeeOut1 = NULL, *pInfTeeOut2 = NULL, *pSplitIn = NULL, *pRenderIn = NULL;
  3082.         IPin *pSplitVout = NULL, *pSplitAout = NULL, *pCodecIn = NULL, *pCodecOut = NULL, *pAudIn = NULL;
  3083.         IPin *pMuxerVIn = NULL, *pMuxerAIn = NULL, *pMuxerOut = NULL;
  3084.  
  3085.         // obtain the output pin of the source filter and connect it to avi splitter
  3086.         hr = g_pBuilder->FindPin(g_pInputFileFilter, PINDIR_OUTPUT, NULL, NULL, TRUE, 0, &pFileOut);
  3087.         if (SUCCEEDED(hr))
  3088.         {
  3089.             ASSERT(pFileOut);
  3090.             //now get the input pin of the splitter
  3091.             hr = g_pBuilder->FindPin(g_pAviSplitter, PINDIR_INPUT, NULL, NULL, TRUE, 0, &pSplitterIn);
  3092.             if (SUCCEEDED(hr))
  3093.             {
  3094.                 ASSERT(pSplitterIn);
  3095.                 //connect the file output pin to the AVI splitter in
  3096.                 //until we do this, the output pin on the splitter won't appear
  3097.                 hr = g_pGraphBuilder->ConnectDirect(pFileOut, pSplitterIn, NULL);
  3098.                 if (SUCCEEDED(hr))
  3099.                 {
  3100.                     // get the video & audio output pins of the avi splitter
  3101.                     hr = g_pBuilder->FindPin(g_pAviSplitter, PINDIR_OUTPUT, NULL, &MEDIATYPE_Video, TRUE, 0, &pSplitterVOut);
  3102.                     hr = g_pBuilder->FindPin(g_pAviSplitter, PINDIR_OUTPUT, NULL, &MEDIATYPE_Audio, TRUE, 0, &pSplitterAOut);
  3103.                     if(SUCCEEDED(hr))
  3104.                     {
  3105.                         ASSERT(pSplitterVOut);
  3106.                         ASSERT(pSplitterAOut);
  3107.                         // Add the DVMuxer to the graph
  3108.                         EXECUTE_ASSERT(S_OK == g_pGraphBuilder->AddFilter(g_pDVMux, L"DV Muxer"));
  3109.                         // get the video & audio input pins on the dvmuxer and connect it to the corressponding output pins of avi splitter
  3110.                         hr = g_pBuilder->FindPin(g_pDVMux, PINDIR_INPUT, NULL, NULL, TRUE, 0, &pMuxerVIn);
  3111.                         if(SUCCEEDED(hr))
  3112.                         {
  3113.                             hr = g_pGraphBuilder->ConnectDirect(pSplitterVOut, pMuxerVIn, NULL);
  3114.                             if(SUCCEEDED(hr))
  3115.                             {
  3116.                                 hr = g_pBuilder->FindPin(g_pDVMux, PINDIR_INPUT, NULL, NULL, TRUE, 0, &pMuxerAIn);
  3117.                                 if(SUCCEEDED(hr))
  3118.                                 {
  3119.                                     hr = g_pGraphBuilder->ConnectDirect(pSplitterAOut, pMuxerAIn, NULL);
  3120.                                     // get the ouput pin of the dv muxer
  3121.                                     if(SUCCEEDED(hr))
  3122.                                     {
  3123.                                         hr = g_pBuilder->FindPin(g_pDVMux, PINDIR_OUTPUT, NULL, NULL, TRUE, 0, &pMuxerOut);
  3124.                                         if (SUCCEEDED(hr))
  3125.                                         {
  3126.                                             //Add the infinite pin tee filter to the graph and connect it downstream to the dv muxer
  3127.                                             EXECUTE_ASSERT(S_OK == g_pGraphBuilder->AddFilter(g_pInfTee, L"Infinite Tee")); 
  3128.                                             hr = g_pBuilder->FindPin(g_pInfTee, PINDIR_INPUT, NULL, NULL, TRUE, 0, &pInfTeeIn);
  3129.                                             if (SUCCEEDED(hr))
  3130.                                             {
  3131.                                                 ASSERT(pInfTeeIn);
  3132.                                                 hr = g_pGraphBuilder->ConnectDirect(pMuxerOut, pInfTeeIn, NULL);
  3133.                                                 if (SUCCEEDED(hr))
  3134.                                                 {
  3135.                                                     //get the inftee output pin, and the DV Camera input pin and connect them
  3136.                                                     hr = g_pBuilder->FindPin(g_pInfTee, PINDIR_OUTPUT, NULL, NULL, TRUE, 0, &pInfTeeOut1);
  3137.                                                     if (SUCCEEDED(hr))
  3138.                                                     {
  3139.                                                         ASSERT(pInfTeeOut1);
  3140.                                                         hr = g_pBuilder->FindPin(g_pDVCamera, PINDIR_INPUT, NULL, NULL, TRUE, 0, &pDvIn);
  3141.                                                         if (SUCCEEDED(hr))
  3142.                                                         {
  3143.                                                             ASSERT(pDvIn);
  3144.                                                             hr = g_pGraphBuilder->ConnectDirect(pInfTeeOut1, pDvIn, NULL);
  3145.                                                             //
  3146.                                                             //the capture portion of the graph should be done now, lets do the preview segment
  3147.                                                             //
  3148.                                                             //get another output pin on the inftee
  3149.                                                             hr = g_pBuilder->FindPin(g_pInfTee, PINDIR_OUTPUT, NULL, NULL, TRUE, 0, &pInfTeeOut2);
  3150.                                                             if (SUCCEEDED(hr))
  3151.                                                             {
  3152.                                                                 // Add the filters DV Splitter, DV Decoder, Video Renderer 
  3153.                                                                 EXECUTE_ASSERT(S_OK == g_pGraphBuilder->AddFilter(g_pDVSplitter, L"DV Splitter"));
  3154.                                                                 EXECUTE_ASSERT(S_OK == g_pGraphBuilder->AddFilter(g_pDVCodec, L"DV Codec"));
  3155.                                                                 EXECUTE_ASSERT(S_OK == g_pGraphBuilder->AddFilter(g_pVideoRenderer, L"VideoRenderer"));
  3156.                                            
  3157.                                                                 // Find input pin of dvsplitter & connect inf tee and dvsplitter
  3158.                                                                 hr = g_pBuilder->FindPin(g_pDVSplitter, PINDIR_INPUT, NULL, NULL, TRUE, 0, &pSplitIn);
  3159.                                                                 if (SUCCEEDED(hr))
  3160.                                                                 {
  3161.                                                                     hr = g_pGraphBuilder->ConnectDirect(pInfTeeOut2, pSplitIn, NULL);
  3162.                                                                     if (SUCCEEDED(hr))
  3163.                                                                     {
  3164.                                                                         // find the vid & aud output pins on the dvsplitter
  3165.                                                                         hr = g_pBuilder->FindPin(g_pDVSplitter, PINDIR_OUTPUT, NULL , &MEDIATYPE_Video, TRUE, 0, &pSplitVout);
  3166.                                                                         if (SUCCEEDED(hr))
  3167.                                                                         {
  3168.                                                                             hr = g_pBuilder->FindPin(g_pDVSplitter, PINDIR_OUTPUT, NULL , &MEDIATYPE_Audio, TRUE, 0, &pSplitAout);
  3169.                                                                             if (SUCCEEDED(hr))
  3170.                                                                             {
  3171.                                                                                 // find the input & output pins on the dv codec
  3172.                                                                                 hr = g_pBuilder->FindPin(g_pDVCodec, PINDIR_INPUT, NULL , NULL, TRUE, 0, &pCodecIn);
  3173.                                                                                 if (SUCCEEDED(hr))
  3174.                                                                                 {
  3175.                                                                                     hr = g_pBuilder->FindPin(g_pDVCodec, PINDIR_OUTPUT, NULL , NULL, TRUE, 0, &pCodecOut);
  3176.                                                                                     if (SUCCEEDED(hr))
  3177.                                                                                     {
  3178.                                                                                         // connect the dvsplitter(vid) & dvcodec
  3179.                                                                                         hr = g_pGraphBuilder->ConnectDirect(pSplitVout, pCodecIn, NULL);
  3180.                                                                                         if (SUCCEEDED(hr))
  3181.                                                                                         {
  3182.                                                                                             //if we have audio, add the filter to the graph connect it to the dvsplitter(aud)
  3183.                                                                                             if (g_pDSound)
  3184.                                                                                             {
  3185.                                                                                                 EXECUTE_ASSERT(S_OK == g_pGraphBuilder->AddFilter(g_pDSound, L"DSound"));
  3186.                                                                                                 hr = g_pBuilder->FindPin(g_pDSound, PINDIR_INPUT, NULL , NULL, TRUE, 0, &pAudIn);
  3187.                                                                                                 if (SUCCEEDED(hr))
  3188.                                                                                                 {
  3189.                                                                                                     hr = g_pGraphBuilder->ConnectDirect(pSplitAout, pAudIn, NULL);
  3190.                                                                                                 } 
  3191.                                                                                             } 
  3192.                                                                                             if (SUCCEEDED(hr)) //verifies audio connection when audio exists
  3193.                                                                                             {
  3194.                                                                                                 // get the input pin on the video renderer and connect it to the dvcodec
  3195.                                                                                                 hr = g_pBuilder->FindPin(g_pVideoRenderer, PINDIR_INPUT, NULL , NULL, TRUE, 0, &pRenderIn);
  3196.                                                                                                 if (SUCCEEDED(hr))
  3197.                                                                                                 {
  3198.                                                                                                     hr = g_pGraphBuilder->ConnectDirect(pCodecOut, pRenderIn, NULL);
  3199.                                                                                                     if (SUCCEEDED(hr))
  3200.                                                                                                     {
  3201.                                                                                                         // Woohoo! succeeded all the way
  3202.                                                                                                         // Set up the Video Window
  3203.                                                                                                         if (g_pVideoWindow)
  3204.                                                                                                         {
  3205.                                                                                                             g_pVideoWindow->put_Owner(NULL);
  3206.                                                                                                             SAFE_RELEASE(g_pVideoWindow);
  3207.                                                                                                         } 
  3208.                                                                                                         hr = g_pBuilder->FindInterface(NULL, &MEDIATYPE_Video, g_pInputFileFilter, IID_IVideoWindow, reinterpret_cast<PVOID *>(&g_pVideoWindow));
  3209.                                                                                                         if (SUCCEEDED(hr))
  3210.                                                                                                         {
  3211.                                                                                        
  3212.                                                                                                             RECT rc, rect;
  3213.                                                                                                             g_pVideoWindow->put_Owner((LONG_PTR)g_hwndApp);     // We own the window now
  3214.                                                                                                             g_pVideoWindow->put_WindowStyle(WS_CHILD);     // you are now a child
  3215.                                                                                                             GetClientRect(g_hwndApp, &rc);
  3216.                                                                                                             GetWindowRect(g_hwndTBar, &rect);
  3217.                                                                                                             g_pVideoWindow->SetWindowPosition(0, rect.bottom - rect.top, g_iVWWidth, g_iVWHeight);
  3218.                                                                                                             g_pVideoWindow->put_Visible(OATRUE);
  3219.                                                                                                         }
  3220.                                                                                                         else
  3221.                                                                                                         {
  3222.                                                                                                             DV_LogOut(LOG_PRIORITY_ERROR, LOG_LEVEL_SUCCINCT, TEXT("FindInterface (IVideoWindow) Failed. hr = 0x%x"), hr);
  3223.                                                                                                         }
  3224.                                                                                                     } 
  3225.                                                                                                     SAFE_RELEASE(pRenderIn);
  3226.                                                                                                 } 
  3227.                                                                                                 SAFE_RELEASE(pAudIn);
  3228.                                                                                             } 
  3229.                                                                                         } 
  3230.                                                                                         SAFE_RELEASE(pCodecOut);
  3231.                                                                                     } 
  3232.                                                                                     SAFE_RELEASE(pCodecIn);
  3233.                                                                                 } 
  3234.                                                                                 SAFE_RELEASE(pSplitAout);
  3235.                                                                             } 
  3236.                                                                             SAFE_RELEASE(pSplitVout);
  3237.                                                                         } 
  3238.                                                                     } 
  3239.                                                                     SAFE_RELEASE(pSplitIn);
  3240.                                                                 } 
  3241.                                                                 SAFE_RELEASE(pInfTeeOut2);
  3242.                                                             }   
  3243.                                                             SAFE_RELEASE(pDvIn);
  3244.                                                         }
  3245.                                                         SAFE_RELEASE(pInfTeeOut1);
  3246.                                                     }
  3247.                                                 }
  3248.                                                 SAFE_RELEASE(pInfTeeIn);
  3249.                                             }
  3250.                                             SAFE_RELEASE(pMuxerOut);
  3251.                                         }
  3252.                                     }
  3253.                                     SAFE_RELEASE(pMuxerAIn);
  3254.                                 }
  3255.                             }
  3256.                             SAFE_RELEASE(pMuxerVIn);
  3257.                         } 
  3258.                         SAFE_RELEASE(pSplitterVOut);
  3259.                         SAFE_RELEASE(pSplitterAOut);
  3260.                     } 
  3261.                 } // Release interfaces appropriately
  3262.                 else
  3263.                 {
  3264.                     // Handler for invalid source file format
  3265.                     if (VFW_E_INVALID_FILE_FORMAT == hr)
  3266.                     {
  3267.                         MBOX(TEXT("The File format is invalid for the input file"));
  3268.                         DV_LogOut(LOG_PRIORITY_ERROR, LOG_LEVEL_SUCCINCT, TEXT("The File format is invalid for the input file"));
  3269.                     } 
  3270.                     else
  3271.                     {
  3272.                         DV_LogOut(LOG_PRIORITY_ERROR, LOG_LEVEL_SUCCINCT, TEXT("Could not connect ouput pin from file (0x%x)"), hr);
  3273.                     } 
  3274.                 }
  3275.                 SAFE_RELEASE(pSplitterIn);
  3276.             } 
  3277.             SAFE_RELEASE(pFileOut);
  3278.         } 
  3279.     }
  3280.     //if something failed, remove all of the filters we could have added here, 
  3281.     //because DV_DisconnectAll only removes connected filters
  3282.     if (FAILED(hr))
  3283.     {
  3284.         if (g_pAviSplitter)
  3285.             g_pGraphBuilder->RemoveFilter(g_pAviSplitter);
  3286.         if (g_pInfTee)
  3287.             g_pGraphBuilder->RemoveFilter(g_pInfTee);
  3288.         if (g_pDVSplitter)
  3289.             g_pGraphBuilder->RemoveFilter(g_pDVSplitter);
  3290.         if (g_pDVCodec)
  3291.             g_pGraphBuilder->RemoveFilter(g_pDVCodec);
  3292.         if (g_pVideoRenderer)
  3293.             g_pGraphBuilder->RemoveFilter(g_pVideoRenderer);
  3294.         if (g_pDSound)
  3295.             g_pGraphBuilder->RemoveFilter(g_pDSound);
  3296.         if (g_pInputFileFilter)
  3297.             g_pGraphBuilder->RemoveFilter(g_pInputFileFilter);
  3298.     } 
  3299.     
  3300.     return hr;
  3301.  
  3302.   
  3303. /*---------------------------------------------------------------------------------------------------------
  3304. Routine:        DV_MakeFileToDvGraph_NoPre_Type2
  3305. Purpose:        Builds and runs the File to DV graph 
  3306. Arguments:    None
  3307. Returns:        HRESULT as apropriate
  3308. Notes:          This is a transmit only graph for DV Type 2 AVI files           
  3309.                     This graph looks like this:
  3310.                      FileSource->AVI_Splitter(vid) ->DVMuxer(vid)----->DV_Camera
  3311.                                         AVI_Splitter(aud)->DVMuxer(aud)                 
  3312. ---------------------------------------------------------------------------------------------------------*/
  3313. HRESULT DV_MakeFileToDvGraph_NoPre_Type2(void)
  3314. {
  3315.     HRESULT hr = S_OK;
  3316.     // making sure there is a input file selected
  3317.     if (NULL == g_InputFileName[0])
  3318.     {
  3319.         MBOX(TEXT("Please set an input file for rendering"));
  3320.         hr = E_FAIL;
  3321.     } 
  3322.     else
  3323.     {
  3324.         //if we are compiling ANSI, the file name needs to be converted to UNICODE
  3325.         // Add the file as source filter to the graph
  3326. #ifndef UNICODE
  3327.         WCHAR wFileName[MAX_PATH];
  3328.         MultiByteToWideChar(CP_ACP, 0, g_InputFileName, -1, wFileName, MAX_PATH);
  3329.         EXECUTE_ASSERT(S_OK == g_pGraphBuilder->AddSourceFilter(wFileName, wFileName, &g_pInputFileFilter));
  3330. #else
  3331.         EXECUTE_ASSERT(S_OK == g_pGraphBuilder->AddSourceFilter(g_InputFileName, g_InputFileName, &g_pInputFileFilter));
  3332. #endif
  3333.         //making sure the file source exists
  3334.         if(g_pInputFileFilter == NULL)
  3335.         {
  3336.             MBOX(TEXT("Please set a correct input file for rendering"));
  3337.             hr = E_FAIL;
  3338.             return hr;
  3339.         } 
  3340.         // Also add the AVI Splitter
  3341.         EXECUTE_ASSERT(S_OK == g_pGraphBuilder->AddFilter(g_pAviSplitter, L"AVI Splitter"));
  3342.  
  3343.         // now we need to connect the pins
  3344.         IPin *pFileOut = NULL, *pSplitterIn = NULL, *pSplitterVOut = NULL, *pSplitterAOut = NULL, *pMuxerVIn=NULL, *pMuxerAIn=NULL, *pMuxerOut=NULL, *pDvIn = NULL;
  3345.  
  3346.         // obtain the output pin of the source filter and connect it to avi splitter
  3347.         hr = g_pBuilder->FindPin(g_pInputFileFilter, PINDIR_OUTPUT, NULL, NULL, TRUE, 0, &pFileOut);
  3348.         if (SUCCEEDED(hr))
  3349.         {
  3350.             ASSERT(pFileOut);
  3351.             //now get the input pin of the splitter
  3352.             hr = g_pBuilder->FindPin(g_pAviSplitter, PINDIR_INPUT, NULL, NULL, TRUE, 0, &pSplitterIn);
  3353.             if (SUCCEEDED(hr))
  3354.             {
  3355.                 ASSERT(pSplitterIn);
  3356.                 //connect the file output pin to the AVI splitter in
  3357.                 //until we do this, the output pin on the splitter won't appear
  3358.                 hr = g_pGraphBuilder->ConnectDirect(pFileOut, pSplitterIn, NULL);
  3359.                 if (SUCCEEDED(hr))
  3360.                 {
  3361.                     // get the video & audio output pins of the avi splitter
  3362.                     hr = g_pBuilder->FindPin(g_pAviSplitter, PINDIR_OUTPUT, NULL, &MEDIATYPE_Video, TRUE, 0, &pSplitterVOut);
  3363.                     hr = g_pBuilder->FindPin(g_pAviSplitter, PINDIR_OUTPUT, NULL, &MEDIATYPE_Audio, TRUE, 0, &pSplitterAOut);
  3364.                     if(SUCCEEDED(hr))
  3365.                     {
  3366.                         ASSERT(pSplitterVOut);
  3367.                         ASSERT(pSplitterAOut);
  3368.                         // Add the DVMuxer to the graph
  3369.                         EXECUTE_ASSERT(S_OK == g_pGraphBuilder->AddFilter(g_pDVMux, L"DV Muxer"));
  3370.                         // get the video & audio input pins on the dvmuxer and connect it to the corressponding output pins of avi splitter
  3371.                         hr = g_pBuilder->FindPin(g_pDVMux, PINDIR_INPUT, NULL, NULL, TRUE, 0, &pMuxerVIn);
  3372.                         if(SUCCEEDED(hr))
  3373.                         {
  3374.                             hr = g_pGraphBuilder->ConnectDirect(pSplitterVOut, pMuxerVIn, NULL);
  3375.                             if(SUCCEEDED(hr))
  3376.                             {
  3377.                                 hr = g_pBuilder->FindPin(g_pDVMux, PINDIR_INPUT, NULL, NULL, TRUE, 0, &pMuxerAIn);
  3378.                                 if(SUCCEEDED(hr))
  3379.                                 {
  3380.                                     hr = g_pGraphBuilder->ConnectDirect(pSplitterAOut, pMuxerAIn, NULL);
  3381.                                     // get the ouput pin of the dv muxer and the dv camera input pin and connect them
  3382.                                     if(SUCCEEDED(hr))
  3383.                                     {
  3384.                                         hr = g_pBuilder->FindPin(g_pDVMux, PINDIR_OUTPUT, NULL, NULL, TRUE, 0, &pMuxerOut);
  3385.                                         if(SUCCEEDED(hr))
  3386.                                         {
  3387.                                             hr = g_pBuilder->FindPin(g_pDVCamera, PINDIR_INPUT, NULL, NULL, TRUE, 0, &pDvIn);
  3388.                                             if (SUCCEEDED(hr))
  3389.                                             {
  3390.                                                 ASSERT(pDvIn);
  3391.                                                 hr = g_pGraphBuilder->ConnectDirect(pMuxerOut, pDvIn, NULL);
  3392.                                                 //
  3393.                                                 //the capture portion of the graph should be done now, lets do the preview segment
  3394.                                                 //
  3395.                                                 if (FAILED(hr))
  3396.                                                 {
  3397.                                                     DV_LogOut(LOG_PRIORITY_ERROR, LOG_LEVEL_MEDIUM, TEXT("Could not connect the DV Muxer to the DV Camera"));
  3398.                                                 } 
  3399.                                                 SAFE_RELEASE(pDvIn);
  3400.                                             } 
  3401.                                         }
  3402.                                         SAFE_RELEASE(pMuxerOut);
  3403.                                     }
  3404.                                 }
  3405.                                 SAFE_RELEASE(pMuxerAIn);
  3406.                             }
  3407.                         }
  3408.                         SAFE_RELEASE(pMuxerVIn);
  3409.                     }                   
  3410.                     SAFE_RELEASE(pSplitterVOut);
  3411.                     SAFE_RELEASE(pSplitterAOut);
  3412.                 } // Release interfaces appropriately
  3413.                 else
  3414.                 {
  3415.                     // Handler for invalid source file format
  3416.                     if (VFW_E_INVALID_FILE_FORMAT == hr)
  3417.                     {
  3418.                         MBOX(TEXT("The File format is invalid for the input file"));
  3419.                         DV_LogOut(LOG_PRIORITY_ERROR, LOG_LEVEL_SUCCINCT, TEXT("The File format is invalid for the input file"));
  3420.                     } 
  3421.                     else
  3422.                     {
  3423.                         DV_LogOut(LOG_PRIORITY_ERROR, LOG_LEVEL_SUCCINCT, TEXT("Could not connect ouput pin from file (0x%x)"), hr);
  3424.                     } 
  3425.                 }
  3426.                 SAFE_RELEASE(pSplitterIn);
  3427.             } 
  3428.             SAFE_RELEASE(pFileOut);
  3429.         } 
  3430.     }
  3431.     //if something failed, remove all of the filters we could have added here, 
  3432.     //because DisconnectAll only removes connected filters
  3433.     if (FAILED(hr))
  3434.     {
  3435.         if (g_pAviSplitter)
  3436.             g_pGraphBuilder->RemoveFilter(g_pAviSplitter);
  3437.         if (g_pInputFileFilter)
  3438.             g_pGraphBuilder->RemoveFilter(g_pInputFileFilter);
  3439.  
  3440.     } 
  3441.     return hr;
  3442.  
  3443. /*-------------------------------------------------------------------------
  3444. Routine:        DV_SetAviOptions
  3445. Purpose:        Routine for changing AVI Mux properties.  In this sample, we just set a few options.  
  3446.                     These options could be set through the Avi Mux property sheet, or through a separate dialog
  3447. Arguments:    pointer to the AVI renderer (from SetOutputFileName())
  3448. Returns:        HRESULT as appropriate
  3449. Notes:          
  3450. ------------------------------------------------------------------------*/
  3451. HRESULT DV_SetAviOptions(IBaseFilter *ppf, InterleavingMode INTERLEAVE_MODE)
  3452. {
  3453.     HRESULT hr;
  3454.     ASSERT(ppf);
  3455.     IConfigAviMux       *pMux           = NULL;
  3456.     IConfigInterleaving *pInterleaving  = NULL;
  3457.  
  3458.     // QI for interface AVI Muxer
  3459.     hr = ppf->QueryInterface(IID_IConfigAviMux, reinterpret_cast<PVOID *>(&pMux));
  3460.     if (SUCCEEDED(hr))
  3461.     {
  3462.         pMux->SetOutputCompatibilityIndex(TRUE);
  3463.         // QI for interface Interleaving
  3464.         hr = ppf->QueryInterface(IID_IConfigInterleaving, reinterpret_cast<PVOID *>(&pInterleaving));
  3465.         if (SUCCEEDED(hr))
  3466.         {
  3467.             // put the interleaving mode (full, none, half)
  3468.             pInterleaving->put_Mode(INTERLEAVE_MODE);
  3469.             SAFE_RELEASE(pInterleaving);
  3470.         } 
  3471.         SAFE_RELEASE(pMux);
  3472.     } 
  3473.     return hr;
  3474.  
  3475.  
  3476. /*-------------------------------------------------------------------------
  3477. Routine:        DV_AboutDlgProc
  3478. Purpose:        simple standard about dialog box proc 
  3479. Arguments:    Usual Dialog Processing parameters
  3480. Returns:        BOOL
  3481. Notes:          
  3482. ------------------------------------------------------------------------*/
  3483. BOOL CALLBACK DV_AboutDlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
  3484. {
  3485.     switch ( msg )
  3486.     {
  3487.     //the only command we process are those that close the dialog   
  3488.         case WM_COMMAND:
  3489.             EndDialog(hwnd, TRUE);
  3490.             return TRUE;
  3491.         case WM_INITDIALOG:
  3492.             return TRUE;
  3493.     }
  3494.     return FALSE;
  3495. }
  3496.  
  3497. /*-------------------------------------------------------------------------
  3498. Routine:        DV_ChooseModeDlgProc
  3499. Purpose:        dialog proc to select camera/vcr mode on devices that do not respond to the queries
  3500. Arguments:    Usual Dialog Processing parameters
  3501. Returns:        BOOL
  3502. Notes:          
  3503. ------------------------------------------------------------------------*/
  3504. BOOL CALLBACK DV_ChooseModeDlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
  3505. {
  3506.     switch ( msg )
  3507.     {
  3508.         case WM_COMMAND:
  3509.             // Choose whether the camera or vcr unit is selected manually
  3510.             switch LOWORD(wParam)
  3511.             {
  3512.                 case IDC_BUTTON_CAMERA :
  3513.                     g_CurrentMode = CameraMode;
  3514.                     EndDialog(hwnd, TRUE);
  3515.                     break;                   
  3516.                 case IDC_BUTTON_VCR :
  3517.                     g_CurrentMode = VcrMode;
  3518.                     EndDialog(hwnd, TRUE);
  3519.                     break;
  3520.                 default :
  3521.                     break;
  3522.             } 
  3523.             break;            
  3524.         case WM_INITDIALOG:
  3525.             return TRUE;
  3526.     }
  3527.     return FALSE;
  3528. }
  3529.   
  3530. /*-------------------------------------------------------------------------
  3531. Routine:        DV_ChangeDecodeSizeProc
  3532. Purpose:        UI wrapper to change DV Decode size
  3533. Arguments:    Usual Dialog Processing parameters
  3534. Returns:        BOOL
  3535. Notes:          
  3536. ------------------------------------------------------------------------*/
  3537. BOOL CALLBACK DV_ChangeDecodeSizeProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
  3538. {
  3539.     int iDisplayPix = 0;
  3540.     HRESULT hr;
  3541.  
  3542.     switch ( msg )
  3543.     {
  3544.         case WM_COMMAND:
  3545.             // Select which DV format resolution you would like to navigate to
  3546.             switch LOWORD(wParam)
  3547.             {
  3548.                 case IDOK :
  3549.                     //get selected size, and set size accordingly
  3550.                     if (Button_GetCheck(GetDlgItem(hwnd, IDC_RADIO_88x60)))
  3551.                     {
  3552.                         g_pDvDec->put_IPDisplay(DVRESOLUTION_DC);
  3553.                         g_iVWWidth = 88;    g_iVWHeight = 60;
  3554.                         g_iAppWidth = g_iVWWidth+5; g_iAppHeight = g_iVWHeight+135;
  3555.                         SendMessage(g_hwndApp, WM_SIZE, SIZE_RESTORED, MAKELONG(g_iAppWidth, g_iAppHeight));
  3556.                     } 
  3557.                     else if (Button_GetCheck(GetDlgItem(hwnd, IDC_RADIO_180x120)))
  3558.                     {
  3559.                         g_pDvDec->put_IPDisplay(DVRESOLUTION_QUARTER);
  3560.                         g_iVWWidth = 160;   g_iVWHeight = 120;
  3561.                         g_iAppWidth = g_iVWWidth+5; g_iAppHeight = g_iVWHeight+115;
  3562.                         SendMessage(g_hwndApp, WM_SIZE, SIZE_RESTORED, MAKELONG(g_iAppWidth, g_iAppHeight));
  3563.                     } 
  3564.                     else if (Button_GetCheck(GetDlgItem(hwnd, IDC_RADIO_360x240)))
  3565.                     {
  3566.                         g_pDvDec->put_IPDisplay(DVRESOLUTION_HALF);
  3567.                         g_iVWWidth = 360;   g_iVWHeight = 240;
  3568.                         g_iAppWidth = g_iVWWidth+5; g_iAppHeight = g_iVWHeight+95;
  3569.                         SendMessage(g_hwndApp, WM_SIZE, SIZE_RESTORED, MAKELONG(g_iAppWidth, g_iAppHeight));
  3570.                     } 
  3571.                     else if (Button_GetCheck(GetDlgItem(hwnd, IDC_RADIO_720x480)))
  3572.                     {
  3573.                         g_pDvDec->put_IPDisplay(DVRESOLUTION_FULL);
  3574.                         g_iVWWidth = 720;   g_iVWHeight = 480;
  3575.                         g_iAppWidth = g_iVWWidth+5; g_iAppHeight = g_iVWHeight+95;
  3576.                         SendMessage(g_hwndApp, WM_SIZE, SIZE_RESTORED, MAKELONG(g_iAppWidth, g_iAppHeight));
  3577.                     } 
  3578.                     else
  3579.                     {
  3580.                         DV_LogOut(LOG_PRIORITY_ERROR, LOG_LEVEL_SUCCINCT, TEXT("Invalid selection in DecodeSize Dialog"));
  3581.                     }                    
  3582.                 //safely fall through                    
  3583.  
  3584.                 case IDCANCEL :
  3585.                     //if it's the preview graph - restart it - otherwise leave it stopped
  3586.                     if (GRAPH_PREVIEW == g_iCurrentGraph)
  3587.                     {
  3588.                         DV_StartGraph();
  3589.                     } 
  3590.                     SAFE_RELEASE(g_pDvDec);
  3591.                     EndDialog(hwnd, TRUE);
  3592.                     break;
  3593.  
  3594.                 default :
  3595.                     break;
  3596.             } 
  3597.             break;
  3598.             
  3599.         case WM_INITDIALOG:
  3600.             /*
  3601.                 can't set the decode size if the graph is running - so we'll stop it.
  3602.                 there are other options, such as graying out the menu item whil the graph is 
  3603.                 playing that could be implemented.  For this simple application, this methos
  3604.                 will suffice.
  3605.             */
  3606.             if (SUCCEEDED(DV_StopGraph()))
  3607.             {
  3608.                 hr = g_pDVCodec->QueryInterface(IID_IIPDVDec, reinterpret_cast<PVOID *>(&g_pDvDec));
  3609.                 if (SUCCEEDED(hr))
  3610.                 {
  3611.                     hr = g_pDvDec->get_IPDisplay(&iDisplayPix);
  3612.                     //set button check appropriately
  3613.                     switch (iDisplayPix)
  3614.                     {
  3615.                         case DVRESOLUTION_DC :
  3616.                             Button_SetCheck(GetDlgItem(hwnd, IDC_RADIO_88x60), TRUE);
  3617.                             break;
  3618.  
  3619.                         case DVRESOLUTION_QUARTER :
  3620.                             Button_SetCheck(GetDlgItem(hwnd, IDC_RADIO_180x120), TRUE);
  3621.                             break;
  3622.  
  3623.                         case DVRESOLUTION_HALF :
  3624.                             Button_SetCheck(GetDlgItem(hwnd, IDC_RADIO_360x240), TRUE);
  3625.                             break;
  3626.  
  3627.                         case DVRESOLUTION_FULL :
  3628.                             Button_SetCheck(GetDlgItem(hwnd, IDC_RADIO_720x480), TRUE);
  3629.                             break;
  3630.  
  3631.                         default :
  3632.                             DV_LogOut(LOG_PRIORITY_ERROR, LOG_LEVEL_SUCCINCT, TEXT("Invalid return from get_IPDisplay"));
  3633.                             break;
  3634.                     } 
  3635.                 } 
  3636.                 else
  3637.                 {
  3638.                     MBOX(TEXT("Cannot determine current Decode size"));
  3639.                     EndDialog(hwnd, FALSE);
  3640.                     DV_LogOut(LOG_PRIORITY_ERROR, LOG_LEVEL_SUCCINCT, TEXT("Could not get IIPDVDec interface.  hr = 0x%x"), hr);
  3641.                 } 
  3642.             } 
  3643.             else
  3644.             {
  3645.                 MBOX(TEXT("Could not stop graph"));
  3646.                 EndDialog(hwnd, FALSE);
  3647.             } 
  3648.             return TRUE;
  3649.     }
  3650.     return FALSE;
  3651. }
  3652.  
  3653. /*-------------------------------------------------------------------------
  3654. Routine:        DV_CapSizeDlgProc
  3655. Purpose:        Dialog proc for cap size dialog
  3656. Arguments:    Usual Dialog Processing parameters
  3657. Returns:        BOOL
  3658. Notes:          
  3659. ------------------------------------------------------------------------*/
  3660. BOOL CALLBACK DV_CapSizeDlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
  3661. {
  3662.   
  3663.     switch ( msg )
  3664.     {
  3665.         case WM_INITDIALOG:
  3666.         {
  3667.             TCHAR           capDisk[8];
  3668.             ULARGE_INTEGER  ulFreeBytes;
  3669.             ULARGE_INTEGER  ulTotalBytes;
  3670.             ULARGE_INTEGER  ulAvailBytes;
  3671.  
  3672.             // make sure output file name has been input for capture
  3673.             if (!g_OutputFileName[0])
  3674.             {
  3675.                 MBOX(TEXT("Please set up an output file name for recording"));
  3676.                 EndDialog(hwnd, FALSE);
  3677.                 return FALSE;
  3678.             } 
  3679.  
  3680.             //need to determine disk space and init the dialog appropriately
  3681.             lstrcpyn(capDisk, g_OutputFileName, 3);
  3682.             capDisk[4] = '\0';
  3683.             GetDiskFreeSpaceEx(capDisk, &ulFreeBytes, &ulTotalBytes, &ulAvailBytes);
  3684.             DV_LogOut(LOG_PRIORITY_INFO, LOG_LEVEL_SUCCINCT, TEXT("Available MB on drive %s is %d MB"), capDisk, ulAvailBytes.QuadPart / (1024 * 1024));
  3685.  
  3686.             //let's see what our top limits are, and set our limits appropriately
  3687.             if ((ulAvailBytes.QuadPart / DV_BYTES_IN_MEG) < 120)
  3688.             {
  3689.                 //less than 120 MB available - subtract 10 MB at a time until we get a usable amount
  3690.                 UINT i = 110;
  3691.                 while ((ulAvailBytes.QuadPart / DV_BYTES_IN_MEG) < i)
  3692.                 {
  3693.                     i -= 10;
  3694.                 } 
  3695.                 SendMessage(GetDlgItem(hwnd, IDC_SPIN_TIME), UDM_SETRANGE, 0, MAKELONG(i / 4, 1));
  3696.                 SendMessage(GetDlgItem(hwnd, IDC_SPIN_SIZE), UDM_SETRANGE, 0, MAKELONG(i, 1));
  3697.             }
  3698.             else
  3699.             {
  3700.                 SendMessage(GetDlgItem(hwnd, IDC_SPIN_TIME), UDM_SETRANGE, 0, MAKELONG( ((ulAvailBytes.QuadPart / (1024 * 1024) ) - 10) / 4, 1));
  3701.                 SendMessage(GetDlgItem(hwnd, IDC_SPIN_SIZE), UDM_SETRANGE, 0, MAKELONG( (ulAvailBytes.QuadPart / (1024 * 1024) ) - 10, 1));
  3702.             }
  3703.  
  3704.             //enable / disable the controls as appropriate
  3705.             switch (g_dwCaptureLimit)
  3706.             {
  3707.                 case DV_CAPLIMIT_NONE :
  3708.                     Button_SetCheck(GetDlgItem(hwnd, IDC_RADIO_NOLIMIT), TRUE);
  3709.                     EnableWindow(GetDlgItem(hwnd, IDC_EDIT_SIZE), FALSE);
  3710.                     EnableWindow(GetDlgItem(hwnd, IDC_SPIN_SIZE), FALSE);
  3711.                     EnableWindow(GetDlgItem(hwnd, IDC_EDIT_TIME), FALSE);
  3712.                     EnableWindow(GetDlgItem(hwnd, IDC_SPIN_TIME), FALSE);
  3713.                     break;
  3714.                 
  3715.                 case DV_CAPLIMIT_TIME :
  3716.                 {
  3717.                     /*check the radio button, disable the size based controls */
  3718.                     Button_SetCheck(GetDlgItem(hwnd, IDC_RADIO_TIME), TRUE);
  3719.                     EnableWindow(GetDlgItem(hwnd, IDC_EDIT_SIZE), FALSE);
  3720.                     EnableWindow(GetDlgItem(hwnd, IDC_SPIN_SIZE), FALSE);
  3721.  
  3722.                     break;
  3723.                 }
  3724.                 case DV_CAPLIMIT_SIZE :
  3725.                 {
  3726.                     /*check the radio button, disable the time based controls */
  3727.                     Button_SetCheck(GetDlgItem(hwnd, IDC_RADIO_SIZE), TRUE);
  3728.                     EnableWindow(GetDlgItem(hwnd, IDC_EDIT_TIME), FALSE);
  3729.                     EnableWindow(GetDlgItem(hwnd, IDC_SPIN_TIME), FALSE);
  3730.                     
  3731.                     break;                    
  3732.                 }
  3733.             }
  3734.             SetDlgItemInt(hwnd, IDC_EDIT_TIME, g_dwTimeLimit, FALSE);
  3735.             SetDlgItemInt(hwnd, IDC_EDIT_SIZE, g_dwDiskSpace, FALSE);
  3736.             break;
  3737.         } 
  3738.         case WM_COMMAND :
  3739.             switch LOWORD(wParam)
  3740.             {
  3741.                 // Update the controls ui according to the choices made
  3742.                 case IDC_RADIO_NOLIMIT :
  3743.                 {
  3744.                     Button_SetCheck(GetDlgItem(hwnd, IDC_RADIO_NOLIMIT), TRUE);
  3745.                     EnableWindow(GetDlgItem(hwnd, IDC_EDIT_SIZE), FALSE);
  3746.                     EnableWindow(GetDlgItem(hwnd, IDC_SPIN_SIZE), FALSE);
  3747.                     EnableWindow(GetDlgItem(hwnd, IDC_EDIT_TIME), FALSE);
  3748.                     EnableWindow(GetDlgItem(hwnd, IDC_SPIN_TIME), FALSE);
  3749.                     break;
  3750.                 }
  3751.                     
  3752.                 case IDC_RADIO_TIME :
  3753.                 {
  3754.                     Button_SetCheck(GetDlgItem(hwnd, IDC_RADIO_TIME), TRUE);
  3755.                     EnableWindow(GetDlgItem(hwnd, IDC_EDIT_SIZE), FALSE);
  3756.                     EnableWindow(GetDlgItem(hwnd, IDC_SPIN_SIZE), FALSE);
  3757.                     EnableWindow(GetDlgItem(hwnd, IDC_EDIT_TIME), TRUE);
  3758.                     EnableWindow(GetDlgItem(hwnd, IDC_SPIN_TIME), TRUE);
  3759.                     break;
  3760.                 } 
  3761.                 
  3762.                 case IDC_RADIO_SIZE :
  3763.                 {
  3764.                     Button_SetCheck(GetDlgItem(hwnd, IDC_RADIO_SIZE), TRUE);
  3765.                     EnableWindow(GetDlgItem(hwnd, IDC_EDIT_TIME), FALSE);
  3766.                     EnableWindow(GetDlgItem(hwnd, IDC_SPIN_TIME), FALSE);
  3767.                     EnableWindow(GetDlgItem(hwnd, IDC_EDIT_SIZE), TRUE);
  3768.                     EnableWindow(GetDlgItem(hwnd, IDC_SPIN_SIZE), TRUE);
  3769.                     break;
  3770.                 } 
  3771.  
  3772.                 case IDOK :
  3773.                 {
  3774.                     BOOL bTranslated = FALSE;
  3775.                     // The selections are made
  3776.                     // update the new global capture flag
  3777.                     if (Button_GetCheck(GetDlgItem(hwnd, IDC_RADIO_NOLIMIT)))
  3778.                     {
  3779.                         g_dwCaptureLimit = DV_CAPLIMIT_NONE;
  3780.                         DV_LogOut(LOG_PRIORITY_INFO, LOG_LEVEL_MEDIUM, TEXT("No capture size limit"));
  3781.                     } 
  3782.                     else if (Button_GetCheck(GetDlgItem(hwnd, IDC_RADIO_TIME)))   
  3783.                     {
  3784.                         g_dwTimeLimit = GetDlgItemInt(hwnd, IDC_EDIT_TIME, &bTranslated, FALSE);
  3785.                         g_dwCaptureLimit = DV_CAPLIMIT_TIME;
  3786.                         DV_LogOut(LOG_PRIORITY_INFO, LOG_LEVEL_MEDIUM, TEXT("Time based limit - %d"), g_dwTimeLimit);
  3787.                     } 
  3788.                     else if (Button_GetCheck(GetDlgItem(hwnd, IDC_RADIO_SIZE)))   
  3789.                     {
  3790.                         g_dwDiskSpace = GetDlgItemInt(hwnd, IDC_EDIT_SIZE, &bTranslated, FALSE);
  3791.                         g_dwCaptureLimit = DV_CAPLIMIT_SIZE;
  3792.                         DV_LogOut(LOG_PRIORITY_INFO, LOG_LEVEL_MEDIUM, TEXT("Disk based limit - %d MB"), g_dwDiskSpace);
  3793.                     } 
  3794.                     EndDialog(hwnd, TRUE);
  3795.                     return TRUE;
  3796.                 }
  3797.                 
  3798.                 case IDCANCEL :
  3799.                     // update nothing much
  3800.                     EndDialog(hwnd, FALSE);
  3801.                     return FALSE;
  3802.                 default :
  3803.                     return FALSE;
  3804.             }            
  3805.             return TRUE;
  3806.     }
  3807.     return FALSE;
  3808. }
  3809.  
  3810. /*-------------------------------------------------------------------------
  3811. Routine:        DV_GetTapeInfo
  3812. Purpose:        Get Frame rate and availability of dvcr tape
  3813. Arguments:    None
  3814. Returns:        HRESULT as appropriate
  3815. Notes:          
  3816. ------------------------------------------------------------------------*/
  3817. HRESULT DV_GetTapeInfo(void)
  3818. {
  3819.     HRESULT hr;
  3820.     LONG    lMediaType = 0;
  3821.     LONG    lInSignalMode = 0;
  3822.  
  3823.     // Query Media Type of the transport
  3824.     hr = g_pExtTrans->GetStatus(ED_MEDIA_TYPE, &lMediaType);
  3825.     if (SUCCEEDED(hr))
  3826.     {
  3827.         if (ED_MEDIA_NOT_PRESENT == lMediaType)
  3828.         {
  3829.             // Update the log & Status Window
  3830.             DV_LogOut(LOG_PRIORITY_INFO, LOG_LEVEL_SUCCINCT, TEXT("No tape is inserted"));
  3831.             DV_StatusText(TEXT("VCR Mode - No tape, or unknown format"), 2);
  3832.             //we want to return failure if there is no tape installed
  3833.             hr = S_FALSE;  
  3834.         } 
  3835.         else
  3836.         {
  3837.             //tape type should always be DVC
  3838.             ASSERT(ED_MEDIA_DVC == lMediaType);
  3839.  
  3840.             // Now lets query for the signal mode of the tape.
  3841.             g_pExtTrans->GetTransportBasicParameters(ED_TRANSBASIC_INPUT_SIGNAL, &lInSignalMode, NULL);
  3842.             Sleep(_MAX_SLEEP);
  3843.             if (SUCCEEDED(hr))
  3844.             {   // determine whether the camcorder supports ntsc or pal
  3845.                 switch (lInSignalMode)
  3846.                 {
  3847.                     case ED_TRANSBASIC_SIGNAL_525_60_SD :
  3848.                     g_AvgTimePerFrame = 33;  // 33 milli-sec (29.97 FPS)
  3849.                     DV_StatusText(TEXT("VCR Mode - NTSC"), 2);
  3850.                     break;
  3851.  
  3852.                 case ED_TRANSBASIC_SIGNAL_525_60_SDL :
  3853.                     g_AvgTimePerFrame = 33;  // 33 milli-sec (29.97 FPS)
  3854.                     DV_StatusText(TEXT("VCR Mode - NTSC"), 2);
  3855.                     break;
  3856.  
  3857.                 case ED_TRANSBASIC_SIGNAL_625_50_SD :
  3858.                     g_AvgTimePerFrame = 40;  // 40 milli-sec (25FPS)
  3859.                     DV_StatusText(TEXT("VCR Mode - PAL"), 2);
  3860.                     break;
  3861.  
  3862.                 case ED_TRANSBASIC_SIGNAL_625_50_SDL :
  3863.                     g_AvgTimePerFrame = 40;  // 40 milli-sec (25FPS)
  3864.                     DV_StatusText(TEXT("VCR Mode - PAL"), 2);
  3865.                     break;
  3866.  
  3867.                 default : 
  3868.                     DV_LogOut(LOG_PRIORITY_ERROR, LOG_LEVEL_SUCCINCT, TEXT("Unsupported or unrecognized tape format type"));
  3869.                     g_AvgTimePerFrame = 33;  // 33 milli-sec (29.97 FPS); default
  3870.                     break;
  3871.                 }
  3872.  
  3873.                 DV_LogOut(LOG_PRIORITY_INFO, LOG_LEVEL_MEDIUM, TEXT("Avg time per frame is %d FPS"), g_AvgTimePerFrame);
  3874.             } 
  3875.             else
  3876.             {
  3877.                 DV_LogOut(LOG_PRIORITY_ERROR, LOG_LEVEL_SUCCINCT, TEXT("GetTransportBasicParameters Failed (0x%x)"), hr);
  3878.             } 
  3879.         }
  3880.     }
  3881.     else
  3882.     {
  3883.         DV_LogOut(LOG_PRIORITY_ERROR, LOG_LEVEL_SUCCINCT, TEXT("GetStatus Failed (0x%x)"), hr);
  3884.     } 
  3885.     return hr;
  3886. }
  3887.  
  3888. /*-------------------------------------------------------------------------
  3889. Routine:        DV_RefreshMode
  3890. Purpose:        Use this to rebuild the necessary stuff to switch between VCR and camera mode
  3891. Arguments:    None
  3892. Returns:        TRUE if successful
  3893. Notes:          
  3894. ------------------------------------------------------------------------*/
  3895. BOOL DV_RefreshMode(void)
  3896. {
  3897.     BOOL bStatus    = FALSE;
  3898.     // Query the current device type    
  3899.     switch(DV_GetDVMode())
  3900.     {
  3901.         case CameraMode :
  3902.             // update the Graph Mode menu items & status window
  3903.             EnableMenuItem(GetMenu(g_hwndApp), IDM_FILETODV, MF_GRAYED);
  3904.             EnableMenuItem(GetMenu(g_hwndApp), IDM_FILETODV_NOPRE, MF_GRAYED);
  3905.             EnableMenuItem(GetMenu(g_hwndApp), IDM_FILETODV_TYPE2, MF_GRAYED);
  3906.             EnableMenuItem(GetMenu(g_hwndApp), IDM_FILETODV_NOPRE_TYPE2, MF_GRAYED);
  3907.             EnableMenuItem(GetMenu(g_hwndApp), IDM_CHECKTAPE, MF_GRAYED);
  3908.             DV_StatusText(TEXT("Camera Mode"), 2);
  3909.             bStatus = TRUE;
  3910.             break;
  3911.  
  3912.         case VcrMode :
  3913.             // Query the tape info & update the status bar
  3914.             DV_GetTapeInfo();  
  3915.             // update the Graph Mode menu items & status window
  3916.             EnableMenuItem(GetMenu(g_hwndApp), IDM_CHECKTAPE, MF_ENABLED);
  3917.             EnableMenuItem(GetMenu(g_hwndApp), IDM_FILETODV, MF_ENABLED);
  3918.             EnableMenuItem(GetMenu(g_hwndApp), IDM_FILETODV_NOPRE, MF_ENABLED);
  3919.             EnableMenuItem(GetMenu(g_hwndApp), IDM_FILETODV_TYPE2, MF_ENABLED);
  3920.             EnableMenuItem(GetMenu(g_hwndApp), IDM_FILETODV_NOPRE_TYPE2, MF_ENABLED);
  3921.             EnableMenuItem(GetMenu(g_hwndApp), IDM_CHECKTAPE, MF_ENABLED);
  3922.             bStatus = TRUE;
  3923.             break;
  3924.  
  3925.         case UnknownMode :
  3926.             DV_LogOut(LOG_PRIORITY_ERROR, LOG_LEVEL_SUCCINCT, TEXT("Should not have reached unknown mode handler"));
  3927.             break;
  3928.             
  3929.         default :
  3930.             DV_LogOut(LOG_PRIORITY_ERROR, LOG_LEVEL_SUCCINCT, TEXT("Could not determine Camera/Vcr Mode"));
  3931.             break;
  3932.     }
  3933.     return bStatus;
  3934.  
  3935. /*-------------------------------------------------------------------------
  3936. Routine:        DV_WriteRegKeys
  3937. Purpose:        Save the input and output file names to the registry
  3938. Arguments:    None
  3939. Returns:        None
  3940. Notes:          
  3941. ------------------------------------------------------------------------*/
  3942. void DV_WriteRegKeys(void)
  3943. {
  3944.     HKEY hKey;
  3945.     LONG lResult;
  3946.     DWORD dwDisp = 0;
  3947.     // Create DVApp's registry keys
  3948.     lResult = RegCreateKeyEx(HKEY_CURRENT_USER, 
  3949.                              TEXT("Software\\Microsoft\\DVApp"), 
  3950.                              NULL, 
  3951.                              NULL, 
  3952.                              REG_OPTION_NON_VOLATILE, 
  3953.                              KEY_ALL_ACCESS, 
  3954.                              NULL,
  3955.                              &hKey,
  3956.                              &dwDisp);
  3957.  
  3958.     // Write the input & output filenames
  3959.     if (REG_OPENED_EXISTING_KEY == dwDisp ||  REG_CREATED_NEW_KEY == dwDisp) 
  3960.     {
  3961.         //note that the sizeof parameter expects BYTES (not characters)
  3962.         RegSetValueEx(hKey, TEXT("InputFile"), NULL, REG_SZ, (PBYTE)g_InputFileName, (lstrlen(g_InputFileName) * sizeof(TCHAR)) + sizeof(TCHAR));
  3963.         RegSetValueEx(hKey, TEXT("OutputFile"), NULL, REG_SZ, (PBYTE)g_OutputFileName, (lstrlen(g_OutputFileName) * sizeof(TCHAR)) + sizeof(TCHAR));
  3964.         RegCloseKey(hKey);
  3965.     }
  3966.  
  3967.  
  3968. /*-------------------------------------------------------------------------
  3969. Routine:        DV_ReadRegKeys
  3970. Purpose:        Save the input and output file names to the registry
  3971. Arguments:    None
  3972. Returns:        None
  3973. Notes:          
  3974. ------------------------------------------------------------------------*/
  3975. void DV_ReadRegKeys(void)
  3976. {
  3977.     HKEY hKey;
  3978.     LONG lResult;
  3979.     DWORD dwType;
  3980.     DWORD a = MAX_PATH * sizeof(TCHAR), b = MAX_PATH * sizeof(TCHAR);
  3981.     // Read the DVApp's registry keys
  3982.     lResult = RegOpenKeyEx(HKEY_CURRENT_USER, TEXT("Software\\Microsoft\\DVApp"), NULL, KEY_ALL_ACCESS, &hKey);
  3983.  
  3984.     // Load the input & output filenames
  3985.     if (ERROR_SUCCESS == lResult)
  3986.     {
  3987.         RegQueryValueEx(hKey, TEXT("InputFile"), NULL, &dwType, (PBYTE)g_InputFileName, &a);
  3988.         RegQueryValueEx(hKey, TEXT("OutputFile"), NULL, &dwType, (PBYTE)g_OutputFileName, &b);
  3989.         RegCloseKey(hKey);
  3990.     }
  3991.     
  3992. }
  3993.  
  3994.  
  3995. /*-------------------------------------------------------------------------
  3996. Routine:        DV_SaveGraph
  3997. Purpose:        Save the filter graph into a *.grf file
  3998. Arguments:    FileName
  3999. Returns:        HRESULT as appropriate
  4000. Notes:          
  4001. ------------------------------------------------------------------------*/
  4002. HRESULT DV_SaveGraph(TCHAR* sGraphFile)
  4003. {
  4004.     IStorage *          pStorage = NULL;
  4005.     IStream *           pStream = NULL;
  4006.     IPersistStream *    pPersistStream = NULL;
  4007.     HRESULT             hr = S_OK;
  4008.  
  4009.     if(g_pGraphBuilder == NULL || sGraphFile == NULL)
  4010.         return E_FAIL;
  4011.  
  4012. #ifndef UNICODE
  4013.     WCHAR swGraphFile[MAX_PATH];
  4014.     MultiByteToWideChar(CP_ACP, 0, sGraphFile, -1, swGraphFile, MAX_PATH);
  4015.  
  4016.     // Either Open or Create the *.GRF file
  4017.     hr = StgOpenStorage( swGraphFile, NULL, STGM_TRANSACTED | STGM_READWRITE | STGM_SHARE_DENY_WRITE, NULL, NULL, &pStorage );
  4018.     if ( STG_E_FILENOTFOUND == hr )
  4019.         hr = StgCreateDocfile( swGraphFile, STGM_CREATE | STGM_TRANSACTED | STGM_READWRITE | STGM_SHARE_EXCLUSIVE , NULL , &pStorage);
  4020. #else
  4021.     // Either Open or Create the *.GRF file
  4022.     hr = StgOpenStorage( sGraphFile, NULL, STGM_TRANSACTED | STGM_READWRITE | STGM_SHARE_DENY_WRITE, NULL, NULL, &pStorage );
  4023.     if ( STG_E_FILENOTFOUND == hr )
  4024.         hr = StgCreateDocfile( sGraphFile, STGM_CREATE | STGM_TRANSACTED | STGM_2READWRITE | STGM_SHARE_EXCLUSIVE , NULL , &pStorage);
  4025.  
  4026. #endif
  4027.  
  4028.     if ( SUCCEEDED(hr) )
  4029.         hr = pStorage->CreateStream( L"ActiveMovieGraph", STGM_WRITE | STGM_CREATE | STGM_SHARE_EXCLUSIVE, NULL, NULL, &pStream );
  4030.  
  4031.     // Persist the stream, save & commit to disk
  4032.     if ( SUCCEEDED(hr) )
  4033.         hr = g_pGraphBuilder->QueryInterface( IID_IPersistStream, (void **) &pPersistStream );
  4034.     if ( SUCCEEDED(hr) )
  4035.         hr = pPersistStream->Save(pStream, TRUE);
  4036.     if ( SUCCEEDED(hr) )
  4037.         hr = pStorage->Commit( STGC_DEFAULT );
  4038.  
  4039.     if ( SUCCEEDED(hr) )
  4040.         DV_LogOut(LOG_PRIORITY_INFO, LOG_LEVEL_MEDIUM, TEXT("Save current Filter Graph to GRF file succeded"));
  4041.     else
  4042.     {
  4043.         MessageBox( NULL, "Save GRF file failed", "DVApp", MB_ICONEXCLAMATION | MB_OK );
  4044.         DV_LogOut(LOG_PRIORITY_ERROR, LOG_LEVEL_SUCCINCT, TEXT("Save current Filter Graph to GRF file failed"));
  4045.     }
  4046.     SAFE_RELEASE(pStorage);
  4047.     SAFE_RELEASE(pStream);
  4048.     SAFE_RELEASE(pPersistStream);
  4049.  
  4050.     return hr;
  4051. }
  4052.  
  4053. /*-------------------------------------------------------------------------
  4054. Routine:        DV_LogOut 
  4055. Purpose:        Show the Message Window with the Log string 
  4056. Arguments:    logging priority, logging level & the message
  4057. Returns:        None
  4058. Notes:          Logs according to the current logging priority & level set
  4059. ------------------------------------------------------------------------*/
  4060. void __cdecl DV_LogOut (LOG_PRIORITY iPriority, LOG_LEVEL ilevel, TCHAR *szFormat, ... )
  4061. {
  4062.     static TCHAR msg[1024];
  4063.     va_list va;
  4064.     va_start(va, szFormat);
  4065.     wvsprintf (msg, szFormat, va);
  4066.     va_end(va);
  4067.  
  4068.     if ( ilevel > g_iLogLevel )         // we can skip this message
  4069.         return;
  4070.     if ( iPriority > g_iLogPriority )   // we can skip this message
  4071.         return;
  4072.  
  4073.     MBOX(msg);
  4074.     return;
  4075.  
  4076.