apShow.cpp
上传用户:maxzhb99
上传日期:2013-03-13
资源大小:48k
文件大小:12k
源码类别:

DirextX编程

开发平台:

Visual C++

  1. // apShow.cpp: CapShow 僋儔僗偺僀儞僾儕儊儞僥乕僔儑儞
  2. //
  3. //////////////////////////////////////////////////////////////////////
  4. #include "stdafx.h"
  5. #include "apShow.h"
  6. //////////////////////////////////////////////////////////////////////
  7. // 峔抸/徚柵
  8. //////////////////////////////////////////////////////////////////////
  9. CapShow::CapShow()
  10. {
  11. this->g_psCurrent  = Stopped;
  12. g_pGB = NULL;
  13. g_pVW = NULL;
  14. g_pMC = NULL;
  15. g_pME = NULL;
  16. g_pGraph = NULL;
  17. g_pCapture = NULL;
  18. }
  19. CapShow::~CapShow()
  20. {
  21. }
  22. void CapShow::SetFont(HWND hwnd)
  23. {
  24. g_hFont = m_blender.SetTextFont(hwnd,TRUE);  // Don't display the Font Select dialog
  25. }
  26. void CapShow::UpdataStr(HWND ghApp,CString str)
  27. {
  28. TCHAR szStr[256];
  29. strcpy(szStr,str);
  30. m_blender.BlendText(g_pWC,ghApp,szStr,g_hFont);
  31. }
  32. void CapShow::OnPaint(HWND hwnd)
  33. {
  34. HRESULT hr;
  35. PAINTSTRUCT ps; 
  36. HDC         hdc; 
  37. RECT        rcClient; 
  38. GetClientRect(hwnd, &rcClient); 
  39. hdc = BeginPaint(hwnd, &ps); 
  40. if(g_pWC) 
  41. // When using VMR Windowless mode, you must explicitly tell the
  42. // renderer when to repaint the video in response to WM_PAINT
  43. // messages.  This is most important when the video is stopped
  44. // or paused, since the VMR won't be automatically updating the
  45. // window as the video plays.
  46. hr = g_pWC->RepaintVideo(hwnd, hdc);  
  47. else  // No video image. Just paint the whole client area. 
  48. FillRect(hdc, &rcClient, (HBRUSH)(COLOR_BTNFACE + 1)); 
  49. EndPaint(hwnd, &ps); 
  50. }
  51. HRESULT CapShow::PlayWindow(HWND ghApp)
  52. {
  53.     USES_CONVERSION;
  54.     HRESULT hr;
  55.     // Get the interface for DirectShow's GraphBuilder
  56.     JIF(CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, 
  57.                          IID_IGraphBuilder, (void **)&g_pGB));
  58.     if(SUCCEEDED(hr))
  59.     {
  60.         // Create the Video Mixing Renderer and add it to the graph
  61.         JIF(InitializeWindowlessVMR(ghApp));
  62.                 
  63.         // QueryInterface for DirectShow interfaces
  64.         JIF(g_pGB->QueryInterface(IID_IMediaControl, (void **)&g_pMC));
  65.         JIF(g_pGB->QueryInterface(IID_IMediaEventEx, (void **)&g_pME));
  66.         JIF(g_pGB->QueryInterface(IID_IMediaSeeking, (void **)&g_pMS));
  67. /*
  68.         // Is this an audio-only file (no video component)?
  69.         if (CheckVideoVisibility())
  70.         {
  71.             JIF(InitVideoWindow(ghApp,1, 1));
  72.         }
  73.         else
  74.         {
  75.             // This sample requires a video clip to be loaded
  76.             Msg(TEXT("This sample requires media with a video component.  ")
  77.                 TEXT("Please select another file."));
  78.             return E_FAIL;
  79.         }
  80. */
  81.         // Select a text font if not already set
  82.         //if (!g_hFont)
  83.             g_hFont = m_blender.SetTextFont(ghApp, FALSE);  // Don't display the Font Select dialog
  84.         // Add the dynamic text bitmap to the VMR's input
  85.         // If the initial blend fails, post a close message to exit the app
  86. hr = m_blender.BlendText(g_pWC, ghApp, "test", g_hFont);
  87.         // Complete the window setup
  88.         ShowWindow(ghApp, SW_SHOWNORMAL);
  89.         UpdateWindow(ghApp);
  90.         SetForegroundWindow(ghApp);
  91.         SetFocus(ghApp);
  92. #ifdef REGISTER_FILTERGRAPH
  93.         if (FAILED(AddGraphToRot(pGB, &g_dwGraphRegister)))
  94.         {
  95.             Msg(TEXT("Failed to register filter graph with ROT!"));
  96.             g_dwGraphRegister = 0;
  97.         }
  98. #endif
  99.         // Run the graph to play the media file
  100.         JIF(g_pMC->Run());
  101.         // Start the text update timer
  102.         //StartTimer();
  103.     }
  104.     return hr;
  105. }
  106. HRESULT CapShow::InitializeWindowlessVMR(HWND ghApp)
  107. {
  108.     IBaseFilter* pVmr = NULL;
  109.     // Create the VMR and add it to the filter graph.
  110.     HRESULT hr = CoCreateInstance(CLSID_VideoMixingRenderer, NULL,
  111. CLSCTX_INPROC, IID_IBaseFilter, (void**)&pVmr);
  112.     if (SUCCEEDED(hr)) 
  113.     {
  114.         hr = g_pGB->AddFilter(pVmr, L"Video Mixing Renderer");
  115.         if (SUCCEEDED(hr)) 
  116.         {
  117.             // Set the rendering mode and number of streams.  
  118.             IVMRFilterConfig* pConfig;
  119.             hr = pVmr->QueryInterface(IID_IVMRFilterConfig, (void**)&pConfig);
  120.             if( SUCCEEDED(hr)) 
  121.             {
  122.                 hr = pConfig->SetRenderingMode(VMRMode_Windowless);
  123.                 
  124.                 // Set two streams - video and alpha-blended bitmap
  125.                 hr = pConfig->SetNumberOfStreams(2);
  126.                 pConfig->Release();
  127.             }
  128.             hr = pVmr->QueryInterface(IID_IVMRWindowlessControl, (void**)&g_pWC);
  129.             if( SUCCEEDED(hr)) 
  130.             {
  131.                 hr = g_pWC->SetVideoClippingWindow(ghApp);
  132.                 hr = g_pWC->SetBorderColor(RGB(0,0,0));
  133.             }
  134.             // Request point filtering (instead of bilinear filtering)
  135.             // to improve the text quality.  In general, if you are 
  136.             // not scaling the app Image, you should use point filtering.
  137.             // This is very important if you are doing source color keying.
  138.             IVMRMixerControl *pMix;
  139.             hr = pVmr->QueryInterface(IID_IVMRMixerControl, (void**)&pMix);
  140.             if( SUCCEEDED(hr)) 
  141.             {
  142.                 DWORD dwPrefs=0;
  143.                 hr = pMix->GetMixingPrefs(&dwPrefs);
  144.                 if (SUCCEEDED(hr))
  145.                 {
  146.                     dwPrefs |= MixerPref_PointFiltering;
  147.                     dwPrefs &= ~(MixerPref_BiLinearFiltering);
  148.                     hr = pMix->SetMixingPrefs(dwPrefs);
  149.                 }
  150.                 pMix->Release();
  151.             }
  152.             // Get alpha-blended bitmap interface
  153.             hr = pVmr->QueryInterface(IID_IVMRMixerBitmap, (void**)&m_blender.pBMP);
  154.  }
  155.         else
  156.             Msg(TEXT("Failed to add VMR to graph!  hr=0x%xrn"), hr);
  157.         pVmr->Release();
  158.     }
  159.     else
  160.         Msg(TEXT("Failed to create VMR!  hr=0x%xrn"), hr);
  161.     return hr;
  162. }
  163. HRESULT CapShow::CaptureVideo(HWND ghApp)
  164. {
  165.     HRESULT hr;
  166.     IBaseFilter *pSrcFilter=NULL;
  167.     // Get DirectShow interfaces
  168.     hr = GetInterfaces(ghApp);
  169.     if (FAILED(hr))
  170.     {
  171.         return hr;
  172.     }
  173.     // Attach the filter graph to the capture graph
  174.     hr = g_pCapture->SetFiltergraph(g_pGraph);
  175.     if (FAILED(hr))
  176.     {
  177.         return hr;
  178.     }
  179.     // Use the system device enumerator and class enumerator to find
  180.     // a video capture/preview device, such as a desktop USB video camera.
  181.     hr = FindCaptureDevice(&pSrcFilter);
  182.     if (FAILED(hr))
  183.     {
  184.         return hr;
  185.     }
  186.    
  187.     // Add Capture filter to our graph.
  188.     hr = g_pGraph->AddFilter(pSrcFilter, L"Video Capture");
  189.     if (FAILED(hr))
  190.     {
  191.         pSrcFilter->Release();
  192.         return hr;
  193.     }
  194.     // Render the preview pin on the video capture filter
  195.     // Use this instead of g_pGraph->RenderFile
  196.     //hr = g_pCapture->RenderStream (&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video,
  197.      //                              pSrcFilter, NULL, NULL);
  198. hr = g_pCapture->RenderStream(NULL, NULL, pSrcFilter, NULL,NULL);
  199.     if (FAILED(hr))
  200.     {
  201.         pSrcFilter->Release();
  202.         return hr;
  203.     }
  204.     // Now that the filter has been added to the graph and we have
  205.     // rendered its stream, we can release this reference to the filter.
  206.     pSrcFilter->Release();
  207.     // Set video window style and position
  208.     hr = SetupVideoWindow(ghApp);
  209.     if (FAILED(hr))
  210.     {
  211.         return hr;
  212.     }
  213.     // Start previewing video data
  214.     hr = g_pMC->Run();
  215.     if (FAILED(hr))
  216.     {
  217.         return hr;
  218.     }
  219. //****************************************************************************
  220. //***************************僥僗僩*******************************************
  221. //****************************************************************************
  222. // Start the media file
  223. hr = PlayWindow(ghApp);
  224. InitializeWindowlessVMR(ghApp);
  225. SetForegroundWindow(ghApp);
  226.     // Remember current state
  227.     g_psCurrent = Running;
  228.   
  229.     return S_OK;
  230. }
  231. HRESULT CapShow::GetInterfaces(HWND ghApp)
  232. {
  233.     HRESULT hr;
  234.     // Create the filter graph
  235.     hr = CoCreateInstance (CLSID_FilterGraph, NULL, CLSCTX_INPROC,
  236.                            IID_IGraphBuilder, (void **) &g_pGraph);
  237.     if (FAILED(hr))
  238.         return hr;
  239.     // Create the capture graph builder
  240.     hr = CoCreateInstance (CLSID_CaptureGraphBuilder2 , NULL, CLSCTX_INPROC,
  241.                            IID_ICaptureGraphBuilder2, (void **) &g_pCapture);
  242.     if (FAILED(hr))
  243.         return hr;
  244.     
  245.     // Obtain interfaces for media control and Video Window
  246.     hr = g_pGraph->QueryInterface(IID_IMediaControl,(LPVOID *) &g_pMC);
  247.     if (FAILED(hr))
  248.         return hr;
  249.     hr = g_pGraph->QueryInterface(IID_IVideoWindow, (LPVOID *) &g_pVW);
  250.     if (FAILED(hr))
  251.         return hr;
  252.     hr = g_pGraph->QueryInterface(IID_IMediaEvent, (LPVOID *) &g_pME);
  253.     if (FAILED(hr))
  254.         return hr;
  255.     return hr;
  256. }
  257. HRESULT CapShow::FindCaptureDevice(IBaseFilter **ppSrcFilter)
  258. {
  259.     HRESULT hr;
  260.     IBaseFilter * pSrc = NULL;
  261.     CComPtr <IMoniker> pMoniker =NULL;
  262.     ULONG cFetched;
  263.     if (!ppSrcFilter)
  264.         return E_POINTER;
  265.     // Create the system device enumerator
  266.     CComPtr <ICreateDevEnum> pDevEnum =NULL;
  267.     hr = CoCreateInstance (CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC,
  268.                            IID_ICreateDevEnum, (void **) &pDevEnum);
  269.     if (FAILED(hr))
  270.     {
  271.         return hr;
  272.     }
  273.     // Create an enumerator for the video capture devices
  274.     CComPtr <IEnumMoniker> pClassEnum = NULL;
  275.     hr = pDevEnum->CreateClassEnumerator (CLSID_VideoInputDeviceCategory, &pClassEnum, 0);
  276.     if (FAILED(hr))
  277.     {
  278.         return hr;
  279.     }
  280.     // If there are no enumerators for the requested type, then 
  281.     // CreateClassEnumerator will succeed, but pClassEnum will be NULL.
  282.     if (pClassEnum == NULL)
  283.     {
  284.         return E_FAIL;
  285.     }
  286.     // Use the first video capture device on the device list.
  287.     // Note that if the Next() call succeeds but there are no monikers,
  288.     // it will return S_FALSE (which is not a failure).  Therefore, we
  289.     // check that the return code is S_OK instead of using SUCCEEDED() macro.
  290.     if (S_OK == (pClassEnum->Next (1, &pMoniker, &cFetched)))
  291.     {
  292.         // Bind Moniker to a filter object
  293.         hr = pMoniker->BindToObject(0,0,IID_IBaseFilter, (void**)&pSrc);
  294.         if (FAILED(hr))
  295.         {
  296.             return hr;
  297.         }
  298.     }
  299.     else
  300.     {
  301.         return E_FAIL;
  302.     }
  303.     // Copy the found filter pointer to the output parameter.
  304.     // Do NOT Release() the reference, since it will still be used
  305.     // by the calling function.
  306.     *ppSrcFilter = pSrc;
  307.     return hr;
  308. }
  309. HRESULT CapShow::SetupVideoWindow(HWND ghApp)
  310. {
  311.     HRESULT hr;
  312.     // Set the video window to be a child of the main window
  313.     hr = g_pVW->put_Owner((OAHWND)ghApp);
  314.     if (FAILED(hr))
  315.         return hr;
  316.     
  317.     // Set video window style
  318.     hr = g_pVW->put_WindowStyle(WS_CHILD | WS_CLIPCHILDREN);
  319.     if (FAILED(hr))
  320.         return hr;
  321.     // Use helper function to position video window in client rect 
  322.     // of main application window
  323.     ResizeVideoWindow(ghApp);
  324.     // Make the video window visible, now that it is properly positioned
  325.     hr = g_pVW->put_Visible(OATRUE);
  326.     if (FAILED(hr))
  327.         return hr;
  328.     return hr;
  329. }
  330. void CapShow::ResizeVideoWindow(HWND ghApp)
  331. {
  332.     // Resize the video preview window to match owner window size
  333.     if (g_pVW)
  334.     {
  335.         RECT rc;
  336.         
  337.         // Make the preview video fill our window
  338.         GetClientRect(ghApp, &rc);
  339.         g_pVW->SetWindowPosition(0, 0, rc.right, rc.bottom);
  340.     }
  341. }
  342. void CapShow::CloseInterfaces()
  343. {
  344.     // Stop previewing data
  345.     if (g_pMC)
  346.         g_pMC->StopWhenReady();
  347.     g_psCurrent = Stopped;
  348.     // Relinquish ownership (IMPORTANT!) of the video window.
  349.     // Failing to call put_Owner can lead to assert failures within
  350.     // the video renderer, as it still assumes that it has a valid
  351.     // parent window.
  352.     if(g_pVW)
  353.     {
  354.         g_pVW->put_Visible(OAFALSE);
  355.         g_pVW->put_Owner(NULL);
  356.     }
  357.    // Release DirectShow interfaces
  358.    // SAFE_RELEASE(g_pMC);
  359.    // SAFE_RELEASE(g_pME);
  360.    // SAFE_RELEASE(g_pVW);
  361.    // SAFE_RELEASE(g_pGraph);
  362.    // SAFE_RELEASE(g_pCapture);
  363. }