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

📄 childview.cpp

📁 这个是在PDA上运行的解码端程序
💻 CPP
字号:
// ChildView.cpp : implementation of the CChildView class
//

#include "stdafx.h"
#include "VideoNet2.h"
#include "ChildView.h"

#include "Mainfrm.h"

#include "DialogConnect.h"

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

static long reccount = 0l;
/////////////////////////////////////////////////////////////////////////////
// CChildView
unsigned char rgbdata[IMAGE_WIDTH*IMAGE_HEIGHT*3];
int buffersize=IMAGE_WIDTH*IMAGE_HEIGHT*3;

CChildView::CChildView()
{
	_bStart = false;	//会议启动标志
    m_bFull = false;	//全屏标志
	
	InitH263Decoder();  // c初始化视频解码器
 
    _bmpinfo=(BITMAPINFO*)(new char[sizeof(BITMAPINFOHEADER)]);
	_bmpinfo->bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
	_bmpinfo->bmiHeader.biWidth=vertical_size;
	_bmpinfo->bmiHeader.biHeight=vertical_size;
	_bmpinfo->bmiHeader.biPlanes=1;
	_bmpinfo->bmiHeader.biBitCount=24;
	_bmpinfo->bmiHeader.biCompression=BI_RGB;
    _bmpinfo->bmiHeader.biSizeImage=0;
	_bmpinfo->bmiHeader.biClrUsed=0;
}

CChildView::~CChildView()
{

}

// zmzhu 20070830
IMPLEMENT_DYNAMIC(CChildView, CWnd)

BEGIN_MESSAGE_MAP(CChildView, CWnd)
	ON_WM_PAINT()
	ON_COMMAND(ID_CON_CONNECT, OnConConnect)
	ON_COMMAND(ID_CON_DISCONNECT, OnConDisconnect)
	ON_COMMAND(ID_CON_FULLSCREEN, OnConFullscreen)
END_MESSAGE_MAP()


/////////////////////////////////////////////////////////////////////////////
// CChildView message handlers

BOOL CChildView::PreCreateWindow(CREATESTRUCT& cs) 
{
	if (!CWnd::PreCreateWindow(cs))
		return FALSE;

	cs.style &= ~WS_BORDER;
	cs.lpszClass = AfxRegisterWndClass(CS_HREDRAW|CS_VREDRAW|CS_DBLCLKS, 
		NULL, HBRUSH(COLOR_WINDOW+1), NULL);

	return TRUE;
}

void CChildView::OnPaint() 
{
	CPaintDC dc(this); // device context for painting
	
	// TODO: Add your message handler code here
	if (!_bStart)
	{
		CDC* pDisplayMemDC ; 
		CBitmap* pBitmap ; 
		CBitmap* pOldBitmap ;


		pDisplayMemDC = new CDC ;
		pBitmap = new CBitmap ;

		_pDrawDC = GetDC(); //GetDC(hwnd)--获取所指窗口的Device Context句柄,
							//若hwnd==NULL时,则取得整个屏幕的Device Context句柄。
  
		pBitmap->LoadBitmap(IDB_BITMAP2);  //装入一副位图
    
		pDisplayMemDC->CreateCompatibleDC(_pDrawDC);
		pOldBitmap = (CBitmap*)pDisplayMemDC->SelectObject(pBitmap) ;
    
		_pDrawDC->BitBlt(0,0,240,320,pDisplayMemDC,0,0,SRCCOPY) ;
		
		pDisplayMemDC->SelectObject(pOldBitmap) ;

		delete pBitmap;
		delete pDisplayMemDC ;
	}
	
	// Do not call CWnd::OnPaint() for painting messages
}


// 会议连接
void CChildView::OnConConnect() 
{
	if (_bStart)			//如果会议启动了则断开
		OnConDisconnect();

	CDialogConnect dlg;
	dlg.m_strIp = _T("10.27.0.81");

	if (dlg.DoModal() == IDOK)		//弹出连接对话框
	{		
		if (_sVideo != NULL)		//如果视频Socket不指向空,则关闭之。
			closesocket(_sVideo);
		
		_sVideo = socket(AF_INET, SOCK_DGRAM, 0);

/****  注:sockaddr_in 的定义如下:
			struct socket_in{
				short sin_family;
				u_short sin_port;
				struct in_addr sin_addr;
				char sin_zero[8];	}
*/
		sockaddr_in addr;			//定义socket地址变量 addr 并清空它。
		memset(&addr, 0, sizeof(addr));	

		addr.sin_family = AF_INET;			//必须是 AF_INET
		addr.sin_port = htons(PORT_VIDEO);	//IP端口号
		addr.sin_addr.s_addr = INADDR_ANY;	//
		if (bind(_sVideo, (sockaddr*)&addr, sizeof(addr)) != 0)
		{
			::MessageBox(NULL,_T("不能产生视频socket!"),_T("Message"),MB_OK);
			return;
		}
		
		_hVideo = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)threadVideo, (void*)this, 0, &_threadId);
		if (_hVideo == NULL)
		{
			::MessageBox(NULL,_T("不能产生接收线程!"),_T("Message"),MB_OK);
			return;
		}
				
		_skSend.remoteaddress = dlg.m_strIp;    //
		_skSend.CreateSocket(PORT_CONTROL,TYPE_CONTROL);

		if (dlg.n_type == 0)		//176x144   //为什么要发三次?
		{
			_skSend.SendControlMessage(MESG1_CONNECT,NULL);
//			_skSend.SendControlMessage(MESG1_CONNECT,NULL);
//			_skSend.SendControlMessage(MESG1_CONNECT,NULL);
		}else if (dlg.n_type == 1)	//320x240   //为什么要发三次?
		{
			_skSend.SendControlMessage(MESG2_CONNECT,NULL);
//			_skSend.SendControlMessage(MESG2_CONNECT,NULL);
//			_skSend.SendControlMessage(MESG2_CONNECT,NULL);
		}

		_bStart = true;

		Invalidate();
		UpdateWindow();

	}	

}

// 会议断开
void CChildView::OnConDisconnect() 
{
	if (!_bStart)			//会议启动了吗?未启动则直接返回!
		return;

	_bStart = false;		//
	
	TerminateThread(_hVideo, 0);
	_hVideo = NULL;

	_skSend.CloseSocket();
	closesocket(_sVideo);

	// Invalidate window so entire client area
	// is redrawn when UpdateWindow is called.
	Invalidate();  
	
	// Update Window to cause View to redraw.
	UpdateWindow();
}

// 接收视频线程
DWORD WINAPI CChildView::threadVideo(void* param)
{
    CChildView* parent = (CChildView*)param;
    SOCKET s = parent->_sVideo;
    unsigned char* vdata =  new unsigned char[20000];
    unsigned int vlength = 20000;
    sockaddr address;
    int addlen = sizeof(address);
    while (1)
    {
        int retvalue = recvfrom(s, (char*)vdata, vlength,0, &address, &addlen);
		Sleep(100);
		continue;
		if(retvalue==SOCKET_ERROR)
		{	
			::MessageBox(NULL,_T("SOCKET_ERROR"),NULL,MB_OK);
			return 1;
		}
		if(retvalue==0)
		{
			::MessageBox(NULL,_T("Server cann't be connected"),_T("Message"),MB_OK);
			return 1;

		}
		parent->DisplayRemoteFrame(vdata,retvalue);
    }

// 记录接受到的帧计数
	reccount++;
	printf("\n reccount = %d ",reccount);

	delete[] vdata;
    return 0;
}

// 显示视频函数
void CChildView::DisplayRemoteFrame(unsigned char *data,int size)
{
	int retvalue;

    if(!_bStart)
	    return;

	retvalue=DecompressFrame(m_bFull, data,size,rgbdata,buffersize); //视频解码

	if(!retvalue)
		return;

	DisplayBt(rgbdata);												//显示
}

void CChildView::DisplayBt(unsigned char *data)
{
    CDC* pDisplayMemDC ; 
	CBitmap* pBitmap ; 
	CBitmap* pOldBitmap ;

	pDisplayMemDC = new CDC ;
	pBitmap = new CBitmap ;
    
    PVOID pBits;
	
	static int old_size = 0;
	if (old_size != vertical_size)
	{
		old_size = vertical_size;
		Invalidate();
		UpdateWindow();
	}
	
    if (m_bFull)
    {
        _bmpinfo->bmiHeader.biWidth=vertical_size;
	    _bmpinfo->bmiHeader.biHeight=horizontal_size;
    }
    else
    {
        _bmpinfo->bmiHeader.biWidth=horizontal_size;
	    _bmpinfo->bmiHeader.biHeight=vertical_size;
    }

    HBITMAP hBitmap=CreateDIBSection(_pDrawDC->GetSafeHdc(),
        _bmpinfo,DIB_RGB_COLORS, (void**)&pBits,NULL,0); 

    memcpy(pBits, rgbdata, horizontal_size*vertical_size*3);

    pBitmap->Attach(hBitmap);

	 //_pDrawDC = AfxGetMainWnd()->GetWindowDC();
	_pDrawDC = GetWindowDC();
    
	pDisplayMemDC->CreateCompatibleDC(_pDrawDC);
    pOldBitmap = (CBitmap*)pDisplayMemDC->SelectObject(pBitmap) ;
    
    if (!m_bFull)
	{
		if ((horizontal_size ==176)&&(vertical_size ==144))
		{
         	_pDrawDC->BitBlt(30, 40,176,144,pDisplayMemDC,0,0,SRCCOPY);
		}
		else if ((horizontal_size ==320)&&(vertical_size ==240))
		{
			_pDrawDC->StretchBlt(20,40,200,240,pDisplayMemDC,0,0,vertical_size,horizontal_size,SRCCOPY);
		}
	}
	else
	{
        _pDrawDC->StretchBlt(0,0,240,320,pDisplayMemDC,0,0,vertical_size,horizontal_size,SRCCOPY);
	}

	pBitmap = pDisplayMemDC->SelectObject(pOldBitmap) ;

	pBitmap->DeleteObject();
	pDisplayMemDC->DeleteDC();
	_pDrawDC->DeleteDC();
	
    delete pBitmap;
	delete pDisplayMemDC;

}

//20080904 zmzhu
///////////////////////////////////////////////////
// 在WINCE 下如何得到屏幕大小?
// GetDeviceCaps
//
// GetDeviceCaps HORZRES/VERTRES
// or
// GetSystemMetrics SM_CXSCREEN, SM_CYSCREEN
//
// 宽
// int nWidth = GetSystemMetrics(SM_CXSCREEN);
// 高
// int nHeight = GetSystemMetrics(SM_CYSCREEN);
////////////////////////////////////////////////////

// mike 20070827
#pragma comment(lib, "Aygshell.lib")

// 全屏显示
void CChildView::OnConFullscreen() 
{
	// TODO: Add your command handler code here
	RECT rc; 
	GetWindowRect(&rc); 
    HWND hWnd = AfxGetMainWnd()->GetSafeHwnd();
#ifdef WINCE
	SHFullScreen(hWnd, SHFS_HIDETASKBAR | SHFS_HIDESIPBUTTON | SHFS_HIDESTARTICON); 
//    ::MoveWindow(hWnd, 0, 0, 240, 320, TRUE);   //zmzhu 20080831
    ::MoveWindow(hWnd, 0, 0, rc.right, rc.bottom, TRUE);

	((CMainFrame*)AfxGetMainWnd())->m_wndCommandBar.ShowWindow(FALSE);
#endif
    m_bFull = true;

    Invalidate();
    UpdateWindow();
}

// 全屏显示切换回原状
void CChildView::RestoreWindow() 
{
	// TODO: Add your command handler code here
    m_bFull = false;

	RECT rc; 
	GetWindowRect(&rc); 
    HWND hWnd = AfxGetMainWnd()->GetSafeHwnd();
#ifdef WINCE	
    SHFullScreen(hWnd, SHFS_SHOWTASKBAR | SHFS_SHOWSIPBUTTON | SHFS_SHOWSTARTICON); 
//    ::MoveWindow(hWnd, 0, 20, 240, 300, TRUE);    //zmzhu 20080831
    ::MoveWindow(hWnd, 0, 20, rc.right, rc.bottom-20, TRUE);
    ((CMainFrame*)AfxGetMainWnd())->m_wndCommandBar.ShowWindow(TRUE);
#endif

    Invalidate();
    UpdateWindow();
}

BOOL CChildView::PreTranslateMessage(MSG* pMsg) 
{
	// TODO: Add your specialized code here and/or call the base class
    if (pMsg->message == WM_LBUTTONDOWN && m_bFull)
    {
        RestoreWindow();
    }
	
	return CWnd ::PreTranslateMessage(pMsg);
}

⌨️ 快捷键说明

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