capturevideo.h

来自「足球机器人功能demo」· C头文件 代码 · 共 234 行

H
234
字号
// CCaptureVideo视频捕捉类头文件
/////////////////////////////////////////////////////////////////////
#if !defined(AFX_CAPTUREVIDEO_H__F5345AA4_A39F_4B07_B843_3D87C4287AA0__INCLUDED_)
#define AFX_CAPTUREVIDEO_H__F5345AA4_A39F_4B07_B843_3D87C4287AA0__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#include <atlbase.h>
#include <windows.h>
#include <dshow.h>
#include <afxsock.h>		// MFC socket extensions
#include "VoyCmd.h"

#define AHEAD		1
#define OVERLOOK	2

class CSampleGrabberCB : public ISampleGrabberCB 
{
public:
	//捕捉设备位置ID
	UINT m_nPosID;

	//截图标记
	BOOL bOneShot;

	//行为处理运行状况标记
	BOOL bWorking;
	
	//协议对象指针
	CVoyCmd * m_pCmd;
	
	//显示窗体句柄
	HWND m_hStill;

    long lWidth;
    long lHeight;
    TCHAR m_szFileName[MAX_PATH];// 位图文件名称
	CString m_strBMPFile;
    
	CSampleGrabberCB()
	{
		m_socket = INVALID_SOCKET;
		m_pCmd = NULL;
		bWorking = FALSE;
		m_nPosID = AHEAD;
    } 
    
	STDMETHODIMP_(ULONG) AddRef()
	{
		return 2;
	}
    
	STDMETHODIMP_(ULONG) Release()
	{
		return 1;
	}
    
	STDMETHODIMP QueryInterface(REFIID riid, void ** ppv)
	{
		if( riid == IID_ISampleGrabberCB || riid == IID_IUnknown )
			{ 
				*ppv = (void *) static_cast<ISampleGrabberCB*> ( this );
				return NOERROR;
			} 
		return E_NOINTERFACE;
    }

    STDMETHODIMP SampleCB( double SampleTime, IMediaSample * pSample )
	{
		return 0;
	}

	STDMETHODIMP BufferCB( double dblSampleTime, BYTE * pBuffer, long lBufferSize )
	{
		if (!pBuffer)return E_POINTER;

		//打开工作标记
		bWorking = TRUE;

		if (m_pCmd != NULL)
		{
			//如果协议对象正与行为对象断开,则跳出
			if(m_pCmd->bToRemoveBeh == FALSE)
			{
				if (m_pCmd->m_pBeh != NULL)
				{
				//	m_pCmd->m_pBeh->m_Ref ++;
					switch(m_nPosID)
					{
					case AHEAD:
						m_pCmd->m_pBeh->AfterUpdateVideoSample(pBuffer,lWidth,lHeight,dblSampleTime,m_pCmd->nState);
						break;
					case OVERLOOK:
						m_pCmd->m_pBeh->AfterUpdateOverlook(pBuffer,lWidth,lHeight,dblSampleTime,m_pCmd->nState);
						break;
					}
					//m_pCmd->m_pBeh->m_Ref --;
				}
			}
		}

		//发送图像
		if (m_socket != INVALID_SOCKET)
		{
			send(m_socket, (char*)pBuffer, lBufferSize, 0);
		}

		//根据截图标记确定是否截取静态图片
		if (bOneShot)
		{
			bWorking = TRUE;
			SaveBitmap(pBuffer, lBufferSize, m_strBMPFile);
			bOneShot = FALSE;
			bWorking = FALSE;
		}

		//工作完成
		bWorking = FALSE;
		return 0;
	}

	//创建位图文件
	BOOL SaveBitmap(BYTE * pBuffer, long lBufferSize, CString strFileName)
	{
		strcpy(m_szFileName,strFileName);
		HANDLE hf = CreateFile(m_szFileName, GENERIC_WRITE, FILE_SHARE_READ, NULL,CREATE_ALWAYS, NULL, NULL);
		if( hf == INVALID_HANDLE_VALUE )
		return 0;
    
		// 写文件头 
		BITMAPFILEHEADER bfh;
		memset( &bfh, 0, sizeof( bfh ) );
		bfh.bfType ='MB';
		bfh.bfSize = sizeof( bfh ) + lBufferSize + sizeof( BITMAPINFOHEADER );
		bfh.bfOffBits = sizeof( BITMAPINFOHEADER ) + sizeof( BITMAPFILEHEADER );
		DWORD dwWritten = 0;
		WriteFile(hf, &bfh, sizeof(bfh),&dwWritten,NULL);
	
		// 写位图格式
		BITMAPINFOHEADER bih;
		memset( &bih, 0, sizeof( bih ) );
		bih.biSize = sizeof( bih );
		bih.biWidth = lWidth;
		bih.biHeight = lHeight;
		bih.biPlanes = 1;
		bih.biBitCount = 24;
		WriteFile( hf, &bih, sizeof( bih ), &dwWritten, NULL );
    
		// 写位图数据
		WriteFile( hf, pBuffer, lBufferSize, &dwWritten, NULL );
		CloseHandle( hf );
		
		// 将截获图片显示到界面上
		if(m_hStill != NULL)
		{
			DisplayCapturedBits(pBuffer, &bih,m_hStill);
		}
		return 0;
    }

	BOOL DisplayCapturedBits(BYTE *pBuffer, BITMAPINFOHEADER *pbih,HWND hwndStill )
    {
        RECT rc;
        ::GetWindowRect( hwndStill, &rc );
        long lStillWidth = rc.right - rc.left;
        long lStillHeight = rc.bottom - rc.top;
        
        HDC hdcStill = GetDC( hwndStill );
        PAINTSTRUCT ps;
        BeginPaint(hwndStill, &ps);

        SetStretchBltMode(hdcStill, COLORONCOLOR);
        StretchDIBits( 
                    hdcStill, 0, 0, 
                    lStillWidth, lStillHeight, 
                    0, 0, lWidth, lHeight, 
                    pBuffer, 
                    (BITMAPINFO*) pbih, 
                    DIB_RGB_COLORS, 
                    SRCCOPY );

        EndPaint(hwndStill, &ps);
        ReleaseDC( hwndStill, hdcStill );    

        return TRUE;
    }

	SOCKET m_socket;
	protected:	
};

class CCaptureVideo
{
friend class CSampleGrabberCB;
public:	
	void SetPosID(UINT inPosID);
	HRESULT Create(int iDeviceID, CStatic* inpPrev,int nMode);	//开启视频函数(可直接使用)
	void SetCmd(CVoyCmd * inpCmd);								//与指令类接口
	BOOL ConnectTo( char *inpIP,int inDesPort);					//与图像接收端连接
	BOOL SetFileDir(CString inDir);								//设置图像文件保存目录
	void GrabOneFrame(CStatic* inpShow);						//截图操作
	int EnumDevices(HWND hList);								//枚举摄像设备到list(仅显示)
	HRESULT Stop();												//停止预览
	CCaptureVideo();
	virtual ~CCaptureVideo();
	CSampleGrabberCB mCB;

protected:

	HWND m_hPreviewWnd;							//御览显示窗体
	bool m_bCapStatus;							//工作状态
	IGraphBuilder *m_pGB;						//GraphBuilder
	ICaptureGraphBuilder2* m_pCapture;			//
	IBaseFilter* m_pBF;							//绑定filter
	IMediaControl* m_pMC;						//媒体控制器指针
	IVideoWindow* m_pVW;						//显示窗体指针
	CComPtr<ISampleGrabber> m_pGrabber;			//
	
	void GetCompFilter(IBaseFilter **pCompFilter);
	void FreeMediaType(AM_MEDIA_TYPE& mt);
	bool BindFilter(int deviceId, IBaseFilter **pFilter);
	void ResizeVideoWindow();
	HRESULT SetupVideoWindow();
	HRESULT InitCaptureGraphBuilder();
	bool ClearGraphs();

	//截图和录像
	CString m_strBaseDir;
	CString m_strCurDir;
	CString m_strVideoFile;	
};
#endif // !defined(AFX_CAPTUREVIDEO_H__F5345AA4_A39F_4B07_B843_3D87C4287AA0__INCLUDED_)

⌨️ 快捷键说明

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