Sipxtapi 长时间通话问题

来源:互联网 发布:sp贴图软件 编辑:程序博客网 时间:2024/05/01 16:20

 

 在使用了一段时间Sipxtapi 开源库制作的软电话,使用者给我反映一个问题,经常在长时间通话之后,软电话一端无法清除听到对方声音或者出现断断续续的声音.排出网络原因之后,确定应该是开源库的问题.

  初步怀疑为本地RTP缓存没有及时清理,导致溢出,产生语音的碎片.试图修改RTP接受类,没有成功,采用另一种方法,定时刷新RTP缓存.方式如下.

  (sipXcall.lib)SipContent.cpp 增加方法体 refresh

 

UtlBoolean SipConnection::refresh()
{
     OsStackTraceLogger stackLogger(FAC_SIPXTAPI, PRI_DEBUG, "SipConnectionrefresh");
     OsSysLog::add(FAC_SIP, PRI_DEBUG,
        "Entering SipConnection::refresh /n ");
  
  SdpSrtpParameters srtpParams;
  memset(&srtpParams, 0, sizeof(srtpParams)); 
  UtlString hostAddresses[MAX_ADDRESS_CANDIDATES] ;
        int receiveRtpPorts[MAX_ADDRESS_CANDIDATES] ;
        int receiveRtcpPorts[MAX_ADDRESS_CANDIDATES] ;
        int receiveVideoRtpPorts[MAX_ADDRESS_CANDIDATES] ;
        int receiveVideoRtcpPorts[MAX_ADDRESS_CANDIDATES] ;
        RTP_TRANSPORT transportTypes[MAX_ADDRESS_CANDIDATES];
        int numAddresses = 0;
        int totalBandwidth = 0;
        int videoFramerate = 0;
  OsStatus OsRet;
        SdpCodecFactory supportedCodecs;

  if(mpMediaInterface)
  {
   mpMediaInterface->getCapabilitiesEx(mConnectionId,
    MAX_ADDRESS_CANDIDATES,
    hostAddresses,
    receiveRtpPorts,
    receiveRtcpPorts,
    receiveVideoRtpPorts,
    receiveVideoRtcpPorts,
    transportTypes,
    numAddresses,
    supportedCodecs,
    srtpParams,
    mBandwidthId,
    totalBandwidth,
    videoFramerate);
   int numCodecs = 0;
   SdpCodec** codecsArray = NULL;
   supportedCodecs.getCodecs(numCodecs, codecsArray);       
  
   OsRet=mpMediaInterface->stopRtpReceive(mConnectionId);


   OsRet = mpMediaInterface->startRtpReceive(mConnectionId,numCodecs,codecsArray);

   return TRUE;
  }
  else
   OsSysLog::add(FAC_SIP, PRI_DEBUG,
   "mpMediaInterface is null");
 return FALSE;

}

 

CpPeerCall.cpp 中增加函数

 

UtlBoolean CpPeerCall::handleRefreshConnection(OsMsg* pEventMessage)
{
 UtlString address;
    UtlString terminalId;
    ((CpMultiStringMessage*)pEventMessage)->getString2Data(address);
    ((CpMultiStringMessage*)pEventMessage)->getString3Data(terminalId);
   
 OsReadLock lock(mConnectionMutex);
    SipConnection* connection =(SipConnection*) findHandlingConnection(address);

    if(connection)
    {
        connection->refresh();
    }
    else
    {
#ifdef TEST_PRINT
        osPrintf("%s-ERROR: CpPeerCall::CP_REFRESH_CONNECTION cannot find connectionId: %s terminalId: %s/n",
            mName.data(), address.data(), terminalId.data());
#endif
    }

return TRUE ;

}

用于接受定时刷新消息

 

handleCallMessage函数中增加

 

 case CallManager::CP_REFRESH_CONNECTION:
        handleRefreshConnection(&eventMessage);
  break;

 

添加了对 CP_REFRESH_CONNECTION 此消息处理.

 

 

在CpCallManager.h  新添加枚举EventSubTypes的一个数值

CP_REFRESH_CONNECTION //添加在最后

 

在文件 CallManager.cpp  handMessage函数中添加

case CP_REFRESH_CONNECTION:

 

在sipXtapi 项目中 增加刷新接口

 

sipXtapi.cpp中增加

 

/*
函数名称:  sipxRefreshCall
功能描述:  刷新线路
输入参数:  const SIPX_CALL hCall  线路
输出:     SIPX_RESULT_SUCCESS 成功 其他 失败
*/

SIPXTAPI_API SIPX_RESULT sipxRefreshCall(const SIPX_CALL hCall)
{
  OsStackTraceLogger stackLogger(FAC_SIPXTAPI, PRI_DEBUG, "sipxRefreshCall");

      OsSysLog::add(FAC_SIPXTAPI, PRI_INFO,
        "sipxRefreshCall hCall=%d /n",
        hCall);

  SIPX_RESULT sr = SIPX_RESULT_FAILURE ;
    SIPX_INSTANCE_DATA* pInst ;
    UtlString callId ;
    UtlString remoteAddress;
   
    if (sipxCallGetCommonData(hCall, &pInst, &callId, &remoteAddress, NULL))
 {
        pInst->pCallManager->holdRefreshConnection(callId.data(), remoteAddress.data(), 0) ;
    sr = SIPX_RESULT_SUCCESS;
 }
 else
 {
     
      OsSysLog::add(FAC_SIPXTAPI, PRI_INFO,
        "sipxRefreshCall  sipxCallGetCommonData fail/n");
 }
    return sr ;
}

sipXtapi.中增加

 


/*
函数名称:  sipxRefreshCall
功能描述:  刷新线路
输入参数:  const SIPX_CALL hCall  线路
输出:     SIPX_RESULT_SUCCESS 成功 其他 失败
*/
SIPXTAPI_API SIPX_RESULT sipxRefreshCall(const SIPX_CALL hCall);

 

 

重新编译整个解决方案,新的sipxtapi.dll中有了sipxRefreshCall 接口,

调用程序中采用一个定时器,电话接通之后,定时调用此接口(我在应用中采用了间隔5秒的周期).

使用之后规避了长时间通话出现本地声音断续,中断的情况.