VFWImageProcessor.cpp
上传用户:sdsuchuang
上传日期:2013-01-12
资源大小:2228k
文件大小:27k
源码类别:

图形图像处理

开发平台:

Visual C++

  1. /*******************************************************************************
  2.     Title............... Video For Windows Class Interface
  3.     Programmer.......... Ken Varn
  4.     Date Created........ 9/20/2000
  5.     Operating System.... Windows NT 4
  6.     Compiler............ Microsoft Visual C++ 6
  7.     File Type........... C++ Source
  8.     Description:
  9.        Class interface to Video For Windows.
  10.        Before using any functions in this class, the Initialize() member
  11.        function must be called on the instantiated object.
  12.        When finished using this class, the Destroy() member function should
  13.        be used.
  14.     Revision History:
  15.        Revision Date.... xx-xx-xx
  16.        Programmer....... xxx
  17.        Comments......... xxx
  18. *******************************************************************************/
  19. #include "stdafx.h"
  20. #include "VFWImageProcessor.h"
  21. #ifdef _DEBUG
  22. #undef THIS_FILE
  23. static char THIS_FILE[]=__FILE__;
  24. #define new DEBUG_NEW
  25. #endif
  26. #pragma comment(lib,"vfw32")
  27. UINT CVFWImageProcessor::m_ValidDriverIndex[MAX_VFW_DEVICES];
  28. USHORT CVFWImageProcessor::m_TotalVideoDrivers = 0;
  29. #define UM_VID_SOURCE      (WM_USER+1)
  30. #define UM_VID_FORMAT      (WM_USER+2)
  31. #define UM_VID_DISPLAY     (WM_USER+3)
  32. //////////////////////////////////////////////////////////////////////
  33. // Construction/Destruction
  34. //////////////////////////////////////////////////////////////////////
  35. CVFWImageProcessor::CVFWImageProcessor()
  36. {
  37.    m_TransferBitmapInfo = NULL;
  38.    m_TransferBitmapInfoSize = 0;
  39.    m_hWndVideo = NULL;
  40.    m_CaptureThread = NULL;
  41.    m_DriverIndex = -1;
  42.    memset(&m_BitmapInfoHeader,0,sizeof(m_BitmapInfoHeader));
  43. }
  44. CVFWImageProcessor::~CVFWImageProcessor()
  45. {
  46.    Destroy();
  47. }
  48. /*******************************************************************************
  49.    Function   : Initialize
  50.    Arguments  : DriverIndex (input) - Index of VFW driver.
  51.    Return     : TRUE Success, FALSE Failure
  52.    Description: Inititlizes the object for using VFW interface to capture
  53.                 device.
  54. *******************************************************************************/
  55. BOOL CVFWImageProcessor::Initialize(SHORT DriverIndex)
  56. {
  57.    BOOL Ret = FALSE;
  58.    SHORT Index;
  59.    Destroy();
  60.    // Reset any error conditions.
  61.    GetPreviousError(NULL,NULL,TRUE);
  62.    // This semaphore will temporarily be used to determine when the
  63.    // capture thread is ready.
  64.    m_ImageReady.ResetEvent();
  65.    // Create message pump for window messages.
  66.    m_CaptureThread = AfxBeginThread(CaptureThreadFunc,(void *) this);
  67.    m_CaptureThread->m_bAutoDelete = FALSE;
  68.    // Wait for event to determine when capture thread is ready.
  69.    ::WaitForSingleObject(m_ImageReady, INFINITE);
  70.    if (m_hWndVideo)
  71.    {
  72.       capSetUserData(m_hWndVideo,this);
  73.       capSetCallbackOnError(m_hWndVideo,ErrorCallbackProc);
  74.       capSetCallbackOnCapControl(m_hWndVideo,ControlCallbackProc);
  75.       capSetCallbackOnStatus(m_hWndVideo,StatusCallbackProc);
  76.       capSetCallbackOnFrame(m_hWndVideo, FrameCallbackProc);
  77.       capSetCallbackOnVideoStream(m_hWndVideo, StreamCallbackProc);
  78.       // Construct list of valid video drivers.
  79.       // This creates a contiguous virtual driver table.
  80.       if (!m_TotalVideoDrivers)
  81.       {
  82.          char szDeviceName[80];
  83.          char szDeviceVersion[80];
  84.          for (Index = 0; Index < MAX_VFW_DEVICES; Index++)
  85.          {
  86.             if (capGetDriverDescription(Index,
  87.                                         szDeviceName,
  88.                                         sizeof(szDeviceName),
  89.                                         szDeviceVersion,
  90.                                         sizeof(szDeviceVersion)))
  91.             {
  92.                try
  93.                {
  94.                   if (capDriverConnect(m_hWndVideo, Index))
  95.                   {
  96.                      m_ValidDriverIndex[m_TotalVideoDrivers] = Index;
  97.                      m_TotalVideoDrivers++;
  98.                      capDriverDisconnect(m_hWndVideo);
  99.                   }
  100.                }
  101.                catch(CException *Ex)
  102.                {
  103.                   Ex->Delete();
  104.                }
  105.                catch(...)
  106.                {
  107.                }
  108.             }
  109.          }
  110.       }
  111.       // Reset any error conditions.
  112.       GetPreviousError(NULL,NULL,TRUE);
  113.       Ret = SetDriver(DriverIndex);
  114.    }
  115.    if (!Ret)
  116.    {
  117.       if (m_ErrorID == 0)
  118.          m_ErrorID = DV_ERR_NONSPECIFIC;
  119.       Destroy();
  120.    }
  121.    return Ret;
  122. }
  123. /*******************************************************************************
  124.    Function   : GetCapWindow
  125.    Arguments  : none
  126.    Return     : HWND of VFW window.
  127.    Description: Used to retrieve the handle used for VFW image processing.
  128. *******************************************************************************/
  129. HWND CVFWImageProcessor::GetCapWindow()
  130. {
  131.    return m_hWndVideo;
  132. }
  133. //
  134. // Copy Constructor
  135. //
  136. CVFWImageProcessor::CVFWImageProcessor(const CVFWImageProcessor &CopyFrom)
  137. {
  138.    m_TransferBitmapInfo = NULL;
  139.    m_TransferBitmapInfoSize = 0;
  140.    m_hWndVideo = NULL;
  141.    m_CaptureThread = NULL;
  142.    m_DriverIndex = -1;
  143.    memset(&m_BitmapInfoHeader,0,sizeof(m_BitmapInfoHeader));
  144.    Copy(CopyFrom);
  145. }
  146. //
  147. // Copy class using operator=
  148. //
  149. CVFWImageProcessor &CVFWImageProcessor::operator =(const CVFWImageProcessor &CopyFrom)
  150. {
  151.    return Copy(CopyFrom);
  152. }
  153. /*******************************************************************************
  154.    Function   : Destroy
  155.    Arguments  : none
  156.    Return     : none
  157.    Description: Closes up the interface for VFW of capture device.
  158. *******************************************************************************/
  159. VOID CVFWImageProcessor::Destroy()
  160. {
  161.    // Reset any error conditions.
  162.    GetPreviousError(NULL,NULL,TRUE);
  163.    if (m_hWndVideo)
  164.    {
  165.       DisablePreviewVideo();
  166.       capCaptureAbort(m_hWndVideo);
  167.       capSetCallbackOnError(m_hWndVideo,NULL);
  168.       capSetCallbackOnCapControl(m_hWndVideo,NULL);
  169.       capSetCallbackOnStatus(m_hWndVideo,NULL);
  170.       capSetCallbackOnFrame(m_hWndVideo,NULL);
  171.       capSetCallbackOnVideoStream(m_hWndVideo, NULL);
  172.       capSetUserData(m_hWndVideo,NULL);
  173.       capDriverDisconnect(m_hWndVideo);
  174.    }
  175.    if (m_CaptureThread)
  176.    {
  177.       DWORD ExitCode;
  178.       INT Timeout = 50;   // Tenths of a Second
  179.       // Terminate the message queue thread and wait for it to end.
  180.       m_CaptureThread->PostThreadMessage(WM_QUIT,0,0);
  181.       while(Timeout)
  182.       {
  183.          GetExitCodeThread(m_CaptureThread->m_hThread, &ExitCode);
  184.          if (ExitCode != STILL_ACTIVE)
  185.          {
  186.             // Thread has ended.
  187.             break;
  188.          }
  189.          else
  190.          {
  191.             Sleep(100);
  192.          }
  193.          --Timeout;
  194.       }
  195.       delete m_CaptureThread;
  196.       m_hWndVideo = NULL;
  197.    }
  198.    m_TransferBitmapInfo = NULL;
  199.    m_TransferBitmapInfoSize = 0;
  200.    m_hWndVideo = NULL;
  201.    m_CaptureThread = NULL;
  202.    m_DriverIndex = -1;
  203.    memset(&m_BitmapInfoHeader,0,sizeof(m_BitmapInfoHeader));
  204. }
  205. /*******************************************************************************
  206.    Function   : CaptureDIB
  207.    Arguments  : Bitmap (output) - Pointer to bitmap to receive image.
  208.                                   If *Bitmap = NULL, then allocation will
  209.                                   be performed automatically.
  210.                 BitmapLength (input) - Size of Bitmap if *Bitmap is not NULL.
  211.                 RetBitmapLength (output) - Actual size of image.
  212.    Return     : TRUE Success, FALSE Failed.
  213.    Description: Captures a DIB image from video capture device.
  214. *******************************************************************************/
  215. BOOL CVFWImageProcessor::CaptureDIB(PBITMAPINFO *Bitmap,
  216.                                     ULONG BitmapLength,
  217.                                     ULONG *RetBitmapLength)
  218. {
  219.    BOOL Ret = FALSE;
  220.    CSingleLock ImageLockObj(&m_ImageProtect);
  221.    DWORD Size = 0;
  222.    // Reset any error conditions.
  223.    GetPreviousError(NULL,NULL,TRUE);
  224.    if (*Bitmap == NULL)
  225.    {
  226.       AllocDIBImage(Bitmap,&Size);
  227.       BitmapLength = Size;
  228.    }
  229.    else
  230.    {
  231.       AllocDIBImage(NULL,&Size);
  232.    }
  233.    if (*Bitmap && Size > 0)
  234.    {
  235.       if (RetBitmapLength)
  236.       {
  237.          *RetBitmapLength = Size;
  238.       }
  239.       // Must assign pointer to class member variable so that the
  240.       // callback function can get to it.
  241.       ImageLockObj.Lock();
  242.       m_TransferBitmapInfo = *Bitmap;
  243.       m_TransferBitmapInfoSize = BitmapLength;
  244.       ImageLockObj.Unlock();
  245.       // Reset event semaphore so we know when an image is ready.
  246.       m_ImageReady.ResetEvent();
  247.       // Start capturing now.  Callback function will capture and signal us when done.
  248.       TRACE("Before Capture Start Calln");
  249.       Ret = capGrabFrame(m_hWndVideo);
  250.       TRACE("After Capture Start Calln");
  251.       if (Ret)
  252.       {
  253.          Ret = FALSE;
  254.          // Wait for capture to complete.
  255.          if (::WaitForSingleObject(m_ImageReady,2000) == WAIT_OBJECT_0)
  256.          {
  257.             TRACE("Image Readyn");
  258.             Ret = TRUE;   // Success
  259.          }
  260.       }
  261.       ImageLockObj.Lock();
  262.       m_TransferBitmapInfo = NULL;
  263.       m_TransferBitmapInfoSize = 0;
  264.       ImageLockObj.Unlock();
  265.       if (!Ret)
  266.       {
  267.          if (RetBitmapLength)
  268.          {
  269.             *RetBitmapLength = (ULONG) 0;
  270.          }
  271.       }
  272.    }
  273.    if (!Ret && m_ErrorID == 0)
  274.    {
  275.       m_ErrorID = DV_ERR_NONSPECIFIC;
  276.    }
  277.    return Ret;
  278. }
  279. /*******************************************************************************
  280.    Function   : CaptureAVI
  281.    Arguments  : Filename (input) - Name of file to capture AVI
  282.                 FramesPerSec (input) - Frames Per second of AVI.
  283.                 Duration (input) - How long to run it in seconds.
  284.                 Quality (input unused)
  285.    Return     : TRUE Success, FALSE Failed.
  286.    Description: Captures AVI to file from current video capture device.
  287. *******************************************************************************/
  288. BOOL CVFWImageProcessor::CaptureAVI(LPCTSTR Filename,
  289.                                     FLOAT FramesPerSec,
  290.                                     ULONG Duration,
  291.                                     UINT Quality)
  292. {
  293.    BOOL Ret = FALSE;
  294.    CAPTUREPARMS OrigCapParms;
  295.    CAPTUREPARMS CapParms;
  296.    // Reset any error conditions.
  297.    GetPreviousError(NULL,NULL,TRUE);
  298.    m_CancelCapture.ResetEvent();
  299.    capCaptureGetSetup(m_hWndVideo,&OrigCapParms,sizeof(OrigCapParms));
  300.    CapParms = OrigCapParms;
  301.    CapParms.dwRequestMicroSecPerFrame = (DWORD) (1.0e6 / FramesPerSec);
  302.    CapParms.fLimitEnabled = TRUE;
  303.    CapParms.wTimeLimit = Duration;
  304.    CapParms.fYield = FALSE;
  305.    CapParms.wPercentDropForError = 100; //Quality;
  306.    capCaptureSetSetup(m_hWndVideo, &CapParms, sizeof(CapParms));
  307.    Ret = capCaptureSequence(m_hWndVideo);
  308.    if (Ret)
  309.    {
  310.       Ret = capFileSaveAs(m_hWndVideo, Filename);
  311.    }
  312.    capCaptureSetSetup(m_hWndVideo, &OrigCapParms, sizeof (OrigCapParms));
  313.    if (!Ret && m_ErrorID == 0)
  314.    {
  315.       m_ErrorID = DV_ERR_NONSPECIFIC;
  316.    }
  317.    return Ret;
  318. }
  319. //
  320. // Private function used to copy objects.
  321. //
  322. CVFWImageProcessor &CVFWImageProcessor::Copy(const CVFWImageProcessor &CopyFrom)
  323. {
  324.    INT DeviceIdx;
  325.    if (&CopyFrom != this)
  326.    {
  327.       Destroy();
  328.       if (CopyFrom.m_hWndVideo)
  329.       {
  330.          CAPDRIVERCAPS DriverCaps;
  331.          capDriverGetCaps(CopyFrom.m_hWndVideo,&DriverCaps,sizeof(DriverCaps));
  332.          // Find the device id in the virtual device list.
  333.          for (DeviceIdx=0;DeviceIdx<MAX_VFW_DEVICES;++DeviceIdx)
  334.          {
  335.             if (m_ValidDriverIndex[DeviceIdx] == DriverCaps.wDeviceIndex)
  336.             {
  337.                Initialize(DeviceIdx);
  338.                break;
  339.             }
  340.          }
  341.       }
  342.    }
  343.    return *this;
  344. }
  345. /*******************************************************************************
  346.    Function   : SetDriver
  347.    Arguments  : DriverIndex (input) - Driver to set
  348.    Return     : TRUE Success, FALSE Failed.
  349.    Description: Sets curretn capture driver.
  350. *******************************************************************************/
  351. BOOL CVFWImageProcessor::SetDriver(SHORT DriverIndex)
  352. {
  353.    BOOL Ret = TRUE;
  354.    CAPTUREPARMS CapParms = {0};
  355.    // Reset any error conditions.
  356.    GetPreviousError(NULL,NULL,TRUE);
  357.    if (DriverIndex >= m_TotalVideoDrivers)
  358.    {
  359.       Ret = FALSE;
  360.       m_ErrorID = DV_ERR_BADDEVICEID;
  361.    }
  362.    if (m_hWndVideo && m_DriverIndex != DriverIndex && Ret)
  363.    {
  364.       if (GetParent(m_hWndVideo) != NULL)
  365.          capPreview(m_hWndVideo,FALSE);
  366.       DisablePreviewVideo();
  367.       capCaptureAbort(m_hWndVideo);
  368.       Ret = capDriverConnect(m_hWndVideo, m_ValidDriverIndex[DriverIndex]);
  369.       if (Ret)
  370.       {
  371.          capGetVideoFormat(m_hWndVideo,(PBITMAPINFO) &m_BitmapInfoHeader,sizeof(m_BitmapInfoHeader));
  372.          capCaptureGetSetup(m_hWndVideo,&CapParms,sizeof(CapParms));
  373.          CapParms.fAbortLeftMouse = FALSE;
  374.          CapParms.fAbortRightMouse = FALSE;
  375.          CapParms.fYield = TRUE;
  376.          CapParms.fCaptureAudio = FALSE;
  377.          CapParms.wPercentDropForError = 100;
  378.          capCaptureSetSetup(m_hWndVideo,&CapParms,sizeof(CapParms));
  379.          m_DriverIndex = DriverIndex;
  380.          if (GetParent(m_hWndVideo) != NULL)
  381.             capPreview(m_hWndVideo,TRUE);
  382.       }
  383.    }
  384.    if (!Ret && m_ErrorID == 0)
  385.    {
  386.       m_ErrorID = DV_ERR_NONSPECIFIC;
  387.    }
  388.    return Ret;
  389. }
  390. /*******************************************************************************
  391.    Function   : GetPreviousError
  392.    Arguments  : ErrorID (output) - ID of Error
  393.                 ErrorString (output) - Description of error.
  394.                 ResetError (input) - TRUE Reset error condition.
  395.    Return     : none
  396.    Description: Gets the last Error ID and Error Description.
  397. *******************************************************************************/
  398. VOID CVFWImageProcessor::GetPreviousError(INT *ErrorID, CString *ErrorString, BOOL ResetError)
  399. {
  400.    if (ErrorID)
  401.       *ErrorID = m_ErrorID;
  402.    if (ErrorString)
  403.       *ErrorString = m_ErrorText;
  404.    if (ResetError)
  405.    {
  406.       m_ErrorID = 0;
  407.       m_ErrorText.Empty();
  408.    }
  409. }
  410. /*******************************************************************************
  411.    Function   : EnablePreviewVideo
  412.    Arguments  : Parent (input) - Parent window that will display video.
  413.                 x (input) - X Location in parent where video will be shown.
  414.                 y (input) - Y location in parent where video will be shown.
  415.                 PreviewRate (input) - Rate of preview in FPS.
  416.    Return     : TRUE Success, FALSE Failed.
  417.    Description: Enables preview video mode.
  418. *******************************************************************************/
  419. BOOL CVFWImageProcessor::EnablePreviewVideo(HWND Parent, INT x, INT y, INT PreviewRate)
  420. {
  421.    // Reset any error conditions.
  422.    return EnablePreviewVideo(Parent,
  423.                              x,y,
  424.                              m_BitmapInfoHeader.biWidth,
  425.                              m_BitmapInfoHeader.biHeight,
  426.                              PreviewRate);
  427. }
  428. /*******************************************************************************
  429.    Function   : EnablePreviewVideo
  430.    Arguments  : Parent (input) - Parent window that will display video.
  431.                 x (input) - X Location in parent where video will be shown.
  432.                 y (input) - Y location in parent where video will be shown.
  433.                 Width (input) - Width of preview window.
  434.                 Height (input) - Height of preview window.
  435.                 PreviewRate (input) - Rate of preview in FPS.
  436.    Return     : TRUE Success, FALSE Failed.
  437.    Description: Enables preview video mode.
  438. *******************************************************************************/
  439. BOOL CVFWImageProcessor::EnablePreviewVideo(HWND Parent, INT x, INT y, INT Width, INT Height, INT PreviewRate)
  440. {
  441.    // Reset any error conditions.
  442.    GetPreviousError(NULL,NULL,TRUE);
  443.    SetParent(m_hWndVideo,Parent);
  444.    SetWindowLong(m_hWndVideo,GWL_STYLE,WS_CHILD);
  445.    SetWindowPos(m_hWndVideo,NULL,x,y,
  446.                 Width,
  447.                 Height,
  448.                 SWP_NOZORDER);
  449.    ShowWindow(m_hWndVideo,SW_SHOW);
  450.    capPreviewRate(m_hWndVideo, PreviewRate);
  451.    return capPreview(m_hWndVideo,TRUE);
  452. }
  453. /*******************************************************************************
  454.    Function   : DisablePreviewVideo
  455.    Arguments  : none
  456.    Return     : TRUE Success, FALSE Failed.
  457.    Description: Disables preview video.
  458. *******************************************************************************/
  459. BOOL CVFWImageProcessor::DisablePreviewVideo()
  460. {
  461.    // Reset any error conditions.
  462.    GetPreviousError(NULL,NULL,TRUE);
  463.    BOOL Ret = capPreview(m_hWndVideo,FALSE);
  464.    SetWindowPos(m_hWndVideo,NULL,0,0,0,0,SWP_NOZORDER);
  465.    SetParent(m_hWndVideo,NULL);
  466.    SetWindowLong(m_hWndVideo,GWL_STYLE,WS_POPUP);
  467.    return Ret;
  468. }
  469. /*******************************************************************************
  470.    Function   : DriverGetCaps
  471.    Arguments  : Caps (output)
  472.    Return     : See capDriverGetCaps()
  473.    Description: Wrapper function for capDriverGetCaps().
  474. *******************************************************************************/
  475. BOOL CVFWImageProcessor::DriverGetCaps(CAPDRIVERCAPS *Caps)
  476. {
  477.    // Reset any error conditions.
  478.   GetPreviousError(NULL,NULL,TRUE);
  479.   return capDriverGetCaps(m_hWndVideo,Caps,sizeof(*Caps));
  480. }
  481. /*******************************************************************************
  482.    Function   : DlgVideoSource
  483.    Arguments  : none
  484.    Return     : See capDlgVideoSource()
  485.    Description: Wrapper function for capDlgVideoSource().
  486. *******************************************************************************/
  487. BOOL CVFWImageProcessor::DlgVideoSource()
  488. {
  489.    // Reset any error conditions.
  490.    GetPreviousError(NULL,NULL,TRUE);
  491.    return PostThreadMessage(m_CaptureThread->m_nThreadID,UM_VID_SOURCE,0,0);
  492. // return capDlgVideoSource(m_hWndVideo);
  493. }
  494. /*******************************************************************************
  495.    Function   : DlgVideoFormat
  496.    Arguments  : none
  497.    Return     : See capDlgVideoFormat()
  498.    Description: Wrapper function for capDlgVideoFormat()
  499. *******************************************************************************/
  500. BOOL CVFWImageProcessor::DlgVideoFormat()
  501. {
  502.    // Reset any error conditions.
  503.    GetPreviousError(NULL,NULL,TRUE);
  504.    return PostThreadMessage(m_CaptureThread->m_nThreadID,UM_VID_FORMAT,0,0);
  505. //   return capDlgVideoFormat(m_hWndVideo);
  506. }
  507. /*******************************************************************************
  508.    Function   : DlgVideoDisplay
  509.    Arguments  : none
  510.    Return     : See capDlgVideoDisplay()
  511.    Description: Wrapper function for capDlgVideoDisplay()
  512. *******************************************************************************/
  513. BOOL CVFWImageProcessor::DlgVideoDisplay()
  514. {
  515.    // Reset any error conditions.
  516.    GetPreviousError(NULL,NULL,TRUE);
  517.    return PostThreadMessage(m_CaptureThread->m_nThreadID,UM_VID_DISPLAY,0,0);
  518. // return capDlgVideoDisplay(m_hWndVideo);
  519. }
  520. /*******************************************************************************
  521.    Function   : CancelCapture
  522.    Arguments  : none
  523.    Return     : none
  524.    Description: Cancels current AVI capture.
  525. *******************************************************************************/
  526. VOID CVFWImageProcessor::CancelCapture()
  527. {
  528.    m_CancelCapture.SetEvent();
  529.    capCaptureAbort(m_hWndVideo);
  530. }
  531. /*******************************************************************************
  532.    Function   : AllocDIBImage
  533.    Arguments  : ppImageData (output)     - Return pointer to allocated
  534.                                            memory.  If passed as NULL,
  535.                                            not used.
  536.                 AllocatedSize (output)   - Size of allocated block.
  537.                                            If passed as NULL, not used.
  538.    Return     : none
  539.    Description: Alllocates image buffer for DIB capture.
  540. *******************************************************************************/
  541. BOOL CVFWImageProcessor::AllocDIBImage(PBITMAPINFO *ppImageData,
  542.                                        ULONG *AllocatedSize)
  543. {
  544.    BOOL Ret = TRUE;
  545.    DWORD Size = 0;
  546.    // Reset any error conditions.
  547.    GetPreviousError(NULL,NULL,TRUE);
  548.    Size = CalcBitmapInfoSize(m_BitmapInfoHeader) + CalcBitmapSize(m_BitmapInfoHeader);
  549.    if (Size > 0)
  550.    {
  551.       if (ppImageData)
  552.       {
  553.          *ppImageData = (BITMAPINFO *) new BYTE[Size];
  554.          (**ppImageData).bmiHeader = m_BitmapInfoHeader;
  555.       }
  556.    }
  557.    else
  558.    {
  559.       Ret = FALSE;
  560.    }
  561.    if (AllocatedSize)
  562.    {
  563.       *AllocatedSize = Size;
  564.    }
  565.    return Ret;
  566. }
  567. /*******************************************************************************
  568.    Function   : GetBitmapInfoHeader()
  569.    Arguments  : none
  570.    Return     : BitmapInfo of capture device.
  571.    Description: See return.
  572. *******************************************************************************/
  573. BITMAPINFOHEADER CVFWImageProcessor::GetBitmapInfoHeader()
  574. {
  575.    return m_BitmapInfoHeader;
  576. }
  577. /*******************************************************************************
  578.    Function   : CalcBitmapSize()
  579.    Arguments  : bmiHeader (input) - BITMAPINFOHEADER from which to calculate
  580.                                     bitmap size.
  581.    Return     : Size of Bitmap.
  582.    Description: Calculates the size of a bitmap based upon the contents of
  583.                 the BITMAPINFOHEADER passed in.
  584. *******************************************************************************/
  585. ULONG CVFWImageProcessor::CalcBitmapSize(const BITMAPINFOHEADER &bmiHeader)
  586. {
  587.    ULONG Size = 0;
  588.    if (bmiHeader.biSizeImage == 0)
  589.    {
  590.       Size = bmiHeader.biWidth *
  591.              bmiHeader.biHeight *
  592.              bmiHeader.biBitCount / 8;
  593.    }
  594.    else
  595.    {
  596.       Size = bmiHeader.biSizeImage;
  597.    }
  598.    return Size;
  599. }
  600. /*******************************************************************************
  601.    Function   : CalcBitmapInfoSize()
  602.    Arguments  : bmiHeader (input) - BITMAPINFOHEADER from which to calculate
  603.                                     bitmap size.
  604.    Return     : Size of Bitmap Info Header.
  605.    Description: Calculates the size of a bitmap info header based upon the
  606.                 contents of the BITMAPINFOHEADER passed in.  This function
  607.                 can be used to determine the offset from the BITMAPINFOHEADER
  608.                 to the actual bitmap data.
  609. *******************************************************************************/
  610. ULONG CVFWImageProcessor::CalcBitmapInfoSize(const BITMAPINFOHEADER &bmiHeader)
  611. {
  612.    UINT bmiSize = (bmiHeader.biSize != 0) ? bmiHeader.biSize : sizeof(BITMAPINFOHEADER);
  613.    return bmiSize + bmiHeader.biClrUsed * sizeof (RGBQUAD);
  614. }
  615. //
  616. // Internal callback functions.
  617. //
  618. static LRESULT CALLBACK ErrorCallbackProc(HWND hWnd, int nErrID, LPSTR lpErrorText)
  619. {
  620.    CVFWImageProcessor *VFWObj = (CVFWImageProcessor *) capGetUserData(hWnd);
  621.    if (VFWObj)
  622.    {
  623.       VFWObj->m_ErrorID = nErrID;
  624.       VFWObj->m_ErrorText = lpErrorText;
  625.    }
  626.    return (LRESULT) TRUE;
  627. }
  628. static LRESULT CALLBACK ControlCallbackProc(HWND hWnd, int nState)
  629. {
  630.    CVFWImageProcessor *VFWObj = (CVFWImageProcessor *) capGetUserData(hWnd);
  631.    LRESULT Ret = TRUE;
  632.    switch(nState)
  633.    {
  634.       case CONTROLCALLBACK_PREROLL:
  635.          if (VFWObj)
  636.          {
  637.             VFWObj->m_CancelCapture.ResetEvent();
  638.          }
  639.          Ret = TRUE;
  640.          break;
  641.       case CONTROLCALLBACK_CAPTURING:
  642.          // if m_CancelCapture is posted, then we cancel AVI capture by returning FALSE.
  643.          if (VFWObj)
  644.          {
  645.             Ret = (::WaitForSingleObject(VFWObj->m_CancelCapture,0) != WAIT_OBJECT_0);
  646.             if (!Ret)
  647.                TRACE("Callback Canceled Capturen");
  648.          }
  649.          break;
  650.    }
  651.    return Ret;
  652. }
  653. static LRESULT CALLBACK StatusCallbackProc(HWND hWnd, int nID, LPCSTR lpsz)
  654. {
  655.    CVFWImageProcessor *VFWObj = (CVFWImageProcessor *) capGetUserData(hWnd);
  656.    switch(nID)
  657.    {
  658.       case IDS_CAP_BEGIN:
  659.          break;
  660.       case IDS_CAP_END:
  661.          break;
  662.    }
  663.    return (LRESULT) TRUE;
  664. }
  665. static LRESULT CALLBACK FrameCallbackProc(HWND hWnd, LPVIDEOHDR lpVHdr)
  666. {
  667.    CVFWImageProcessor *VFWObj = (CVFWImageProcessor *) capGetUserData(hWnd);
  668.    LRESULT Ret = TRUE;
  669.    if (VFWObj)
  670.    {
  671.       if (!VFWObj->m_hWndVideo)
  672.       {
  673.          Ret = FALSE;
  674.       }
  675.       else
  676.       {
  677.          CSingleLock ImageLockObj(&VFWObj->m_ImageProtect, TRUE);
  678.          if (VFWObj->m_TransferBitmapInfo)
  679.          {
  680.             ULONG Size;
  681.             VFWObj->m_TransferBitmapInfo->bmiHeader = VFWObj->m_BitmapInfoHeader;
  682.             Size =  min(VFWObj->m_TransferBitmapInfoSize - VFWObj->CalcBitmapInfoSize(VFWObj->m_TransferBitmapInfo->bmiHeader),
  683.                         lpVHdr->dwBytesUsed);
  684.             memcpy(((CHAR *) VFWObj->m_TransferBitmapInfo) + VFWObj->CalcBitmapInfoSize(VFWObj->m_TransferBitmapInfo->bmiHeader),
  685.                    lpVHdr->lpData,
  686.                    Size);
  687.          }
  688.          ImageLockObj.Unlock();
  689.          VFWObj->m_ImageReady.SetEvent();
  690.       }
  691.    }
  692.    else
  693.    {
  694.       Ret = FALSE;
  695.    }
  696.    return Ret;
  697. }
  698. static LRESULT CALLBACK StreamCallbackProc(HWND hWnd, LPVIDEOHDR lpVHdr)
  699. {
  700.    CVFWImageProcessor *VFWObj = (CVFWImageProcessor *) capGetUserData(hWnd);
  701.    LRESULT Ret = TRUE;
  702.    return Ret;
  703. }
  704. static UINT CaptureThreadFunc(VOID *pCVFWImageProcessor)
  705. {
  706.    CVFWImageProcessor *pImageProc = (CVFWImageProcessor *) pCVFWImageProcessor;
  707.    UINT Ret = 0;
  708.    HWND VideoWindow;
  709.    MSG Msg;
  710.    VideoWindow = capCreateCaptureWindow(NULL,WS_POPUP,
  711.                                         0,0,
  712.                                         1,1,0,0);
  713.    pImageProc->m_hWndVideo = VideoWindow;
  714.    pImageProc->m_ImageReady.SetEvent();
  715.    // Process window messages for VFW window until a WM_QUIT is posted.
  716.    while(GetMessage(&Msg,NULL,0,0))
  717.    {
  718.       TranslateMessage(&Msg);
  719.       DispatchMessage(&Msg);
  720.       switch(Msg.message)
  721.       {
  722.          case UM_VID_SOURCE:
  723.             capDlgVideoSource(pImageProc->m_hWndVideo);
  724.             break;
  725.          case UM_VID_FORMAT:
  726.             capDlgVideoFormat(pImageProc->m_hWndVideo);
  727.             break;
  728.          case UM_VID_DISPLAY:
  729.             capDlgVideoDisplay(pImageProc->m_hWndVideo);
  730.             break;
  731.       }
  732.    }
  733.    Ret = Msg.wParam;
  734. // Ret = AfxGetThread()->Run();
  735.    if (VideoWindow)
  736.    {
  737.       DestroyWindow(VideoWindow);
  738.    }
  739.    return Ret;
  740. }