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 + -
显示快捷键?