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

📄 vfwimageprocessor.cpp

📁 一个VFW的视频捕捉系统
💻 CPP
📖 第 1 页 / 共 2 页
字号:



#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;
         CapParms.wPercentDropForError = 100;
         capCaptureSetSetup(m_hWndVideo,&CapParms,sizeof(CapParms));
         m_DriverIndex = DriverIndex;

         if (GetParent(m_hWndVideo) != NULL)
            capPreview(m_hWndVideo,TRUE);
      }
   }

   if (!Ret && m_ErrorID == 0)
   {

⌨️ 快捷键说明

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