// 基于TCP/IP 可视电话主窗口的窗口过程
LONG APIENTRY MainWndProc(HWND hWnd,UINT message,UINT wParam,
LONG lParam){
static HANDLE hThreadG7231,hThreadTCPListen,hThreadTCPRev;
DWORDThreadIDG7231,ThreadIDTCPListen,ThreadIDTCPRev;
static THREADPACK tp;
static THREADPACK tp1;
unsigned char Buf[80];
CAPSTATUS capStatus;
switch (message) {
case WM_CREATE:
Init_Wsock(hWnd); //初始化一些数据结构
Init_BS(2,&bs);
vd_tx_pdu.V_S = 0;vd_tx_pdu.N_S = 0;
vd_rx_pdu.V_R = 0;vd_tx_sdu.bytes = 0;
if( dnldProg ( hWnd, "h324g723.exe") )
{//装入语音编解码的DSP核心
MessageBox(hWnd,"Load G.723.1 Kernel Error","Error",MB_OK);
PostQuitMessage(0); }
else
MessageBox(hWnd,"Load G.723.1 Kernel OK!","Indication",MB_OK);
//创建语音编解码的线程
parag7231.hWnd = hWnd;
hThreadG7231=CreateThread (NULL, 0,
(LPTHREAD_START_ROUTINE)G723Proc,
(G7231DATA *)¶g7231,CREATE_SUSPENDED,
(LPDWORD)&ThreadIDG7231);
if (!hThreadG7231){
wsprintf(Buf, "Error in creating G7231 thread: %d",GetLastError());
MessageBox (hWnd, Buf, "WM_CREATE", MB_OK);}
//创建TCP/IP接收线程
tp1.hWnd = hWnd;
hThreadTCPRev = CreateThread (NULL, 0,
(LPTHREAD_START_ROUTINE)AcceptThreadProcRev,
(G7231DATA *)&tp1,CREATE_SUSPENDED,
(LPDWORD)&ThreadIDTCPRev);
if (!hThreadTCPRev){
wsprintf(Buf, "Error in creating TCP Receive thread: %d",GetLastError());
MessageBox (hWnd, Buf, "WM_CREATE", MB_OK);}
//开始侦听网络
SendMessage(hWnd,WM_COMMAND,IDM_LISTEN,NULL);
break;
case WM_VIDEO_ENCODE: //图象编码
if(needencode)EncodeFunction(hWnd);
needencode = SendVideoToBuff(&vd_tx_sdu, buff);
frameMode=TRUE;
capPreview(capWnd,FALSE);capOverlay(capWnd,FALSE);
capGrabFrameNoStop(capWnd);
break;
case WM_VIDEO_DECODE: //图象解码
Video_Decod_begin = 1;
play_movie();
Video_Decod_begin = 0;
break;
case WM_COMMAND:
switch(LOWORD(wParam)) {
case IDM_CONNECT: //
响应对方的呼叫,接通可视电话
WskConnect( hWnd );
ResumeThread(hThreadTCPRev);//运行TCP/IP接收线程
ResumeThread(hThreadG7231);//运行语音编解码线程
BeginG7231Codec();
//初始化图象采集卡,并开始采集图象
frameMode = FALSE;
capWnd= capCreateCaptureWindow((LPSTR)"Capture Window",
WS_CHILD | WS_VISIBLE,
100, 100, 176,144 ,
(HWND) hWnd, (int) 0) ;
capSetCallbackOnError(capWnd, (FARPROC)ErrorCallbackProc) ;
capSetCallbackOnStatus(capWnd, (FARPROC)StatusCallbackProc) ;
capSetCallbackOnFrame(capWnd, (FARPROC)FrameCallbackProc) ;
capDriverConnect(capWnd, 0);
CenterCaptureWindow(hWnd, capWnd);
capDlgVideoSource(capWnd);
capDlgVideoFormat(capWnd);
capDlgVideoCompression(capWnd);
capGetStatus(capWnd,&capStatus,sizeof(CAPSTATUS));
StartNewVideoChannel(hWnd, capWnd) ;
image = image_one;
frameMode = TRUE;
capPreview(capWnd,FALSE);
capOverlay(capWnd,FALSE);
capGrabFrameNoStop(capWnd);
break;
case IDM_LISTEN: //拨对方号码,呼叫对方
sock = socket( AF_INET, SOCK_STREAM, 0);
if (sock == INVALID_SOCKET) {
MessageBox(hWnd, "socket() failed", "Error", MB_OK);
closesocket(sock);
break;}
if (!FillAddr(hWnd, &local_sin, FALSE )) //
获取TCP/IP地址和端口号
break;
EnableMenuItem(GetMenu( hWnd ), IDM_LISTEN, MF_GRAYED);
SetWindowText( hWnd, "Waiting for connection..");
bind ( sock , (struct sockaddr FAR *)&local_sin,sizeof(local_sin);
if (listen( sock, MAX_PENDING_CONNECTS ) < 0) {
sprintf(szBuff, "%d is the error", WSAGetLastError());
MessageBox(hWnd, szBuff, "listen(sock) failed", MB_OK);
break;}
tp.hWnd = hWnd;//开始本地的TCP/IP接收线程
_beginthread(AcceptThreadProc,0,&tp);
ResumeThread(hThreadG7231); //
开始本地语音编解码的线程
break;
case IDM_DISCONNECT: //挂断可视电话
CloseG7231Codec();
SuspendThread(hThreadG7231);
SuspendThread(hThreadTCPRev);
WSACleanup();
Init_Video_Decod_Again();
capSetCallbackOnError(capWnd, NULL) ;
capSetCallbackOnStatus(capWnd, NULL) ;
InvalidateRect(hWnd,NULL,1);
capSetCallbackOnFrame(capWnd, NULL) ;
capSetCallbackOnVideoStream(capWnd, NULL) ;
capDriverDisconnect(capWnd);
Init_Wsock(hWnd);
MessageBox(hWnd,
"Now closing the Video telephone","",MB_OK);
SetDisConnectMenus(hWnd);
SendMessage(hWnd, WM_COMMAND,IDM_LISTEN,NULL);
break;
case IDM_EXIT:
CloseG7231Codec();
SendMessage(hWnd, WM_CLOSE, 0, 0l);
break;
default:
return (DefWindowProc(hWnd, message, wParam, lParam));
}
break;
case WM_CLOSE:
if (IDOK != MessageBox( hWnd, "OK to close window?", gszAppName,
MB_ICONQUESTION | MB_OKCANCEL ))
break ;
case WM_DESTROY:
WSACleanup();
CloseG7231Codec();
TerminateThread(hThreadG7231,0);
TerminateThread(hThreadTCPRev,0);
capSetCallbackOnError(capWnd, NULL) ;
capSetCallbackOnStatus(capWnd, NULL) ;
capSetCallbackOnFrame(capWnd, NULL) ;
capSetCallbackOnVideoStream(capWnd, NULL) ;
capDriverDisconnect(capWnd);
FreeAll();
PostQuitMessage(0);
break;
default: /* Passes it on if unproccessed*/
return (DefWindowProc(hWnd, message, wParam, lParam));
}
return (0);
}
//主叫方TCP/IP接收线程
DWORD WINAPI AcceptThreadProc( PTHREADPACK ptp ){
SOCKADDR_IN acc_sin;/* Accept socket address - internet style*/
int acc_sin_len;/* Accept socket address length */
int status;
acc_sin_len = sizeof(acc_sin);
//调用阻塞函数accept,一直到远端响应为止
sock = accept( sock,(struct sockaddr FAR *)
&acc_sin,(int FAR *) &acc_sin_len );
if (sock < 0) {
sprintf(szBuff, "%d is the error", WSAGetLastError());
MessageBox(ptp->hWnd, szBuff, "accept(sock) failed", MB_OK);
return (1);
}
SetConnectMenus( ptp->hWnd ); //远端提机,可视电话接通
BeginG7231Codec();
while (1) {
beg1: status = recv((SOCKET)sock, r_mux_buf,
MY_MSG_LENGTH, NO_FLAGS_SET );
if (status == SOCKET_ERROR) {
status = WSAGetLastError();
if( status == 10054 ){
MessageBox(ptp->hWnd,"对方挂断电话","Indication", MB_OK);
SendMessage( ptp->hWnd, WM_COMMAND,IDM_DISCONNECT,NULL);
_endthread();
return (1);
}
goto beg1;
}
if (status) {
r_mux_buf[ status ] = '/0';
if( r_mux_buf_filled == 1 )
r_mux_buf_overwrite = 1;
else
r_mux_buf_filled = 1;
r_mux_buf_length = status;
}
else {
MessageBox( hWnd, "Connection broken", "Error", MB_OK);
SendMessage( ptp->hWnd, WM_COMMAND,
IDM_DISCONNECT,NULL);
_endthread();
return (2);
}
demux(); //线路码流H.223解码
}
return (0);
}
//被叫方TCP/IP接收线程
DWORD WINAPI AcceptThreadProcRev( PTHREADPACK ptp ){
int status;
while (1) {
beg2:status = recv((SOCKET)sock, r_mux_buf,
MY_MSG_LENGTH, NO_FLAGS_SET );
if (status == SOCKET_ERROR) {
status =WSAGetLastError();
if( status == 10054 ){
MessageBox(ptp->hWnd,"对方挂断电话","Indication", MB_OK);
SendMessage( ptp->hWnd, WM_COMMAND,
IDM_DISCONNECT,NULL);
return (1);
}
goto beg2;
}
if (status) {
r_mux_buf[ status ] = '/0';
if( r_mux_buf_filled == 1 )
r_mux_buf_overwrite = 1;
else
r_mux_buf_filled = 1;
r_mux_buf_length = status;
}
else {
MessageBox( hWnd, "Connection broken", "Error", MB_OK);
SendMessage( ptp->hWnd, WM_COMMAND,
IDM_DISCONNECT,NULL);
return (2);
}
demux();
}/* while (forever) */
return (0);
}
//语音编解码线程
DWORD WINAPI G723Proc(G7231DATA *data){
int i,len;
Audio_tx_pduad_tx_pdu;
unsigned char mux[MAX_MUX_PDU_SIZE];
do {
len = 0;
//检测本地有无语音,图象码流要传输
i = DetectAudioVideoData();
switch(i){
case AUDIO_ONLY: //只有语音码流
AL2_CRC_coder(&ad_tx_sdu,&ad_tx_pdu);
//H.223打包
len = AL2_To_MUX(&ad_tx_pdu, mux);
break;
case VIDEO_ONLY://只有图象码流
SDU_To_PDU(&vd_tx_sdu,&vd_tx_pdu);
tx_AL3_I_PDU(&vd_tx_pdu ,&bs , 1);
//H.223打包
len = AL3_To_MUX(&vd_tx_pdu,mux);
break;
case AUDIO_VIDEO://语音和图象码流
AL2_CRC_coder(&ad_tx_sdu,&ad_tx_pdu);
SDU_To_PDU(&vd_tx_sdu,&vd_tx_pdu);
tx_AL3_I_PDU(&vd_tx_pdu ,&bs , 1);
//H.223打包
len = AL2_AL3_To_MUX(&ad_tx_pdu,&vd_tx_pdu,mux);
break;
case NO_AUDIO_VIDEO://此刻无码流要传输
break;
}
//TCP/IP发送码流
if(len != 0)
send((SOCKET)sock,mux,len,0);
//是否接收到待解码的码流,有就调用解码器
PutVideoStreamToDecod();
} while(1);
return (0);
}