WaitForIncomingData
/** Waits at most a time \c delay until incoming data has been detected.
* Waits at most a time \c delay until incoming data has been detected. Only works when you're not
* using the poll thread. If \c dataavailable is not \c NULL, it should be set to \c true if data
* was actually read and to \c false otherwise.
*/
int WaitForIncomingData(const RTPTime &delay,bool *dataavailable = 0);
该函数主要是通过调用RTPSelect检测是否有数据可以接收,如果有数据等待接收,就会设置dataavailable为true,此时数据仍然保存在系统接收缓存里面,没有真正读取到程序内存当中
其中设置了超时等待的接收时间
Poll
/** If you're not using the poll thread, this function must be called regularly to process incoming data
* and to send RTCP data when necessary.
*/
int Poll();
该函数是从系统接收缓存中,调用recvfrom函数读取网络数据到用户态中,然后解析成RTP包,推进列表,等待处理
RTPPollThread
/** If \c usethread is \c true, the session will use a poll thread to automatically process incoming
* data and to send RTCP packets when necessary.
*/
int SetUsePollThread(bool usethread);
一旦调用该函数设置为true,当然前提是定义宏RTP_SUPPORT_THREAD,将会调用jrtplib内部的pollthread线程进行数据的接收,不再需要调用上面两个函数
例子1
当重写实现了 virtual void OnRTPPacket(RTPPacket *pack, const RTPTime &receivetime, const RTPAddress *senderaddress);函数对于RTP数据包的处理,可以直接循环调用poll完成数据的接收和处理
while (m_startrecv)
{
int nStatus = m_VedioRTPSession.Poll();
if (nStatus < 0)
{
break;
}
std::this_thread::sleep_for(std::chrono::milliseconds(50));
}
例子2
当没有实现OnValidatedRTPPacket,获取到的packet包会继续传递到packetlist列表中,相关的处理函数
int RTPInternalSourceData::ProcessRTPPacket(RTPPacket *rtppack,const RTPTime &receivetime,bool *stored,RTPSources *sources),这个时候,就可以调用GotoFirstSourceWithData和GetNextPacket在线程中单独处理RTP数据
while (m_startrecv)
{
bool is_data_available = false;
RTPTime delay(0, 40);
m_VedioRTPSession.WaitForIncomingData(delay, &is_data_available);
if (is_data_available)
{
int nStatus = m_VedioRTPSession.Poll();
if (nStatus < 0)
{
break;
}
m_VedioRTPSession.BeginDataAccess();
if (m_VedioRTPSession.GotoFirstSourceWithData())
{
do
{
RTPPacket * pkt = NULL;
while (m_startrecv && (pkt = m_VedioRTPSession.GetNextPacket()) != NULL)
{
m_VedioRTPSession.OnRTPPacket(pkt);
m_VedioRTPSession.DeletePacket(pkt);
}
} while (m_startrecv && m_VedioRTPSession.GotoNextSourceWithData());
}
m_VedioRTPSession.EndDataAccess();
}
std::this_thread::sleep_for(std::chrono::milliseconds(50));
}
性能分析
当前RTP数据流可能是均与推送过来,每一个毫秒都会接收到一个RTP数据包,导致WaitForIncomingData函数会一直频繁调用,一路可能就需要占用30%CPU,因此,进行合理的休眠,能够降低系统的CPU功耗。目前触发调用取到数据以后,会进行休眠40毫秒:std::this_thread::sleep_for(std::chrono::milliseconds(40));