live555 整体框架剖析



 
//监听rtsp服务端口
portNumBits rtspServerPortNum = 554
rtspServer = DynamicRTSPServer::createNew(*env, rtspServerPortNum, authDB)
	setUpOurSocket(env, ourPort)【DynamicRTSPServer】
    env.taskScheduler().turnOnBackgroundReadHandling(fServerSocket, incomingConnectionHandler, this)【GenericMediaServer】
		setBackgroundHandling(socketNum, SOCKET_READABLE, handlerProc, clientData);【BasicTaskScheduler】
			fHandlers->assignHandler(socketNum, conditionSet, handlerProc, clientData);
			if (conditionSet&SOCKET_READABLE) FD_SET((unsigned)socketNum, &fReadSet);
			if (conditionSet&SOCKET_WRITABLE) FD_SET((unsigned)socketNum, &fWriteSet);
			if (conditionSet&SOCKET_EXCEPTION) FD_SET((unsigned)socketNum, &fExceptionSet);
		
//有客户端连接时,创建新的socket并处理
incomingConnectionHandler【GenericMediaServer】
	incomingConnectionHandlerOnSocket【GenericMediaServer】
		int clientSocket = accept(serverSocket, (struct sockaddr*)&clientAddr, &clientAddrLen);
		(void)createNewClientConnection(clientSocket, clientAddr);【RTSPServer】
			return new RTSPClientConnection(*this, clientSocket, clientAddr);【RTSPServer】
				envir().taskScheduler().setBackgroundHandling(fOurSocket, SOCKET_READABLE|SOCKET_EXCEPTION, incomingRequestHandler, this);【GenericMediaServer::ClientConnection】
	
//接收客户端发送的数据,根据cmdName的内容不同来调用不同的处理函数
incomingRequestHandler【GenericMediaServer::ClientConnection】
	incomingRequestHandler【GenericMediaServer::ClientConnection】
		int bytesRead = readSocket(envir(), fOurSocket, &fRequestBuffer[fRequestBytesAlreadySeen], fRequestBufferBytesLeft, dummy);
			recvfrom【GroupsockHelper.cpp】
		handleRequestBytes(bytesRead);【RTSPServer::RTSPClientConnection】
			parseRTSPRequestString((char*)fRequestBuffer, fLastCRLF+2 - fRequestBuffer,cmdName, sizeof cmdName...)
			if (strcmp(cmdName, "OPTIONS") == 0) 
				handleCmd_OPTIONS();
			if (strcmp(cmdName, "GET_PARAMETER") == 0)
				handleCmd_SET_PARAMETER((char const*)fRequestBuffer);
			if (strcmp(cmdName, "DESCRIBE") == 0) 
				handleCmd_DESCRIBE(urlPreSuffix, urlSuffix, (char const*)fRequestBuffer);
			if (strcmp(cmdName, "SETUP") == 0)
				clientSession->handleCmd_SETUP(this, urlPreSuffix, urlSuffix, (char const*)fRequestBuffer);
				playAfterSetup = clientSession->fStreamAfterSETUP;
			if (strcmp(cmdName, "TEARDOWN") == 0
			|| strcmp(cmdName, "PLAY") == 0
			|| strcmp(cmdName, "PAUSE") == 0
			|| strcmp(cmdName, "GET_PARAMETER") == 0
			|| strcmp(cmdName, "SET_PARAMETER") == 0) 
				clientSession->handleCmd_withinSession(this, cmdName, urlPreSuffix, urlSuffix, (char const*)fRequestBuffer);
				
				
handleCmd_DESCRIBE
	ServerMediaSession*session = fOurServer.lookupServerMediaSession(urlTotalSuffix);【RTSPServer::RTSPClientConnection】
		lookupServerMediaSession(char const* streamName, Boolean isFirstLookupInSession = True)【DynamicRTSPServer】//isFirstLookupInSession为true
			ServerMediaSession* sms = RTSPServer::lookupServerMediaSession(streamName);【DynamicRTSPServer】//isFirstLookupInSession为true
			//未找到MediaSession,创建一个
			sms = createNewSMS(envir(), streamName, fid); 
				if (strcmp(extension, ".ts") == 0) 【ServerMediaSession】
					NEW_SMS("MPEG Transport Stream");
						sms = ServerMediaSession::createNew(env, fileName, fileName, descStr);
					//ServerMediaSession中包含ServerMediaSubsession列表
					sms->addSubsession(MPEG2TransportFileServerMediaSubsession::createNew(env, fileName, indexFileName, reuseSource));
					
				if (strcmp(extension, ".264") == 0)
					NEW_SMS("H.264 Video");
						sms = ServerMediaSession::createNew(env, fileName, fileName, descStr);
					sms->addSubsession(H264VideoFileServerMediaSubsession::createNew(env, fileName, reuseSource));
			addServerMediaSession(sms);【DynamicRTSPServer】
				char const* sessionName = serverMediaSession->streamName();
				//GenericMediaServer::HashTable* fServerMediaSessions( maps 'stream name' strings to "ServerMediaSession" objects)中包含一系列ServerMediaSession
				fServerMediaSessions->Add(sessionName, (void*)serverMediaSession);
	//获取sdp信息作为handleCmd_DESCRIBE的返回值			
	sdpDescription = session->generateSDPDescription();【ServerMediaSession】
		ServerMediaSubsession* subsession;
		for (subsession = fSubsessionsHead; subsession != NULL;subsession = subsession->fNext)//fSubsessionsHead subsession列表头
			char const* sdpLines = subsession->sdpLines();【OnDemandServerMediaSubsession】
				if (fSDPLines == NULL)
					FramedSource* inputSource = createNewStreamSource(0, estBitrate);
						//.264
						ByteStreamFileSource* fileSource = ByteStreamFileSource::createNew(envir(), fFileName);
						H264VideoStreamFramer::createNew(envir(), fileSource);
						//.ts
						ByteStreamFileSource* fileSource = ByteStreamFileSource::createNew(envir(), fFileName, inputDataChunkSize);
						MPEG2TransportStreamFramer::createNew(envir(), fileSource);
					RTPSink* dummyRTPSink = createNewRTPSink(dummyGroupsock, rtpPayloadType, inputSource);
						//.264
						H264VideoRTPSink::createNew(envir(), rtpGroupsock, rtpPayloadTypeIfDynamic);
						//.ts
						SimpleRTPSink::createNew(envir(), rtpGroupsock,33, 90000, "video", "MP2T",1, True, False /*no 'M' bit*/);
					setSDPLinesFromRTPSink(dummyRTPSink, inputSource, estBitrate);
						char const* auxSDPLine = getAuxSDPLine(rtpSink, inputSource);【H264VideoFileServerMediaSubsession:.264,OnDemandServerMediaSubsession:.ts】
						//返回的sdp信息中包含了sdp中的m
						char const* const sdpFmt ="m=%s %u RTP/AVP %d\r\n"


//.264获取sdp信息流程	ByteStreamFileSource为source,H264VideoRTPSink为sink			
char const* auxSDPLine = getAuxSDPLine(rtpSink, inputSource);【H264VideoFileServerMediaSubsession:.264】
	// Start reading the file:
    fDummyRTPSink->startPlaying(*inputSource, afterPlayingDummy, this);【MediaSink】
		fAfterFunc = afterFunc;
		fAfterClientData = afterClientData;
		continuePlaying();【H264or5VideoRTPSink】
			
		
	// Check whether the sink's 'auxSDPLine()' is ready:
    checkForAuxSDPLine(this);
 
				
				
	
	
				
		
		
	
	
	
//taskScheduler socket网络事件轮询,如果收到网络事件,则调用对应的回调函数
TaskScheduler* scheduler = BasicTaskScheduler::createNew();
UsageEnvironment* env = BasicUsageEnvironment::createNew(*scheduler)
env->taskScheduler().doEventLoop()【BasicTaskScheduler0】
	for(;;)
		SingleStep()【BasicTaskScheduler】
			select(fMaxNumSockets, &readSet, &writeSet, &exceptionSet, &tv_timeToDelay);
				HandlerIterator iter(*fHandlers);
				HandlerDescriptor* handler;
				(*handler->handlerProc)(handler->clientData, resultConditionSet);【BasicTaskScheduler】
		
	
	
			
			
			
			
 
 
 
DynamicRTSPServer->RTSPServerSupportingHTTPStreaming->RTSPServer->GenericMediaServer->Medium
BasicTaskScheduler->BasicTaskScheduler0->TaskScheduler
RTSPServer::RTSPClientSession->GenericMediaServer::ClientSession
ServerMediaSession->Medium 
MPEG2TransportFileServerMediaSubsession->FileServerMediaSubsession->OnDemandServerMediaSubsession->ServerMediaSubsession->Medium	
     H264VideoFileServerMediaSubsession->FileServerMediaSubsession->OnDemandServerMediaSubsession->ServerMediaSubsession->Medium	

ByteStreamFileSource->FramedFileSource->FramedSource->MediaSource->Medium  //(h264,h265,ts的createNewStreamSource)
H264VideoRTPSink->H264or5VideoRTPSink->VideoRTPSink->MultiFramedRTPSink->RTPSink->MediaSink->Medium   //(h264 的createNewRTPSink)
H265VideoRTPSink->H264or5VideoRTPSink->VideoRTPSink->MultiFramedRTPSink->RTPSink->MediaSink->Medium   //(h265 的createNewRTPSink)
SimpleRTPSink->MultiFramedRTPSink->RTPSink->MediaSink->Medium//(ts 的createNewRTPSink)
	
	 
	 
	 
注意
ServerMediaSession中包含ServerMediaSubsession列表。
GenericMediaServer中包含HashTable* fServerMediaSessions; // maps 'stream name' strings to "ServerMediaSession" objects

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

sunxiaopengsun

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值