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

📄 h324port.cpp

📁 基于NMS的video access 3.1编写的DEMO程序 实现2个功能 1) H324握手 2) VIDEO MAIL
💻 CPP
字号:
#include "h324port.h"
#include "routine.h"

void get_video_codec_string( DWORD videoCodec, char *str )
{
	switch( videoCodec )
	{
	case H324_MPEG4_VIDEO:
		strcpy( str, "MPEG4" );
		break;
	case H324_H263_VIDEO:
		strcpy( str, "H263 in RFC2429" );
		break;
	case H324_H261_VIDEO:
		strcpy( str, "H261" );
		break;
	case H324_H264_VIDEO:
		strcpy( str, "H264" );
		break;
	default:
		strcpy( str, "UNKNOWN" );
		break;
	}
}

int TH324Port::OpenServices(int board, int timeslot, int userid, const char *ip)
{
	CTA_SERVICE_DESC ServDesc[2] = {0};
	CTA_EVENT event;
	int ret;

	if(ctaCreateQueue(NULL, 0,  &m_quehd) != 0)
		return false;

	if(ctaCreateContext(m_quehd, userid, "h324demo", &m_ctahd) != 0)
		return false;

	ServDesc[0].name.svcname      = "ADI";
	ServDesc[0].name.svcmgrname   = "ADIMGR";
	ServDesc[0].mvipaddr.board    = board;
	ServDesc[0].mvipaddr.stream   = 0;
	ServDesc[0].mvipaddr.timeslot = timeslot;
	ServDesc[0].mvipaddr.mode     = ADI_VOICE_DUPLEX;

	ServDesc[1].name.svcname      = "MSP";
	ServDesc[1].name.svcmgrname   = "MSPMGR";
	ServDesc[0].mvipaddr.board    = board;
	ServDesc[1].mvipaddr.stream    = 0;
	ServDesc[1].mvipaddr.timeslot = timeslot;
	ServDesc[1].mvipaddr.mode     = ADI_VOICE_DUPLEX;

	if( (ret = ctaOpenServices( m_ctahd, ServDesc, 2))!= 0 )
		return ret;

	WaitNmsEvent(m_ctahd, &event);
	if((event.id != CTAEVN_OPEN_SERVICES_DONE) || (event.value != CTA_REASON_FINISHED))
		return event.value;

	printf("\t board = %d, timeslot = %d\n", board, timeslot);

	m_board = board;
	m_timeslot = timeslot;
	m_userid = userid;

	strcpy(m_LocalIP, ip);
	return 0;
}

void TH324Port::FreeRes()
{
	if( mspDestroyEndpoint(m_muxep) == 0) //释放license
	{
		CTA_EVENT event;
		while(1)
		{
			WaitNmsEvent(m_ctahd, &event);
			if(event.id == MSPEVN_DESTROY_ENDPOINT_DONE)
				break;
		}
	}
}

void TH324Port::WaitNmsEvent(CTAHD ctahd, CTA_EVENT *eventp)
{
	while(1)
	{
		ctaWaitEvent(m_quehd, eventp, -1);
		BOOL consumed;
		h324SubmitEvent(eventp, &consumed);
		if(consumed)
			continue;
		ShowEvent(eventp);
		if(eventp->ctahd == ctahd)
			return;
	}
}

bool TH324Port::SetLocalCaps()
{
	H324_TERM_CAPS localTermCaps;
	if( h324GetTermCaps(m_muxep, H324_LOCAL_TERMINAL, &localTermCaps) != 0)
		return false;

	//localTermCaps.muxCap.videoWithAL2 = FALSE;

	for(WORD i = 0; i < localTermCaps.wCapCount; i++)
	{
		switch(localTermCaps.capTable[i].choice)
		{
		case H324_H263_VIDEO:
			localTermCaps.capTable[i].bTransmit = true;
			localTermCaps.capTable[i].u.h263.mode.bit_rate = 4300;
			localTermCaps.capTable[i].u.h263.mode.unrestricted_vector= true;
			localTermCaps.capTable[i].u.h263.mode.arithmetic_coding  = true;
			localTermCaps.capTable[i].u.h263.capability.pb = FALSE;
			localTermCaps.capTable[i].u.h263.capability.temporal_spatial_tradeoff = FALSE;
			localTermCaps.capTable[i].u.h263.capability.max_bit_rate = 4300;
			localTermCaps.capTable[i].u.h263.mode.resolution     = h263_qcif_resolution_chosen;
			localTermCaps.capTable[i].u.h263.capability.bit_mask = h263_qcif_mpi_present;
			localTermCaps.capTable[i].u.h263.capability.qcif_mpi = 2;
			break;
		case H324_AMR_AUDIO:
			localTermCaps.capTable[i].bTransmit = true;
			break;
		case H324_RX_USER_INPUT:
			break;
		}

	}


	if( h324SetTermCaps(m_muxep, &localTermCaps) != 0)
		return false;
	return true;
}

bool TH324Port::Start324Stack()
{
	CTA_EVENT event;

	MSP_ENDPOINT_ADDR		addr = {0};
	MSP_ENDPOINT_PARAMETER	parm = {0};

	H324_START_PARAMS h324params;
	h324params.size         = sizeof(h324params);
	h324params.iCapCount    = 3;
	h324params.terminalType = 201;
	h324params.iCap[0] = H324_AMR_AUDIO;
	h324params.iCap[1] = H324_H263_VIDEO;
	h324params.iCap[2] = H324_RX_USER_INPUT;
	h324params.bAutoChannelSetup = TRUE;

	addr.size               = sizeof MSP_ENDPOINT_ADDR;
	addr.nBoard		  	      = m_board;
	addr.eEpType            = MSP_ENDPOINT_MUX;
	addr.EP.Mux.nTimeslot   = m_timeslot;

	parm.size				= sizeof(parm);
	parm.eParmType          = MSP_ENDPOINT_MUX;

	if(mspCreateEndpoint(m_ctahd, &addr, &parm, &m_muxep) != 0)
		return false;

	WaitNmsEvent(m_ctahd, &event);
	if((event.id != MSPEVN_CREATE_ENDPOINT_DONE) || (event.value != CTA_REASON_FINISHED))
		return false;

	if(h324Start(m_ctahd, m_muxep, &h324params) != 0)
		return false;

	return true;
}

bool TH324Port::SetupCall()
{
	int ret = h324SetupCall(m_muxep);
	if(ret)
		printf("error(0x%x) in h324SetupCal", ret );
	return (ret == 0);
}

bool TH324Port::StartMSP(int localport, int remoteport)
{
	m_localport = localport;
	m_remoteport = remoteport;

	CreateVideoEp();
	return true;
}

bool TH324Port::StopMSP()
{
	return true;
}

bool TH324Port::CreateVideoEp()
{
	m_mspstate = 0;

	MSP_ENDPOINT_ADDR		addr = {0};
	MSP_ENDPOINT_PARAMETER	parm = {0};

	addr.size               = sizeof MSP_ENDPOINT_ADDR;
	addr.nBoard							= m_board;
	addr.eEpType            = MSP_ENDPOINT_RTPFDX_VIDEO_H263;

	strcpy(addr.EP.RtpRtcp.SrcIpAddress, m_LocalIP);
	addr.EP.RtpRtcp.nSrcPort	=	m_localport;
	strcpy(addr.EP.RtpRtcp.DestIpAddress, m_LocalIP);
	addr.EP.RtpRtcp.nDestPort	=	m_remoteport;

	parm.size                 = sizeof(parm);
	parm.eParmType            = MSP_ENDPOINT_RTPFDX_VIDEO_H263;
	parm.EP.RtpRtcp.TypeOfService= 0;
	parm.EP.RtpRtcp.startRtcp = 0;
	parm.EP.RtpRtcp.RtpTsFreq = 90000;
	parm.EP.RtpRtcp.Session_bw= 64000;
	parm.EP.RtpRtcp.frameQuota= 2;
	parm.EP.RtpRtcp.linkEvents= 0;

	parm.EP.RtpRtcp.PayloadMap.payload_id = 34;
	parm.EP.RtpRtcp.PayloadMap.vocoder = 34;

	printf("\t mux(%d) video SrcPort = %d, DestPort = %d\n",
		m_userid,
		addr.EP.RtpRtcp.nSrcPort,
		addr.EP.RtpRtcp.nDestPort
		);

	return 0 == mspCreateEndpoint(m_ctahd, &addr, &parm, &m_videoep);
}

bool TH324Port::CreatVideoChannel()
{
	m_mspstate++;

	MSP_CHANNEL_ADDR		addr = {0};

	MSP_CHANNEL_PARAMETER	parm = {0};

	addr.channelType = (msp_channel_type)MGH263VideoChannel;
	addr.size = sizeof(addr);
	addr.nBoard = m_board;

	parm.size = sizeof(parm);
	parm.channelType = (msp_channel_type)MGH263VideoChannel;

	parm.ChannelParms.VideoParms.size = sizeof(parm.ChannelParms.VideoParms);
	parm.ChannelParms.VideoParms.JitterParms.size =	sizeof(parm.ChannelParms.VideoParms.JitterParms);
	parm.ChannelParms.VideoParms.JitterParms.depth = H2NMS_WORD(2);
	parm.ChannelParms.VideoParms.JitterParms.adapt_enabled = H2NMS_WORD(0);

	return 0 == mspCreateChannel(m_ctahd, &addr, NULL, &m_videochannel);

}

bool TH324Port::ConnectVideoEP()
{
	m_mspstate++;

	return 0 == mspConnect(m_videoep, m_videochannel, m_muxep);
}

bool TH324Port::EnableVideoChannel()
{
	m_mspstate++;

	return 0 == mspEnableChannel(m_videochannel);
}

bool TH324Port::CreateAudioEp()
{
	m_mspstate++;

	MSP_ENDPOINT_ADDR		addr = {0};
	MSP_ENDPOINT_PARAMETER	parm = {0};

	addr.size								= sizeof MSP_ENDPOINT_ADDR;
	addr.nBoard							= m_board;
	addr.eEpType						= MSP_ENDPOINT_RTPFDX;

	strcpy(addr.EP.RtpRtcp.SrcIpAddress, m_LocalIP);
	addr.EP.RtpRtcp.nSrcPort	=	m_localport + 2;
	strcpy(addr.EP.RtpRtcp.DestIpAddress, m_LocalIP);
	addr.EP.RtpRtcp.nDestPort	= m_remoteport + 2;

  parm.size                   = sizeof(parm);
  parm.eParmType              = MSP_ENDPOINT_RTPFDX;
  parm.EP.RtpRtcp.startRtcp   = 0;
  parm.EP.RtpRtcp.RtpTsFreq   = 8000;
  parm.EP.RtpRtcp.Session_bw  = 4750;
  parm.EP.RtpRtcp.frameQuota  = 2;
  parm.EP.RtpRtcp.linkEvents  = 0;
	parm.EP.RtpRtcp.dtmf_event_control = SEND_FIRST_EVENT | SEND_LAST_EVENT;

	parm.EP.RtpRtcp.PayloadMap.payload_id = MSP_CONST_VOCODER_AMR3267;
	parm.EP.RtpRtcp.PayloadMap.vocoder = MSP_CONST_VOCODER_AMR3267;

	printf("\t mux(%d) audio SrcPort = %d, DestPort = %d\n",
		m_userid,
		addr.EP.RtpRtcp.nSrcPort,
		addr.EP.RtpRtcp.nDestPort
		);

	return 0 == mspCreateEndpoint(m_ctahd, &addr, &parm, &m_audioep);
}

bool TH324Port::CreatAudioChannel()
{
	m_mspstate++;

	MSP_CHANNEL_ADDR		addr = {0};
	MSP_CHANNEL_PARAMETER	parm = {0};

	addr.channelType		= (msp_channel_type)MGAMRBypassChannel;
	addr.size		        = sizeof(addr);
	addr.nBoard				= m_board;

	parm.size				= sizeof(parm);
	parm.channelType		= (msp_channel_type)MGAMRBypassChannel;
	parm.ChannelParms.VoiceParms.size                         =
		sizeof(parm.ChannelParms.VoiceParms);
	parm.ChannelParms.VoiceParms.JitterParms.size             =
		sizeof(parm.ChannelParms.VoiceParms.JitterParms);
	parm.ChannelParms.VoiceParms.JitterParms.depth            = H2NMS_WORD(2);
	parm.ChannelParms.VoiceParms.JitterParms.adapt_enabled    = H2NMS_WORD(0);

	return 0 == mspCreateChannel(m_ctahd, &addr, &parm, &m_audiochannel);
}

bool TH324Port::ConnectAudioEP()
{
	m_mspstate++;

	return 0 == mspConnect(m_audioep, m_audiochannel, m_muxep);
}

bool TH324Port::EnableAudioChannel()
{
	m_mspstate++;

	return 0 == mspEnableChannel(m_audiochannel);
}

void TH324Port::OnRemoteCap(CTA_EVENT *pEvent)
{
	H324_TERM_CAPS* pTermCaps = (H324_TERM_CAPS*)(pEvent->buffer);
	WORD i;
	char string[40];
	char line[80];

	if(pTermCaps)
	{
		line[0] = '\0';
		for(i = 0; (DWORD)i < pTermCaps->wCapCount; i++)
		{
			sprintf(string, " %d ",pTermCaps->capTable[i].choice);
			strcat(line, string);
		}
		printf("Remote terminal offered %d capabilities of types %s\n",	pTermCaps->wCapCount, line );
	}
}

void TH324Port::OnLcd(CTA_EVENT *pEvent)
{
	char video_str[20];
	H324_LCD *l_pLCD;

	printf( "\tEvent: H324EVN_LCD received\n");

	l_pLCD = (H324_LCD*)(pEvent->buffer);
	// Extract the codec from the remote LCD (or from the bidir LCD)
	if( ((l_pLCD->rxChoice == H324_MPEG4_VIDEO)||(l_pLCD->rxChoice == H324_H263_VIDEO)||(l_pLCD->rxChoice == H324_H264_VIDEO)) &&
		l_pLCD->bReceive )
	{
		int txVideoCodec = l_pLCD->rxChoice;
		get_video_codec_string( txVideoCodec, video_str );
		printf("\tTx video codec from H324EVN_LCD event: %d (%s)\n",
				txVideoCodec, video_str);
	}

	if (l_pLCD->bReceive)
		printf( "\t(remote) rxChoice %d  rxChannel %d\n", l_pLCD->rxChoice, l_pLCD->rxChannel);

	if (l_pLCD->bTransmit)
		printf("\t(local)  txChoice %d  txChannel %d\n", l_pLCD->txChoice, l_pLCD->txChannel);
}


void TH324Port::OnMspEvent(CTA_EVENT *pEvent)
{
	printf("mspstate = %d\n", m_mspstate);

	switch(m_mspstate)
	{
	case 0:
		//CreateVideoEp();
		DisableVideoEp();
		break;
	case 1:
		Enable2429VideoEp();
		break;
	case 2:
		EnableVideoEp();
		break;
	case 3:
		CreatVideoChannel();
		break;
	case 4:
		ConnectVideoEP();
		break;
	case 5:
		EnableVideoChannel();
		break;

		
	case 6:
		CreateAudioEp();
		break;
	case 7:
		CreatAudioChannel();
		break;
	case 8:
		ConnectAudioEP();
		break;
	case 9:
		EnableAudioChannel();
		break;
	}
}

bool TH324Port::DisableVideoEp()
{
	m_mspstate++;

	return 0 == mspDisableEndpoint(m_videoep);
}

bool TH324Port::Enable2429VideoEp()
{
	m_mspstate++;

	msp_ENDPOINT_RTPFDX_H263_ENCAP_CTRL cmd;
	cmd.h263Encap = H2NMS_DWORD(MSP_H263_RFC2429);
	return 0 == mspSendCommand(m_videoep,
         mspBuildCommand(MSP_ENDPOINT_RTPFDX_VIDEO_H263, MSP_CMD_RTPFDX_H263_ENCAP_CTRL),
         &cmd,
         sizeof(cmd));
}

bool TH324Port::EnableVideoEp()
{
	m_mspstate++;

	return 0 == mspEnableEndpoint(m_videoep);
}

⌨️ 快捷键说明

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