数据流量监测工具源玛共享3[带录制功能]

  在前一篇文章 《数据流量监测工具源玛共享2[嵌入式流媒体测试工具] 》提 到在shell 上输入rate_stat命令就可以全部显示数据在某模块中的所有走向;输入rate_show命令就可以知道某数据在某个检测点的数据包头信息,比如数 据包长度、序列号、尾包标志等参数。这篇文章对前面的工具作进一步的改进,将原来的rate_stat、rate_show、rate_probe分别改为pkt_prof、pkt_show、pkt_probe并添加定点和多点录象播发的功能pkt_rec(/sync).

1.如何使用录制功能及demo程序
a.启动MCU设备和终端设备,开视频会议

b.telnet到ip为172.16.66.29的MCU设备,然后使用pkt_prof 命令罗列所有监测点

c.录制指定点的数据流

d.使用自己编写的播放工具播放录制下来的视频图象(感兴趣的网友可以留下email,可以发给你们)



e.几个监测点的代码
这些demo来自于视频会议的。
demo1:将数据包发送到网络
 NW_BOOL rtpDataSendFromCodec2Net(IN NW_VOID            
* pData, 
                         IN NW_INT32        nLen, 
                         IN TRtpParam        
* pRtpParam, 
                         IN NW_INT32        nDestNum, 
                         IN TForwardUnit    
* pDests)
{
    
static    NW_UINT8     tempBuf[1600= {0};
    NW_INT32             nMaxCallID         
= 0;
    NW_INT32            nIndex;
    NW_UINT8            nStackCallId;
    NW_UINT8             
*ptr;
    NW_UINT8             
*tempBuf1         = NULL;
    NW_INT32             operationCode     
= OP_STREAM;
    EStRtpMediaType        eRtpMediaType     
= pDests[0].oUnit.tRtpUnit.eRtpMediaType;
    
    tempBuf1 
= tempBuf;
    ((TIPBoardPacketHdr
*)tempBuf1)->sIdentifier        = PKT_ID;
    ((TIPBoardPacketHdr
*)tempBuf1)->byVersion        = PKT_VER;
    ((TIPBoardPacketHdr
*)tempBuf1)->byDirection        = PKT_DIR_MAIN_2_IP;
    ((TIPBoardPacketHdr
*)tempBuf1)->byDataType        = PKT_DATATYPE_STREAM;
    ((TIPBoardPacketHdr
*)tempBuf1)->byOperation        = operationCode;
    ((TIPBoardPacketHdr
*)tempBuf1)->byOperationType    = eRtpMediaType;
    ((TIPBoardPacketHdr
*)tempBuf1)->sPayloadLen        = /*36*/24 + nLen + nDestNum;
    
    memcpy(tempBuf1
+16,&nLen,4);
    memcpy(tempBuf1
+20,&nDestNum,4);
    
    
for (nIndex = 0; nIndex < nDestNum; nIndex++)
    
{
        
/* 进行判断防止因定义时是Union而导致了nDevID和nCallID的复用。[zhengxb, 2006-04-30] */
        
if(FU_NET != pDests[nIndex].eUnitType)
        
{
            
continue;
        }

        
        nStackCallId    
= pDests[nIndex].oUnit.tRtpUnit.nCallId;
        memcpy(tempBuf1
+24+nIndex,&nStackCallId, 1);
        
if ( nStackCallId < MIN_GW_VCALLID && nMaxCallID < nStackCallId)
        
{
            nMaxCallID 
= nStackCallId;
        }
    
        
#ifdef _PACKET_PROFILER_    
        
{
            
if (AUDIO_FIRST == eRtpMediaType)
            
{
                
static NW_INT32            nCallerID         = INVALID_VALUE;
                
static const EStreamType     eStreamType    = STREAM_AUDIO;
                
static EStreamIdType         eStreamIdType     = STREAM_ID_CALL;    
                NW_INT32                 nStreamID         
= nStackCallId;
                TStream                    tStream;                    

                tStream.nSequence        
= pRtpParam->sequenceNumber;        
                tStream.nMarker            
= pRtpParam->marker;
                tStream.nLen                
= nLen - RTP_HEADER_LEN;    
                tStream.pData            
= pData + RTP_HEADER_LEN;
                tStream.bKeyframe        
= FALSE;

                pkt_probe(ADD_PREFIX(
"DP"),__LINE__,&nCallerID,eStreamIdType,nStreamID,eStreamType,&tStream);
            }

            
else
            
{
                
static NW_INT32            nCallerID         = INVALID_VALUE;
                
static const EStreamType     eStreamType    = STREAM_VIDEO;
                
static EStreamIdType         eStreamIdType     = STREAM_ID_CALL;    
                NW_INT32                 nStreamID         
= nStackCallId;
                TStream                    tStream;                    

                tStream.nSequence        
= pRtpParam->sequenceNumber;        
                tStream.nMarker            
= pRtpParam->marker;
                tStream.nLen                
= nLen - RESERVE_HEADER_LEN;    
                tStream.pData            
= pData + RESERVE_HEADER_LEN;
                tStream.bKeyframe        
= mdfIsKeyFrame(pRtpParam->payload, pData + RESERVE_HEADER_LEN);

                pkt_probe(ADD_PREFIX(
"DP"),__LINE__,&nCallerID,eStreamIdType,nStreamID,eStreamType,&tStream);
            }
    
        }

#endif    
    }

    
    stRtpPack(nMaxCallID, eRtpMediaType, pData, nLen, pRtpParam);

    memcpy(tempBuf1
+24+nDestNum,pData, nLen);
    
if (NULL != ibCallBackSendData)
    
{    
        ibCallBackSendData(
0, tempBuf,24+nLen+nDestNum,eRtpMediaType,nMaxCallID,TRUE);
    }


    
return TRUE;
}


在1.c中录制的监测点位于 sfDataWrite中
demo2:将数据从编码缓冲写到平滑缓冲,平滑处理后调用 rtpDataSendFromCodec2Net发送到网络
   NW_BOOL sfDataWrite(IN NW_INT32 nRingId, IN NW_VOID
*  pContext)
{
    PTSfEntryInfo            pEntry        
= NULL;
    PTSfRingInfo            pRing        
= NULL;
    NW_INT32                nCodecId;    
    NW_INT32                nSfPacketNum;
    NW_INT32                nIndex;
    NW_UINT8                
*pData        = NULL;
    NW_INT32                nLen        
= 0;
    NW_INT32                nPacketNum    
= 0;
    NW_UINT16                nSequenceNum;
    NW_UINT32                nTimestamp;
    TRtpParam                
*pRtpParam    = NULL;
    EPayload                ePayload;
    TFrameBufferInfo        
*pFrame        = (TFrameBufferInfo*)pContext;
    TVBufferInfoFromCodec    
*pBuffer    = NULL;    

    
if(nRingId<0 || nRingId>=DP_SF_MAX_RING_NUM)
        
return FALSE;

    pRing            
= &(g_pStRingInfo[nRingId]);
    nSfPacketNum    
= pRing->nRxPacketNum;

    pBuffer            
= &(pFrame->buffer_info.bufferInfoFromVCoder);
    pData            
= pBuffer->buffer;
    nLen                
= pBuffer->dataLen;

    。。。

    
if (nSfPacketNum < DP_SF_MAX_RX_PACKET_NUM)
    
{
        
for (nIndex = 0; nIndex < nPacketNum; nIndex++)
        
{            
            pEntry    
= &(pRing->pEntry[pRing->nWrite]);
            
            nSequenceNum                
= rtpVideoSequenceNumGet(MIXER_INDEX(nCodecId));
            pRtpParam                    
= &(pEntry->tRtpParam);
            pEntry
->nLen                    = mdfLenGet(pData);
            pEntry
->bKeyframe            = pBuffer->bKeyFrame;
            pRtpParam
->payload            = ePayload;            
            pRtpParam
->sequenceNumber    = nSequenceNum;
            pRtpParam
->timestamp            = nTimestamp;
            pRtpParam
->sByte                = RTP_HEADER_LEN;
            pRtpParam
->len                = pEntry->nLen;
            
if (nIndex == nPacketNum - 1)
            
{
                pRtpParam
->marker        = TRUE;
            }

            
else
            
{
                pRtpParam
->marker        = FALSE;
            }

            
#ifdef _PACKET_PROFILER_    
            
{
                
static NW_INT32            nCallerID         = INVALID_VALUE;
                
static const EStreamType     eStreamType    = STREAM_VIDEO;
                
static const EStreamIdType     eStreamIdType     = STREAM_ID_CHAN;    
                
static TStream                tStream;                    
                NW_INT32                 nStreamID         
= nRingId;

                tStream.nSequence        
= pRtpParam->sequenceNumber;        
                tStream.nMarker            
= pRtpParam->marker;
                tStream.nLen                
= pRtpParam->len - RESERVE_HEADER_LEN;    
                tStream.pData            
= pData  + BUFFER_NODE_HEADER_SIZE + RESERVE_HEADER_LEN;
                tStream.bKeyframe        
= pBuffer->bKeyFrame;

                pkt_probe(ADD_PREFIX(
"DP"),__LINE__,&nCallerID,eStreamIdType,nStreamID,eStreamType,&tStream);
            }

#endif    
            memcpy(pEntry
->pData, pData + BUFFER_NODE_HEADER_SIZE, pEntry->nLen);
            pEntry
->bState    = TRUE;
            
++(pRing->nRxPacketNum);
            pRing
->nWrite    = (pRing->nWrite + 1 + DP_SF_MAX_ENTRY_NUM)%DP_SF_MAX_ENTRY_NUM;

            pData    
+= NET_BUFFER_VIDEO_NODE_SIZE;
            pEntry
->bState    = TRUE;        
        }

        
return TRUE;
    }

    
else
    
{
        sfRingReset(nRingId, TRUE);
        
return FALSE;
    }

}

2.pkt_profiler.h
...
   #define
 _PACKET_PROFILER_
#ifdef _PACKET_PROFILER_

#define  ADD_PREFIX(x) (x##"@"##__FUNCTION__)    /*添加模块名前缀,可用于模块检索*/

typedef 
struct  _tagStream
{    
    NW_BYTE        nMarker;                        
/*一帧数据的尾包吗*/    
    NW_UINT16    nSequence;                        
/*数据包序列号*/    
    NW_BOOL    bKeyframe;                        
/*I 帧标识*/
    NW_UINT8
*    pData;                            /*裸数据包地址*/
    NW_INT32    nLen;                            
/*裸数据包长度*/
}
 TStream;

typedef 
enum  _tagStreamType
{
    STREAM_NONE            
= 0,
    STREAM_AUDIO        
= 1 << 0,
    STREAM_VIDEO        
= 1 << 1

}
 EStreamType;

typedef 
enum  _tagStreamIdType
{
    STREAM_ID_INVALID        
= 0
    STREAM_ID_DSP            
= 1,                 /*数据包发给DSP 或从DSP 接收*/
    STREAM_ID_CHAN        
= 2,                    /*数据包写入缓冲 或从 缓冲读取*/    
    STREAM_ID_CALL        
= 3                    /*数据包发给协议栈 或从 协议栈读取*/
}
 EStreamIdType;

NW_VOID pkt_probe(
    
const  NW_CHAR *      pchFuncName,                 /*监测点所在函数的函数名信息*/
    
const  NW_INT32     nLine,                         /*监测点所在位置*/
    NW_INT32
*          pCallerID,                     /*监测点所在函数的调用ID ,唯一*/
    EStreamIdType     eStreamIdType,                
/*监测点数据来源类型*/
    NW_INT32         nStreamId,                    
/*监测点数据通道ID,唯一*/
    EStreamType         eStreamType,                
/*监测点数据类型,音频或视频*/
    TStream
*          pStream    );                     /*监测点数据流详细信息*/

#endif /*_PACKET_PROFILER_*/

3.pkt_profiler.c
...
#ifdef _PACKET_PROFILER_
/**
  * 1.工具介绍: 
  *  a.<功能>:数据诊断工具packet profiler 主要用于查看全部或某
  *  具体监测点(每个监测点使用pkt_probe 探测数据)
  *  的数据流状况并在出现异常情况时可以使用
  *  pkt_prof、pkt_show、pkt_rec、pkt_check 等命令诊断数据流。 
  *  这些命令的具体功能和用法可以使用pkt_help 查看。

  *  b.<用法>:这些命令的提供提高了数据流bug 的诊断能力,
  *  也提高了对数据流bug 定位的正确性、便利性、
  *  快捷性。如果你想查看某个检测点的状况,可以
  *  先使用pkt_prof 显示音频或视频类型某模块下的所有
  *  检测点的Caller ID ,接着使用pkt_show、pkt_rec、pkt_check 
  *  查看具体检测点下的异常情况。我们可以使用
  *  pkt_probe 添加检测点。

  *  c.<建议>:该工具支持多任务支持跨模块调用,建议以后
  *  单独拿出来作为一个公共工具模块放在common目录下
  *  让更多的模块享受这种调式的乐趣。
  
  * 2.工具命令:
  *  a.<pkt_prof>:可以在异常情况下打印所有或某模块中的
  *  数据流的流向。 虽然有fdtShow 提供流向表查询功能
  *  但它无法知晓某数据通道是否确实有数据流经已经
  *  以及以多少码流流过。

  *  b.<pkt_show>:可以在异常情况下打印某具体监测点数据
  *  详细信息包括数据长度、数据地址、序列号等信息。
  *  这个命令用于代码开发阶段很使用。

  *  c.<pkt_rec/sync>:可以在异常情况下录制声音或图象。
  *  比如发现某路数据声音出现断断续续或重音现象
  *  就可以使用该功能去检查有嫌疑的检测点并最终
  *  定位异常源自模块中的哪个位置。
*/

static  NW_UINT32 dword_swap(NW_UINT32 x)
{
    
return ( ((x & 0x000000FF<< 24| ((x & 0xFF000000>> 24|    
        (((x) 
& 0xFF00<< 8| (((x) & 0xFF0000>> 8));
}


#define  CALLER_ID0                (1)
#define  MAX_CALLERS             (50)                         /*流量统计监测点的最大数目*/
#define  MAX_CHANNELS             (200)                        /*每个监测点支持通道的最大数目*/
#define  MAX_FUNC_NAME_LEN     (50)                            /*监测点调用函数的函数名最大长度*/
#define  MAX_HINT_INFO_LEN         (80)                            /*监测点调用函数的函数名最大长度*/
#define  TICKS_PER_SECOND        (60)

/*  NOTE:
  * 1.为了不干扰正在运行的其它程序,profiler  的录制功能
  * (record) 块使用静态内存。虽然可以在初始化阶段为其分
  * 配动态内存,但为了坚守profiler 模块的独立性,还是不建议。
  * 2.如果考虑内存消耗,可以关闭_PACKET_WRITE_FILE_ 来关闭录制
  * (record) 功能。目前不支持多路数据同时保存。
  
*/

#define  _PACKET_WRITE_FILE_                                 /*如果要考虑到内存分配,那么可以关闭此功能*/


typedef 
struct  _TagPacketInfo
{    
    NW_INT32         nPackets;                                
/*监测点流经总包数*/    
    NW_INT32         nPacketRate;                            
/*监测点流量*/    
    NW_INT32        nPrevPackets;                            
/*该点上一次监测的累计包数*/        
    NW_INT32        nPrevTicks;                                
/*该点上一次监测的累计时间*/
    NW_INT32        nPacketShown;                            
/*显示数据包头的数目*/
    NW_INT32         nInterval;                                
/*前后两次监测的时间跨度*/
    NW_BOOL         bFrame;                                    
/*如果统计单位为帧*/    
#ifdef _PACKET_WRITE_FILE_
    NW_BOOL         bSaved;                                    
/*录制该通道*/    
    NW_INT32         nOffsetPrev;                                
/*录制开始标志*/    
    NW_INT32         nOffsetCurr;                                
/*录制起始偏移量*/    
    NW_INT32         nFrameLen;    
    NW_BOOL         bFisrtPacket;                    
    NW_BOOL         bStart;
    NW_BOOL         bReady;            
#endif
    EStreamIdType     eStreamIdType;                            
/*数据流来源ID 类型,可以是DSP ID,可以是CHANNEL ID*/

}
TPacketInfo;

typedef 
struct  _TagCallerInfo
{    
    NW_CHAR        pchFuncName[MAX_FUNC_NAME_LEN];        
/*调用函数的函数名,caller名称*/
    NW_CHAR         nFuncLen;                                
/*调用函数的函数名实际长度*/        
    NW_SHORT        nLine;                                    
/*调用函数的调用点位置*/        
    TPacketInfo        tPacket[MAX_CHANNELS];                    
/*调用函数的调用的统计信息*/

}
TCallerInfo;

static  TCallerInfo     g_tCaller[MAX_CALLERS];
static  NW_INT32    g_nCallers                  =  CALLER_ID0;                     /*不从0 开始,可以提供更多灵活性,见pkt_rec*/
static  NW_BOOL    g_bActivated              =  FALSE;
static  NW_BOOL     g_bInitialized              =  FALSE;
static  NW_INT32    g_eStreamType              =   0 ;    
static  NW_CHAR     g_strModulePrefix[MAX_FUNC_NAME_LEN];
static  NW_BOOL    g_bModulePrefixFiltered      =  FALSE;

NW_VOID         pkt_start(
void );
NW_VOID         pkt_stop(
void );
NW_BOOL         pkt_started(
void );
NW_VOID         pkt_stat(
void );
NW_VOID          pkt_help(NW_INT32 nSelection); 
NW_VOID         pkt_check(NW_INT32 nCallerID,NW_INT32 nStreamId);
#ifdef _PACKET_WRITE_FILE_
NW_VOID         pkt_rec(NW_INT32 nCallerID,NW_INT32 nStreamId,NW_INT32 nRecoredLen);
#endif

#ifdef _PACKET_WRITE_FILE_ 
#define              MAX_MULTI_RECORD_POINTS        16
#define              MAX_BUF_SIZE                     200*1024 /*录制缓冲区大小*/

typedef 
struct  _TagRec
{    
    NW_INT32  nCallerID;                            
    NW_INT32  nChannelID;
    
}
TRec;
    
static  NW_UINT8    s_pFileBuf[MAX_BUF_SIZE];
static  NW_UINT32    s_nFileBufLen     = 0 ;

NW_VOID pkt_dump(
const  NW_CHAR *  pchFuncName,NW_INT32 nStreamId,EStreamType eStreamType,TPacketInfo *  ptPacket);

NW_VOID pkt_dump(
const  NW_CHAR *  pchFuncName,NW_INT32 nStreamId,EStreamType eStreamType,TPacketInfo *  ptPacket)
{
    FILE    
*            fptr                 = NULL;
    
static NW_BYTE     nFilename[100]    = {0};
    EStreamIdType     eStreamIdType    
= 0;
    NW_INT32         nOffset            
= 0;
    
    
if (NULL == pchFuncName)
    
{
        printf(
"Invalid function name! ");
        
return;
    }


    
if (NULL == ptPacket)
    
{
        printf(
"%s:Invalid packet info! ",pchFuncName);
        
return;
    }


    eStreamIdType     
= ptPacket->eStreamIdType;
    nOffset            
= ptPacket->nOffsetCurr - ptPacket->nOffsetPrev;    

    
if (STREAM_ID_DSP != eStreamIdType 
    
&& STREAM_ID_CHAN != eStreamIdType 
    
&& STREAM_ID_CALL != eStreamIdType)
    
{    
        printf(
"%s:Invalid stream id type %d! ",pchFuncName,eStreamIdType);    
        
return;
    }
    
    
    
if (nStreamId>=0 && nStreamId<MAX_CHANNELS)
    
{
        sprintf(nFilename,
"%s.%s_%s_%d.%s",
            pchFuncName,STREAM_AUDIO
==eStreamType?"audio":"video",
                STREAM_ID_DSP 
== eStreamIdType?"dsp":(STREAM_ID_CHAN == eStreamIdType? "chan":"call"),
                    nStreamId,STREAM_AUDIO
==eStreamType?"dat":"mpeg4");

        fptr 
= fopen(nFilename,"wb");
        
        
if (NULL == fptr)
        
{
            printf(
"%s:Failed to open %s! ",pchFuncName,nFilename);    
            
return;
        }

        
else
        
{
            
if (nOffset > 0)
            
{
                
if (nOffset > s_nFileBufLen) 
                
{
                    nOffset 
= s_nFileBufLen;
                }

                    
                fwrite(s_pFileBuf
+ptPacket->nOffsetPrev,1,nOffset, fptr);
            }

        }

        
        fclose(fptr);
    }

    
else
    
{
        printf(
"%s:Invalid stream id %d! ",pchFuncName,nStreamId);
    }

}

#endif  /*_PACKET_WRITE_FILE_*/

NW_VOID pkt_probe(
const  NW_CHAR *  pchFuncName, const  NW_INT32 nLine,NW_INT32 *  pCallerID,EStreamIdType eStreamIdType,NW_INT32 nStreamId,EStreamType eStreamType,TStream *  pStream)
{
    NW_INT32         nCaller                 
= 0;
    NW_INT32         nChannel            
= 0;
    NW_INT32        nCurrTicks             
= 0;    
    NW_INT32        nModulePrefixLen    
= 0;
    NW_INT32        nPrefix                
= 0;
    TCallerInfo
*         ptCaller                = NULL;
    TPacketInfo
*        ptPacket            = NULL;

    
if (!pkt_started())
    
{
        
return;
    }


    
if (!g_bInitialized)
    
{
        
return;
    }

    
    
if (NULL == pchFuncName || NULL == pCallerID)
    
{
        printf(
"Invalid function name or caller ID pointer!");
        
return;
    }


    
if (nStreamId < 0 || nStreamId >= MAX_CHANNELS)
    
{
        printf(
"%s:Invalid stream id %d!",pchFuncName,nStreamId);
        
return;
    }
    

    
if (STREAM_ID_DSP != eStreamIdType 
    
&& STREAM_ID_CHAN != eStreamIdType 
    
&& STREAM_ID_CALL != eStreamIdType)
    
{    
        printf(
"%s:Invalid stream id type %d!",pchFuncName,eStreamIdType);
        
return;
    }
    

    
if (!(eStreamType & g_eStreamType))
    
{/*过滤不想统计的通道*/    
        
return;            
    }
    

    
if (INVALID_VALUE == *pCallerID)
    
{    /*分配CALLER ID , 支持多任务!*/
        
if ((nCaller = g_nCallers++>= MAX_CALLERS)
        
{
            printf(
"%s:Falied to allocate caller ID %d!",pchFuncName,nCaller);
            
return;    
        }

        
        ptCaller                 
= &g_tCaller[nCaller];
        ptCaller
->nFuncLen    = strlen(pchFuncName);
        
if (ptCaller->nFuncLen >= MAX_FUNC_NAME_LEN)
        
{
            printf(
"%s:Too long function name! ",pchFuncName);        
            
return;
        }

        
        ptCaller
->nFuncLen     = sprintf(ptCaller->pchFuncName,"%s",pchFuncName);
        ptCaller
->nLine        = nLine;
        
*pCallerID             = nCaller;/*返回当前监测点的ID,以备后用*/
    }

    
else
    
{
        nCaller 
= *pCallerID;
    }


    ptCaller     
= &g_tCaller[nCaller];
    ptPacket     
= &g_tCaller[nCaller].tPacket[nStreamId];

    
if (nCaller >= CALLER_ID0 && nCaller < MAX_CALLERS)
    
{
        
if (STREAM_ID_DSP != ptPacket->eStreamIdType 
        
&& STREAM_ID_CHAN != ptPacket->eStreamIdType
        
&& STREAM_ID_CALL != ptPacket->eStreamIdType)    
        
{
            ptPacket
->eStreamIdType = eStreamIdType;
        }

    
        
if (NULL != pStream && ptPacket->nPacketShown>0 && ptPacket->nPacketShown-->0)
        
{
            printf(
"%s(%4d):len %4d,seqence %d,marker %d,keyframe %d ",
                    ptCaller
->pchFuncName,ptCaller->nLine,pStream->nLen,pStream->nSequence,pStream->nMarker,pStream->bKeyframe);            
            
return;
        }
    

        
if (g_bModulePrefixFiltered)
        
{
            nModulePrefixLen 
= strlen(g_strModulePrefix);

            
if (nModulePrefixLen> 0 && nModulePrefixLen< MAX_FUNC_NAME_LEN)
            
{
                
while (nModulePrefixLen>0
                
{
                    
if (ptCaller->pchFuncName[nModulePrefixLen-1!= g_strModulePrefix[nModulePrefixLen-1])
                    
{
                        
return;        
                    }

                    nModulePrefixLen
--;
                }

            }

        }

    
#ifdef _PACKET_WRITE_FILE_
        
/*录制声音或图象*/
        
if (ptPacket->bSaved
        
&& NULL != pStream && NULL != pStream->pData 
        
&& pStream->nLen >0 && pStream->nLen < 1600)
        
{
            NW_BYTE
*        pData            = NULL;
            NW_INT32         nDataLen        
= 0;    
            NW_INT32         nMarker            
= FALSE;    

            pData             
= pStream->pData;
            nDataLen            
= pStream->nLen;
            nMarker            
= pStream->nMarker;
        
            
if(!ptPacket->bReady && ptPacket->nOffsetPrev == ptPacket->nOffsetCurr)
            
{        
                ptPacket
->bStart = TRUE;
                
if (STREAM_VIDEO == eStreamType)
                
{
                    
if (pStream->bKeyframe)
                    
{
                        ptPacket
->bReady         = TRUE;
                        ptPacket
->bFisrtPacket    = FALSE;
                        ptPacket
->nFrameLen    = 0;
                        
if (0 == ptPacket->nOffsetPrev)
                        
{                    
                            printf(
"0%s ","%");
                        }

                    }

                }

                
else 
                
{
                    ptPacket
->bReady             = TRUE;
                    
if (0 == ptPacket->nOffsetPrev)
                    
{                    
                        printf(
"0%s ","%");
                    }

                }
                
            }

            
            
/*
            *audio:|pkt 1||pkt 2|...|pkt n|...
            *video:|frame len|pkt 1||pkt 2|...|pkt n|...                
            
*/

            
if(ptPacket->bReady)
            
{        
                
if (!ptPacket->bFisrtPacket && STREAM_VIDEO == eStreamType) /*first packet of a frame*/
                
{
                    ptPacket
->bFisrtPacket     =     TRUE;                                
                    ptPacket
->nFrameLen    =     0;
                    ptPacket
->nOffsetCurr    +=     sizeof(ptPacket->nFrameLen);                    
                }
                            

                
if (ptPacket->nOffsetCurr - ptPacket->nOffsetPrev + nDataLen < s_nFileBufLen)
                
{
                    memcpy(s_pFileBuf 
+ ptPacket->nOffsetCurr,pData,nDataLen);

                    
if (0 == ptPacket->nOffsetPrev && ((10*(ptPacket->nOffsetCurr - ptPacket->nOffsetPrev))/s_nFileBufLen) != 
                    ((
10*(ptPacket->nOffsetCurr - ptPacket->nOffsetPrev + nDataLen))/s_nFileBufLen))
                    
{
                        printf(
"█ ");
                    }

            
                    ptPacket
->nOffsetCurr += (nDataLen+0x3)&~0x3;

                    
if (STREAM_VIDEO == eStreamType)
                    
{
                        ptPacket
->nFrameLen += (nDataLen+0x3)&~0x3;
                        
if (nMarker) /*last packet of a frame*/                    
                        
{
                            
*(NW_INT32*)(s_pFileBuf+ptPacket->nOffsetCurr - ptPacket->nFrameLen - sizeof(ptPacket->nFrameLen)) = dword_swap(ptPacket->nFrameLen);    
                            ptPacket
->nFrameLen     = 0;
                            ptPacket
->bFisrtPacket     = FALSE;
                        }
    
                    }

                }

                
else
                
{
                    ptPacket
->bSaved    = FALSE;
                    ptPacket
->bReady    = FALSE;
                    
                    pkt_dump(ptCaller
->pchFuncName,nStreamId,eStreamType,ptPacket);                    

                    
for (nCaller = CALLER_ID0; nCaller < g_nCallers; nCaller++)
                    
{    
                        
for (nChannel = 0; nChannel < MAX_CHANNELS; nChannel++)
                        

                            
if (g_tCaller[nCaller].tPacket[nChannel].bStart 
                            
&& g_tCaller[nCaller].tPacket[nChannel].bSaved)
                            
{
                                
break;
                            }

                        }


                        
if (MAX_CHANNELS != nChannel)
                        
{
                            
break;
                        }

                    }


                    
if (nCaller == g_nCallers)
                    
{
                        printf(
"█ 100%s","%");
                        pkt_stop();    
                    }

                }
    
            }

        }
        
#endif
        
/*等待用户设置检测时间*/
        
if (1 > ptPacket->nInterval) 
        
{    
            
return;
        }


        
/*如果统计单位是帧*/
        
if (STREAM_VIDEO == eStreamType) 
        
{
            
if (NULL != pStream && pStream->nMarker && !ptPacket->bFrame)
            
{
                ptPacket
->bFrame = TRUE;
            }

            
            
if (NULL != pStream && ptPacket->bFrame && !pStream->nMarker)
            
{
                
return;
            }

        }


        ptPacket
->nPackets++;

        nCurrTicks 
= tickGet();

        
if (0 == ptPacket->nPrevTicks)
        
{
            ptPacket
->nPrevPackets     = ptPacket->nPackets;
            ptPacket
->nPrevTicks        = nCurrTicks;
        }

        
else
        
{
            
if (nCurrTicks != ptPacket->nPrevTicks
            
&& nCurrTicks-ptPacket->nPrevTicks >= ptPacket->nInterval)
            
{
                ptPacket
->nPacketRate    = TICKS_PER_SECOND*(ptPacket->nPackets - ptPacket->nPrevPackets) 
                    
/(nCurrTicks - ptPacket->nPrevTicks);

                ptPacket
->nPrevTicks         = 0;
                ptPacket
->nInterval         = 0;
            }

        }

    }

}


NW_VOID     pkt_prof(NW_CHAR
*  pchMediaType,NW_CHAR *  pchModulePrefix)
{
    TCallerInfo
*             ptCaller                = NULL;
    TPacketInfo
*            ptPacket            = NULL;
    NW_INT32             nCaller                
= 0;
    NW_INT32             nChannel            
= 0;
    NW_INT32            nModulePrefixLen    
= 0;
    
static const NW_INT32     nInterval            = 4*TICKS_PER_SECOND;/*second*/
    
static const NW_INT32     nErrorPercentage        = 5;/*误差占整个计时的百分比*/

    
if (NULL == pchMediaType && NULL == pchModulePrefix)
    
{
        
if (g_eStreamType > 0)
        
{
            pkt_stat();
            
return;
        }

        pkt_help(
1);
        
return;
    }


    
if (1 > nInterval || 1 > nErrorPercentage)
    
{
        printf(
"%s:Invalid param,interval %d,error %d! ",pchMediaType,nInterval,nErrorPercentage);
        
return;
    }

    
    pkt_stop();

    
if (NULL != pchModulePrefix)
    
{
        nModulePrefixLen 
= strlen(pchModulePrefix);

        
if (nModulePrefixLen> MAX_FUNC_NAME_LEN)
        
{
            printf(
"%s:Too long module prefix! ",pchModulePrefix);
            
return;
        }

        
        g_bModulePrefixFiltered 
= FALSE;
        taskDelay(
3);/*等待pkt_prof  g_bModulePrefixFiltered 相关代码执行完毕*/
        memset(
&g_strModulePrefix[0],0,sizeof(NW_CHAR)*MAX_FUNC_NAME_LEN);
        sprintf(g_strModulePrefix,
"%s",pchModulePrefix);
        g_bModulePrefixFiltered 
= TRUE;
    }

    
else
    
{
        g_bModulePrefixFiltered 
= FALSE;
        taskDelay(
3);
        memset(
&g_strModulePrefix[0],0,sizeof(NW_CHAR)*MAX_FUNC_NAME_LEN);
    }


    g_eStreamType 
= 0;
        
    
if (0 == strcmp(pchMediaType,"audio"))
    
{
        g_eStreamType 
|= STREAM_AUDIO;
    }

    
else if (0 == strcmp(pchMediaType,"video"))
    
{
        g_eStreamType 
|= STREAM_VIDEO;        
    }

    
else
    
{
        pkt_help(
1);
        
return;
    }

        
    
/*如果有数据流,设置统计时间*/
    
if (!g_bInitialized)
    
{    /*第一次要初始化*/
        memset(
&g_tCaller[0],0,sizeof(TCallerInfo)*MAX_CALLERS);

        
for (nCaller = CALLER_ID0; nCaller < MAX_CALLERS; nCaller++)
        
{    
            
for (nChannel = 0; nChannel < MAX_CHANNELS; nChannel++)
            
{
                g_tCaller[nCaller].tPacket[nChannel].bFrame             
= FALSE; 
#ifdef _PACKET_WRITE_FILE_
                g_tCaller[nCaller].tPacket[nChannel].bSaved            
= FALSE; 
#endif
                g_tCaller[nCaller].tPacket[nChannel].eStreamIdType     
= STREAM_ID_INVALID; 
            }

        }

        g_bInitialized 
= TRUE;
    }


    
for (nCaller = CALLER_ID0; nCaller < MAX_CALLERS; nCaller++)
    
{    
        
for (nChannel = 0; nChannel < MAX_CHANNELS; nChannel++)
        
{
            g_tCaller[nCaller].tPacket[nChannel].nInterval         
= nInterval;
            g_tCaller[nCaller].tPacket[nChannel].nPackets         
= 0;
            g_tCaller[nCaller].tPacket[nChannel].nPacketRate     
= 0;
        }

    }


    pkt_start();
        
    printf(
"wait %d seconds for profiling %s rates%s%s... ",((TICKS_PER_SECOND/10)+nInterval+nInterval/(100/nErrorPercentage))/TICKS_PER_SECOND,
        pchMediaType,NULL 
== pchModulePrefix? "":" from the module with prefix ",NULL == pchModulePrefix? "":pchModulePrefix);

    taskDelay(nInterval);
/*统计时间*/    
    taskDelay(nInterval
/(100/nErrorPercentage));/*考虑大概%20 的偏差*/    
    
    pkt_stat();
    
    pkt_stop();
}


/*显示数据包RTP 头信息*/
NW_VOID pkt_show(NW_INT32 nCallerID,NW_INT32 nStreamId,NW_INT32 nPacketNum)
{
    
static NW_INT32     nCallerID2        = 0
    
static NW_INT32     nStreamId2        = 0;
    
static NW_INT32     nPacketNum2    = 0;    
    NW_INT32         nCaller            
= 0;
    NW_INT32         nChannel        
= 0;

    
if (!g_bInitialized)
    
{
        printf(
"You gotta use pkt_prof to do initialization first!");
        
return;
    }

    
    pkt_stop();    

    
if (0 != nCallerID)
    
{
        nCallerID2     
= nCallerID;
        nStreamId2     
= nStreamId;
        nPacketNum2     
= nPacketNum;    
    }


    
if (nCallerID2 <CALLER_ID0 || nCallerID2 >= MAX_CALLERS)
    
{
        printf(
"Invalid caller ID %d ",nCallerID2);    
        pkt_help(
2);
        
return;
    }

    
    
if (nStreamId2 < 0 || nStreamId2 >= MAX_CHANNELS)
    
{
        printf(
"Invalid stream ID %d ",nStreamId2);        
        pkt_help(
2);
        
return;
    }
    
    
    
if (1 > nPacketNum2)
    
{
        printf(
"Invalid packet num %d ",nPacketNum2);            
        pkt_help(
2);
        
return;    
    }

                
    
if (1 > g_tCaller[nCallerID2].nFuncLen) 
    
{
        printf(
"Invalid func len %d ",g_tCaller[nCallerID2].nFuncLen);        
        
return;
    }


    
for (nCaller = CALLER_ID0; nCaller < MAX_CALLERS; nCaller++)
    
{    
        
for (nChannel = 0; nChannel < MAX_CHANNELS; nChannel++)
        
{
            g_tCaller[nCaller].tPacket[nChannel].nPacketShown 
= 0;
        }

    }

    
    g_tCaller[nCallerID2].tPacket[nStreamId2].nPacketShown 
= nPacketNum2;

    pkt_start();
    
    taskDelay(
300*nPacketNum2/TICKS_PER_SECOND);/*300 为一秒中可能接收到的最大包数目*/    
    
    pkt_stop();            
}


#ifdef _PACKET_WRITE_FILE_ 
/*record*/     
NW_BOOL pkt_confirmed(
void )
{
    
static NW_BOOL     bFtpOpened         = FALSE;        
    NW_BYTE         szLocalIP[
16]    = {0};
    NW_CHAR        ch            
= '0';
    
    
if (!bFtpOpened)
    
{
        printf(
"NOTE:Be 100%s sure whether host wftp server has been opened or not. ","%",szLocalIP);            
        printf(
"Opened yet? Go,check and enter 'Y' or 'N' to make sure:");

        ch 
= getchar();
        
while ('Y' != ch && 'N' != ch)
        
{                    
            ch 
= getchar();
        }

        
        
if('N' == ch)
        
{
            printf(
"Open WFTP server and enter 'Y' to continue or 'A'  to exit:");

            ch 
= getchar();
            
while ('Y' != ch && 'A' != ch )
            
{
                ch 
= getchar();
            }

    
            
if('Y' != ch)
            
{
                
return FALSE;
            }

            
else
            
{
                printf(
"Warning:it'll cause a long delay in multi-pictures if WFTP server wasn't opened practically!");
            }

        }


        bFtpOpened 
= TRUE;
    }


    
return TRUE;
}


/*单点录制*/
NW_VOID pkt_rec(NW_INT32 nCallerID,NW_INT32 nStreamId,NW_INT32 nRecoredLen)
{
    
static NW_INT32     nCallerID2        = 0
    
static NW_INT32     nStreamId2        = 0;
    
static NW_INT32     nRecoredLen2    = 0;
    NW_INT32         nCaller            
= 0;
    NW_INT32         nChannel        
= 0;    
    NW_CHAR        ch                
= '0';

    
if (!g_bInitialized)
    
{
        printf(
"You gotta use pkt_prof to do initialization first!");
        
return;
    }

    
    pkt_stop();    
            
    
if (0 != nCallerID)
    
{
        nCallerID2     
= nCallerID;
        nStreamId2     
= nStreamId;
        nRecoredLen2    
= nRecoredLen;    
    }


    
if (nCallerID2 < CALLER_ID0 || nCallerID2 >= MAX_CALLERS)
    
{
        printf(
"Invalid caller ID %d ",nCallerID2);        
        pkt_help(
5);
        
return;
    }

    
    
if (nStreamId2 < 0 || nStreamId2 >= MAX_CHANNELS)
    
{
        printf(
"Invalid stream ID %d ",nStreamId2);        
        pkt_help(
5);
        
return;
    }
    

    
if (1 > g_tCaller[nCallerID2].nFuncLen) 
    
{
        printf(
"Invalid func len %d ",g_tCaller[nCallerID2].nFuncLen);            
        
return;
    }
    

    
/*如果nRecoredLen 没有输入或0 则采取默认值*/
    
if (0 == nRecoredLen2)
    
{
        nRecoredLen2 
= MAX_BUF_SIZE;
    }


    
if (nRecoredLen2 > MAX_BUF_SIZE)
    
{
        pkt_help(
4);
        
return;
    }

    
else
    
{
        s_nFileBufLen 
= nRecoredLen2;
    }


    
if (!pkt_confirmed())
    
{    /*确认不成功*/
        printf(
"Failed to confirm! ");        
        
return;
    }

    
    
for (nCaller = CALLER_ID0; nCaller < MAX_CALLERS; nCaller++)
    
{    
        
for (nChannel = 0; nChannel < MAX_CHANNELS; nChannel++)
        
{
            g_tCaller[nCaller].tPacket[nChannel].bSaved         
= FALSE;
            g_tCaller[nCaller].tPacket[nChannel].bStart        
= FALSE;
            g_tCaller[nCaller].tPacket[nChannel].bReady        
= FALSE;            
            g_tCaller[nCaller].tPacket[nChannel].nOffsetPrev    
= 0;
            g_tCaller[nCaller].tPacket[nChannel].nOffsetCurr    
= 0;
        }

    }


    memset(s_pFileBuf
+g_tCaller[nCallerID2].tPacket[nStreamId2].nOffsetCurr,0,s_nFileBufLen*sizeof(NW_UINT8));

    g_tCaller[nCallerID2].tPacket[nStreamId2].nFrameLen     
= 0;    
    g_tCaller[nCallerID2].tPacket[nStreamId2].bFisrtPacket     
= FALSE;    
    g_tCaller[nCallerID2].tPacket[nStreamId2].bSaved         
= TRUE;

    pkt_start();
}



/*多点录制: 为了同步多点的数据流, 所有
  *同步录制的点共享MAX_BUF_SIZE 长度的内存
  *空间。一次设定多点录制列表,之后可
  *以使用pkt_rec2() 反复利用。该功能对调试
  *音频重音很有用。
*/

NW_VOID pkt_rec_sync(NW_INT32 nRecordedPoints)
{
    TPacketInfo
*        ptPacket                    = NULL;
    
static TRec          tRecList[MAX_MULTI_RECORD_POINTS];
    
static NW_BOOL     bInitialized                    = FALSE;
    
static NW_INT32    nPoints                        = 0;
    NW_INT32        nPoint,nRecPoints            
= nRecordedPoints;
    NW_INT32         nRecoredLen                    
= 0;
    NW_INT32        nCaller,nCallerID                
= 0;
    NW_INT32        nChannel,nChannelID            
= 0;
    NW_INT32        nChannelPrev,nChannelIDPrev    
= 0;
    
    
if (!bInitialized)
    
{
        
if (nRecPoints < 1 || nRecPoints > MAX_MULTI_RECORD_POINTS)
        
{
            printf(
"Invalid caller num %d! ",nRecPoints);
            pkt_help(
6);
            
return;
        }


        
if (!pkt_confirmed())
        
{    /*确认不成功*/
            printf(
"Failed to confirm! ");        
            
return;
        }


        memset(
&tRecList[0],0,sizeof(TRec)*MAX_MULTI_RECORD_POINTS);
        bInitialized    
= TRUE;
        nPoints        
= 0;        
    }


    
if (bInitialized)
    
{        
        
if (nRecPoints < 0 || nRecPoints > MAX_MULTI_RECORD_POINTS)
        
{
            printf(
"Invalid caller num %d! ",nRecPoints);
            pkt_help(
6);
            
return;
        }
        

        pkt_stop();    

        
if (nRecPoints > 0)
        
{
            nPoints 
= nRecPoints;
        }

        
        
if (0 == nPoints)
        
{
            printf(
"recorded points overriden %d! ",nPoints);                
            
return;
        }


        
for (nCaller = CALLER_ID0; nCaller < MAX_CALLERS; nCaller++)
        
{    
            
for (nChannel = 0; nChannel < MAX_CHANNELS; nChannel++)
            
{
                g_tCaller[nCaller].tPacket[nChannel].bSaved         
= FALSE;
                g_tCaller[nCaller].tPacket[nChannel].bStart        
= FALSE;
                g_tCaller[nCaller].tPacket[nChannel].bReady        
= FALSE;
                g_tCaller[nCaller].tPacket[nChannel].nOffsetPrev    
= 0;
                g_tCaller[nCaller].tPacket[nChannel].nOffsetCurr    
= 0;
            }

        }

        
        nRecoredLen 
= (MAX_BUF_SIZE/nPoints - 0x1& ~0x3;
        s_nFileBufLen 
= nRecoredLen;
        
        
for (nPoint =0; nPoint < nPoints; nPoint++)
        
{
            nCallerID     
= INVALID_VALUE;
            nChannelID    
= INVALID_VALUE;
            
            
if (0 == nRecPoints)
            
{
                nCallerID        
= tRecList[nPoint].nCallerID;
                nChannelID    
= tRecList[nPoint].nChannelID;            
            }

            
else
            
{
                printf(
"Recorded point ID %d:Enter caller ID and channel ID:",nPoint);            
                
while (nCallerID <CALLER_ID0 || nCallerID >= MAX_CALLERS 
                
|| nChannelID < CALLER_ID0 || nChannelID >= MAX_CHANNELS 
                
|| (nPoint > 0 && nCallerID == tRecList[nPoint-1].nCallerID && nChannelID == tRecList[nPoint-1].nChannelID))
                
{
                    
if ((nPoint > 0 && nCallerID == tRecList[nPoint-1].nCallerID && nChannelID == tRecList[nPoint-1].nChannelID)) 
                    
{
                        printf(
"No repeat points allowed! Enter again:");            
                    }
 
                    
                    scanf(
"%d,%d",&nCallerID,&nChannelID);
                }

            
                tRecList[nPoint].nCallerID     
= nCallerID;
                tRecList[nPoint].nChannelID     
= nChannelID;
            }

            
            ptPacket                     
= &g_tCaller[nCallerID].tPacket[nChannelID];
            ptPacket
->nOffsetPrev        = nPoint*nRecoredLen;
            ptPacket
->nOffsetCurr        = nPoint*nRecoredLen;
            ptPacket
->bFisrtPacket         = FALSE;                        
            ptPacket
->nFrameLen         = 0;    
            ptPacket
->bSaved             = TRUE;

            memset(s_pFileBuf 
+ ptPacket->nOffsetPrev,0,nRecoredLen*sizeof(NW_UINT8));
        }


        pkt_start();
    }

}


#endif

NW_VOID     pkt_stat(
void )
{
    TCallerInfo
*             ptCaller        = NULL;
    TPacketInfo
*            ptPacket    = NULL;
    NW_INT32             nCaller        
= 0;
    NW_INT32             nChannel    
= 0;
    NW_BOOL            bFound        
= 0;

    
if (!g_bInitialized)
    
{
        printf(
"You gotta use pkt_prof to do initialization first!");
        
return;
    }

    
    
if (1 > g_nCallers)
    
{
        printf(
"No stream coming! ");
        
return;
    }


    printf(
"------------------------------------------------------------------------------- ");        
    
for (nCaller = CALLER_ID0; nCaller < MAX_CALLERS; nCaller++)
    
{    
        ptCaller     
= &g_tCaller[nCaller];

        
if (1 > ptCaller->nFuncLen) 
        
{
            
continue;
        }

        
        bFound 
= FALSE;
            
        
for (nChannel = 0; nChannel < MAX_CHANNELS; nChannel++)
        
{
            ptPacket     
= &g_tCaller[nCaller].tPacket[nChannel];

            
if (ptPacket->nInterval > 0)
            
{
                ptPacket
->nInterval = 0;
            }


            
if (ptPacket->nPacketRate > 0)
            
{
                printf(
"%-28s(%-4d) caller %-2d,%-4s id %-3d: %-3d %-s/s,%-3d %-7s ",
                    ptCaller
->pchFuncName,ptCaller->nLine,nCaller,STREAM_ID_DSP == ptPacket->eStreamIdType?"dsp":
                        (STREAM_ID_CHAN 
== ptPacket->eStreamIdType? "chan":"call"),nChannel,
                            ptPacket
->nPacketRate,ptPacket->bFrame? "f":"p",
                                ptPacket
->nPackets,ptPacket->bFrame? "frames":"packets");            

                bFound 
= TRUE;
            }

        }

        
        
if (bFound)
        
{
            printf(
" ");        
        }

    }

    printf(
"------------------------------------------------------------------------------- ");        
}


NW_VOID     pkt_check(NW_INT32 nCallerID,NW_INT32 nStreamId)
{
    TPacketInfo
*        ptPacket        = NULL;
    
static NW_INT32     nCallerID2        = 0
    
static NW_INT32     nStreamId2        = 0;
    NW_INT32         nCaller            
= 0;
    NW_INT32         nChannel        
= 0;

    
if (!g_bInitialized)
    
{
        printf(
"You gotta use pkt_prof to do initialization first!");
        
return;
    }

    
    
if (0 != nCallerID)
    
{
        nCallerID2     
= nCallerID;
        nStreamId2     
= nStreamId;
    }


    
if (nCallerID2 <CALLER_ID0 || nCallerID2 >= MAX_CALLERS)
    
{
        printf(
"Invalid caller ID %d ",nCallerID2);    
        pkt_help(
2);
        
return;
    }

    
    
if (nStreamId2 < 0 || nStreamId2 >= MAX_CHANNELS)
    
{
        printf(
"Invalid stream ID %d ",nStreamId2);        
        pkt_help(
2);
        
return;
    }
    
            
    
if (1 > g_tCaller[nCallerID2].nFuncLen) 
    
{
        printf(
"Invalid func len %d ",g_tCaller[nCallerID2].nFuncLen);        
        
return;
    }


    ptPacket     
= &g_tCaller[nCallerID2].tPacket[nStreamId2];

    printf(
"caller %-2d,%-4s id %-2d:nPackets     %-d ",nCallerID2,STREAM_ID_DSP == ptPacket->eStreamIdType?"dsp":
        (STREAM_ID_CHAN 
== ptPacket->eStreamIdType? "chan":"call"),nChannel,ptPacket->nPackets);
    printf(
"caller %-2d,%-4s id %-2d:nPacketRate  %-d ",nCallerID2,STREAM_ID_DSP == ptPacket->eStreamIdType?"dsp":
        (STREAM_ID_CHAN 
== ptPacket->eStreamIdType? "chan":"call"),nChannel,ptPacket->nPacketRate);
    printf(
"caller %-2d,%-4s id %-2d:nPrevPackets %-d ",nCallerID2,STREAM_ID_DSP == ptPacket->eStreamIdType?"dsp":
        (STREAM_ID_CHAN 
== ptPacket->eStreamIdType? "chan":"call"),nChannel,ptPacket->nPrevPackets);
    printf(
"caller %-2d,%-4s id %-2d:nPrevTicks   %-d ",nCallerID2,STREAM_ID_DSP == ptPacket->eStreamIdType?"dsp":
        (STREAM_ID_CHAN 
== ptPacket->eStreamIdType? "chan":"call"),nChannel,ptPacket->nPrevTicks);
    printf(
"caller %-2d,%-4s id %-2d:nPacketShown %-d ",nCallerID2,STREAM_ID_DSP == ptPacket->eStreamIdType?"dsp":
        (STREAM_ID_CHAN 
== ptPacket->eStreamIdType? "chan":"call"),nChannel,ptPacket->nPacketShown);
    printf(
"caller %-2d,%-4s id %-2d:nInterval    %-d ",nCallerID2,STREAM_ID_DSP == ptPacket->eStreamIdType?"dsp":
        (STREAM_ID_CHAN 
== ptPacket->eStreamIdType? "chan":"call"),nChannel,ptPacket->nInterval);
    printf(
"caller %-2d,%-4s id %-2d:bFrame       %-d ",nCallerID2,STREAM_ID_DSP == ptPacket->eStreamIdType?"dsp":
        (STREAM_ID_CHAN 
== ptPacket->eStreamIdType? "chan":"call"),nChannel,ptPacket->bFrame);
    printf(
"caller %-2d,%-4s id %-2d:bSaved       %-d ",nCallerID2,STREAM_ID_DSP == ptPacket->eStreamIdType?"dsp":
        (STREAM_ID_CHAN 
== ptPacket->eStreamIdType? "chan":"call"),nChannel,ptPacket->bSaved);    
}


NW_VOID     pkt_start(
void )
{
    g_bActivated 
= TRUE;
}


NW_VOID     pkt_stop(
void )
{
    g_bActivated 
= FALSE;
}


NW_BOOL     pkt_started(
void )
{
    
return g_bActivated;
}


NW_VOID     pkt_reset(
void )
{
    NW_INT32         nCaller                 
= 0;
    NW_INT32         nChannel            
= 0;

    
for (nCaller = CALLER_ID0; nCaller < MAX_CALLERS; nCaller++)
    
{    
        
for (nChannel = 0; nChannel < MAX_CHANNELS; nChannel++)
        
{
            g_tCaller[nCaller].tPacket[nChannel].bFrame             
= FALSE; 
#ifdef _PACKET_WRITE_FILE_
            g_tCaller[nCaller].tPacket[nChannel].bSaved            
= FALSE; 
#endif
            g_tCaller[nCaller].tPacket[nChannel].eStreamIdType     
= STREAM_ID_INVALID; 
        }

    }


    g_eStreamType             
= 0;    
    g_bModulePrefixFiltered     
= FALSE;
    g_bActivated             
= FALSE;

    memset(
&g_strModulePrefix[0],0,sizeof(NW_CHAR)*MAX_FUNC_NAME_LEN);
}



/*当出现异常时, 本模块可以诊断的手段*/
NW_VOID      pkt_help(NW_INT32 nSelection) 
{    /*NOTE : 打印是否对齐在UltraEdit 下看*/

    
switch (nSelection)
    
{
        
case 0:
        
{    
            printf(
"------------------------------------------------------------------------------ ");        
            printf(
"pkt_help(0)        详细介绍pkt_help ");
            printf(
"pkt_help(1)        详细介绍pkt_prof ");
            printf(
"pkt_help(2)        详细介绍pkt_show ");
            printf(
"pkt_help(3)        详细介绍pkt_check ");
            printf(
"pkt_help(4)        详细介绍pkt_reset ");
#ifdef _PACKET_WRITE_FILE_
            printf(
"pkt_help(5)        详细介绍pkt_rec ");
            printf(
"pkt_help(6)        详细介绍pkt_rec_sync ");
#endif
            printf(
"------------------------------------------------------------------------------ ");        
        }
break;
            
        
case 1:
        
{            
            printf(
"------------------------------------------------------------------------------ ");        
            printf(
"NW_VOID pkt_prof(NW_CHAR* pchMediaType,NW_CHAR* pchModulePrefix) ");
            printf(
"1. 功能介绍:       打印所有或某监测点数据流通路径及速率 ");            
            printf(
"2. 范例展示:       pkt_prof 'video','DP'  ");                
            printf(
"3. 参数输入: ");
            printf(
"   pchMediaType:   媒体流类型, 如输入字符串audio  / video 显示音视频 ");                
            printf(
"   pchModulePrefix:模块的前缀, 如输入字符串COMM / DP表示通信层或DP ");                
            printf(
"------------------------------------------------------------------------------ ");        
          }
break;
        
        
case 2:
        
{
            printf(
"------------------------------------------------------------------------------ ");        
            printf(
"NW_VOID pkt_show(NW_INT32 nCallerID,NW_INT32 nStreamId,NW_INT32 nPacketNum) ");
            printf(
"1. 功能介绍:       打印某监测点的一系列序列号 ");
            printf(
"2. 范例展示:       pkt_show 2,1,10 ");                    
            printf(
"3. 参数输入: ");
            printf(
"   nCallerID:      监测点的函数调用ID, 调用pkt_prof 可以查看 ");                
            printf(
"   nStreamId:      监测点的通道ID, 调用pkt_prof 可以查看 ");                
            printf(
"   nPacketNum:     要求打印的数据包数目 ");                        
            printf(
"------------------------------------------------------------------------------ ");        
        }
break;    

        
case 3:
        
{
            printf(
"------------------------------------------------------------------------------ ");        
            printf(
"NW_VOID pkt_check(NW_INT32 nCallerID,NW_INT32 nStreamId) ");
            printf(
"1. 功能介绍:       打印某监测点的详细统计信息 ");
            printf(
"2. 范例展示:       pkt_check 2,1 ");                    
            printf(
"3. 参数输入: ");
            printf(
"   nCallerID:      监测点的函数调用ID, 调用pkt_prof 可以查看 ");                
            printf(
"   nStreamId:      监测点的通道ID, 调用pkt_prof 可以查看 ");                
            printf(
"------------------------------------------------------------------------------ ");        
        }
break;    
        
        
case 4:
        
{
            printf(
"------------------------------------------------------------------------------ ");        
            printf(
"NW_VOID pkt_reset(void) ");
            printf(
"1. 功能介绍:       复位所有监测点状态 ");
            printf(
"2. 范例展示:       pkt_reset ");                
            printf(
"3. 参数输入:       NONE ");
            printf(
"------------------------------------------------------------------------------ ");        
        }
break;    
        
#ifdef _PACKET_WRITE_FILE_
        
case 5:
        
{
            printf(
"------------------------------------------------------------------------------ ");        
            printf(
"NW_VOID pkt_rec(NW_INT32 nCallerID,NW_INT32 nStreamId,NW_INT32 nRecoredLen)) ");
            printf(
"1. 功能介绍:       录制某监测点的数据流并传送到WFTP 用户目录 ");
            printf(
"2. 范例展示:       pkt_rec 2,1 ");                
            printf(
"3. 参数输入: ");
            printf(
"   nCallerID:      监测点的函数调用ID, 调用pkt_prof 可以查看 ");                
            printf(
"   nStreamId:      监测点的通道ID, 调用pkt_prof 可以查看 ");                
            printf(
"   nRecoredLen:    准备录制多少长度,不超过%d K ",MAX_BUF_SIZE/1024);                            
            printf(
"------------------------------------------------------------------------------ ");        
        }
break;    

        
case 6:
        
{
            printf(
"------------------------------------------------------------------------------ ");        
            printf(
"NW_VOID pkt_rec_sync(NW_INT32 nRecordedPoints) ");
            printf(
"1. 功能介绍:       同时录制多个监测点的数据流 ");
            printf(
"2. 范例展示:       pkt_rec_sync 2 ");                
            printf(
"3. 参数输入: ");
            printf(
"   nRecordedPoints:同时录制多少个检测点, 最多支持%d 点 ",MAX_MULTI_RECORD_POINTS);                
            printf(
"4. 注意事项:       该功能只对具备录制能力的监测点(rate:f/s) ");
            printf(
"------------------------------------------------------------------------------ ");        
        }
break;            
#endif
        
default:
        
{    /*递归显示*/
            pkt_help(
0);
        }
break;                    
    }

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值