⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vfwimageprocessor.cpp

📁 一个vc的视频捕捉源程序
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/*******************************************************************************
    Title............... Video For Windows Class Interface
    Programmer.......... Ken Varn
    Date Created........ 9/20/2000
    Operating System.... Windows NT 4
    Compiler............ Microsoft Visual C++ 6
    File Type........... C++ Source

    Description:
       Class interface to Video For Windows.

       Before using any functions in this class, the Initialize() member
       function must be called on the instantiated object.

       When finished using this class, the Destroy() member function should
       be used.

    Revision History:
       Revision Date.... xx-xx-xx
       Programmer....... xxx
       Comments......... xxx
*******************************************************************************/


#include "stdafx.h"

#include "VFWImageProcessor.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

#pragma comment(lib,"vfw32")

UINT CVFWImageProcessor::m_ValidDriverIndex[MAX_VFW_DEVICES];
USHORT CVFWImageProcessor::m_TotalVideoDrivers = 0;

#define UM_VID_SOURCE      (WM_USER+1)
#define UM_VID_FORMAT      (WM_USER+2)
#define UM_VID_DISPLAY     (WM_USER+3)

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CVFWImageProcessor::CVFWImageProcessor()

{
   m_TransferBitmapInfo = NULL;
   m_TransferBitmapInfoSize = 0;
   m_hWndVideo = NULL;
   m_CaptureThread = NULL;

   m_DriverIndex = -1;

   memset(&m_BitmapInfoHeader,0,sizeof(m_BitmapInfoHeader));
}

CVFWImageProcessor::~CVFWImageProcessor()
{
   Destroy();
}

/*******************************************************************************
   Function   : Initialize
   Arguments  : DriverIndex (input) - Index of VFW driver.
   Return     : TRUE Success, FALSE Failure
   Description: Inititlizes the object for using VFW interface to capture
                device.
*******************************************************************************/
BOOL CVFWImageProcessor::Initialize(SHORT DriverIndex)
{
   BOOL Ret = FALSE;
   SHORT Index;

   Destroy();

   // Reset any error conditions.
   GetPreviousError(NULL,NULL,TRUE);

   // This semaphore will temporarily be used to determine when the
   // capture thread is ready.
   m_ImageReady.ResetEvent();

   // Create message pump for window messages.
   m_CaptureThread = AfxBeginThread(CaptureThreadFunc,(void *) this);
   m_CaptureThread->m_bAutoDelete = FALSE;

   // Wait for event to determine when capture thread is ready.
   ::WaitForSingleObject(m_ImageReady, INFINITE);

   if (m_hWndVideo)
   {
      capSetUserData(m_hWndVideo,this);
      capSetCallbackOnError(m_hWndVideo,ErrorCallbackProc);
      capSetCallbackOnCapControl(m_hWndVideo,ControlCallbackProc);
      capSetCallbackOnStatus(m_hWndVideo,StatusCallbackProc);
      capSetCallbackOnFrame(m_hWndVideo, FrameCallbackProc);
      capSetCallbackOnVideoStream(m_hWndVideo, StreamCallbackProc);

      // Construct list of valid video drivers.
      // This creates a contiguous virtual driver table.

      if (!m_TotalVideoDrivers)
      {
         char szDeviceName[80];
         char szDeviceVersion[80];

         for (Index = 0; Index < MAX_VFW_DEVICES; Index++)
         {
            if (capGetDriverDescription(Index,
                                        szDeviceName,
                                        sizeof(szDeviceName),
                                        szDeviceVersion,
                                        sizeof(szDeviceVersion)))
            {
               try
               {
                  if (capDriverConnect(m_hWndVideo, Index))
                  {
                     m_ValidDriverIndex[m_TotalVideoDrivers] = Index;
                     m_TotalVideoDrivers++;
                     capDriverDisconnect(m_hWndVideo);
                  }
               }
               catch(CException *Ex)
               {
                  Ex->Delete();
               }
               catch(...)
               {

               }
            }
         }
      }

      // Reset any error conditions.
      GetPreviousError(NULL,NULL,TRUE);

      Ret = SetDriver(DriverIndex);
   }

   if (!Ret)
   {
      if (m_ErrorID == 0)
         m_ErrorID = DV_ERR_NONSPECIFIC;

      Destroy();
   }

   return Ret;
}


/*******************************************************************************
   Function   : GetCapWindow
   Arguments  : none
   Return     : HWND of VFW window.
   Description: Used to retrieve the handle used for VFW image processing.
*******************************************************************************/
HWND CVFWImageProcessor::GetCapWindow()
{
   return m_hWndVideo;
}

//
// Copy Constructor
//
CVFWImageProcessor::CVFWImageProcessor(const CVFWImageProcessor &CopyFrom)
{
   m_TransferBitmapInfo = NULL;
   m_TransferBitmapInfoSize = 0;

   m_hWndVideo = NULL;
   m_CaptureThread = NULL;
   m_DriverIndex = -1;
   memset(&m_BitmapInfoHeader,0,sizeof(m_BitmapInfoHeader));

   Copy(CopyFrom);
}


//
// Copy class using operator=
//
CVFWImageProcessor &CVFWImageProcessor::operator =(const CVFWImageProcessor &CopyFrom)
{
   return Copy(CopyFrom);
}


/*******************************************************************************
   Function   : Destroy
   Arguments  : none
   Return     : none
   Description: Closes up the interface for VFW of capture device.
*******************************************************************************/
VOID CVFWImageProcessor::Destroy()
{
   // Reset any error conditions.
   GetPreviousError(NULL,NULL,TRUE);

   if (m_hWndVideo)
   {
      DisablePreviewVideo();

      capCaptureAbort(m_hWndVideo);
      capSetCallbackOnError(m_hWndVideo,NULL);
      capSetCallbackOnCapControl(m_hWndVideo,NULL);
      capSetCallbackOnStatus(m_hWndVideo,NULL);
      capSetCallbackOnFrame(m_hWndVideo,NULL);
      capSetCallbackOnVideoStream(m_hWndVideo, NULL);

      capSetUserData(m_hWndVideo,NULL);
      capDriverDisconnect(m_hWndVideo);
   }

   if (m_CaptureThread)
   {
      DWORD ExitCode;
      INT Timeout = 50;   // Tenths of a Second

      // Terminate the message queue thread and wait for it to end.
      m_CaptureThread->PostThreadMessage(WM_QUIT,0,0);

      while(Timeout)
      {
         GetExitCodeThread(m_CaptureThread->m_hThread, &ExitCode);

         if (ExitCode != STILL_ACTIVE)
         {
            // Thread has ended.
            break;
         }
         else
         {
            Sleep(100);
         }

         --Timeout;
      }

      delete m_CaptureThread;

      m_hWndVideo = NULL;
   }

   m_TransferBitmapInfo = NULL;
   m_TransferBitmapInfoSize = 0;
   m_hWndVideo = NULL;
   m_CaptureThread = NULL;
   m_DriverIndex = -1;

   memset(&m_BitmapInfoHeader,0,sizeof(m_BitmapInfoHeader));
}



/*******************************************************************************
   Function   : CaptureDIB
   Arguments  : Bitmap (output) - Pointer to bitmap to receive image.
                                  If *Bitmap = NULL, then allocation will
                                  be performed automatically.
                BitmapLength (input) - Size of Bitmap if *Bitmap is not NULL.
                RetBitmapLength (output) - Actual size of image.
   Return     : TRUE Success, FALSE Failed.
   Description: Captures a DIB image from video capture device.
*******************************************************************************/
BOOL CVFWImageProcessor::CaptureDIB(PBITMAPINFO *Bitmap,
                                    ULONG BitmapLength,
                                    ULONG *RetBitmapLength)
{
   BOOL Ret = FALSE;
   CSingleLock ImageLockObj(&m_ImageProtect);

   DWORD Size = 0;

   // Reset any error conditions.
   GetPreviousError(NULL,NULL,TRUE);

   if (*Bitmap == NULL)
   {
      AllocDIBImage(Bitmap,&Size);
      BitmapLength = Size;
   }
   else
   {
      AllocDIBImage(NULL,&Size);
   }

   if (*Bitmap && Size > 0)
   {
      if (RetBitmapLength)
      {
         *RetBitmapLength = Size;
      }

      // Must assign pointer to class member variable so that the
      // callback function can get to it.
      ImageLockObj.Lock();
      m_TransferBitmapInfo = *Bitmap;
      m_TransferBitmapInfoSize = BitmapLength;
      ImageLockObj.Unlock();

      // Reset event semaphore so we know when an image is ready.
      m_ImageReady.ResetEvent();

      // Start capturing now.  Callback function will capture and signal us when done.
      TRACE("Before Capture Start Call\n");
      Ret = capGrabFrame(m_hWndVideo);
      TRACE("After Capture Start Call\n");

      if (Ret)
      {
         Ret = FALSE;

         // Wait for capture to complete.
         if (::WaitForSingleObject(m_ImageReady,2000) == WAIT_OBJECT_0)
         {
            TRACE("Image Ready\n");
            Ret = TRUE;   // Success
         }
      }

      ImageLockObj.Lock();
      m_TransferBitmapInfo = NULL;
      m_TransferBitmapInfoSize = 0;
      ImageLockObj.Unlock();

      if (!Ret)
      {
         if (RetBitmapLength)
         {
            *RetBitmapLength = (ULONG) 0;
         }
      }
   }

   if (!Ret && m_ErrorID == 0)
   {
      m_ErrorID = DV_ERR_NONSPECIFIC;
   }

   return Ret;
}


/*******************************************************************************
   Function   : CaptureAVI
   Arguments  : Filename (input) - Name of file to capture AVI
                FramesPerSec (input) - Frames Per second of AVI.
                Duration (input) - How long to run it in seconds.
                Quality (input unused)
   Return     : TRUE Success, FALSE Failed.
   Description: Captures AVI to file from current video capture device.
*******************************************************************************/
BOOL CVFWImageProcessor::CaptureAVI(LPCTSTR Filename,
                                    FLOAT FramesPerSec,
                                    ULONG Duration,
                                    UINT Quality)
{
   BOOL Ret = FALSE;
   CAPTUREPARMS OrigCapParms;
   CAPTUREPARMS CapParms;
   // Reset any error conditions.
   GetPreviousError(NULL,NULL,TRUE);

   m_CancelCapture.ResetEvent();

   capCaptureGetSetup(m_hWndVideo,&OrigCapParms,sizeof(OrigCapParms));
   CapParms = OrigCapParms;
   CapParms.dwRequestMicroSecPerFrame = (DWORD) (1.0e6 / FramesPerSec);
   CapParms.fLimitEnabled = TRUE;
   CapParms.wTimeLimit = Duration;
   CapParms.fYield = FALSE;
   CapParms.wPercentDropForError = 100; //Quality;

   capCaptureSetSetup(m_hWndVideo, &CapParms, sizeof(CapParms));

   Ret = capCaptureSequence(m_hWndVideo);

   if (Ret)
   {
      Ret = capFileSaveAs(m_hWndVideo, Filename);
   }

   capCaptureSetSetup(m_hWndVideo, &OrigCapParms, sizeof (OrigCapParms));

   if (!Ret && m_ErrorID == 0)
   {
      m_ErrorID = DV_ERR_NONSPECIFIC;
   }

   return Ret;
}


//
// Private function used to copy objects.
//
CVFWImageProcessor &CVFWImageProcessor::Copy(const CVFWImageProcessor &CopyFrom)
{
   INT DeviceIdx;

   if (&CopyFrom != this)
   {
      Destroy();

      if (CopyFrom.m_hWndVideo)
      {
         CAPDRIVERCAPS DriverCaps;

         capDriverGetCaps(CopyFrom.m_hWndVideo,&DriverCaps,sizeof(DriverCaps));

         // Find the device id in the virtual device list.
         for (DeviceIdx=0;DeviceIdx<MAX_VFW_DEVICES;++DeviceIdx)
         {
            if (m_ValidDriverIndex[DeviceIdx] == DriverCaps.wDeviceIndex)
            {
               Initialize(DeviceIdx);
               break;
            }
         }
      }
   }

   return *this;
}


/*******************************************************************************
   Function   : SetDriver
   Arguments  : DriverIndex (input) - Driver to set
   Return     : TRUE Success, FALSE Failed.
   Description: Sets curretn capture driver.
*******************************************************************************/
BOOL CVFWImageProcessor::SetDriver(SHORT DriverIndex)
{
   BOOL Ret = TRUE;
   CAPTUREPARMS CapParms = {0};

   // Reset any error conditions.
   GetPreviousError(NULL,NULL,TRUE);

   if (DriverIndex >= m_TotalVideoDrivers)
   {
      Ret = FALSE;
      m_ErrorID = DV_ERR_BADDEVICEID;
   }

   if (m_hWndVideo && m_DriverIndex != DriverIndex && Ret)
   {
      if (GetParent(m_hWndVideo) != NULL)
         capPreview(m_hWndVideo,FALSE);

      DisablePreviewVideo();
      capCaptureAbort(m_hWndVideo);

      Ret = capDriverConnect(m_hWndVideo, m_ValidDriverIndex[DriverIndex]);

      if (Ret)
      {
         capGetVideoFormat(m_hWndVideo,(PBITMAPINFO) &m_BitmapInfoHeader,sizeof(m_BitmapInfoHeader));
         capCaptureGetSetup(m_hWndVideo,&CapParms,sizeof(CapParms));
         CapParms.fAbortLeftMouse = FALSE;
         CapParms.fAbortRightMouse = FALSE;
         CapParms.fYield = TRUE;
         CapParms.fCaptureAudio = FALSE;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -