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

📄 capture_process.cpp

📁 本系统为单机版视频管理系统
💻 CPP
字号:
#include "stdafx.h"

#include "Capture_Process.h"

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

#pragma comment(lib,"vfw32")

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

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


//下面为视频处理函数
CCapture_Main::CCapture_Main()

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

   m_DriverIndex = -1;

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

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

 //视频采集初始化
BOOL CCapture_Main::Initialize(SHORT DriverIndex)
{
   BOOL Ret = FALSE;
   SHORT Index;

   Destroy();
 
   m_ImageReady.ResetEvent();

   m_CaptureThread = AfxBeginThread(CaptureThreadFunc,(void *) this);
   m_CaptureThread->m_bAutoDelete = FALSE;

   ::WaitForSingleObject(m_ImageReady, INFINITE);

   if (m_hWndVideo)
   {
      capSetUserData(m_hWndVideo,this);
      capSetCallbackOnStatus(m_hWndVideo,StatusCallbackProc);
      capSetCallbackOnVideoStream(m_hWndVideo, StreamCallbackProc);

		capSetCallbackOnCapControl(m_hWndVideo,ControlCallbackProc);//


      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(...)
               {

               }
            }
         }
      }
 
      Ret = SetDriver(DriverIndex);
   }

   return Ret;
}
 
CCapture_Main::CCapture_Main(const CCapture_Main &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);
}

 //释放函数
VOID CCapture_Main::Destroy()
{
     
   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; 
      m_CaptureThread->PostThreadMessage(WM_QUIT,0,0);
      while(Timeout)
      {
         GetExitCodeThread(m_CaptureThread->m_hThread, &ExitCode);

         if (ExitCode != STILL_ACTIVE)
         {
            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));
}

 //录像录制函数//录在c盘根目录下
BOOL CCapture_Main::CaptureAVI(LPCTSTR Filename,FLOAT FramesPerSec,ULONG Duration,UINT Quality)
{
   BOOL Ret = FALSE;
    CAPTUREPARMS OrigCapParms;
   CAPTUREPARMS CapParms;
   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));

   return Ret;
}


CCapture_Main &CCapture_Main::Copy(const CCapture_Main &CopyFrom)
{
   INT DeviceIdx;

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

      if (CopyFrom.m_hWndVideo)
      {
         CAPDRIVERCAPS DriverCaps;

         capDriverGetCaps(CopyFrom.m_hWndVideo,&DriverCaps,sizeof(DriverCaps));
         for (DeviceIdx=0;DeviceIdx<MAX_VFW_DEVICES;++DeviceIdx)
         {
            if (m_ValidDriverIndex[DeviceIdx] == DriverCaps.wDeviceIndex)
            {
               Initialize(DeviceIdx);
               break;
            }
         }
      }
   }

   return *this;
}

 //设置驱动程序
BOOL CCapture_Main::SetDriver(SHORT DriverIndex)
{
   BOOL Ret = TRUE;
   CAPTUREPARMS CapParms = {0};

   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)
   {
      m_ErrorID = DV_ERR_NONSPECIFIC;
   }*/
   return Ret;
}

 //是否允许视频采集
BOOL CCapture_Main::EnablePreviewVideo(HWND Parent, INT x, INT y, INT PreviewRate)
{ 
   return   EnablePreviewVideo(Parent,
                             x,y,
                             m_BitmapInfoHeader.biWidth,
                             m_BitmapInfoHeader.biHeight,
                             PreviewRate); 
}

 //对采集的窗体进行子窗体大小位置
BOOL CCapture_Main::EnablePreviewVideo(HWND Parent, INT x, INT y, INT Width, INT Height, INT PreviewRate)
{
 
//将视频窗口设置为当前窗口的子页
   SetParent(m_hWndVideo,Parent);
   SetWindowLong(m_hWndVideo,GWL_STYLE,WS_CHILD);
//这个函数为窗口指定新位置和状态。它也可改变窗口在内部窗口列表中的位
   SetWindowPos(m_hWndVideo,NULL,x,y,
                Width,
                Height,
                SWP_NOZORDER);
   ShowWindow(m_hWndVideo,SW_SHOW);
   //发送给捕捉窗口来设置在预览模式下帧的显示频率
   capPreviewRate(m_hWndVideo, PreviewRate);
   return capPreview(m_hWndVideo,TRUE);//进行视频播放
}

 
BOOL CCapture_Main::DisablePreviewVideo()
{
 //进行视频断开
  // BOOL Ret = capPreview(m_hWndVideo,FALSE);
  // return Ret;

  BOOL Ret = capPreview(m_hWndVideo,FALSE);

   SetWindowPos(m_hWndVideo,NULL,0,0,0,0,SWP_NOZORDER);
   SetParent(m_hWndVideo,NULL);
   SetWindowLong(m_hWndVideo,GWL_STYLE,WS_POPUP);

   return Ret;

}

 // 得到捕捉窗口的硬件的性能
BOOL CCapture_Main::DriverGetCaps(CAPDRIVERCAPS *Caps)
{

  return capDriverGetCaps(m_hWndVideo,Caps,sizeof(*Caps));
}

 //综合设定
BOOL CCapture_Main::DlgVideoSource()
{
	return PostThreadMessage(m_CaptureThread->m_nThreadID,UM_VID_SOURCE,0,0);
}


 //视频格式设定
BOOL CCapture_Main::DlgVideoFormat()
{
   return PostThreadMessage(m_CaptureThread->m_nThreadID,UM_VID_FORMAT,0,0);

}

 //进行视频采集
BOOL CCapture_Main::DlgVideoDisplay()
{

   return PostThreadMessage(m_CaptureThread->m_nThreadID,UM_VID_DISPLAY,0,0);

}

//把从帧缓存中复制出图像存为设备无关位图书馆(DIB),应用程序也可
//以使用这两个单帧捕捉消息来编辑帧序列,
//或者创建一个慢速摄影序列
  
 
//捕取对图像的大小
 
ULONG CCapture_Main::CalcBitmapSize(const BITMAPINFOHEADER &bmiHeader)

{
   ULONG Size = 0;

   if (bmiHeader.biSizeImage == 0)
   {
      Size = bmiHeader.biWidth *
             bmiHeader.biHeight *
             bmiHeader.biBitCount / 8;
   }
   else
   {
      Size = bmiHeader.biSizeImage;
   }

   return Size;
}
 
/* BOOL Capture_LX(CCapture_Main &ImageProc, LPCTSTR Filename)
{

  ULONG Length = 0;
   CFile File;
   BOOL Ret = FALSE;
   CHAR Ext[_MAX_EXT];

   _splitpath(Filename,NULL,NULL,NULL,Ext);

   if (stricmp(Ext,".avi") == 0)
   {
      Ret = ImageProc.CaptureAVI(Filename,4.0,10,10);
   }


   return Ret;
}
*/
 ULONG CCapture_Main::CalcBitmapInfoSize(const BITMAPINFOHEADER &bmiHeader)

 {
   UINT bmiSize = (bmiHeader.biSize != 0) ? bmiHeader.biSize : sizeof(BITMAPINFOHEADER);
  return bmiSize + bmiHeader.biClrUsed * sizeof (RGBQUAD);
 }

static LRESULT CALLBACK StatusCallbackProc(HWND hWnd, int nID, LPCSTR lpsz)

{
   CCapture_Main *VFWObj = (CCapture_Main *) capGetUserData(hWnd);

   switch(nID)
   {
      case IDS_CAP_BEGIN:
         break;

      case IDS_CAP_END:
         break;
   }

   return (LRESULT) TRUE;
}

 
 static LRESULT CALLBACK FrameCallbackProc(HWND hWnd, LPVIDEOHDR lpVHdr)

{
   CCapture_Main *VFWObj = (CCapture_Main *) capGetUserData(hWnd);
   LRESULT Ret = TRUE;

   if (VFWObj)
   {
      if (!VFWObj->m_hWndVideo)
      {
         Ret = FALSE;
      }
      else
      {
         CSingleLock ImageLockObj(&VFWObj->m_ImageProtect, TRUE);

         if (VFWObj->m_TransferBitmapInfo)
         {
            ULONG Size;

            VFWObj->m_TransferBitmapInfo->bmiHeader = VFWObj->m_BitmapInfoHeader;

            Size =  min(VFWObj->m_TransferBitmapInfoSize - VFWObj->CalcBitmapInfoSize(VFWObj->m_TransferBitmapInfo->bmiHeader),
                        lpVHdr->dwBytesUsed);

            memcpy(((CHAR *) VFWObj->m_TransferBitmapInfo) + VFWObj->CalcBitmapInfoSize(VFWObj->m_TransferBitmapInfo->bmiHeader),
                   lpVHdr->lpData,
                   Size);
         }

         ImageLockObj.Unlock();

         VFWObj->m_ImageReady.SetEvent();
      }
   }
   else
   {
      Ret = FALSE;
   }

   return Ret;
}
  

static LRESULT CALLBACK StreamCallbackProc(HWND hWnd, LPVIDEOHDR lpVHdr)

{
   CCapture_Main *VFWObj = (CCapture_Main *) capGetUserData(hWnd);
   LRESULT Ret = TRUE;

   return Ret;
}



static UINT CaptureThreadFunc(VOID *pCVFWImageProcessor)
{
   CCapture_Main *pImageProc = (CCapture_Main *) pCVFWImageProcessor;
   UINT Ret = 0;
   HWND VideoWindow;
   MSG Msg;

   VideoWindow = capCreateCaptureWindow(NULL,WS_POPUP,
                                        0,0,
                                        1,1,0,0);

   pImageProc->m_hWndVideo = VideoWindow;

   pImageProc->m_ImageReady.SetEvent();
 
   while(GetMessage(&Msg,NULL,0,0))
   {
      TranslateMessage(&Msg);
      DispatchMessage(&Msg);

      switch(Msg.message)
      {
         case UM_VID_SOURCE:
            capDlgVideoSource(pImageProc->m_hWndVideo);
            break;

         case UM_VID_FORMAT:
            capDlgVideoFormat(pImageProc->m_hWndVideo);
            break;

         case UM_VID_DISPLAY:
            capDlgVideoDisplay(pImageProc->m_hWndVideo);
            break;
      }
   }

   Ret = Msg.wParam;
 

   if (VideoWindow)
   {
      DestroyWindow(VideoWindow);
   }

   return Ret;
}
BOOL CCapture_Main::PICPIC() //将图片放到剪贴板
{
    SendMessage(m_hWndVideo, WM_CAP_EDIT_COPY, 0, 0);
//	SendMessage(m_hWndVideo, WM_CAP_DLG_VIDEOCOMPRESSION, 0, 0);
	return true;
}
static LRESULT CALLBACK ControlCallbackProc(HWND hWnd, int nState)
{
   CCapture_Main *VFWObj = (CCapture_Main *) capGetUserData(hWnd);
   LRESULT Ret = TRUE;

   switch(nState)
   {
      case CONTROLCALLBACK_PREROLL:
         if (VFWObj)
         {
            VFWObj->m_CancelCapture.ResetEvent();
         }

         Ret = TRUE;
         break;

      case CONTROLCALLBACK_CAPTURING:
         // if m_CancelCapture is posted, then we cancel AVI capture by returning FALSE.
         if (VFWObj)
         {
            Ret = (::WaitForSingleObject(VFWObj->m_CancelCapture,0) != WAIT_OBJECT_0);

            if (!Ret)
               TRACE("Callback Canceled Capture\n");
         }

         break;
   }

   return Ret;
}






BOOL CCapture_Main::VideoCompress()//视频压缩
{
    SendMessage(m_hWndVideo, WM_CAP_DLG_VIDEOCOMPRESSION, 0, 0);
 	return true;
}

⌨️ 快捷键说明

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