workdevice.cpp

来自「MPEG4网络视频服务器客户端图象监控软件」· C++ 代码 · 共 495 行

CPP
495
字号
// WorkDevice.cpp: implementation of the CWorkDevice class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "DvsUser.h"
#include "WorkDevice.h"

#include "ViewStatic.h"
#include "RecvDataThread.h"
#include "DealDataThread.h"

#include "DvsUserDlg.h"

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

#define	WM_WORKDESTROY	WM_USER+2000

extern CDvsUserDlg* g_User;
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
//---------------------------------------------------------------
//
//
//
//---------------------------------------------------------------
IMPLEMENT_DYNCREATE(CWorkDevice, CObject)
//---------------------------------------------------------------
//
//
//
//---------------------------------------------------------------
CWorkDevice::CWorkDevice()
{
//	m_lpBuffer			= NULL;
	m_lpDisp			= NULL;
	m_lpBlock			= NULL;
	m_nDisp				= 0;

	m_pView				= NULL;
	pDataSock			= NULL;
	recvDataThread		= NULL;
	dealDataThread		= NULL;
	pArray				= NULL;

	m_bStart			= FALSE;
	m_bInitOK			= FALSE;
	m_bKeyFrame			= FALSE;
	m_bFirstKey			= TRUE;

	m_bPostDestroy		= FALSE;

	SetSaveFlag(FALSE);				//设置存盘标志
}
//---------------------------------------------------------------
//
//
//
//---------------------------------------------------------------
CWorkDevice::~CWorkDevice()
{
	Destroy();
}
//---------------------------------------------------------------
//
//
//
//---------------------------------------------------------------
int CWorkDevice::Init()
{
//	m_lpBuffer						= new char[1024];
	m_lpBlock						= new char[1024*100];
	m_lpDisp						= new char[352*288*2];

	ZeroMemory(&bi_in, sizeof(BITMAPINFO));
	bi_in.bmiHeader.biSize			= sizeof(BITMAPINFOHEADER);
	bi_in.bmiHeader.biWidth			= 352;
	bi_in.bmiHeader.biHeight		= 288;
	bi_in.bmiHeader.biSizeImage		= 0;
	bi_in.bmiHeader.biCompression	= mmioFOURCC('m','p','4','2');
	bi_in.bmiHeader.biPlanes		= 1;
	bi_in.bmiHeader.biBitCount		= 16;

	ZeroMemory(&bi_out, sizeof(BITMAPINFO));
//	bi_out.bmiHeader.biSize			= sizeof(BITMAPINFOHEADER) + 12;
	bi_out.bmiHeader.biSize			= sizeof(BITMAPINFOHEADER);
	bi_out.bmiHeader.biWidth		= 352;
	bi_out.bmiHeader.biHeight		= 288;
	bi_out.bmiHeader.biSizeImage	= 352*288*2;
//	bi_out.bmiHeader.biCompression	= BI_BITFIELDS;
	bi_out.bmiHeader.biCompression	= 0;
	bi_out.bmiHeader.biPlanes		= 1;
	bi_out.bmiHeader.biBitCount		= 16;

	((DWORD*) this->bi_out.bmiColors)[0] = (DWORD)0xF800;
	((DWORD*) this->bi_out.bmiColors)[1] = (DWORD)0x07E0;
	((DWORD*) this->bi_out.bmiColors)[2] = (DWORD)0x001F;
	
	
	hIC	= ::ICOpen(mmioFOURCC('V','I','D','C'), mmioFOURCC('m','p','4','2'), ICMODE_DECOMPRESS);
	if(hIC)
	{
		ICDecompressBegin(hIC, &bi_in, &bi_out);
	}
	else{
		MessageBox(NULL, _TEXT("未检测到Microsoft MPEG4视频解码程序, 无法显示图象!"), _TEXT("提示"), 0|MB_ICONINFORMATION|MB_SYSTEMMODAL);
	}

	recvDataThread	= new CRecvDataThread();
	recvDataThread->Create(this);

	dealDataThread	= new CDealDataThread();
	dealDataThread->Create(this);

	m_bInitOK		= TRUE;
	return 1;
}
//---------------------------------------------------------------
//
//
//
//---------------------------------------------------------------
int CWorkDevice::Start()
{
	while(m_bInitOK == FALSE)
	{
		::Sleep(100);
	}
	pArray	= new CPtrArray();
	recvDataThread->Resume();
	dealDataThread->Resume();

	m_bStart		= TRUE;
	m_bKeyFrame		= FALSE;
	m_bFirstKey		= TRUE;
	return 1;
}
//---------------------------------------------------------------
//
//
//
//---------------------------------------------------------------
int CWorkDevice::Stop()
{
	return 1;
}
//---------------------------------------------------------------
//
//
//
//---------------------------------------------------------------
int CWorkDevice::Destroy()
{
	m_bStart		= FALSE;
	m_bInitOK		= FALSE;

	SetSaveFlag(FALSE);			//结束存盘

	if(pDataSock)
	{
		pDataSock->Close();
		delete pDataSock;
		pDataSock = NULL;
	}
	if(recvDataThread)
	{
		recvDataThread->Terminate();
		delete recvDataThread;
		recvDataThread = NULL;
	}
	if(dealDataThread)
	{
		dealDataThread->Terminate();
		delete dealDataThread;
		dealDataThread = NULL;
	}

	if(m_lpBlock)
	{
		delete m_lpBlock;	m_lpBlock = NULL;	
	}
	if(m_lpDisp)
	{
		delete m_lpDisp;	m_lpDisp = NULL;
	}

	::Sleep(100);
	
	if(pArray)
	{
		int nCount	= pArray->GetSize();
		TRACE("too many number = %d\n", nCount);
		for(int i=0; i<nCount; i++)
		{
			LPSTR lpTemp = (LPSTR)pArray->GetAt(i);
			delete lpTemp;
			lpTemp = NULL;
		}
		pArray->RemoveAll();
		delete pArray;
		pArray = NULL;
	}
	
	if(hIC)
	{
		ICDecompressEnd(hIC);	hIC = NULL;
	}


	m_bPostDestroy = FALSE;
	return 1;
}
//---------------------------------------------------------------
//
//
//
//---------------------------------------------------------------
VOID CWorkDevice::SetSaveParam()
{
	aviFile.SetSaveTime(g_User->g_nFileSaveTime);
	aviFile.SetDataPath(g_User->g_strFileSavePath);
}
//---------------------------------------------------------------
//
//
//
//---------------------------------------------------------------
VOID CWorkDevice::SetSaveFlag(BOOL bSave)
{
	if(bSave)
	{
		AVISTREAMINFO	si;	
		ZeroMemory(&si, sizeof(AVISTREAMINFO));
		si.fccType		= streamtypeVIDEO;
		si.fccHandler	= mmioFOURCC('m','p','4','2');
		si.dwScale		= 1;
		si.dwSuggestedBufferSize = 352*288*2;
		SetRect(&si.rcFrame, 0, 0, 352, 288);

		SetSaveParam();
		aviFile.CreateFile(&si, &bi_in.bmiHeader, m_nViewWindow, 25);

		m_bSaveFile = TRUE;		

	}
	else{
		m_bSaveFile = FALSE;
		aviFile.ClearParam();
	}
}
//---------------------------------------------------------------
//
//
//
//---------------------------------------------------------------
INT CWorkDevice::SetViewWindow(CViewStatic* pView, int nViewWindow)
{
	m_nViewWindow = nViewWindow;

	if(m_pView)
	{
		m_pView->CloseDraw();
	}
	m_pView	= pView;
	m_pView->CloseDraw();
	m_pView->InitDraw();
	
//	m_pView->CloseDDraw();
//	m_pView->InitDDraw();
	
	return 1;
}
//---------------------------------------------------------------
//
//
//
//---------------------------------------------------------------
VOID CWorkDevice::RecvDataProc()
{
	VIDEO_DATA recvDATA;

	recvDATA.dwDataLen = 0;

	LPSTR lpszBuffer = new char[1024+sizeof(VIDEO_DATA)];

	if(pDataSock == NULL) 
	{
		::Sleep(200);
		return;
	}
	if(!pDataSock->RecvProc(&recvDATA, sizeof(VIDEO_DATA)))
	{
		if(m_bStart == TRUE)
		{
			if(g_User->m_hWnd)
			{
				//%%ERROR
				if(m_bPostDestroy == FALSE)
				{
					g_User->PostMessage(WM_WORKDESTROY, (WPARAM)this, 0);
					m_bPostDestroy = TRUE;
				}				
			}
		}
		::Sleep(200);
		return;
	}

	if(pDataSock == NULL) 
	{
		::Sleep(200);
		return;
	}
	if(!pDataSock->RecvProc(lpszBuffer+sizeof(VIDEO_DATA), recvDATA.dwDataLen))
	{
		if(m_bStart == TRUE)
		{
			if(g_User->m_hWnd)
			{
				//%%ERROR
				g_User->PostMessage(WM_WORKDESTROY, (WPARAM)this, 0);
			}
		}
		::Sleep(200);
		return;
	}
	
	memcpy(lpszBuffer, &recvDATA, sizeof(VIDEO_DATA));
	if(lpszBuffer)
	{
		cs.Lock();
		pArray->Add(lpszBuffer);
		cs.Unlock();		
	}
//	TRACE("Frame Size == %d\n", DATA.dwDataLen);

}
//---------------------------------------------------------------
//
//
//
//---------------------------------------------------------------
VOID CWorkDevice::DealDataProc()
{
VIDEO_DATA		sendData;
LPSTR			lpszBuffer = NULL;
INT				nSize;

	nSize	= pArray->GetSize();
	if(nSize >= 1)
	{
		cs.Lock();
		lpszBuffer = (char*)pArray->GetAt(0);
		pArray->RemoveAt(0);
		cs.Unlock();
	}
	else{
		::Sleep(70);
		return;
	}
	
	memcpy(&sendData, lpszBuffer, sizeof(VIDEO_DATA));
	
	switch(sendData.dwDataType)
	{
	case	DATA_HEADER:
		{
			memcpy(&BLOCK, lpszBuffer+sizeof(VIDEO_DATA), sizeof(BLOCKINFO));
			if(BLOCK.bKeyFrame == 0)
				m_bKeyFrame = TRUE;
			else//BLOCK.bKeyFrame != 1
				m_bKeyFrame = FALSE;
			memcpy(m_lpBlock+m_nDisp, lpszBuffer+sizeof(VIDEO_DATA), sendData.dwDataLen);
			m_nDisp += sendData.dwDataLen;
			break;
		}

	case	DATA_BODY:
		{
			memcpy(m_lpBlock+m_nDisp, lpszBuffer+sizeof(VIDEO_DATA), sendData.dwDataLen);
			m_nDisp += sendData.dwDataLen;
			break;
		}

	case	DATA_TAIL:
		{
			memcpy(m_lpBlock+m_nDisp, lpszBuffer+sizeof(VIDEO_DATA), sendData.dwDataLen);
			DeCodeFrame(m_nDisp+sendData.dwDataLen-sizeof(BLOCKINFO));
			m_nDisp = 0;
			break;
		}

	case	DATA_FULL:
		{
			memcpy(&BLOCK, lpszBuffer+sizeof(VIDEO_DATA), sizeof(BLOCKINFO));
			if(BLOCK.bKeyFrame == 0 )
				m_bKeyFrame = TRUE;
			else//BLOCK.bKeyFrame != 1
				m_bKeyFrame = FALSE;

			memcpy(m_lpBlock, lpszBuffer+sizeof(VIDEO_DATA), sendData.dwDataLen);
			DeCodeFrame(sendData.dwDataLen-sizeof(BLOCKINFO));
			break;
		}
	}

	delete lpszBuffer;
	lpszBuffer = NULL;
}
//---------------------------------------------------------------
//
//
//
//---------------------------------------------------------------
VOID CWorkDevice::DeCodeFrame(int nFrameLen)
{
CString strDate;
CTime	time;

	bi_in.bmiHeader.biSizeImage = nFrameLen;
	
	if(m_bSaveFile)
	{
		aviFile.WriteData(m_lpBlock+sizeof(BLOCKINFO), m_bKeyFrame, nFrameLen);

	}
/////////////////////////////////////////////////////////////////////////////////
	if(m_bFirstKey == TRUE)
	{
		if(m_bKeyFrame == TRUE)
		{
			m_bFirstKey = FALSE;
		}
		else{//m_bKeyFrame == FALSE
			return;
		}
	}
/////////////////////////////////////////////////////////////////////////////////
	if(hIC)
	{
		if(m_bKeyFrame)
		{
			DWORD dwRet = ICDecompress(hIC, 
							0, 
							(LPBITMAPINFOHEADER)&bi_in,
							m_lpBlock+sizeof(BLOCKINFO),
							(LPBITMAPINFOHEADER)&bi_out,
							m_lpDisp);
			if(dwRet != ICERR_OK)
			{
				TRACE("Decompress keyframe error!\n");
				time = CTime::GetCurrentTime();
				strDate = time.Format("%H:%M:%S");
				TRACE("Frame Size = %d, key frame = %d, time = %s\n", nFrameLen, m_bKeyFrame, strDate);
				return;
			}
		}

		else{
			
			DWORD dwRet = ICDecompress(hIC, 
							ICDECOMPRESS_NOTKEYFRAME, 
							(LPBITMAPINFOHEADER)&bi_in,
							m_lpBlock+sizeof(BLOCKINFO),
							(LPBITMAPINFOHEADER)&bi_out,
							m_lpDisp);
			if(dwRet != ICERR_OK) 
			{
				TRACE("Decompress error!\n");
				time = CTime::GetCurrentTime();
				strDate = time.Format("%H:%M:%S");
				TRACE("Frame Size = %d, key frame = %d, time = %s\n", nFrameLen, m_bKeyFrame, strDate);
				return;
			}
		}				
		
		if(m_pView)
		{
			m_pView->Draw(m_lpDisp, 0);
//			m_pView->DDraw(m_lpDisp, 0);
		}

	}
}
//---------------------------------------------------------------
//
//
//
//---------------------------------------------------------------

⌨️ 快捷键说明

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