您的位置:首页 > 其它

Live555源码阅读之Mediaserver总体预览

2015-10-10 13:07 288 查看
这篇博文是随手记录,思路稍显紊乱,仅供自己记录参阅,后续如若有时间详细分析与学习

rtspserver创建及工作流程分析

rtspServer = DynamicRTSPServer::createNew(*env, rtspServerPortNum, authDB);//构造rtspServer

DynamicRTSPServer ---> //继承

RTSPServerSupportingHTTPStreaming --->

RTSPServer --->

GenericMediaServer --->

Medium

主要构造工作

GenericMediaServer::GenericMediaServer(UsageEnvironment& env, int ourSocket,

Port ourPort,unsigned reclamationSeconds)

{

...

ignoreSigPipeOnSocket(fServerSocket);

// Arrange to handle connections from others:

env.taskScheduler().turnOnBackgroundReadHandling(fServerSocket, incomingConnectionHandler, this);

}

turnOnBackgroundReadHandling --->

BasicTaskScheduler::setBackgroundHandling(socketNum, SOCKET_READABLE, handlerProc, clientData) --->

fHandlers->assignHandler(socketNum, conditionSet, handlerProc, clientData)

//这里说明一下,HandlerSet &fHandlers,负责注册基于socketNum的读写以及异常的事件处理

//维护一个HandlerDescriptor类的双向链表,包含了socketNum和对应的handlerProc处理方法

BasicTaskScheduler::BasicTaskScheduler(unsigned maxSchedulerGranularity)

: fMaxSchedulerGranularity(maxSchedulerGranularity), fMaxNumSockets(0)

#if defined(__WIN32__) || defined(_WIN32)

, fDummySocketNum(-1)

#endif

{

FD_ZERO(&fReadSet);

FD_ZERO(&fWriteSet);

FD_ZERO(&fExceptionSet);

if (maxSchedulerGranularity > 0) schedulerTickTask(); // ensures that we handle events frequently

}

//BasicTaskScheduler类继承自BasicTaskScheduler0,初始化读写异常文件描述符集,调用schedulerTickTask,这个函数对应的处理函数是自身,反复调用

BasicTaskScheduler0::BasicTaskScheduler0()

: fLastHandledSocketNum(-1), fTriggersAwaitingHandling(0), fLastUsedTriggerMask(1), fLastUsedTriggerNum(MAX_NUM_EVENT_TRIGGERS-1) {

fHandlers = new HandlerSet;

for (unsigned i = 0; i < MAX_NUM_EVENT_TRIGGERS; ++i) {

fTriggeredEventHandlers[i] = NULL;

fTriggeredEventClientDatas[i] = NULL;

}

}

//BasicTaskScheduler0构造函数创建了用于存储socket事件处理映射的HandlerSet,并初始化触发事件数组

主函数最终调用env->taskScheduler().doEventLoop();进入事件处理循环(主循环),等待客户端连接等一系列操作

/////////////////////////////////////////////////////////////////////////////////

服务器接收到客户端连接请求回调函数incomingConnectionHandlerOnSocket(fServerSocket) --->

int clientSocket = accept(serverSocket, (struct sockaddr*)&clientAddr, &clientAddrLen) &&&

(void)createNewClientConnection(clientSocket, clientAddr) --->

RTSPServer::RTSPClientConnection::RTSPClientConnection(RTSPServer& ourServer, int clientSocket, struct sockaddr_in clientAddr)

: GenericMediaServer::ClientConnection(ourServer, clientSocket, clientAddr),

fOurRTSPServer(ourServer), fClientInputSocket(fOurSocket), fClientOutputSocket(fOurSocket),

fIsActive(True), fRecursionCount(0), fOurSessionCookie(NULL) {

resetRequestBuffer();

}

调用GenericMediaServer::ClientConnection的构造函数

GenericMediaServer::ClientConnection::ClientConnection(GenericMediaServer& ourServer, int clientSocket, struct sockaddr_in clientAddr)

: fOurServer(ourServer), fOurSocket(clientSocket), fClientAddr(clientAddr) {

// Add ourself to our 'client connections' table:

fOurServer.fClientConnections->Add((char const*)this, this);

// Arrange to handle incoming requests:

resetRequestBuffer();

envir().taskScheduler().setBackgroundHandling(fOurSocket, SOCKET_READABLE|SOCKET_EXCEPTION, incomingRequestHandler, this);

//将客户端socket加入后台处理调度程序,绑定回调处理函数incomingRequestHandler,当客户端有数据可读或异常的时候

}

/////////////////////////////////////////////////////////////////////////////////

客户端请求处理回调函数incomingRequestHandler

void GenericMediaServer::ClientConnection::incomingRequestHandler() {

struct sockaddr_in dummy; // 'from' address, meaningless in this case

int bytesRead = readSocket(envir(), fOurSocket, &fRequestBuffer[fRequestBytesAlreadySeen], fRequestBufferBytesLeft, dummy);

handleRequestBytes(bytesRead);

}

其中readSocket调用recvfrom将接收到的数据存储于fRequestBuffer[fRequestBytesAlreadySeen],

而handleRequestBytes是最核心的解析请求并做出相应操作的函数,星级5颗星。

下面我们来看一下handleRequestBytes函数,它是GenericMediaServer类中声明的虚函数,在RTSPServer中实现

--->

.......//一系列前序操作

handleCmd_PLAY --->

OnDemandServerMediaSubsession::startStream --->

streamState->startPlaying --->

fRTPSink->startPlaying --->

continuePlaying() --->这里关注h264--->

H264or5VideoRTPSink::continuePlaying() ---> 到父类 --->

MultiFramedRTPSink::continuePlaying() --->

buildAndSendPacket(True) --->

设置rtp头 && packFrame() --->

fSource->getNextFrame(fOutBuf->curPtr(), fOutBuf->totalBytesAvailable(), afterGettingFrame, this, ourHandleClosure, this) --->

afterGettingFrame 作为回调函数,this 作为数据指针传入回调函数,进而调用类内函数afterGettingFrame1 --->

sendPacketIfNecessary() ---> 发送完成后调用 --->

envir().taskScheduler().scheduleDelayedTask(uSecondsToGo, (TaskFunc*)sendNext, this); ---> 加入 sendNext任务

sendNext --->

sink->buildAndSendPacket(False);//与上面的buildAndSendPacket(True)构成循环发送体系,使视频流持续发送,这里的false,ture仅代表是否为第一个包.

至此大体流程走完,初学,后续会细读代码。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: