📄 videowin.cpp
字号:
// VideoWin.cpp : implementation file
//
#include "stdafx.h"
#include "Demo.h"
#include "VideoWin.h"
#include "DemoDlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CVideoWin
#define VIDEO_MULTI_CHANNEL 0
#define VIDEO_SINGLE_CHANNEL 1
#define VIDEO_PLAYBACK 2
extern RECT rectList[MAX_CHANNELS +1];
extern HANDLE ChannelHandle[MAX_CHANNELS];
int iLastSelect = 0;
int iOldSelect =-1;
int DisplayMode = 0; // 0: normal video preview
// 1: single video channel preview
// 2: playback mode
extern BOOL bDdrawMode;
extern COLORREF gBackgroundColor;
extern BOOL bOverlayMode;
extern BOOL bAudioPre;
extern void CALLBACK DrawFun(long nport, HDC hDc,LONG nUser);
void SelectRect(int i, CDC *dc);
int GetSelect(CPoint point);
static BOOL bFirstPreview = TRUE;
static CBrush tempBrush(gBackgroundColor);
CVideoWin::CVideoWin()
{
}
CVideoWin::~CVideoWin()
{
}
BEGIN_MESSAGE_MAP(CVideoWin, CEdit)
//{{AFX_MSG_MAP(CVideoWin)
ON_WM_LBUTTONDOWN()
ON_WM_LBUTTONDBLCLK()
ON_WM_PAINT()
ON_WM_MOVE()
ON_WM_MOVING()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CVideoWin message handlers
void CVideoWin::OnLButtonDown(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
TRACE("mouse click at %i %i\n", point.x, point.y);
if(DisplayMode != VIDEO_MULTI_CHANNEL)
return;
CDC *pDC = GetDC();
SelectRect(GetSelect(point), pDC);
CString str;
for(int i = 0; i < GetTotalDSPs(); i++){
str.Format("Channel %d",i);
pDC->SetTextColor(RGB(255,0,0));
pDC->SetBkMode(TRANSPARENT);
pDC->TextOut(rectList[i].left+5,rectList[i].top+10,str);
}
DrawTitle(CacRects(GetTotalDSPs()));
ReleaseDC(pDC);
CEdit::OnLButtonDown(nFlags, point);
}
int GetSelect(CPoint point)
{
for(int i =0; i < GetTotalDSPs(); i++){
if(PtInRect(&rectList[i], point)){
return i;
}
}
return -1;
}
void ClearSelect(CDC *dc)
{
}
void CVideoWin::OnLButtonDblClk(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
int s;
if((DisplayMode == VIDEO_MULTI_CHANNEL) && ((s = GetSelect(point)) != -1)){
// deselect old rect first
for(int i = 0; i < GetTotalDSPs(); i++){
StopVideoPreview(ChannelHandle[i]);
}
RECT previewWnd;
GetClientRect(&previewWnd);
TRACE("clear client area\n");
CDC *dc = GetDC(); // device context for painting
// CBrush tempBrush(gBackgroundColor);
CBrush *oldBrush = dc->SelectObject(&tempBrush);
dc->Rectangle(&previewWnd);
dc->SelectObject(oldBrush);
if( previewWnd.bottom -previewWnd.top >=576 && previewWnd.right -previewWnd.left >=704)
{
CString title;
title.Format("channel %02d", s);
dc->SetTextColor(RGB(255,0,0));
dc->SetBkMode(TRANSPARENT);
dc->TextOut(10,10,title);
}
ReleaseDC(dc);
//::StartVideoPreview(ChannelHandle[s], m_hWnd, &previewWnd, FALSE, vdfYUV444Planar/*vdfRGB16*/, 25);
if(bDdrawMode)
::StartVideoPreview(ChannelHandle[s], m_hWnd, &previewWnd, FALSE, vdfRGB16, 25);
else
::StartVideoPreview(ChannelHandle[s], m_hWnd, &previewWnd, FALSE, vdfYUV422Planar, 25);
DisplayMode = VIDEO_SINGLE_CHANNEL;
}else if(DisplayMode == VIDEO_SINGLE_CHANNEL){
/*for(int i = 0; i < GetTotalDSPs(); i++){
StopVideoPreview(ChannelHandle[i]);
}
for(i = 0; i < GetTotalDSPs(); i++){
if(bDdrawMode)
::StartVideoPreview(ChannelHandle[i], m_hWnd, &rectList[i], FALSE, vdfRGB16, 25);
else
::StartVideoPreview(ChannelHandle[i], m_hWnd, &rectList[i], FALSE, vdfYUV422Planar, 25);
}
*/
CDC *pDC = GetDC();
StartVideoPreview(pDC);
ReleaseDC(pDC);
DisplayMode = VIDEO_MULTI_CHANNEL;
}
CEdit::OnLButtonDblClk(nFlags, point);
}
int SplitRects(int width, int height, int cols, int rows, RECT *rectList)
{
int numRects = cols * rows;
int inCols, inRows;
int subRectH = height / rows;
int subRectW = width / cols;
ASSERT((cols >= 1) && (rows >= 1));
for(int i = 0; i < numRects; i++){
inRows = i / cols;
inCols = i % cols;
rectList[i].left = inCols * subRectW;
rectList[i].top = inRows * subRectH;
rectList[i].right = rectList[i].left + subRectW;
rectList[i].bottom = rectList[i].top + subRectH;
}
/* if (numRects ==4)
{
rectList[0].left = rectList[0].left;
rectList[0].top = rectList[0].top;
rectList[0].right +=100;
rectList[0].bottom +=50;
rectList[1].left +=100 ;
rectList[1].top = rectList[1].top;
rectList[1].right = rectList[1].right;
rectList[1].bottom +=50;
rectList[2].left = rectList[2].left;
rectList[2].top +=50;
rectList[2].right +=100;
rectList[2].bottom = rectList[2].bottom;
rectList[3].left +=100;
rectList[3].right +=50;
rectList[3].top = rectList[3].top;
rectList[3].bottom = rectList[3].bottom;
}
*/
return numRects;
}
void CVideoWin::OnPaint()
{
CPaintDC dc(this); // device context for painting
// TODO: Add your message handler code here
TRACE("VideoWin:OnPaint, iLastSelect=%d\n", iLastSelect);
StartVideoPreview(&dc);
// CString str;
// for(int i = 0; i < GetTotalDSPs(); i++){
// str.Format("Channel %d",i);
// dc.SetTextColor(RGB(255,0,0));
// dc.SetBkMode(TRANSPARENT);
// dc.TextOut(rectList[i].left+5,rectList[i].top+10,str);
// }
// Do not call CEdit::OnPaint() for painting messages
}
void CVideoWin::OnMove(int x, int y)
{
CEdit::OnMove(x, y);
CDC *dc = GetDC();
StartVideoPreview(dc);
ReleaseDC(dc);
// TODO: Add your message handler code here
}
void CVideoWin::OnMoving(UINT fwSide, LPRECT pRect)
{
CEdit::OnMoving(fwSide, pRect);
// TODO: Add your message handler code here
}
void CVideoWin::StartVideoPreview(CDC *dc)
{
for(int i = 0; i < GetTotalDSPs(); i++){
StopVideoPreview(ChannelHandle[i]);
}
RECT previewWnd;
GetClientRect(&previewWnd);
//CDC *pDC = GetDlgItem(IDC_VIDEOWIN)->GetDC();
// CBrush tempBrush(gBackgroundColor);
CBrush *oldBrush = dc->SelectObject(&tempBrush);
dc->Rectangle(&previewWnd);
dc->SelectObject(oldBrush);
int rectWidth = previewWnd.right - previewWnd.left;
int rectHeight = previewWnd.bottom - previewWnd.top;
int numRects = GetTotalDSPs();
CString str;
ZeroMemory(rectList, sizeof(rectList));
numRects = CacRects(GetTotalDSPs());
for(i = 0; i < GetTotalDSPs(); i++){
if(bDdrawMode)
::StartVideoPreview(ChannelHandle[i], m_hWnd, &rectList[i], FALSE, vdfRGB16, 25);
else
::StartVideoPreview(ChannelHandle[i], m_hWnd, &rectList[i], FALSE, vdfYUV422Planar, 25);
str.Format("Channel %d",i);
dc->SetTextColor(RGB(255,0,0));
dc->SetBkMode(TRANSPARENT);
dc->TextOut(rectList[i].left+5,rectList[i].top+10,str);
}
DrawTitle(numRects);
}
void CVideoWin::SelectRect(int i, CDC *dc)
{
if (bAudioPre)
{
SetAudioPreview(ChannelHandle[iLastSelect],FALSE);
SetAudioPreview(ChannelHandle[i],TRUE);
}
if((i == -1) ||(DisplayMode != VIDEO_MULTI_CHANNEL))return;
iLastSelect = i;
CHKVisionDlg* mainwnd =(CHKVisionDlg*) AfxGetMainWnd();
if(bOverlayMode)
{
CPen penWhite;
// CBrush tempBrush(gBackgroundColor);
CBrush *oldBrush = dc->SelectObject(&tempBrush);
RECT previewWnd;
GetClientRect(&previewWnd);
dc->Rectangle(&previewWnd);
dc->SelectObject(oldBrush);
int oldrop2 = dc->SetROP2(R2_XORPEN);
penWhite.CreatePen(PS_SOLID, 1, RGB(255, 255, 255));
CPen* pOldPen = dc->SelectObject(&penWhite);
if(i >= 0){
dc->MoveTo(rectList[i].left+1, rectList[i].top+1);
dc->LineTo(rectList[i].right-1, rectList[i].top+1);
dc->LineTo(rectList[i].right-1, rectList[i].bottom-1);
dc->LineTo(rectList[i].left+1, rectList[i].bottom-1);
dc->LineTo(rectList[i].left+1, rectList[i].top+1);
}
iLastSelect = i;
dc->SelectObject(pOldPen);
dc->SetROP2(oldrop2);
}
else
{
for(i =0; i < GetTotalDSPs(); i++)
{
if (i == iLastSelect)
RegisterDrawFun(i,DrawFun,(DWORD)mainwnd);
else
mainwnd->StopDrawFun(i);
}
}
return;
}
void CVideoWin::DrawTitle(int numRects)
{
if(bOverlayMode)
{
CDC *dc = GetDC();
int numBmps;
if((numBmps = numRects - GetTotalDSPs())){
CDC tempDC;
CBitmap tbmp;
tbmp.LoadBitmap(IDB_HKTITLE);
tempDC.CreateCompatibleDC(dc);
CBitmap *oldBitmap = tempDC.SelectObject(&tbmp);
int i = numRects-1;
//if(i >=1)i--;
//else return;
while(numBmps--){
dc->StretchBlt(rectList[i].left, rectList[i].top, rectList[i].right - rectList[i].left, rectList[i].bottom - rectList[i].top,
&tempDC, 0, 0,352, 288, SRCCOPY);
i--;
}
tempDC.SelectObject(oldBitmap);
}
ReleaseDC(dc);
return;
}
else
return;
}
int CVideoWin::CacRects(int numRects)
{
RECT r;
GetClientRect(&r);
int rectWidth = r.right - r.left;
int rectHeight = r.bottom - r.top;
switch(numRects){
case 1:
numRects = SplitRects(rectWidth, rectHeight, 1, 1, rectList);
break;
case 2:
case 3:
case 4:
numRects = SplitRects(rectWidth, rectHeight, 2, 2, rectList);
break;
case 5:
case 6:
case 7:
case 8:
case 9:
numRects = SplitRects(rectWidth, rectHeight, 3, 3, rectList);
break;
case 10:
case 11:
case 12:
case 13:
case 14:
case 15:
case 16:
numRects = SplitRects(rectWidth, rectHeight, 4, 4, rectList);
break;
case 17:
case 18:
case 19:
case 20:
case 21:
case 22:
case 23:
case 24:
case 25:
numRects = SplitRects(rectWidth, rectHeight, 5, 5, rectList);
break;
case 26:
case 27:
case 28:
case 29:
case 30:
case 31:
case 32:
case 33:
case 34:
case 35:
case 36:
numRects = SplitRects(rectWidth, rectHeight, 6, 6, rectList);
break;
case 37:
case 38:
case 39:
case 40:
case 41:
case 42:
case 43:
case 44:
case 45:
case 46:
case 47:
case 48:
case 49:
numRects = SplitRects(rectWidth, rectHeight, 7, 7, rectList);
break;
case 50:
case 51:
case 52:
case 53:
case 54:
case 55:
case 56:
case 57:
case 58:
case 59:
case 60:
case 61:
case 62:
case 63:
case 64:
numRects = SplitRects(rectWidth, rectHeight, 8, 8, rectList);
break;
default:
numRects = SplitRects(rectWidth, rectHeight, 5 , 5, rectList);
break;
}
return numRects;
}
void CVideoWin::DrawVect(UINT Channel, CHAR *MotionData,HDC hDc,VideoStandard_t standard)
{
int picW=352, picH=288;
RECT rc,rc1;
float ratioX, ratioY;
int w,h;
if (DisplayMode ==VIDEO_MULTI_CHANNEL)
{
rc1.left =0;
rc1.top =0;
rc1.right = rectList[Channel].right - rectList[Channel].left;
rc1.bottom = rectList[Channel].bottom - rectList[Channel].top;
}
else
GetClientRect(&rc1);
rc = rc1;
PMOTION_DATA_HEADER motionDataHeader = (PMOTION_DATA_HEADER)MotionData;
if ((motionDataHeader->BlockSize !=396) && (motionDataHeader->BlockSize !=99) && \
(motionDataHeader->BlockSize !=330) && (motionDataHeader->BlockSize !=88) && \
(motionDataHeader->BlockSize !=792) && (motionDataHeader->BlockSize !=660) )
{
/* if (DisplayMode ==VIDEO_MULTI_CHANNEL)
{
w = rc1.right;
h = rc1.bottom;
}
else
{
w = rc1.right - rc1.left ;
h = rc1.bottom - rc1.top;
}
if (w >= 700)
rc.right = rc.left + 704;
else if ( w >= 270)
rc.right = rc.left + 352;
else if ( w >= 150)
rc.right = rc.left + 176;
else
rc.right = rc.left + 88;
if (h >= 570)
rc.bottom = rc.top + 576;
else if (h >= 180)
rc.bottom = rc.top + 288;
else if (h >= 120)
rc.bottom = rc.top + 144;
else
rc.bottom = rc.top + 72;
*/
picW=704;
picH=576;
if (standard == StandardNTSC)
picH = 480;
ratioX = (rc.right - rc.left)/(float)picW;
ratioY = (rc.bottom - rc.top)/(float)picH;
UINT* pBuf = (UINT *) MotionData;
for(int y =0; y < 18; y++)
{
UINT val = pBuf[y];
for(int x =0; x <22; x++)
{
if( val&(1<<x))
::Rectangle(hDc,rc.left+ x * 32 * ratioX, rc.top + y * 32 * ratioY,
rc.left + (x * 32 + 32) * ratioX, rc.top + (y * 32 + 32) * ratioY);
}
}
return ;
}
if (motionDataHeader->PicFormat == ENC_2CIF_FORMAT)
{
picW = 704;
if (motionDataHeader->VerticalBlocks ==18)
picH = 288;
else
picH = 240;
}
else if(motionDataHeader->PicFormat == ENC_CIF_FORMAT)
{
picW = 352;
if (motionDataHeader->VerticalBlocks ==18)
picH = 288;
else
picH = 240;
}
else if (motionDataHeader->PicFormat == ENC_QCIF_FORMAT)
{
picW = 176;
if (motionDataHeader->VerticalBlocks ==9)
picH = 144;
else
picH =128;
}
else
return ;
ratioX = (rc.right - rc.left)/(float)picW;
ratioY = (rc.bottom - rc.top)/(float)picH;
USHORT* pBuf = (USHORT *)&MotionData[sizeof(MOTION_DATA_HEADER)]; //(UINT *) MotionData;
for(int y =0; y < picH/16; y++)
{
for(int x =0; x < picW/16; x++)
{
if (pBuf[y * picW/16 + x])
::Rectangle(hDc,rc.left+ x * 16 * ratioX, rc.top + y * 16 * ratioY,
rc.left + (x * 16 + 16) * ratioX, rc.top + (y * 16 + 16) * ratioY);
}
}
}
void CVideoWin::DrawVectEx(UINT Channel, CHAR *MotionData)
{
PMOTION_DATA_HEADER motionDataHeader = (PMOTION_DATA_HEADER)MotionData;
if(iLastSelect == -1)return;
if((DisplayMode != VIDEO_MULTI_CHANNEL) && (Channel != iLastSelect))
return;
CDC *dc = GetDC(); // device context for painting
if(dc == NULL){
TRACE("Can not obtain DC to draw\n");
return;
}
RECT rc;
float ratioX, ratioY;
if(DisplayMode == VIDEO_MULTI_CHANNEL){
rc = rectList[Channel];
}else{
GetClientRect(&rc);
}
VERIFY(dc);
CPen penWhite;
CBrush tempBrush(gBackgroundColor);
CBrush *oldBrush = dc->SelectObject(&tempBrush);
// clear rect
dc->Rectangle(&rc);
dc->SelectObject(oldBrush);
int picW=704, picH=576;
VideoStandard_t videostandard;
int bright,constrast,sat,hue;
GetVideoPara(ChannelHandle[Channel],&videostandard,&bright,&constrast,&sat,&hue);
if(videostandard==1)
{
picH=480;
}
else
{
picH=576;
}
ratioX = (rc.right - rc.left)/(float)picW;
ratioY = (rc.bottom - rc.top)/(float)picH;
int oldrop2 = dc->SetROP2(R2_XORPEN);
penWhite.CreatePen(PS_SOLID, 1, RGB(255, 255, 255));
CPen* pOldPen = dc->SelectObject(&penWhite);
UINT* pBuf = (UINT *) MotionData;
for(int y =0; y < 18; y++)
{
UINT val = pBuf[y];
for(int x =0; x <22; x++)
{
if( val&(1<<x))
dc->Rectangle(rc.left+ x * 32 * ratioX, rc.top + y * 32 * ratioY,
rc.left + (x * 32 + 32) * ratioX, rc.top + (y * 32 + 32) * ratioY);
}
}
dc->SelectObject(pOldPen);
dc->SetROP2(oldrop2);
ReleaseDC(dc);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -