📄 test1300dlg.cpp
字号:
return CDialog::DestroyWindow();
}
BOOL CTest1300Dlg::CreateDirectDraw(HWND hWnd, PBITMAPINFOHEADER lpbiOut)
{
DDSURFACEDESC ddsd;
HRESULT ddrval;
ddrval = DirectDrawCreate( NULL, &lpDD, NULL );
if( ddrval != DD_OK ) {
return FALSE;
}
ddrval = lpDD->SetCooperativeLevel( hWnd, DDSCL_NORMAL );
if( ddrval != DD_OK ) {
DestroyDirectDraw();
return FALSE;
}
// Create the primary surface
ZeroMemory(&ddsd, sizeof(ddsd));
ddsd.dwSize = sizeof( ddsd );
ddsd.dwFlags = DDSD_CAPS ;
ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
ddrval = lpDD->CreateSurface( &ddsd, &lpDDSPrimary, NULL );
if( ddrval != DD_OK ) {
DestroyDirectDraw();
return FALSE;
}
// create a clipper for the primary surface
ddrval = lpDD->CreateClipper( 0, &lpClipper, NULL );
if( ddrval != DD_OK ) {
DestroyDirectDraw();
return FALSE;
}
ddrval = lpClipper->SetHWnd( 0, hWnd );
if( ddrval != DD_OK ) {
DestroyDirectDraw();
return FALSE;
}
ddrval = lpDDSPrimary->SetClipper( lpClipper );
if( ddrval != DD_OK ) {
DestroyDirectDraw();
return FALSE;
}
// Create Offscreen Surface
ZeroMemory(&ddsd, sizeof(ddsd));
ddsd.dwSize = sizeof(ddsd);
ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH;
ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
ddsd.dwWidth = lpbiOut->biWidth;
ddsd.dwHeight = lpbiOut->biHeight;
ddrval = lpDD->CreateSurface(&ddsd, &lpDDSOne, NULL);
if( ddrval != DD_OK ) {
DestroyDirectDraw();
return FALSE;
}
m_bShowUpdated = FALSE;
return TRUE;
}
void CTest1300Dlg::DestroyDirectDraw()
{
if ( lpDDSPrimary ) { lpDDSPrimary->Release();lpDDSPrimary = NULL; }
if ( lpDDSOne ) { lpDDSOne->Release(); lpDDSOne = NULL; }
if ( lpClipper ) { lpClipper->Release(); lpClipper = NULL; }
if ( lpDD ) { lpDD->Release(); lpDD = NULL; }
return;
}
DWORD WINAPI AcceptThread(LPVOID lpV)
{
CTest1300Dlg *pDlg = (CTest1300Dlg *)lpV;
XSocket *pSock=NULL;
unsigned char pPlayBuffer[DEFAULT_WIDTH*DEFAULT_HEIGHT*4];
unsigned char pbuffer[MAX_DATA_SIZE+sizeof(struct packet_header)];
PacketHeader *header=(PacketHeader*)pbuffer;
BOOL bFirstFrame=TRUE;
DWORD t1, t2, num;
FILE *fp=NULL;
int i420_num = 0;
fp = fopen("C:\\Capture.yuv", "ab");
bFirstFrame = TRUE;
// Receive Packet Header
while( pDlg->m_Socket.Recv((char*)header, HEADERSIZE)==HEADERSIZE ) {
// TRACE3("Header: Version=0x%x, Type=0x%x, Length=%d, ", header->version,
// header->type, header->length);
// TRACE1("reserved=0x%x\n", header->reserved);
if ( header->version!=0x48 ) {
TRACE0("receive non-valid packet header, version error\n");
break;
}
if ( header->reserved!=0xffff) {
TRACE0("receive non-valid packet header, reserved error\n");
break;
}
// Receive
if ( pDlg->m_Socket.Recv(header->data, header->length-HEADERSIZE)
!=(header->length-HEADERSIZE) ) {
TRACE0("receive non-valid packet data\n");
break;
}
// TRACE3("The Last Three bytes is 0x%x, 0x%x, 0x%x\n",
// header->data[header->length-HEADERSIZE-3],
// header->data[header->length-HEADERSIZE-2],
// header->data[header->length-HEADERSIZE-1]);
// check
switch(header->type) {
case IFRAME:
//TRACE0("IFRAME\n");
// Decode
if (ICDecompress(pDlg->m_hIC, 0, pDlg->m_lpbiIn, header->data,
pDlg->m_lpbiOut, pPlayBuffer) != ICERR_OK ) {
// Handle the decompression error that occurred.
pDlg->m_Socket.Close();
break;
}
break;
case PFRAME:
//TRACE0("PFRAME\n");
// Decode
if (ICDecompress(pDlg->m_hIC, 0, pDlg->m_lpbiIn, header->data,
pDlg->m_lpbiOut, pPlayBuffer) != ICERR_OK ) {
// Handle the decompression error that occurred.
pDlg->m_Socket.Close();
break;
}
// if ( bFirstFrame==TRUE ) {
// TRACE1("request first I frame when receive 0x%x type frame\n", header->type);
// continue;
// }
break;
case I420FRAME:
if ( fp!=NULL ) {
i420_num++;
// fwrite(header->data, sizeof(unsigned char), pDlg->m_lpbiOut->biWidth*pDlg->m_lpbiOut->biHeight*3/2, fp);
TRACE1("fwrite %d frames\n", i420_num);
}
yv12_to_rgb24_mmx(pPlayBuffer, pDlg->m_lpbiOut->biWidth*3,
(unsigned char*)header->data,
(unsigned char*)(header->data+pDlg->m_lpbiOut->biWidth*pDlg->m_lpbiOut->biHeight),
(unsigned char*)(header->data+pDlg->m_lpbiOut->biWidth*pDlg->m_lpbiOut->biHeight*5/4),
pDlg->m_lpbiOut->biWidth, pDlg->m_lpbiOut->biWidth/2, pDlg->m_lpbiOut->biWidth, pDlg->m_lpbiOut->biHeight);
break;
default:
TRACE1("non-valid 0x%x type frame\n", header->type);
break;
}
if ( bFirstFrame==TRUE ) {
t1 = timeGetTime();
t2 = t1;
num = 0;
bFirstFrame=FALSE;
}
else {
t2 = timeGetTime();
num++;
if ( (t2-t1)>5000 ) {
bFirstFrame=TRUE;
// TRACE1(" FPS is %ffps\n", (num*1000.0) / (t2-t1));
}
}
// Show
pDlg->ShowImage(pPlayBuffer);
}
pDlg->m_Socket.Close();
i420_num = 0;
if ( fp!=NULL ) {
fclose(fp);
fp = NULL;
}
pDlg->m_hAcceptThread = NULL;
TRACE0("Leave AcceptThread\n");
return 0;
}
BOOL CTest1300Dlg::ShowImage(void *pBuffer)
{
HRESULT ddrval;
HDC hDCSOne;
RECT srcRect, dstRect;
if ( m_bShowUpdated==TRUE ) {
DestroyDirectDraw();
if ( CreateDirectDraw(m_ShowBox.m_hWnd, m_lpbiOut)==FALSE ) return FALSE;
}
srcRect.top = 0; srcRect.left= 0;
srcRect.bottom = DEFAULT_HEIGHT; srcRect.right=DEFAULT_WIDTH;
::GetWindowRect(m_ShowBox.m_hWnd, &dstRect); // cost 10/100000 ms
// dstRect.right = dstRect.left+DEFAULT_WIDTH;
// dstRect.bottom= dstRect.top+DEFAULT_HEIGHT;
ddrval = lpDDSOne->GetDC(&hDCSOne);
if ( ddrval!=DD_OK ) {
TRACE0("DDSOne GetDC error\n");
return FALSE;
}
if ( 0 ) { // flip
::SetDIBitsToDevice(hDCSOne, 0, 0, m_lpbiOut->biWidth, -m_lpbiOut->biHeight,
0, -m_lpbiOut->biHeight-1,
-m_lpbiOut->biHeight-1, -m_lpbiOut->biHeight, pBuffer, (BITMAPINFO*)m_lpbiOut, DIB_RGB_COLORS);
}
else {
::SetDIBitsToDevice(hDCSOne, 0, 0, m_lpbiOut->biWidth, m_lpbiOut->biHeight,
0, 0, 0, m_lpbiOut->biHeight, pBuffer, (BITMAPINFO*)m_lpbiOut, DIB_RGB_COLORS);
}
ddrval = lpDDSOne->ReleaseDC(hDCSOne);
ddrval = lpDDSPrimary->Blt( &dstRect, lpDDSOne, &srcRect, /* DDBLT_DONOTWAIT | */DDBLT_ASYNC, NULL);
if ( ddrval!=DD_OK ) {
TRACE0("lpDDSPrimary Blt error\n");
return FALSE;
}
return TRUE;
}
void CTest1300Dlg::OnSize(UINT nType, int cx, int cy)
{
CDialog::OnSize(nType, cx, cy);
// TODO: Add your message handler code here
// Set ShowBox to Size
if ( ::IsWindow(m_ShowBox.m_hWnd) ) {
BOOL br = m_ShowBox.SetWindowPos(NULL, 0, 0, cx-240, cy-60, SWP_NOMOVE | SWP_SHOWWINDOW);
m_bShowUpdated = TRUE;
TRACE3("cx %d, cy %d, return %d\n", cx, cy, br);
}
}
void CTest1300Dlg::OnConnect()
{
// TODO: Add your control notification handler code here
if ( m_hAcceptThread!=NULL ) { // disconnect
m_Socket.Close();
int i=0;
while ( m_hAcceptThread!=NULL && i++<300 ) {
Sleep(10);
}
m_Connect.SetWindowText("连接");
return;
}
m_Connect.SetWindowText("连接中");
// create listen server
if ( m_Socket.CreateTCPClient(m_Address, m_Port)==FALSE ) {
MessageBox("Socket Create Error\n");
return;
}
m_Connect.SetWindowText("已连接");
DWORD idListen;
//Begin a thread to accept connection
m_hAcceptThread = CreateThread(NULL, 0, AcceptThread,
(LPVOID)this, 0, &idListen);
if ( m_hAcceptThread==NULL ){
m_Socket.Close();
TRACE0("AcceptThread Create Error\n");
}
}
void CTest1300Dlg::OnConfig()
{
// TODO: Add your control notification handler code here
typedef struct config {
char ip[16];
char gateway[16];
char netmask[16];
int port;
int chn;
int quality;
}CONFIG;
CONFIG cfg;
UpdateData(TRUE);
strcpy(cfg.ip,m_cfgip);
cfg.port = m_cfgport;
strcpy(cfg.gateway,m_cfggateway);
strcpy(cfg.netmask,m_cfgnetmask);
cfg.chn = m_cfgchn;
cfg.quality = m_cfgquality;
if ( m_hAcceptThread==NULL ) return;
int ret = m_Socket.Send((char*)&cfg, sizeof(CONFIG));
TRACE1("m_Socket send %d bytes\n", ret);
return;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -