EasyDarwin

面向企业级的流媒体平台框架

EasyDarwin开始于2013年,遵循 Apple开源License APSL,为了敏捷流媒体服务器开发和简化企业流媒体应用开发而诞生的。

详细 >>

EasyDarwin RTSP会话流程解析1


EasyDarwin RTSP会话流程解析1...

一、首先是本地监听的建立:StartServer() ->

-->QTSServer::Initialize()

--->QTSServer::CreateListeners()

//函数中根据本地xml配置文件中的rtsp_port进行监听的建立

-->QTSServer::StartTasks() //开启Socket读取

具体函数在:

QTSServer::CreateListeners()
{

newListenerArray[curPortIndex] = NEW RTSPListenerSocket();
QTSS_Error err = newListenerArray[curPortIndex]->Initialize(thePortTrackers[count3].fIPAddr,
thePortTrackers[count3].fPort);//fIPAddr为本地IP,fPort为配置端口号

}

void QTSServer::StartTasks()
{
fRTCPTask = new RTCPTask();
fStatsTask = new RTPStatsUpdaterTask();
//
// Start listening
for (UInt32 x = 0; x < fNumListeners; x++)
fListeners[x]->RequestEvent(EV_RE);
}

二、会话建立

先看RTSPListenerSocket类:

Socket的读取统一归于EventContext类中的EventThread线程,具体到EventThread::Entry()中的select_waitevent()捕获。

EventThread::Entry()函数中查找EventThread::fRefTable,获取对应的EventContext。得到的是EventContext类型的派生类RTSPListenerSocket。

EventThread::Entry()
{

EventContext* theContext = (EventContext*)ref->GetObject();
theContext->ProcessEvent(theCurrentEvent.er_eventbits);

}

调用RTSPListenerSocket的ProcessEvent()函数,进而调用TCPListenerSocket::ProcessEvent(),在TCPListenerSocket::ProcessEvent()中accept Socket

theTask = this->GetSessionTask(&theSocket);//创建RTSPSession
if (theTask == NULL)
{ //this should be a disconnect. do an ioctl call?
close(osSocket);
if (theSocket)
theSocket->fState &= ~kConnected; // turn off connected state
}
else
{
Assert(osSocket != EventContext::kInvalidFileDesc);
//set options on the socket
//we are a server, always disable nagle algorithm
int one = 1;
int err = ::setsockopt(osSocket, IPPROTO_TCP, TCP_NODELAY, (char*)&one, sizeof(int));
AssertV(err == 0, OSThread::GetErrno());
err = ::setsockopt(osSocket, SOL_SOCKET, SO_KEEPALIVE, (char*)&one, sizeof(int));
AssertV(err == 0, OSThread::GetErrno());
int sndBufSize = 96L * 1024L; err = ::setsockopt(osSocket, SOL_SOCKET, SO_SNDBUF, (char*)&sndBufSize, sizeof(int));
AssertV(err == 0, OSThread::GetErrno());
//setup the socket. When there is data on the socket,
//theTask will get an kReadEvent event
theSocket->Set(osSocket, &addr);
theSocket->InitNonBlocking(osSocket);
theSocket->SetTask(theTask); //将处理Socket的类转入到RTSPSession
theSocket->RequestEvent(EV_RE); //将当前Socket加入select侦听队列
}

将(TCPSocket*)theSocket加入到侦听队列中,从上以后就开始对该条已建立accept的(TCPSocket*)theSocket描述请求由此处所创建的(RTSPSession*)theTask进行处理。

三、RTSP交互

同样Socket的读取统一归于EventContext类中的EventThread线程,具体到EventThread::Entry()中的select_waitevent()捕获。

EventThread::Entry()函数中查找EventThread::fRefTable,获取对应的EventContext。此时查找到第二部分中加入到侦听队列的Socket,进入 到EventContext中的ProcessEvent()函数:

virtual void ProcessEvent(int /*eventBits*/)
{
if (EVENTCONTEXT_DEBUG)
{
if (fTask== NULL)
qtss_printf("EventContext::ProcessEvent context=%lu task=NULL\n",(UInt32) this);
else
qtss_printf("EventContext::ProcessEvent context=%lu task=%lu TaskName=%s\n",(UInt32)this,(UInt32) fTask, fTask->fTaskName);
}
if (fTask != NULL)
fTask->Signal(Task::kReadEvent);
}

激活第二部分中theSocket所映射的theTask,进行Socket读取。此处fTask就是RTSPSession类。把RTSPSession加入到TaskThread的队列等待RTSPSession::Run()被调用,

进而就是RTSPSession::Run()对具体的RTSP请求进行的处理。

好了,今天就简单推进到此处,下一部分将深入到RTSPSession中具体对报文如何解析,以及RTSPSession如何与其他模块&Task进行交互进行分析!



------------------------------ 分割线 ------------------------------
本站文章除注明转载外,均为本站原创或编辑,欢迎大家转载,但请务必注明出处,尊重他人成果,谢谢。
转载请注明:EasyDarwin;非本站文章均来自互联网,转载目的在于传递更多信息,并不代表本站赞同其观点和对其真实性负责。
文章中如果有错误可联系:johnson@easydarwin.org
推荐文章
安防和移动互联网行业比较火热的移动端手机......>
有人问到像美拍、秒拍这些短视频拍摄是怎么......>
最近更新
Easydarwin中大量使用gettimeofday来获取系......>
最近很多EasyDarwin爱好者提出了手机移动端......>
第一个到达的音频RTP包就将作为音频的关键帧......>
打开手机直播立即就能显示出主播视频,其实就......>
h264的功能分为两层,视频编码层(VCL)和网......>
友情链接 | 申请链接
EasyDarwin官方微信!