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

📄 docommand.c

📁 这是G.723和G.729的音频编解码的源代码
💻 C
字号:
//***************************************************************************************************
//Initlize
//***************************************************************************************************
void CommandReceiveChannelCallBack(BYTE* pFrame,int nLength,BOOL bFrameState,LPVOID lpUserData)
{
	static CVideoCommDlg* pDlg=(CVideoCommDlg*)lpUserData;	
	if(bFrameState==FS_VALID)
		pDlg->ChannelToCommandDec(pFrame,nLength);		
}

void CVideoCommDlg::ChannelToCommandDec(BYTE * pFrame, int nSize)
{
	if(pFrame[0]>=1&&pFrame[0]<=31)
		m_nQuant=pFrame[0];
}

//Add a command channel
	//Define var, in .h
	CReceiveChannel * m_pCommandReceiveChannel;
	CSendChannel    * m_pCommandSendChannel;
	CMultiplex      * m_pMultiplex;
	CDemultiplex    * m_pDemultiplex;

	//Allocate channel
	//channel number, priority, max frame length, callback
	m_pCommandReceiveChannel=new CReceiveChannel(2,1,8,CommandReceiveChannelCallBack);
	//channel number, priority, max frame length
	m_pCommandSendChannel=new CSendChannel(2,1,8);
	m_pDemultiplex=new CDemultiplex(100);
	m_pMultiplex=new CMultiplex;

	//Initialize receive channel
	m_pCommandReceiveChannel->Initialize(this);

	//add channel to multiplex and demultiplex
	m_pMultiplex->AddAChannel(m_pCommandSendChannel);
	m_pDemultiplex->AddAChannel(m_pCommandReceiveChannel);

//************************************************************************************
//Send command
//************************************************************************************
void CVideoCommDlg::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) 
{
	// TODO: Add your message handler code here and/or call default
	if(nSBCode==SB_ENDSCROLL)
	{		
		int nQuant=((CSliderCtrl*)pScrollBar)->GetPos();
		if(m_pCommandSendChannel)
		{
			BYTE byTemp=(BYTE)nQuant;
			m_pCommandSendChannel->SendData(&byTemp,1);
			byTemp=255;
			m_pCommandSendChannel->SendData(&byTemp,1);
		}
	}
	CDialog::OnHScroll(nSBCode, nPos, pScrollBar);
}

////////////////////////////////////////////////////////////
//pbyFrame-------一帧数据
//nFrameLength---帧长
//Purpose-----------将帧打成包,并送入m_PacketList中。
BOOL CSendChannel::SendData(BYTE* pbyFrame,int nFrameLength)
{
	//Lock();
	CSingleLock sLock(&m_LockSection);
	sLock.Lock();

	static CPacker Packer;

	int nPacketNumber=nFrameLength/m_nMaxPacketLength;
	int nRemainderLength=nFrameLength%m_nMaxPacketLength;
	int nOffset=0;	
	int nPackedPacketLength=0;

	for(int i=0;i<nPacketNumber;i++)
	{
		Packer.Pack(pbyFrame+nOffset,m_nMaxPacketLength,
					m_pbyPackedPacket,m_nMaxPackedPacketLength,
					&nPackedPacketLength,(BYTE)m_nChannelNumber,PT_CONTINUE);

		nOffset+=m_nMaxPacketLength;
		CPacket tempPacket(m_pbyPackedPacket,nPackedPacketLength);
		m_PacketList.AddTail(tempPacket);
	}

	Packer.Pack(pbyFrame+nOffset,nRemainderLength,
					m_pbyPackedPacket,m_nMaxPackedPacketLength,
					&nPackedPacketLength,(BYTE)m_nChannelNumber,PT_END);

	CPacket tempPacket(m_pbyPackedPacket,nPackedPacketLength);
	m_PacketList.AddTail(tempPacket);

	//Unlock();
	return TRUE;
}

inline BOOL CPacker::Pack(BYTE * pbyIn,int nInLength,
						  BYTE* pbyOut,int nOutLength,
						  int* npPacketLength,BYTE byMT,BYTE byPT)
{	
	m_byMediaType=byMT;
	m_byPacketType=byPT;
	m_byPM=byMT|byPT;

	UINT uTemp=(UINT)nOutLength;

	BOOL b=UniPack(pbyIn,pbyOut,nInLength,uTemp);

	*npPacketLength=(int)uTemp;
	return b;
}

BOOL CPacker::UniPack(BYTE * pbyInputFrame,BYTE* pbyPackedFrame,UINT uInputLength,UINT& uPackedLength)
{
	m_uLength=uInputLength;
	BYTE by;
	UINT i,j;
	
	for(i=0;i<uInputLength;i++)
	{
		by=pbyInputFrame[i];
		//if(by==FRAME_FLAG||by==ESCAPE_CODE||by=='+')
		if(by==FRAME_FLAG||by==ESCAPE_CODE
			||by==FLOW_CONTROL_XON||by==FLOW_CONTROL_XOFF||by==IDLE_CODE)
			m_uLength++;
	}

	if(pbyPackedFrame==NULL)
	{
		uPackedLength=m_uLength+2;
		return FALSE;
	}

	if(uPackedLength<m_uLength+2)
	{
		uPackedLength=m_uLength+2;
		return FALSE;
	}
		
	pbyPackedFrame[0]=FRAME_FLAG;
	pbyPackedFrame[1]=m_byPM;
	j=2;
	for(i=0;i<uInputLength;i++)
	{
		by=pbyInputFrame[i];
		if(by==FRAME_FLAG)
		{
			pbyPackedFrame[j]=ESCAPE_CODE;
			j++;
			pbyPackedFrame[j]=ESCAPE_FLAG;
			j++;
		}
		else if(by==ESCAPE_CODE)
		{
			pbyPackedFrame[j]=ESCAPE_CODE;
			j++;
			pbyPackedFrame[j]=ESCAPE_CODE;
			j++;
		}
		else if(by==FLOW_CONTROL_XON)
		{
			pbyPackedFrame[j]=ESCAPE_CODE;
			j++;
			pbyPackedFrame[j]=ESCAPE_FLOW_CONTROL_XON;
			j++;
		}
		else if(by==FLOW_CONTROL_XOFF)
		{
			pbyPackedFrame[j]=ESCAPE_CODE;
			j++;
			pbyPackedFrame[j]=ESCAPE_FLOW_CONTROL_XOFF;
			j++;
		}
		else if(by==IDLE_CODE)
		{
			pbyPackedFrame[j]=ESCAPE_CODE;
			j++;
			pbyPackedFrame[j]=ESCAPE_IDLE_CODE;
			j++;
		}
		/*
		else if(by=='+')
		{
			pbyPackedFrame[j]=ESCAPE_CODE;
			j++;
			pbyPackedFrame[j]=by;
			j++;
		}
		*/
		else
		{
			pbyPackedFrame[j]=by;
			j++;
		}
	}
	m_uLength++;
	m_uLength++;
	uPackedLength=m_uLength;
	return TRUE;
}

//*************************************************************************************
//Receive
//**************************************************************************************
//////////////////////////////////////////////////////////////////////////////
//pbyStream--从硬件读入的数据
//nLength----数据的长度
//功能-------将读入的数据重新组装成packet,并送入相应的解码器中
void CDemultiplex::InputStream(BYTE* pbyStream,int nLength)
{	
	if(pbyStream==NULL)return;
	if(nLength<1)return;
	if(m_bFindFrameHeader)
	{//have find frame header

		int nPos=FindFrameFlag(pbyStream,nLength);
		if(nPos==-1)
		{//this frame do not contain frame flag
			ProcessNoFindFrameFlag(pbyStream,nLength);
			return;		
		}
		//nPos!=-1		
		//this frame have frame flag
		ProcessFindFrameFlag(pbyStream,nLength,nPos);
		//find next frame flag:
		InputStream(pbyStream+nPos+1,nLength-nPos-1);
	}
	else
	{
		m_bFindFrameHeader=FALSE;
		m_nValidLength=0;

		int nPos=FindFrameFlag(pbyStream,nLength);
		if(nPos==-1)	
			return;

		m_bFindFrameHeader=TRUE;
		InputStream(pbyStream+nPos+1,nLength-nPos-1);
	}
}

BOOL CDemultiplex::ProcessFindFrameFlag(BYTE* pbyStream,int nLength,int nFlagPos)
{
	//this frame have frame flag
	if(nFlagPos+m_nValidLength<=m_nMaxFrameLength)
	{
		//have get a complete frame
		CopyMemory(m_pbyFrame+m_nValidLength,pbyStream,nFlagPos);
		m_nValidLength+=nFlagPos;
		ProcessAFrame();
		m_nValidLength=0;
		return TRUE;
	}
	//have an error occur
	//discard all data that stored in frame buffer
	m_bFindFrameHeader=FALSE;
	m_nValidLength=0;
	return FALSE;
}

void CDemultiplex::ProcessAFrame()
{		
	int nPacketLength;
	CPacker Packer;
	int nPM=Packer.Unpack(m_pbyFrame,m_nValidLength,&nPacketLength);//去掉填充码和转义码
	
	int nMT=nPM&MT_MASK;//media type,媒体类型
	//packet type,包类型,将一个packet拆成几个frame,前几个frame的
	//PT_MASK为PT_CONTINUE,最后一个为PT_END,以便于重新组装成packet
	int nPT=nPM&PT_MASK;

	if(m_pChannelArray[nMT]!=NULL)
	{
		if(nPT==PT_END)//一个packet的最后一个frame,packet组装完成
			m_pChannelArray[nMT]->InputPacket(m_pbyFrame,nPacketLength,TRUE);
		else
			m_pChannelArray[nMT]->InputPacket(m_pbyFrame,nPacketLength,FALSE);
	}
}

//组装完成后,将根据媒体类型调用相应的回调函数将packet送入相应的
//解码器中(音频解码器,视频解码器,命令解码器)
void CReceiveChannel::InputPacket(BYTE* pbyPacket,int nLength,BOOL bIsEndPacket)
{
	if(m_nValidLength+nLength<=m_nMaxFrameLength)
	{
		CopyMemory(m_pFrameBuffer+m_nValidLength,pbyPacket,nLength);
		m_nValidLength+=nLength;

		if(bIsEndPacket)//组装完成
		{			
			if(m_pChannelCallBackFunc)
				(*m_pChannelCallBackFunc)(m_pFrameBuffer,m_nValidLength,FS_VALID,m_lpUserData);
			m_nValidLength=0;
		}
		return;
	}
	else
	{	
		 if(m_pChannelCallBackFunc)
		 {
			(*m_pChannelCallBackFunc)(m_pFrameBuffer,m_nValidLength,FS_INVALID,m_lpUserData);
			(*m_pChannelCallBackFunc)(pbyPacket,nLength,FS_INVALID,m_lpUserData);
		 }
		m_nValidLength=0;
	}
}


//在硬件的WriteThread中被调用
int CMultiplex::DetachStream(BYTE* pbyPacket,int nLength)
{	
	int nValidLength=0;
	for(int i=m_nTotalChannel-1;i>=0;i--)
	{
		//如果该通道有效且该通道中的packet的个数不为0
		if(pChannelArray[i]&&pChannelArray[i]->GetCount())
		{
			//发送pChannelArray[i]->m_nPriority个packet
			for(int j=0;j<=pChannelArray[i]->m_nPriority;j++)
			{					
				//pChannelArray[i]->GetHead().m_nLength----为第i个通道中某一个packet的长度
				//如果已经发送的BYTE数目超过所能发送的长度,则退出
				if(pChannelArray[i]->GetHead().m_nLength+nValidLength>nLength)
				{
					if(nValidLength==0)//无效packet
						pChannelArray[i]->RemoveHead();
					return nValidLength;
				}
			
				//将通道中的packet写入复接缓冲,最终pbyPacket中的内容将被写入硬件以发送出去
				CopyMemory(pbyPacket+nValidLength,pChannelArray[i]->GetHead().m_pPacket,pChannelArray[i]->GetHead().m_nLength);
				nValidLength+=pChannelArray[i]->GetHead().m_nLength;
				pChannelArray[i]->RemoveHead();//将通道中的packet删除,以准备发送下一个
			}
		}
	}
	return nValidLength;
}

⌨️ 快捷键说明

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