织梦CMS - 轻松建站从此开始!

罗索

windows mobile下用directshow做一个简单的摄象头预览并抓取BMP

落鹤生 发布于 2010-06-19 19:00 点击:次 
前些日子在CSDN上遇到很多人问directshow是如何驱动摄象头的,看来很多人对于directshow的一些基本知识还不够清晰,于是我就写一篇文章介绍一下
TAG:

前些日子在CSDN上遇到很多人问directshow是如何驱动摄象头的,看来很多人对于directshow的一些基本知识还不够清晰,于是我就写一篇文章介绍一下:

directshow的原理大概大家都知道,基本就是用微软封装的接口来实现硬件无关性,但是最终调用的接口都要在驱动层有对应的实现:

为了更清楚地演示directshow的数据传输过程,我必须说明的这个程序的基本流程。我采用的是vs2005 + windows mobile 6。0 professional 仿真模拟器,驱动层传出的是176*144格式的rgb565的数据,最后我将保存图片为RGB24的bmp图片。

说明:source filter从驱动层获取数据后一般分成两个pin将数据传出,一个是still pin用于传输静态数据,一帧的数据,一个是capture pin用于传出连续的视频数据,用RenderStream的方式gcap.pBuilder->RenderStream(&PIN_CATEGORY_PREVIEW,&MEDIATYPE_Video, gcap.pCap, NULL, gcap.pRenderP);默认会产生Smart Tee这个filter,这个filter将接收到的数据分成两份,同样也是分成两个pin传出,本例中我只用到smartTee传出的preview这个pin,连接到Render Filter以显示图象数据.

以下是主要程序部分(DDCam.cpp):

  1. #include <windows.h> 
  2. #include <mmsystem.h> 
  3. #include "streams.h" 
  4. #include <cs.h> 
  5. #include <csmedia.h> 
  6. #include <camera.h> 
  7. #include <aygshell.h> 
  8. #include "ddcam.h" 
  9. #include "grabber.h" 
  10. #include <windef.h> 
  11.  
  12. #define MAX_LOADSTRING 100 
  13. #define WM_GRAPHNOTIFY WM_APP + 1 
  14. #define SAFE_RELEASE(x) { if (x) x->Release(); x = NULL; } 
  15. #define CHK( x ) do{ if( FAILED( hr = ( x ))) { goto Cleanup; }} while( FALSE ); 
  16. #define ERR( x ) do{ hr = x; goto Cleanup; } while( FALSE ); 
  17.  
  18. #define ARRAYSIZE(s) (sizeof(s) / sizeof(s[0])) 
  19.  
  20. struct _capstuff { 
  21.  TCHAR szCaptureFile[_MAX_PATH]; 
  22.  WORD wCapFileSize; 
  23.  ICaptureGraphBuilder2 *pBuilder; 
  24.  IVideoWindow *pVWS, *pVWP; 
  25.  IMediaEventEx *pME; 
  26.  IAMDroppedFrames *pDF; 
  27.  IAMVideoCompression *pVC; 
  28.  IAMVideoControl *pAMVidControl; 
  29.  IAMCameraControl *pCamControl; 
  30.  IAMVideoProcAmp *pVProcAmp; 
  31.  IAMStreamConfig *pConfigP; //Preview config 
  32.  IAMStreamConfig *pVSC;// for video cap 
  33.  IBaseFilter *pRenderS;//Still render 
  34.  IBaseFilter *pRenderP;//Preview render 
  35.  IBaseFilter *pCap; 
  36.  IGraphBuilder *pGraph; 
  37.  CSampleGrabber *pGrab; 
  38.  IFileSinkFilter *pSink; 
  39.  BOOL fStillGraphBuilt; 
  40.  BOOL fPreviewGraphBuilt; 
  41.  BOOL fStillCapturing; 
  42.  BOOL fPreviewing; 
  43. } gcap; 
  44.  
  45. // Global Variables: HINSTANCE 
  46. g_hInstance = NULL; 
  47. // The current instance 
  48. HWND g_hWnd; 
  49. //The window instance 
  50. HWND g_hWndMenu; 
  51. //Menu handle 
  52. HWND hWndMenuStill = NULL; 
  53. // Forward declarations of functions included in this code module: 
  54. ATOM MyRegisterClass (HINSTANCELPTSTR); 
  55. BOOL InitInstance (HINSTANCEint); 
  56. LRESULT CALLBACK WndProc (HWNDUINTWPARAMLPARAM); 
  57. LRESULT CALLBACK About (HWNDUINTWPARAMLPARAM); 
  58. HRESULT SetCapMode(IBaseFilter *pCap); 
  59. HRESULT OpenCamera(LPCOLESTR lpFile,BOOL bCapture,BOOL bStill,BOOL bPreview); 
  60. BOOL WriteBMPToDisk(unsigned char *pStillImageBuffer,long size); 
  61. void UpdatePictureNumber(); 
  62. BOOL WriteBMPToTXT(unsigned char *pStillImageBuffer,long lBufferSize); 
  63. HRESULT ActivatePreviousInstance(const TCHAR* pszClass,
  64. const TCHAR* pszTitle,BOOL* pfActivated); 
  65.  
  66. int g_PicNumber=0; 
  67.  
  68. HRESULT Callback( IMediaSample * pSample, REFERENCE_TIME * StartTime, REFERENCE_TIME *
  69.  StopTime,BOOL TypeChanged ) 
  70.  unsigned char *pbuf; 
  71.  HRESULT hr = S_OK; 
  72.  // NOTE: We cannot do anything with this sample until we call GetConnectedMediaType 
  73.  // on the filter to find out what format these samples are. 
  74.  RETAILMSG(1, (TEXT("Callback with sample %lx for time %ld"),
  75.  pSample, long( *StartTime / 10000 ) ) ); 
  76.  hr = pSample->GetPointer(&pbuf); 
  77.  LONG lSize = pSample->GetActualDataLength(); 
  78.  BOOL bReturn = WriteBMPToDisk(pbuf,lSize); 
  79.  WriteBMPToTXT(pbuf,lSize); 
  80.  if(bReturn == FALSE) 
  81.  { 
  82.  return S_FALSE; 
  83.  } 
  84.  return hr; 
  85.  
  86. BOOL StartPreview() 
  87.  HRESULT hr; 
  88.  IMediaControl *pMC = NULL; 
  89.  hr = gcap.pGraph->QueryInterface(IID_IMediaControl, (void **)&pMC); 
  90.  if(SUCCEEDED(hr)) 
  91.  { 
  92.  hr = pMC->Run(); 
  93.  if(FAILED(hr)) 
  94.  { 
  95.  // stop parts that ran 
  96.  pMC->Stop(); 
  97.  } 
  98.  pMC->Release(); 
  99.  } 
  100.  if(FAILED(hr)) 
  101.  { 
  102.  return FALSE; 
  103.  } 
  104.  return TRUE; 
  105.  
  106. // stop the preview graph 
  107. BOOL StopPreview() { 
  108.  // way ahead of you 
  109.  if(!gcap.fPreviewing) 
  110.  { 
  111.  return FALSE; 
  112.  } 
  113.  // stop the graph 
  114.  IMediaControl *pMC = NULL; 
  115.  HRESULT hr = gcap.pGraph->QueryInterface(IID_IMediaControl, (void **)&pMC); 
  116.  if(SUCCEEDED(hr)) 
  117.  { 
  118.  hr = pMC->Stop(); 
  119.  pMC->Release(); 
  120.  } 
  121.  if(FAILED(hr)) 
  122.  { 
  123.  return FALSE; 
  124.  } 
  125.  gcap.fPreviewing = FALSE; 
  126.  return TRUE; 
  127.  
  128. BOOL CloseCamera() 
  129.  SAFE_RELEASE(gcap.pCap); 
  130.  SAFE_RELEASE(gcap.pConfigP); 
  131.  SAFE_RELEASE(gcap.pVWS); 
  132.  SAFE_RELEASE(gcap.pVWP); 
  133.  SAFE_RELEASE(gcap.pGraph); 
  134.  SAFE_RELEASE(gcap.pBuilder); 
  135.  return TRUE; 
  136.  
  137. HRESULT CaptureStillImage() 
  138.  HRESULT hr; 
  139.  hr = SetCapMode(gcap.pCap); //Run still pin 
  140.  return hr; 
  141.  
  142. HRESULT InitCapFilter() 
  143.  HRESULT hr = S_OK; 
  144.  GUID clsid = DEVCLASS_CAMERA_GUID; 
  145.  IPersistPropertyBag *pPropertyBag = NULL; 
  146.  // Create Capture Filter 
  147.  CHK( hr = CoCreateInstance(CLSID_VideoCapture, NULL, CLSCTX_INPROC_SERVER,
  148. IID_IBaseFilter,(void **)&gcap.pCap) ); 
  149.  DEVMGR_DEVICE_INFORMATION pdi; 
  150.  HANDLE hand = FindFirstDevice(DeviceSearchByGuid,&clsid,&pdi); 
  151.  RETAILMSG(1, (TEXT("CamTest: Find device: %x %x\r\n"),hand,pdi.szDeviceName)); 
  152.  CHK( hr = gcap.pCap->QueryInterface(IID_IPersistPropertyBag,
  153.  (void **)&pPropertyBag) ); 
  154.  if (!SUCCEEDED(hr)) 
  155.  { 
  156.  return hr; 
  157.  } 
  158.  VARIANT varCamName; 
  159.  IPropertyBag *propBag = NULL; 
  160.  varCamName.byref = L"CAM1:" ; 
  161.  CHK( hr = pPropertyBag->Load(propBag,NULL) ); 
  162.  SAFE_RELEASE(pPropertyBag); 
  163. Cleanup: 
  164.  if(FAILED(hr)) 
  165.  { 
  166.  OutputDebugString(L"Initial Error!"); 
  167.  SendMessage(g_hWnd,WM_CLOSE,0,0); 
  168.  } 
  169.  return hr; 
  170.  
  171. HRESULT SetupVideoWindow(IVideoWindow *pVW) 
  172.  HRESULT hr = S_OK; 
  173.  if (pVW) 
  174.  { 
  175.  CHK( hr = pVW->SetWindowPosition(0,0,240,268) ); 
  176.  CHK( hr = pVW->put_Owner((OAHWND)g_hWnd) ); 
  177.  CHK( hr = pVW->put_WindowStyle(WS_CHILD) ); 
  178.  } 
  179. Cleanup: 
  180.  if(FAILED(hr)) 
  181.  { 
  182.  OutputDebugString(L"Setup window Error!"); 
  183.  } 
  184.  return hr; 
  185.  
  186. HRESULT ConnectFilters(IGraphBuilder *pGraph,IBaseFilter *pF1,
  187.  int iPin1,IBaseFilter *pF2,int iPin2,IPin **ppPinout) 
  188.  IPin *pPin1, *pPin2; 
  189.  IEnumPins *pEnum; 
  190.  unsigned long fetched; 
  191.  HRESULT hr = S_OK; 
  192.  hr = pF1->EnumPins(&pEnum); 
  193.  while (iPin1>0) 
  194.  { 
  195.  hr = pEnum->Next(1,&pPin1,&fetched); //Skip Capture pin 
  196.  iPin1--; 
  197.  } 
  198.  hr = pEnum->Next(1,&pPin1,&fetched); 
  199.  hr = pF2->EnumPins(&pEnum); 
  200.  while (iPin2>0) 
  201.  { 
  202.  hr = pEnum->Next(1,&pPin2,&fetched); //Skip Capture pin 
  203.  iPin2--; 
  204.  } 
  205.  hr = pEnum->Next(1,&pPin2,&fetched); 
  206.  hr = pGraph->Connect(pPin1,pPin2); 
  207.  if (ppPinout) 
  208.  { 
  209.  *ppPinout = pPin1; 
  210.  } 
  211.  if (!SUCCEEDED(hr)) 
  212.  RETAILMSG(1, (TEXT("CamTest: Fail to Connect Pin! %x\r\n"),hr)); 
  213.  return hr; 
  214.  
  215. HRESULT BuildGraph() 
  216.  HRESULT hr; 
  217.  gcap.pGrab = new CSampleGrabber(NULL,&hr,FALSE); 
  218.  gcap.pGrab->AddRef(); 
  219.  gcap.pGrab->SetCallback(&Callback); 
  220.  CMediaType mt; 
  221.  mt.SetType(&MEDIATYPE_Video); 
  222.  mt.SetSubtype(&MEDIASUBTYPE_RGB24); 
  223.  gcap.pGrab->SetAcceptedMediaType(&mt); 
  224.  // Create the Filter Graph Manager. 
  225.  hr = CoCreateInstance(CLSID_FilterGraph, NULL, 
  226.  CLSCTX_INPROC_SERVER, IID_IGraphBuilder, (void **)&gcap.pGraph); 
  227.  // Create the Capture Graph Builder. 
  228.  hr = CoCreateInstance(CLSID_CaptureGraphBuilder, NULL, 
  229.  CLSCTX_INPROC_SERVER, IID_ICaptureGraphBuilder2, 
  230.  (void **)&gcap.pBuilder); 
  231.  hr = gcap.pGraph->AddFilter(gcap.pCap,L"Video Capture Source"); 
  232.  hr = gcap.pGraph->AddFilter(gcap.pGrab,L"SampleGrabber"); 
  233.  gcap.pBuilder->SetFiltergraph(gcap.pGraph); 
  234.  hr = CoCreateInstance(CLSID_VideoRenderer, NULL, 
  235.  CLSCTX_INPROC_SERVER, IID_IBaseFilter, 
  236.  (void **)&gcap.pRenderP); 
  237.  hr = CoCreateInstance(CLSID_VideoRenderer, NULL, 
  238.  CLSCTX_INPROC_SERVER, IID_IBaseFilter, 
  239.  (void **)&gcap.pRenderS); 
  240.  hr = gcap.pGraph->AddFilter(gcap.pRenderP,L"Video Render"); 
  241.  hr = gcap.pGraph->AddFilter(gcap.pRenderS,L"Video Render"); 
  242.  hr = gcap.pBuilder->RenderStream(&PIN_CATEGORY_PREVIEW,&MEDIATYPE_Video, 
  243.  gcap.pCap, NULL, gcap.pRenderP); 
  244.  hr = gcap.pRenderP->QueryInterface(IID_IVideoWindow, (void**)&gcap.pVWP); 
  245.  hr = gcap.pBuilder->RenderStream(&PIN_CATEGORY_STILL,&MEDIATYPE_Video, 
  246.  gcap.pCap, gcap.pGrab, gcap.pRenderS); 
  247.  // Query for video interfaces, which may not be relevant for audio files 
  248.  //hr = gcap.pGraph->QueryInterface(IID_IMediaEventEx, (void **)&gcap.pME); 
  249.  //hr = gcap.pCap->QueryInterface(IID_IAMVideoProcAmp,(void **)&gcap.pVProcAmp); 
  250.  //// Query the output pin for IAMStreamConfig (not shown). 
  251.  //hr = gcap.pBuilder->FindInterface( 
  252.  // &PIN_CATEGORY_PREVIEW, // Preview pin. 
  253.  // 0, // Any media type. 
  254.  // gcap.pCap, // Pointer to the capture filter. 
  255.  // IID_IAMStreamConfig, (void**)&gcap.pConfigP); 
  256.  // Have the graph signal event via window callbacks for performance 
  257.  SetupVideoWindow(gcap.pVWP); 
  258.  gcap.pVWP->put_MessageDrain((OAHWND)g_hWnd); 
  259.  gcap.pVWP->put_Owner((OAHWND)g_hWnd); 
  260.  //hr = gcap.pME->SetNotifyWindow((OAHWND)g_hWnd, WM_GRAPHNOTIFY, 0); 
  261.  return hr; 
  262.  
  263. HRESULT SetCapMode(IBaseFilter *pCap) 
  264.  HRESULT hr; 
  265.  IPin *pPin = NULL; 
  266.  hr = gcap.pCap->FindPin(L"Still",&pPin); 
  267.  if (SUCCEEDED(hr)) 
  268.  { 
  269.  hr = gcap.pCap->QueryInterface(IID_IAMVideoControl,(void **)&gcap.pAMVidControl); 
  270.  hr = gcap.pAMVidControl->SetMode(pPin, VideoControlFlag_Trigger); 
  271.  MessageBox(NULL,L"拍照成功,生成的图片保存在根目录下",L"成功",64); 
  272.  pPin->Release(); 
  273.  } 
  274.  else 
  275.  { 
  276.  RETAILMSG(1, (TEXT("CamTest: Fail to Find Pin! %x\r\n"),hr)); 
  277.  } 
  278.  return hr; 
  279.  
  280. int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance, 
  281.  LPTSTR lpCmdLine,int nCmdShow) 
  282.  MSG msg; 
  283.  HACCEL hAccelTable; //Init COM 
  284.  // Get COM interfaces 
  285.  if(FAILED(CoInitializeEx(NULL, COINIT_MULTITHREADED))) 
  286.  { 
  287.  RETAILMSG(1, (TEXT("CoInitialize Failed!\r\n"))); 
  288.  return FALSE; 
  289.  } 
  290.  // Perform application initialization: 
  291.  if (!InitInstance (hInstance, nCmdShow)) 
  292.  { 
  293.  return FALSE; 
  294.  } 
  295.  hAccelTable = LoadAccelerators(hInstance, (LPCTSTR)IDC_WCETEST); 
  296.  // Main message loop: 
  297.  while (GetMessage(&msg, NULL, 0, 0)) 
  298.  { 
  299.  if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg)) 
  300.  { 
  301.  TranslateMessage(&msg); 
  302.  DispatchMessage(&msg); 
  303.  } 
  304.  } 
  305.  // Finished with COM 
  306.  CoUninitialize(); 
  307.  return msg.wParam; 
  308.  
  309. //FUNCTION: InitInstance(HANDLE, int) 
  310. //PURPOSE: Saves instance handle and creates main window 
  311. //COMMENTS: 
  312. //In this function, we save the instance handle in a global variable and 
  313. //create and display the main program window.
  314. BOOL InitInstance(HINSTANCE hInstance, int nCmdShow) 
  315.  HRESULT hr; 
  316.  BOOL fActivated; 
  317.  TCHAR szTitle[MAX_LOADSTRING]; 
  318.  // The title bar text 
  319.  TCHAR szWindowClass[MAX_LOADSTRING]; 
  320.  // The window class name 
  321.  g_hInstance = hInstance; 
  322.  // Store instance handle in our global variable 
  323.  // Initialize global strings 
  324.  LoadString(hInstance, IDC_WCETEST, szWindowClass, MAX_LOADSTRING); 
  325.  WNDCLASS wc; 
  326.  wc.style = CS_HREDRAW | CS_VREDRAW; 
  327.  wc.lpfnWndProc = (WNDPROC) WndProc; 
  328.  wc.cbClsExtra = 0; 
  329.  wc.cbWndExtra = 0; 
  330.  wc.hInstance = hInstance; 
  331.  wc.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_WCETEST)); 
  332.  wc.hCursor = 0; 
  333.  wc.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH); 
  334.  wc.lpszMenuName = 0; 
  335.  wc.lpszClassName = szWindowClass; 
  336.  RegisterClass(&wc); 
  337.  LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING); 
  338.  if(FAILED(ActivatePreviousInstance(szWindowClass, szTitle, &fActivated))
  339. ||fActivated) 
  340.  { 
  341.  return(0); 
  342.  } 
  343.  g_hWnd = CreateWindow(szWindowClass, szTitle, WS_VISIBLE, 
  344.  CW_USEDEFAULT, CW_USEDEFAULT, GetSystemMetrics(SM_CXSCREEN), 
  345.  GetSystemMetrics(SM_CYSCREEN), NULL, NULL, hInstance, NULL); 
  346.  if (!g_hWnd) 
  347.  { 
  348.  return FALSE; 
  349.  } 
  350.  ShowWindow(g_hWnd, nCmdShow); 
  351.  UpdateWindow(g_hWnd); 
  352.  hr = InitCapFilter(); 
  353.  if (SUCCEEDED(hr)) 
  354.  { 
  355.  BuildGraph(); 
  356.  StartPreview(); 
  357.  } 
  358.  else 
  359.  { 
  360.  RETAILMSG(1,(TEXT("CamTest: Fail to create Capture filter. \r\n"))); 
  361.  } 
  362.  return TRUE; 
  363.  
  364. /******************************************************** 
  365.  OnCreate 
  366. *********************************************************/ 
  367. LRESULT OnCreate(HWND hwnd,CREATESTRUCT* lParam) 
  368.  // create the menu bar 
  369.  SHMENUBARINFO mbi; 
  370.  ZeroMemory(&mbi, sizeof(SHMENUBARINFO)); 
  371.  mbi.cbSize = sizeof(SHMENUBARINFO); 
  372.  mbi.hwndParent = hwnd; 
  373.  mbi.nToolBarId = IDM_MENU; 
  374.  mbi.hInstRes = g_hInstance; 
  375.  mbi.dwFlags = SHCMBF_HMENU; 
  376.  if(!SHCreateMenuBar(&mbi)) 
  377.  { 
  378.  // Couldn't create the menu bar. Fail creation of the window. 
  379.  return(-1); 
  380.  } 
  381.  return(0);// continue creation of the window 
  382.  
  383. // FUNCTION: WndProc(HWND, unsigned, WORD, LONG) 
  384. // PURPOSE: Processes messages for the main window. 
  385. // WM_COMMAND - process the application menu 
  386. // WM_PAINT - Paint the main window 
  387. // WM_DESTROY - post a quit message and return 
  388. LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam){
  389.  LRESULT lResult = TRUE; 
  390.  switch(message) 
  391.  { 
  392.  case WM_CLOSE: 
  393.  StopPreview(); 
  394.  CloseCamera(); 
  395.  DestroyWindow(hWnd); 
  396.  break
  397.  case WM_CREATE: 
  398.  lResult = OnCreate(hWnd, (CREATESTRUCT*)lParam); 
  399.  break
  400.  case WM_COMMAND: 
  401.  switch (wParam) 
  402.  { 
  403.  case ID_CAPTURE: 
  404.  CaptureStillImage(); 
  405.  break
  406.  } 
  407.  break
  408.  case WM_DESTROY: 
  409.  PostQuitMessage(0); 
  410.  break
  411.  default
  412.  lResult = DefWindowProc(hWnd, message, wParam, lParam); 
  413.  break
  414.  } 
  415.  return(lResult);
  416. }
  417. BOOL WriteBMPToTXT(unsigned char *pStillImageBuffer,long lBufferSize) 
  418.  TCHAR x[256]; 
  419.  const TCHAR *picture_path = TEXT("\\My Documents\\My Pictures") ; 
  420.  UpdatePictureNumber(); 
  421.  wsprintf(x, TEXT("%s\\%d.txt"), picture_path, g_PicNumber++); 
  422.  HANDLE hf = CreateFile(x,GENERIC_WRITE,FILE_SHARE_READ,NULL,CREATE_ALWAYS,NULL,NULL); 
  423.  if(hf == INVALID_HANDLE_VALUE) 
  424.  return FALSE; 
  425.  DWORD dwWritten=0; 
  426.  if( !WriteFile(hf,pStillImageBuffer,lBufferSize,&dwWritten,NULL) ) 
  427.  { 
  428.  return FALSE; 
  429.  } 
  430.  CloseHandle(hf); 
  431.  return TRUE; 
  432. }

 

  1. //保存为24位的图片
  2. BOOL WriteBMPToDisk(unsigned char *pStillImageBuffer,long lBufferSize)
  3. {
  4.  TCHAR x[256];
  5.  UpdatePictureNumber();
  6.  wsprintf(x, TEXT("%d.bmp"), g_PicNumber++);
  7.  HANDLE hf = CreateFile(x,GENERIC_WRITE,FILE_SHARE_READ,
  8. NULL,CREATE_ALWAYS,NULL,NULL);
  9.  if(hf == INVALID_HANDLE_VALUE)
  10.  return FALSE;
  11.  BITMAPFILEHEADER bfh;
  12.  memset(&bfh,0,sizeof(bfh));
  13.  bfh.bfType=0x4D42/*((WORD) ('M' << 8) | 'B')*/;
  14.  bfh.bfSize=sizeof(bfh)+lBufferSize+sizeof(BITMAPFILEHEADER);
  15.  bfh.bfOffBits=sizeof(BITMAPINFOHEADER)+sizeof(BITMAPFILEHEADER);
  16.  DWORD dwWritten=0;
  17.  WriteFile(hf,&bfh,sizeof(bfh),&dwWritten,NULL);
  18.  BITMAPINFOHEADER bih;
  19.  memset(&bih,0,sizeof(bih));
  20.  bih.biSize=sizeof(bih);
  21.  bih.biWidth=144;
  22.  bih.biHeight=176;
  23.  bih.biPlanes=1;
  24.  bih.biBitCount=24;
  25.  if( !WriteFile(hf,&bih,sizeof(bih),&dwWritten,NULL) )
  26.  {
  27.  return FALSE;
  28.  }
  29.  if( !WriteFile(hf,pStillImageBuffer,lBufferSize,&dwWritten,NULL) )
  30.  {
  31.  return FALSE;
  32.  }
  33.  CloseHandle(hf);
  34.  return TRUE;
  35. }
  36. // Look for cam.cfg
  37. // If it doesn't exist, create it, and set picture number to 1.
  38. // If it exists, read the value stored inside, increment the number,
  39. // and write it back.
  40. void UpdatePictureNumber()
  41. {
  42.  DWORD dwSize;
  43.  HANDLE hFile;
  44.  char *buffer;
  45.  buffer = (char *)malloc(1024);
  46.  hFile = CreateFile(TEXT("\\temp\\cam.cfg"), GENERIC_WRITE | GENERIC_READ,
  47.  0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
  48.  dwSize = 0;

  49.  if (hFile == INVALID_HANDLE_VALUE)
  50.  {
  51. // File did not exist, so we are going to create it, and initialize the counter.
  52.  g_PicNumber = 1; 
  53.  hFile = CreateFile(TEXT("\\temp\\cam.cfg"), GENERIC_WRITE | GENERIC_READ,
  54. 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); 
  55.  buffer[0] = g_PicNumber & 0x00FF; 
  56.  buffer[1] = (g_PicNumber & 0xFF00) >> 8; 
  57.  
  58.  WriteFile(hFile, buffer, 2, &dwSize, NULL); 
  59.  CloseHandle(hFile); 
  60.  } else 
  61.  { 
  62.  dwSize = 0; 
  63.  ReadFile(hFile, buffer, 2, &dwSize, NULL); 
  64.  g_PicNumber = buffer[1];
  65.  g_PicNumber <<= 8;
  66.  g_PicNumber |= buffer[0];
  67.  g_PicNumber++;
  68.  CloseHandle(hFile);
  69.  hFile = CreateFile(TEXT("\\temp\\cam.cfg"), GENERIC_WRITE | GENERIC_READ,
  70.  0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
  71.  buffer[0] = g_PicNumber & 0x00FF; 
  72.  buffer[1] = (g_PicNumber & 0xFF00) >> 8; 
  73.  dwSize = 0; 
  74.  WriteFile(hFile, buffer, 2, &dwSize, NULL); 
  75.  CloseHandle(hFile);
  76.  }

  77.  free(buffer); 
  78.  
  79. HRESULT ActivatePreviousInstance(const TCHAR* pszClass, 
  80. const TCHAR* pszTitle,BOOL* pfActivated) 
  81.  HRESULT hr = S_OK; 
  82.  int cTries; 
  83.  HANDLE hMutex = NULL; 
  84.  
  85.  *pfActivated = FALSE; 
  86.  cTries = 5; 
  87.  while(cTries > 0) 
  88.  { 
  89.  hMutex = CreateMutex(NULL, FALSE, pszClass); // NOTE: We don't want to own the object.  
  90.  if(NULL == hMutex) 
  91.  { 
  92.  // Something bad happened, fail.  
  93.  hr = E_FAIL; 
  94.  goto Exit; 
  95.  } 
  96.  
  97.  if(GetLastError() == ERROR_ALREADY_EXISTS) 
  98.  { 
  99.  HWND hwnd; 
  100.  
  101.  CloseHandle(hMutex); 
  102.  hMutex = NULL; 
  103.  
  104.  // There is already an instance of this app  
  105.  // running. Try to bring it to the foreground.  
  106.  
  107.  hwnd = FindWindow(pszClass, pszTitle); 
  108.  if(NULL == hwnd) 
  109.  { 
  110.  // It's possible that the other window is in the process of being created...  
  111.  Sleep(500); 
  112.  hwnd = FindWindow(pszClass, pszTitle); 
  113.  } 
  114.  
  115.  if(NULL != hwnd) 
  116.  { 
  117.  // Set the previous instance as the foreground window 
  118.  // The "| 0x01" in the code below activates  
  119.  // the correct owned window of the  
  120.  // previous instance's main window.  
  121.  SetForegroundWindow((HWND) (((ULONG) hwnd) | 0x01)); 
  122.  
  123.  // We are done.  
  124.  *pfActivated = TRUE; 
  125.  break
  126.  } 
  127.  
  128.  // It's possible that the instance we found isn't coming up,  
  129.  // but rather is going down. Try again.  
  130.  cTries--; 
  131.  } 
  132.  else 
  133.  { 
  134.  // We were the first one to create the mutex  
  135.  // so that makes us the main instance. 'leak'  
  136.  // the mutex in this function so it gets cleaned  
  137.  // up by the OS when this instance exits.  
  138.  break
  139.  } 
  140.  } 
  141.  if(cTries <= 0) 
  142.  { 
  143.  // Someone else owns the mutex but we cannot find  
  144.  // their main window to activate. 
  145.  hr = E_FAIL; 
  146.  goto Exit; 
  147.  } 
  148. Exit: 
  149.  return(hr); 
  150.  
  151. void setscreenMetrics(HWND hWnd,int width,int height) 
  152.  DEVMODE lpDevMode; 
  153.  lpDevMode.dmBitsPerPel=24; 
  154.  lpDevMode.dmPelsWidth=width; 
  155.  lpDevMode.dmPelsHeight=height; 
  156.  lpDevMode.dmSize=sizeof(lpDevMode); 
  157.  lpDevMode.dmFields=DM_PELSWIDTH|DM_PELSHEIGHT; 
  158.  LONG result; 
  159.  result=ChangeDisplaySettingsEx(NULL,&lpDevMode,hWnd,0,NULL); 
  160.  if(result==DISP_CHANGE_SUCCESSFUL) 
  161.  { 
  162.  MessageBoxW(hWnd,_T("success!"),_T("alert"),MB_OK); 
  163.  } 
  164.  else 
  165.  { 
  166.  MessageBoxW(hWnd,_T("failure!"),_T("alert"),MB_OK); 
  167.  } 

主要构建Graph的代码:

  1. HRESULT BuildGraph() 
  2.  HRESULT hr; 
  3.  gcap.pGrab = new CSampleGrabber(NULL,&hr,FALSE); 
  4.  gcap.pGrab->AddRef(); 
  5.  gcap.pGrab->SetCallback(&Callback); 
  6.  CMediaType mt; 
  7.  mt.SetType(&MEDIATYPE_Video); 
  8.  mt.SetSubtype(&MEDIASUBTYPE_RGB24); 
  9.  gcap.pGrab->SetAcceptedMediaType(&mt); 
  10.  
  11.  // Create the Filter Graph Manager. 
  12.  hr = CoCreateInstance(CLSID_FilterGraph, NULL, 
  13.  CLSCTX_INPROC_SERVER, IID_IGraphBuilder, (void **)&gcap.pGraph); 
  14.  
  15.  // Create the Capture Graph Builder. 
  16.  hr = CoCreateInstance(CLSID_CaptureGraphBuilder, NULL, 
  17.  CLSCTX_INPROC_SERVER, IID_ICaptureGraphBuilder2, 
  18.  (void **)&gcap.pBuilder); 
  19.  
  20.  hr = gcap.pGraph->AddFilter(gcap.pCap,L"Video Capture Source"); 
  21.  hr = gcap.pGraph->AddFilter(gcap.pGrab,L"SampleGrabber"); 
  22.  
  23.  gcap.pBuilder->SetFiltergraph(gcap.pGraph); 
  24.  
  25.  hr = CoCreateInstance(CLSID_VideoRenderer, NULL, 
  26.  CLSCTX_INPROC_SERVER, IID_IBaseFilter, 
  27.  (void **)&gcap.pRenderP); 
  28.  
  29.  hr = CoCreateInstance(CLSID_VideoRenderer, NULL, 
  30.  CLSCTX_INPROC_SERVER, IID_IBaseFilter, 
  31.  (void **)&gcap.pRenderS); 
  32.  
  33.  hr = gcap.pGraph->AddFilter(gcap.pRenderP,L"Video Render"); 
  34.  hr = gcap.pGraph->AddFilter(gcap.pRenderS,L"Video Render"); 
  35.  
  36.  hr = gcap.pBuilder->RenderStream(&PIN_CATEGORY_PREVIEW,
  37. &MEDIATYPE_Video, gcap.pCap, NULL, gcap.pRenderP); 
  38.  hr = gcap.pRenderP->QueryInterface(IID_IVideoWindow, (void**)&gcap.pVWP); 
  39.  hr = gcap.pBuilder->RenderStream(&PIN_CATEGORY_STILL,
  40. &MEDIATYPE_Video, gcap.pCap, gcap.pGrab, gcap.pRenderS); 
  41.  
  42.  // Query for video interfaces, which may not be relevant for audio files 
  43.  //hr = gcap.pGraph->QueryInterface(IID_IMediaEventEx, (void **)&gcap.pME);  
  44.  
  45.  //hr = gcap.pCap->QueryInterface(IID_IAMVideoProcAmp,(void **)&gcap.pVProcAmp); 
  46.  //// Query the output pin for IAMStreamConfig (not shown). 
  47.  //hr = gcap.pBuilder->FindInterface( 
  48.  // &PIN_CATEGORY_PREVIEW, // Preview pin. 
  49.  // 0, // Any media type. 
  50.  // gcap.pCap, // Pointer to the capture filter. 
  51.  // IID_IAMStreamConfig, (void**)&gcap.pConfigP);  
  52.  
  53.  // Have the graph signal event via window callbacks for performance 
  54.  SetupVideoWindow(gcap.pVWP); 
  55.  gcap.pVWP->put_MessageDrain((OAHWND)g_hWnd); 
  56.  gcap.pVWP->put_Owner((OAHWND)g_hWnd); 
  57.  //hr = gcap.pME->SetNotifyWindow((OAHWND)g_hWnd, WM_GRAPHNOTIFY, 0);  
  58.  return hr; 

另外SampleGrabber这个filter是要一个transform filter,可以在 directx 的directshow sample里找到,主要代码如下(Grabber.cpp):

还有个头文件Grabber.h:

另外还可以自己编译baseclasses里的工程生成mobile下的strmbasd.lib 和 strmbase.lib,当然,windows mobile6是有自己的strmbase.lib的,只有strmbasd.lib没有而已,不过你可以通过AKU目录下的baseclasses来编译生成wm下的baseclasses工程,这样便于调试. 其中strmbasd.lib和strmbase.lib分别用于Debug和Release下的。

很简单吧 

代码下载处: http://bbs.rosoo.net/thread-828-1-1.html

有问题多多联系!

(czbever)
本站文章除注明转载外,均为本站原创或编译欢迎任何形式的转载,但请务必注明出处,尊重他人劳动,同学习共成长。转载请注明:文章转载自:罗索实验室 [http://www.rosoo.net/a/201006/9672.html]
本文出处:CSDN博客 作者:czbever
顶一下
(4)
80%
踩一下
(1)
20%
------分隔线----------------------------
发表评论
请自觉遵守互联网相关的政策法规,严禁发布色情、暴力、反动的言论。
评价:
表情:
用户名: 验证码:点击我更换图片
栏目列表
将本文分享到微信
织梦二维码生成器
推荐内容