<menu id="w8yyk"><menu id="w8yyk"></menu></menu>
  • <dd id="w8yyk"><nav id="w8yyk"></nav></dd>
    <menu id="w8yyk"></menu>
    <menu id="w8yyk"><code id="w8yyk"></code></menu>
    <menu id="w8yyk"></menu>
    <xmp id="w8yyk">
    <xmp id="w8yyk"><nav id="w8yyk"></nav>
  • 網站首頁 > 物聯資訊 > 技術分享

    CCapture directshow 視頻捕獲類

    2016-09-28 00:00:00 廣州睿豐德信息科技有限公司 閱讀
    睿豐德科技 專注RFID識別技術和條碼識別技術與管理軟件的集成項目。質量追溯系統、MES系統、金蝶與條碼系統對接、用友與條碼系統對接

     

    [cpp] view plaincopy  
    1. // Capture.h for class CCapture  
    2.   
    3. #include <dshow.h>  
    4. #include <qedit.h>  
    5. #include <atlbase.h>  
    6. #if !defined(CAPTURE_H_________)  
    7. #define CAPTURE_H_________  
    8.   
    9. // image size: 160*120  176*144   320*240  640*480  1024*1806  
    10. #define IMG_WIDTH 320  
    11. #define IMG_HEIGHT 240  
    12.   
    13. typedef void (*capCallBackFunc)(LPVOID lParam);  
    14. enum DeviceType{DTypeVideo, DTypeAudio};  
    15. class CSampleGrabberCB; // 用于不會幀數據保存圖片的接口  
    16. class CCapture  
    17. {  
    18.     friend class CSampleGrabberCB;  
    19. public:  
    20.     // 設置回調函數 用于處理獲取的圖片幀數據  
    21.     CDialog *m_dlgParent;  
    22.     capCallBackFunc calFunc;  
    23.     void SetCallBKFun(capCallBackFunc f);  
    24.     /////////////////////////////////  
    25.     CCapture();  
    26.     virtual ~CCapture();  
    27.     int EnumDevice(HWND hCmbList, DeviceType deviceType); // 設備枚舉  
    28. //  void SaveGraph(TCHAR *wFileName);   // 保存濾波器鏈表  
    29.     void SetCameraFormat(HWND hwndParent);  // 設置攝像頭的視頻格式  
    30.     void SetCameraFilter(HWND hwndParent);  // 設置攝像頭的圖像參數  
    31.     HRESULT CaptureVideo(CString inFileName);   // 捕獲保存視頻  
    32.     HRESULT CaptureImage(CString inFileName);   // 抓取保存圖片  
    33.     HRESULT CaptureImage(); // 抓取圖片并顯示  
    34.     HRESULT Preview(int iDevVideoID, HWND hVideo, int iDevAudioID = 0, HWND hAudio = NULL); // 采集預覽視頻  
    35.     HRESULT InitCaptureGraphBuilder();  // 創建濾波器管理器,查詢其各種控制接口  
    36.     void StopCapture();  // 停止捕獲  
    37.     void FreeMediaType(AM_MEDIA_TYPE &mt);  // 釋放對象內存  
    38.   
    39.     void SetOnShot(BOOL bFlag);   // 設置是否捕獲幀數據  
    40.     void SetParent(CDialog *pdlg);  
    41. protected:  
    42.     bool BindFilter(int iDeviceID, IBaseFilter **pOutFilter, DeviceType deviceType); // 把指定的設備濾波器捆綁到鏈表中  
    43.     void ResizeVideoWindow();           // 更改視頻顯示窗口  
    44.     HRESULT SetupVideoWindow();         // 設置視頻顯示窗口的特性  
    45.     static UINT ThreadFunDrawText(LPVOID lParam);  
    46. private:  
    47.     HWND m_hWnd;            // 視頻顯示窗口的句柄  
    48.     IBaseFilter *m_pVideoCap;       // 視頻捕獲濾波器  
    49.     IBaseFilter *m_pAudioCap;       // 音頻捕獲濾波器  
    50.     CComPtr<ISampleGrabber> m_pGrabber;       // 抓取圖片濾波器  
    51.     IBaseFilter *m_pMux;    // 寫文件濾波器  
    52.     ICaptureGraphBuilder2 *m_pCapGB;    // 增強型捕獲濾波器鏈表管理  
    53.     IGraphBuilder *m_pGB;   // 濾波鏈表管理器  
    54.     IVideoWindow *m_pVW;    // 視頻顯示窗口接口  
    55.     IMediaControl *m_pMC;   // 媒體控制接口  
    56.     static bool m_bRecording;       // 錄制視頻標志  
    57.   
    58.     IBaseFilter *m_pXviDCodec;   //mpeg4 濾波器  
    59. };  
    60.   
    61.   
    62. #endif  


     

    [cpp] view plaincopy  
      1. /// Capture.cpp for class CCapture implement  
      2. //  
      3. ///  
      4. ////////////////////////////////////////  
      5.   
      6. #include "StdAfx.h"  
      7. #include "Capture.h"  
      8. #include <atlconv.h>  
      9. #include "VideoChatDlg.h"  
      10. #include "yuv2bmp.h"  
      11.   
      12. #ifndef srelease  
      13. #define srelease(x) if (NULL != x)\  
      14. {\  
      15.     x->Release();\  
      16.     x = NULL;\  
      17. }  
      18. #endif  
      19.   
      20. #ifndef MAX_PATH  
      21. #define  MAX_PATH 1024  
      22. #endif  
      23. BOOL bOneShot = FALSE; // 全局變量  
      24. capCallBackFunc fun;  
      25.   
      26. class CSampleGrabberCB : public ISampleGrabberCB  
      27. {  
      28. public:  
      29.     long lWidth;  
      30.     long lHeight;  
      31.     CCapture *pCap;  
      32.     TCHAR m_szFileName[MAX_PATH]; // 位圖文件名稱  
      33.     CSampleGrabberCB(){  
      34.         strcpy(m_szFileName, ".\\sample.bmp");  
      35.     }  
      36.     STDMETHODIMP_(ULONG) AddRef() { return 2; }   
      37.     STDMETHODIMP_(ULONG) Release() { return 1; }   
      38.     STDMETHODIMP QueryInterface(REFIID riid, void ** ppv){   
      39.         if( riid == IID_ISampleGrabberCB || riid == IID_IUnknown ){    
      40.         *ppv = (void *) static_cast<ISampleGrabberCB*> ( this );   
      41.             return NOERROR;   
      42.         }    
      43.         return E_NOINTERFACE;   
      44.     }   
      45.     STDMETHODIMP SampleCB( double SampleTime, IMediaSample * pSample ){   
      46.         return 0;   
      47.     }   
      48.     STDMETHODIMP BufferCB( double dblSampleTime, BYTE * pBuffer, long lBufferSize ){   
      49.         if( !bOneShot )  
      50.             return 0;  
      51.         if (!pBuffer)  
      52.         {  
      53.             AfxMessageBox(_T("Save Bmp File Failure!"));  
      54.             return E_POINTER;   
      55.         }  
      56.         if (pBuffer != NULL && pCap)  
      57.         {  
      58. //          BYTE *rgb = new BYTE[lWidth*lHeight*3];   
      59. //          YUV422_C_RGB(pBuffer,rgb, (int)lHeight, (int)lWidth);  
      60. //          outBmpBuf(pBuffer, pCap);  // 將一幀圖像數據傳給顯示函數  
      61. //          ((CVideoNetDlg *)pCap->m_dlgParent)->SendVideo(pBuffer, (int)lBufferSize);  
      62.         }  
      63.     //  SaveBitmap(pBuffer, lBufferSize);  // 保存成位圖文件  
      64. //      bOneShot = FALSE; // 停止捕獲圖像  
      65. //      AfxMessageBox(_T("Get bmp data success."));  
      66.         return 0;   
      67.     }  
      68.     void outBmpBuf(BYTE *buf, CCapture* cap)  
      69.     {  
      70.         cap->calFunc(buf);  
      71.     }  
      72.     // 創建位圖文件  
      73.     BOOL SaveBitmap(BYTE *pBuffer, long lBufferLen)  
      74.     {  
      75.         HANDLE hf = CreateFile(m_szFileName, GENERIC_WRITE,   
      76.             FILE_SHARE_READ, NULL, CREATE_ALWAYS, NULL, NULL);  
      77.         if (hf == INVALID_HANDLE_VALUE) return 0;  
      78.         // 寫文件頭  
      79.         BITMAPFILEHEADER fileheader;  
      80.         ZeroMemory(&fileheader, sizeof(BITMAPFILEHEADER));  
      81.         fileheader.bfType = 'MB';  
      82.         fileheader.bfSize = sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+lBufferLen;  
      83.         fileheader.bfOffBits = sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER);  
      84.         DWORD dwWritter = 0;  
      85.         WriteFile(hf, &fileheader, sizeof(BITMAPFILEHEADER), &dwWritter, NULL);  
      86.         // 寫文圖格式  
      87.         BITMAPINFOHEADER infoHeader;  
      88.         ZeroMemory(&infoHeader, sizeof(BITMAPINFOHEADER));  
      89.         infoHeader.biSize = sizeof(BITMAPINFOHEADER);  
      90.         infoHeader.biSizeImage = lBufferLen;  
      91.         infoHeader.biWidth = lWidth;  
      92.         infoHeader.biHeight = lHeight;  
      93.         infoHeader.biBitCount = 24;  
      94.         WriteFile(hf, &infoHeader, sizeof(BITMAPINFOHEADER), &dwWritter, NULL);  
      95.         // 寫位圖數據  
      96.         WriteFile(hf, pBuffer, lBufferLen, &dwWritter, NULL);  
      97.         CloseHandle(hf);  
      98.         MessageBox(NULL, _T("Save bmp file succeed!"), _T("warn"), MB_OK|MB_ICONINFORMATION);  
      99.         return 0;  
      100.     }  
      101. };  
      102.   
      103. /////////////////////////////////////////////  
      104. /// for class CCapture's Function  
      105. ///  
      106. ////////////////////////////////////////////////  
      107. CSampleGrabberCB samCB;  
      108. CCapture::CCapture()  
      109. {  
      110.     CoInitialize(NULL);  // 初始化COM庫  
      111.     m_hWnd = NULL;  
      112.     m_pVideoCap = NULL;  
      113.     m_pAudioCap = NULL;  
      114.     m_pCapGB = NULL;  
      115.     m_pGB = NULL;  
      116.     m_pMC = NULL;  
      117.     m_pMux = NULL;  
      118.     m_pVW = NULL;  
      119.     m_pGrabber = NULL;  
      120.     m_dlgParent = NULL;  
      121. }  
      122. bool CCapture::m_bRecording = false;  
      123.   
      124. CCapture::~CCapture()  
      125. {  
      126.     if (m_pMC) m_pMC->Stop();  
      127.     if (m_pVW)  
      128.     {  
      129.         m_pVW->put_Owner(NULL);  
      130.         m_pVW->put_Visible(OAFALSE);  
      131.     }  
      132.     m_hWnd = NULL;  
      133.     srelease(m_pVideoCap);  
      134.     srelease(m_pGB);  
      135.     srelease(m_pCapGB);  
      136.     srelease(m_pMC);  
      137.     srelease(m_pVW);  
      138.     m_bRecording = false;  
      139.     CoUninitialize(); // 釋放COM庫  
      140. }  
      141.   
      142. int CCapture::EnumDevice( HWND hCmbList, DeviceType deviceType )  
      143. {  
      144.     if (hCmbList == NULL) return -1;  
      145.     int id = 0;  
      146.     /////枚舉捕獲設備  
      147.     ICreateDevEnum *pCreateDevEnum;  
      148.     HRESULT hr = CoCreateInstance(CLSID_SystemDeviceEnum,  
      149.         NULL,  
      150.         CLSCTX_INPROC_SERVER,  
      151.         IID_ICreateDevEnum,  
      152.         (LPVOID *)&pCreateDevEnum);  
      153.     if ( hr != NOERROR) return -1;  
      154.     //////// 獲取視頻類的枚舉器  
      155.     IEnumMoniker *pEm;           //枚舉監控器接口  
      156.     if (deviceType == DTypeVideo)  
      157.         hr = pCreateDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, &pEm, 0);  
      158.     // 如果獲取音頻類的枚舉器 用下面的代碼  
      159.     else   
      160.          hr = pCreateDevEnum->CreateClassEnumerator(CLSID_AudioInputDeviceCategory, &pEm, 0);  
      161. //  if (hr != NOERROR) return -1;  
      162.     if (!pEm || FAILED(hr)) return -1;  
      163.     ////////////////////////  
      164.     pEm->Reset();   // 類型枚舉器復位  
      165.     ULONG cFetched;  
      166.     IMoniker *pM;    // 監控器接口指針  
      167.     while(hr = pEm->Next(1, &pM, &cFetched), hr == S_OK)  
      168.     {  
      169.         IPropertyBag *pBag;   // 屬性頁接口指針  
      170.         hr = pM->BindToStorage(0, 0, IID_IPropertyBag, (void **)&pBag);  
      171.         // 獲取設備屬性頁  
      172.         if (SUCCEEDED(hr))  
      173.         {  
      174.             VARIANT var;  
      175.             var.vt = VT_BSTR;       // 保存的是二進制數據  
      176.             // 獲取firendlyName 形式的信息  
      177.             hr = pBag->Read(L"FriendlyName", &var, NULL);  
      178.             if (hr == NOERROR) // 獲取成功  
      179.             {  
      180.                 id++;  
      181.                 char szDeviceName[256] = {0};  
      182.                 WideCharToMultiByte(CP_ACP, 0, var.bstrVal, -1, szDeviceName,80, NULL, NULL);  // 字符串編碼轉換UNICODE TO ANSI  
      183.                 ::SendMessage(hCmbList, CB_ADDSTRING, 0, (LPARAM)szDeviceName);//添加到組合列表框  
      184.                 SysFreeString(var.bstrVal);  //釋放資源,特別要注意  
      185.             }  
      186.             pBag->Release();  
      187.         }  
      188.         pM->Release();  
      189.     }  
      190.     return 0;  
      191. }  
      192.   
      193. void CCapture::ResizeVideoWindow()  
      194. {  
      195.     if (m_pVW)  
      196.     {  
      197.         // 讓圖像充滿整個指定窗口  
      198.         CRect rc;  
      199.         ::GetClientRect(m_hWnd, &rc);  
      200.         m_pVW->SetWindowPosition(0, 0, rc.right, rc.bottom);  
      201.     }  
      202. }  
      203.   
      204. HRESULT CCapture::SetupVideoWindow()  
      205. {  
      206.     HRESULT hr;  
      207.     //m_hWnd為類CCapture的成員變量,在使用該函數前須初始化  
      208.     hr = m_pVW->put_Visible(OAFALSE);  // 視頻窗口不可見  
      209.     hr = m_pVW->put_Owner((OAHWND)m_hWnd);  // 設置視頻窗口  
      210.     if (FAILED(hr)) return hr;  
      211.     hr = m_pVW->put_WindowStyle(WS_CHILD | WS_CLIPCHILDREN); //設置窗口類型  
      212.     if (FAILED(hr)) return hr;  
      213.     ResizeVideoWindow();   // 更改窗口大小  
      214.     hr = m_pVW->put_Visible(OATRUE);  // 顯示視頻窗口  
      215.     return hr;  
      216. }  
      217.   
      218. HRESULT CCapture::InitCaptureGraphBuilder()  
      219. {  
      220.     HRESULT hr;  
      221.     //創建IGraphBuilder接口(濾波器鏈表管理器) m_pGB  
      222.     hr = CoCreateInstance(CLSID_FilterGraph, NULL,  
      223.         CLSCTX_INPROC, IID_IGraphBuilder, (void **)&m_pGB);  
      224.     if (FAILED(hr)) return hr;  
      225.     //創建ICaptureGraphBuilder2接口(增強型捕獲濾波器鏈表管理器)m_pCapGB  
      226.     hr = CoCreateInstance(CLSID_CaptureGraphBuilder2, NULL,  
      227.         CLSCTX_INPROC, IID_ICaptureGraphBuilder2, (void **)&m_pCapGB);  
      228.     if (FAILED(hr)) return hr;  
      229.     // 創建抓取圖片濾波器  
      230.     if (m_pGrabber){  
      231.         m_pGrabber.Release();  
      232.         m_pGrabber = NULL;  
      233.     }  
      234.   
      235.     hr = CoCreateInstance(CLSID_SampleGrabber, NULL,CLSCTX_INPROC_SERVER, IID_ISampleGrabber, (void **)&m_pGrabber);  
      236. //  hr = m_pGrabber.CoCreateInstance( CLSID_SampleGrabber );   
      237.     if (FAILED(hr)) return hr;  
      238.     // 初始化濾波器鏈表管理器IGraphBuilder  
      239.     m_pCapGB->SetFiltergraph(m_pGB);  
      240.     // 查詢媒體控制接口  
      241.     hr = m_pGB->QueryInterface(IID_IMediaControl, (void **)&m_pMC);  
      242.     if (FAILED(hr))  return hr;  
      243.     // 查詢視頻窗口接口  
      244.     hr = m_pGB->QueryInterface(IID_IVideoWindow, (LPVOID *)&m_pVW);  
      245.     if (FAILED(hr)) return hr;  
      246.     /////  
      247.     return hr;  
      248. }  
      249.   
      250. HRESULT CCapture::Preview( int iDevVideoID, HWND hVideo, int iDevAudioID /*= 0*/HWND hAudio /*= NULL*/ )  
      251. {  
      252.     HRESULT hr;  
      253.     if (m_pMC)  
      254.         m_pMC->Stop();  
      255.     m_bRecording = false;  
      256.     // 初始化視頻捕獲濾波器鏈表管理器  
      257.     hr = InitCaptureGraphBuilder();  
      258.     if (FAILED(hr)) return hr;  
      259.   
      260.     // 把指定的視頻采集設備與濾波器捆綁  
      261.     if (BindFilter(iDevVideoID, &m_pVideoCap, DTypeVideo))   
      262.     {  
      263.         // 把濾波器添加到濾波器鏈表中  
      264.         hr = m_pGB->AddFilter(m_pVideoCap, L"Video Capture Filter");  
      265.         if (FAILED(hr)) return hr;  
      266.     }  
      267.     else return FALSE;  
      268.   
      269.     if (BindFilter(iDevAudioID, &m_pAudioCap, DTypeAudio))  
      270.     {  
      271.         hr = m_pGB->AddFilter(m_pAudioCap, L"Audio Capture Filter");  
      272.         if (FAILED(hr))  
      273.         {  
      274.             MessageBox(NULL, _T("綁定音頻設備失敗!"), _T("系統提示"), MB_OK|MB_ICONINFORMATION);  
      275.         //  return hr;  
      276.         }  
      277.     }  
      278.     else  
      279.     {  
      280.         MessageBox(NULL, _T("綁定音頻設備失敗!"), _T("系統提示"), MB_OK|MB_ICONINFORMATION);  
      281.     //  return FALSE;  
      282.     }  
      283.     // 如果我們想抓取24位的RGB圖片,如下設置媒體圖片類型  
      284.     CComQIPtr<IBaseFilter, &IID_IBaseFilter> pGrabBase(m_pGrabber);  
      285.   
      286.     AM_MEDIA_TYPE mediaType;  
      287.     VIDEOINFOHEADER vih;  
      288.   
      289.     IAMStreamConfig* pConfig = NULL;  
      290.     m_pCapGB->FindInterface(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video, m_pVideoCap, IID_IAMStreamConfig, (void**)&pConfig);  
      291.     // 設置視頻格式  
      292.     ZeroMemory(&mediaType, sizeof(AM_MEDIA_TYPE));  
      293.     vih.bmiHeader.biWidth = IMG_WIDTH;  
      294.     vih.bmiHeader.biHeight = IMG_HEIGHT;  
      295.     vih.bmiHeader.biSizeImage = IMG_HEIGHT*IMG_WIDTH*3;  
      296.     mediaType.pbFormat = (BYTE *)(&vih);  
      297.     mediaType.cbFormat = sizeof(VIDEOINFOHEADER);  
      298.     mediaType.subtype = MEDIASUBTYPE_YUY2;  
      299.     mediaType.majortype = MEDIATYPE_Video;  
      300.     mediaType.formattype = FORMAT_VideoInfo;  
      301.     hr = pConfig->SetFormat(&mediaType);  
      302.     hr = m_pGrabber->SetMediaType(&mediaType);   
      303.     if( FAILED( hr ) ){   
      304.         AfxMessageBox("Fail to set media type!");   
      305.         return hr;   
      306.     }  
      307.       
      308.     hr = m_pGB->AddFilter(pGrabBase, L"SampleGrabber");  
      309.     if (FAILED(hr)) return hr;  
      310.     // 渲染媒體, 把鏈表中濾波器鏈接起來  
      311.     hr = m_pCapGB->RenderStream(&PIN_CATEGORY_PREVIEW, &MEDIATYPE_Audio, m_pAudioCap, NULL, NULL);  
      312.     hr = m_pCapGB->RenderStream(&PIN_CATEGORY_PREVIEW, &MEDIATYPE_Video, m_pVideoCap, pGrabBase, NULL);  
      313.     if (FAILED(hr))  
      314.         hr = m_pCapGB->RenderStream(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video, m_pVideoCap, pGrabBase, NULL);  
      315.     if( FAILED( hr ) ){  
      316.         AfxMessageBox(_T("Can’t build the graph"));  
      317.         return hr;  
      318.     }  
      319.   
      320.     ////////// 設置圖片捕獲數據  
      321.     hr = m_pGrabber->GetConnectedMediaType( &mediaType );  
      322.     if ( FAILED( hr) ){  
      323.         AfxMessageBox(_T("Failt to read the connected media type"));  
      324.         return hr;  
      325.     }  
      326.     VIDEOINFOHEADER * pVih = (VIDEOINFOHEADER*)mediaType.pbFormat;  
      327.     samCB.lWidth = pVih->bmiHeader.biWidth;  
      328.     samCB.lHeight = pVih->bmiHeader.biHeight;  
      329.     samCB.pCap = (CCapture *)this;  
      330.     FreeMediaType(mediaType);  
      331.     hr = m_pGrabber->SetBufferSamples( TRUE );  // 如果此處為false 第一次抓取圖片時失敗(不用回調方式)  
      332.     hr = m_pGrabber->SetOneShot( FALSE );       
      333.     hr = m_pGrabber->SetCallback( &samCB, 1 );  
      334.     SetOnShot(TRUE);// ture 時開始捕獲視頻幀數據  
      335.     // 設置視頻顯示窗口  
      336.     m_hWnd = hVideo;  
      337.     SetupVideoWindow(); // 設置顯示窗口  
      338.     hr = m_pMC->Run();  // 開始采集、預覽視頻,并在指定窗口顯示  
      339.     if (FAILED(hr))   
      340.     {  
      341.         MessageBox(NULL, _T("請檢查該設備是否被占用!"), _T("系統提示"), MB_OK|MB_ICONINFORMATION);  
      342.         return hr;  
      343.     }  
      344.     return S_OK;  
      345. }  
      346.   
      347. #if 1  // avi video format  
      348. HRESULT CCapture::CaptureVideo( CString inFileName )  // 錄制視頻  
      349. {  
      350.     HRESULT hr = 0;  
      351.     DWORD dwId;  
      352.     HANDLE hThread;  
      353.     m_bRecording = false;  
      354.     m_pMC->Stop();   // 先停止視頻采集  
      355.   
      356.     // 設置文件名,注意第二個參數類型  
      357.     hr = m_pCapGB->SetOutputFileName(&MEDIASUBTYPE_Avi, inFileName.AllocSysString(), &m_pMux, NULL);  
      358.   
      359.     //渲染媒體 連接捕獲器和AVI Muxer過濾器   
      360.     hr = m_pCapGB->RenderStream(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video, m_pVideoCap, NULL, m_pMux);  
      361.     hr = m_pCapGB->RenderStream(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Audio, m_pAudioCap, NULL, m_pMux);  
      362.     //設置音頻流為主流   
      363.     IConfigAviMux *pConfigMux;  
      364.     m_pMux->QueryInterface(IID_IConfigAviMux, (void **)&pConfigMux);  
      365.     hr = pConfigMux->SetMasterStream(1);   // 0 為視頻  1為音頻  
      366.   
      367.     pConfigMux->Release();  
      368.     m_pMux->Release();  
      369.     m_bRecording = true;  
      370.     hThread = CreateThread(NULL, 0,  
      371.         (LPTHREAD_START_ROUTINE)ThreadFunDrawText,  
      372.         (LPVOID)m_hWnd,  
      373.         0, &dwId);  
      374.     m_pMC->Run();  // 恢復視頻采集,同時寫入文件  
      375.       
      376.     return hr;  
      377. }  
      378. #else  // mpeg4 format video  
      379. HRESULT CCapture::CaptureVideo(CString inFileName)  
      380. {  
      381.     HRESULT hr=0;  
      382.       
      383.     m_pMC->Stop();  
      384.       
      385.     m_pGB->AddFilter(m_pXviDCodec,L"99 Xvid MPEG-4 Codec");  
      386.     m_pXviDCodec->Release();  
      387.       
      388.     hr = m_pCapGB->SetOutputFileName(&MEDIASUBTYPE_Avi, inFileName.AllocSysString(), &m_pMux, NULL );  
      389.     hr = ConnectFilters(m_pGB,m_pSmartTee_1,m_pXviDCodec, 0);    //0,連接capture引腳  
      390.     hr = ConnectFilters(m_pGB,m_pXviDCodec,m_pMux, 2);    //2,默認自然連接  
      391.     m_pMux->Release();  
      392.       
      393.     m_pMC->Run();  
      394.       
      395.     return hr;  
      396. }  
      397. #endif  
      398.   
      399. ///////////////////////////////  
      400.   
      401. HRESULT CCapture::CaptureImage() // 抓取并顯示圖像  
      402. // 采用CB接口回調函數存儲圖片  
      403.     bOneShot = TRUE;  
      404.     return 0;  
      405. }  
      406.   
      407. HRESULT CCapture::CaptureImage( CString inFileName ) // 抓取圖像  
      408. {  
      409.     HRESULT hr;  
      410.     AM_MEDIA_TYPE mediaType;  
      411.     hr = m_pGrabber->GetConnectedMediaType(&mediaType);  
      412.     if (FAILED(hr))  return hr;  
      413.     VIDEOINFOHEADER *pVih;  
      414.     if (mediaType.formattype == FORMAT_VideoInfo &&   
      415.         (mediaType.cbFormat >= sizeof(VIDEOINFOHEADER)) &&  
      416.         mediaType.pbFormat != NULL)  
      417.     {  
      418.         pVih = (VIDEOINFOHEADER *)mediaType.pbFormat;  
      419.     }  
      420.     else       
      421.         return VFW_E_INVALIDMEDIATYPE;  
      422.   
      423. //  hr = m_pGrabber->SetOneShot(TRUE);  
      424.     if (SUCCEEDED(m_pGrabber->SetBufferSamples(TRUE)) )  // 設置為緩沖形式)  
      425.     {  
      426.         long cbBuffer = 0;  
      427.         hr = m_pGrabber->GetCurrentBuffer(&cbBuffer, NULL);  
      428.         BYTE *pBuffer = new BYTE[cbBuffer];  
      429.         if (!pBuffer) return -1;  
      430.         // 獲取一幀媒體的數據  
      431.         hr = m_pGrabber->GetCurrentBuffer(&cbBuffer, (long *)pBuffer);  
      432.         if (FAILED(hr))  return hr;  
      433. //          if (pBuffer != NULL)  
      434. //          {  
      435. //              calFunc(pBuffer);   // 將一幀圖像數據傳給顯示函數  
      436. //      }  
      437.   
      438.         ///-------------------------測試所得數據是rgb格式還是yuv格式--------  
      439.         long n1,n2;  
      440.         int datalen = IMG_WIDTH*IMG_HEIGHT*3;  
      441.         BYTE *rgb = new BYTE[datalen];  
      442.           
      443.         YUV422_C_RGB(pBuffer,rgb, IMG_HEIGHT, IMG_WIDTH);  
      444.         n1 = strlen((char *)pBuffer);  
      445.         n2 = strlen((char *)rgb);  
      446. //      ((CVideoNetDlg *)(m_dlgParent))->SendVideo((BYTE *)pBuffer, (int)cbBuffer);  
      447.         ///------------------------------------------------------------------  
      448. ///////////////////////////////////////////////////////////////  
      449.         // Create a file to hold the bitmap  
      450.         HANDLE hf = CreateFile(inFileName, GENERIC_WRITE, FILE_SHARE_READ,    
      451.             NULL, CREATE_ALWAYS, NULL, NULL );  
      452.           
      453.         if( hf == INVALID_HANDLE_VALUE ){  
      454.             MessageBox(NULL, _T("Create bmp file failure!"), _T(""), MB_OK|MB_ICONINFORMATION);  
      455.             return 0;  
      456.         }  
      457.           
      458.         // Write out the file header  
      459.         //  
      460.         // 信息頭  
      461.         BITMAPFILEHEADER bfh;  
      462.         memset( &bfh, 0, sizeof( bfh ) );  
      463.         bfh.bfType = 'MB';  
      464.         bfh.bfSize = sizeof( bfh ) + cbBuffer + sizeof( BITMAPINFOHEADER );  
      465.         bfh.bfOffBits = sizeof( BITMAPINFOHEADER ) + sizeof( BITMAPFILEHEADER );  
      466.           
      467.         DWORD Written = 0;  
      468.         WriteFile( hf, &bfh, sizeof( bfh ), &Written, NULL );  
      469.           
      470.         // Write the bitmap format  
      471.         //文件頭  
      472.         BITMAPINFOHEADER bih;  
      473.         memset( &bih, 0, sizeof( bih ) );  
      474.         bih.biSize = sizeof( bih );  
      475.         bih.biWidth = pVih->bmiHeader.biWidth;  
      476.         bih.biHeight = pVih->bmiHeader.biHeight;  
      477.         bih.biPlanes = 1;  
      478.         bih.biBitCount = 24;  
      479.           
      480.         Written = 0;  
      481.         WriteFile( hf, &bih, sizeof( bih ), &Written, NULL );  
      482.           
      483.         // Write the bitmap bits  
      484.         //  
      485.         Written = 0;  
      486.         WriteFile( hf, rgb, datalen, &Written, NULL );       
      487.         CloseHandle( hf );  
      488.         delete pBuffer;  
      489.         MessageBox(NULL, _T("Save photo succeeded!"), _T("抓取圖片提示"), MB_OK|MB_ICONINFORMATION);  
      490.     }  
      491.     m_pGrabber->SetOneShot(FALSE);  
      492.     m_pGrabber->SetBufferSamples(FALSE);  
      493.     FreeMediaType(mediaType);  
      494.     return 0;  
      495. }  
      496.   
      497. bool CCapture::BindFilter( int iDeviceID, IBaseFilter **pOutFilter, DeviceType deviceType )  
      498. {  
      499.     if (iDeviceID < 0) return false;  
      500.     // 枚舉所有的視頻設備  
      501.     ICreateDevEnum *pCreateDevEnum;  
      502.     //生成設備枚舉器pCreateDevEnum  
      503.     HRESULT hr = CoCreateInstance(CLSID_SystemDeviceEnum,  
      504.         NULL, CLSCTX_INPROC_SERVER, IID_ICreateDevEnum, (void **)&pCreateDevEnum);  
      505.     if (hr != NOERROR) return false;  
      506.     IEnumMoniker *pEM;  
      507.     // 創建視頻輸入設備類枚舉器  
      508.     if (deviceType == DTypeVideo)  
      509.         hr = pCreateDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, &pEM, 0);  
      510.     // 音頻設備枚舉器  
      511.     else  
      512.         hr = pCreateDevEnum->CreateClassEnumerator(CLSID_AudioInputDeviceCategory, &pEM, 0);  
      513.     if (hr != NOERROR) return false;  
      514.     pEM->Reset();  // 復位該設備  
      515.     ULONG cFetched;  
      516.     IMoniker *pM;  
      517.     int indexDev = 0;  
      518.     // 獲取設備  
      519.     while(hr = pEM->Next(1, &pM, &cFetched), hr == S_OK, indexDev <= iDeviceID)  
      520.     {  
      521.         IPropertyBag *pBag;  
      522.         // 獲取該設備屬性集  
      523.         hr = pM->BindToStorage(0,0,IID_IPropertyBag,(void **)&pBag);  
      524.         if (SUCCEEDED(hr))  
      525.         {  
      526.             VARIANT var;  
      527.             var.vt = VT_BSTR;  
      528.             hr = pBag->Read(L"FriendlyName", &var, NULL);  
      529.             if (hr == NOERROR)  
      530.             {  
      531.                 // 采集設備與捕獲濾波器捆綁  
      532.                 if (indexDev == iDeviceID) pM->BindToObject(0, 0, IID_IBaseFilter, (void **)pOutFilter);  
      533.                 SysFreeString(var.bstrVal);  
      534.             }  
      535.             pBag->Release();  
      536.         }  
      537.         pM->Release();  
      538.         indexDev++;  
      539.     }  
      540.     return true;  
      541. }  
      542.   
      543. void CCapture::SetCameraFormat( HWND hwndParent ) // 設置視頻格式  
      544. {  
      545.     HRESULT hr;  
      546.     IAMStreamConfig *pSC; // 流配置接口  
      547.     ISpecifyPropertyPages *pSpec; //屬性頁接口  
      548.     m_pMC->Stop();  // 只有停止后才能進行引腳屬性的設置  
      549.     m_bRecording = false;  
      550.     // 首先查詢捕獲CAPTURE、視頻Video接口  
      551.     hr = m_pCapGB->FindInterface(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video,  
      552.         m_pVideoCap, IID_IAMStreamConfig, (void **)&pSC);  
      553.   
      554.     CAUUID cauuid; // 所有屬性頁結構體  
      555.     hr = pSC->QueryInterface(IID_ISpecifyPropertyPages, (void **)&pSpec);  
      556.     if (hr == S_OK)  
      557.     {  
      558.         // 顯示屬性頁窗口  
      559.         hr = pSpec->GetPages(&cauuid);  // 獲取所有屬性頁  
      560.         hr = OleCreatePropertyFrame(hwndParent, 30, 30, NULL, 1,  
      561.             (IUnknown **)&pSC, cauuid.cElems, (GUID *)cauuid.pElems, 0, 0, NULL);  
      562.         // 釋放內存資源  
      563.         CoTaskMemFree(cauuid.pElems);  
      564.         pSpec->Release();  
      565.         pSC->Release();  
      566.     }  
      567.     // 恢復運行  
      568.     m_pMC->Run();          
      569. }  
      570.   
      571. void CCapture::SetCameraFilter( HWND hwndParent ) // 設置圖像各參數設置  
      572. {  
      573.     HRESULT hr = 0;  
      574.     ISpecifyPropertyPages *pSpec;  
      575.     hr = m_pVideoCap->QueryInterface(IID_ISpecifyPropertyPages, (void **)&pSpec);  
      576.     if (SUCCEEDED(hr))  
      577.     {  
      578.         // 獲取濾波器名稱和IUnknown 接口指針  
      579.         FILTER_INFO FilterInfo;  
      580.         hr = m_pVideoCap->QueryFilterInfo(&FilterInfo);  
      581.         IUnknown *pFilterUnk;  
      582.         m_pVideoCap->QueryInterface(IID_IUnknown, (void **)&pFilterUnk);  
      583.         // 顯示該頁  
      584.         CAUUID caGUID;  
      585.         pSpec->GetPages(&caGUID);  
      586.         OleCreatePropertyFrame(hwndParent,  
      587.             0, 0,  
      588.             FilterInfo.achName,  
      589.             1,  
      590.             &pFilterUnk,  
      591.             caGUID.cElems,  
      592.             caGUID.pElems,  
      593.             0,  
      594.             0, NULL);  
      595.         // 釋放內存資源  
      596.         CoTaskMemFree(caGUID.pElems);  
      597.         pFilterUnk->Release();  
      598.         FilterInfo.pGraph->Release();  
      599.         pSpec->Release();  
      600.     }  
      601. }  
      602.   
      603. void CCapture::StopCapture()  
      604. {  
      605.     m_pMC->Stop();  
      606. }  
      607.   
      608. UINT CCapture::ThreadFunDrawText( LPVOID lParam )  
      609. {  
      610.     HWND hwnd = (HWND)lParam;  
      611.     if (hwnd == NULL) return -1;  
      612.     HDC hdc = GetDC(hwnd);  
      613.     CRect rcDraw, rcTime;  
      614.     CTime time, time0;  
      615.     CTimeSpan timespan;  
      616.     CString strTime;  
      617.     CBrush br;  
      618.     time0 = CTime::GetCurrentTime();  
      619.     br.CreateSolidBrush(RGB(255,0,0));  
      620.     GetClientRect(hwnd, &rcDraw);  
      621.     rcTime = rcDraw;  
      622.     rcTime.bottom = rcTime.top + 30;  
      623.     rcDraw.top = rcDraw.bottom - 30;  
      624.     SelectObject(hdc, &br);  
      625.     SetTextColor(hdc, 0x0000ff);  
      626.     SetBkMode(hdc, TRANSPARENT);  
      627.     while(m_bRecording)  
      628.     {  
      629.         time = CTime::GetCurrentTime();  
      630.         timespan = time - time0;  
      631.         strTime = time.Format(_T(" %Y-%m-%d 星期%w %H:%M:%S"));  
      632.         DrawText(hdc, strTime, strTime.GetLength(), &rcTime, DT_VCENTER|DT_LEFT|DT_SINGLELINE);  
      633.         strTime = timespan.Format(_T("%H:%M:%S "));  
      634.         strTime = _T("●錄制 ") + strTime;  
      635.         DrawText(hdc, strTime, strTime.GetLength(), &rcDraw, DT_VCENTER|DT_RIGHT|DT_SINGLELINE);  
      636.     }  
      637.     return 0;  
      638. }  
      639.   
      640. void CCapture::FreeMediaType(AM_MEDIA_TYPE &mt)  
      641. {  
      642.     if (mt.cbFormat != 0)  
      643.     {  
      644.         CoTaskMemFree((PVOID)mt.pbFormat);  
      645.         mt.cbFormat = 0;  
      646.         mt.pbFormat = NULL;  
      647.     }  
      648.     if (mt.pUnk != NULL)  
      649.     {  
      650.         mt.pUnk->Release();  
      651.         mt.pUnk = NULL;  
      652.     }  
      653. }  
      654.   
      655. void CCapture::SetOnShot( BOOL bFlag )  
      656. {  
      657.     bOneShot = bFlag;  
      658. }  
      659.   
      660. void CCapture::SetCallBKFun( capCallBackFunc f )  
      661. {  
      662.     this->calFunc = f;  
      663.     samCB.pCap = static_cast<CCapture *>(this);  
      664. }  
      665.   
      666. void CCapture::SetParent( CDialog *pdlg )  
      667. {  
      668.     m_dlgParent = pdlg;  
      669. }  
    RFID管理系統集成商 RFID中間件 條碼系統中間層 物聯網軟件集成
    最近免费观看高清韩国日本大全