📄 docommand.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 + -