Rtsp流媒体服务器小结Word格式.docx

上传人:b****2 文档编号:5588684 上传时间:2023-05-05 格式:DOCX 页数:20 大小:46.77KB
下载 相关 举报
Rtsp流媒体服务器小结Word格式.docx_第1页
第1页 / 共20页
Rtsp流媒体服务器小结Word格式.docx_第2页
第2页 / 共20页
Rtsp流媒体服务器小结Word格式.docx_第3页
第3页 / 共20页
Rtsp流媒体服务器小结Word格式.docx_第4页
第4页 / 共20页
Rtsp流媒体服务器小结Word格式.docx_第5页
第5页 / 共20页
Rtsp流媒体服务器小结Word格式.docx_第6页
第6页 / 共20页
Rtsp流媒体服务器小结Word格式.docx_第7页
第7页 / 共20页
Rtsp流媒体服务器小结Word格式.docx_第8页
第8页 / 共20页
Rtsp流媒体服务器小结Word格式.docx_第9页
第9页 / 共20页
Rtsp流媒体服务器小结Word格式.docx_第10页
第10页 / 共20页
Rtsp流媒体服务器小结Word格式.docx_第11页
第11页 / 共20页
Rtsp流媒体服务器小结Word格式.docx_第12页
第12页 / 共20页
Rtsp流媒体服务器小结Word格式.docx_第13页
第13页 / 共20页
Rtsp流媒体服务器小结Word格式.docx_第14页
第14页 / 共20页
Rtsp流媒体服务器小结Word格式.docx_第15页
第15页 / 共20页
Rtsp流媒体服务器小结Word格式.docx_第16页
第16页 / 共20页
Rtsp流媒体服务器小结Word格式.docx_第17页
第17页 / 共20页
Rtsp流媒体服务器小结Word格式.docx_第18页
第18页 / 共20页
Rtsp流媒体服务器小结Word格式.docx_第19页
第19页 / 共20页
Rtsp流媒体服务器小结Word格式.docx_第20页
第20页 / 共20页
亲,该文档总共20页,全部预览完了,如果喜欢就下载吧!
下载资源
资源描述

Rtsp流媒体服务器小结Word格式.docx

《Rtsp流媒体服务器小结Word格式.docx》由会员分享,可在线阅读,更多相关《Rtsp流媒体服务器小结Word格式.docx(20页珍藏版)》请在冰点文库上搜索。

Rtsp流媒体服务器小结Word格式.docx

1.DarwinStreamingServer支持包括Windows,Linux以及Solaris在内的多种操作系统平台。

我们知道,Windows和Unix(或Unix-like)操作系统之间无论从内核还是编程接口上都有着本质的区别,即使是Linux和Solaris,在编程接口上也大为不同。

为此,DSS开发了多个用于处理时间、临界区、信号量、事件、互斥量和线程等操作系统相关的类,这些类为上层提供了统一的使用接口,但在内部却需要针对不同的操作系统采用不同的方法实现。

OSCond状态变量的基本功能和操作,OSMutex互斥量的基本功能和操作,

OSThread线程类,OSFileSource简单文件类,OSQueue队列类,

OSHashTable哈希表类,OSHeap堆类,OSRef参考引用类。

2.Task类,用来处理事件通知机制。

在Task.h/cpp文件中,定义了三个主要的类,分别是:

任务线程池类(TaskThreadPoolClass)、任务线程类(TaskThreadClass)以及任务类(TaskClass)。

每个Task对象有两个主要的方法:

Signal和Run。

当服务器希望发送一个事件给某个Task对象时,就会调用Signal()方法;

而Run()方法是在Task对象获得处理该事件的时间片后运行的,服务器中的大部分工作都是在不同Task对象的Run()函数中进行的。

每个Task对象的目标就是利用很小的且不会阻塞的时间片完成服务器指定某个工作。

任务线程类(TaskThread)是OSThread类的一个子类,代表专门用于运行任务类的一个线程。

在每个任务线程对象内部都有一个OSQueue_Blocking类型的任务队列,存储该线程需要执行的任务。

服务器调用一个任务的Signal函数,实际上就是将该任务加入到某个任务线程类的任务队列中去。

另外,为了统一管理这些任务线程,DSS还开发了任务线程池类,该类负责生成、删除以及维护内部的任务线程列表。

这种由事件去触发任务的概念已经被集成到了DSS的各个子系统中。

例如,在DSS中经常将一个Task对象和一个Socket对象关联在一起,当Socket对象收到事件(通过select()函数),相对应的Task对象就会被传信(通过Signal()函数);

而包含着处理代码的Run()函数就将在某个任务线程中运行。

3.Socket类

DSS中的Socket类一般都采用异步模式的(即非阻塞的),而且能够向对应的Task对象传信(Signal),Socket类中具有代表性的类是:

EventContext、EventThread、Socket、UDPSocket、TCPSocket以及TCPListenerSocket等等。

在eventcontext.h/.cpp文件中,定义了两个类:

EventContext类和EventThread类。

EventContext提供了检测Unix式的文件描述符(Socket就是一种文件描述符)产生的事件(通常是EV_RE或EV_WR)的能力,同时还可以传信指定的任务。

EventThread类是OSThread类的子类,它本身很简单,只是重载了OSThread的纯虚函数Entry(),用以监控所有的Socket端口是否有数据到来。

EventContext对象负责维护指定的描述符,其主要函数包括InitNonBlocking、CleanUp和RequestEvent等。

其中InitNonBlocking函数调用SocketAPIioctlsocket将用户指定的描述符设置为异步,CleanUp函数用于关闭该描述符;

另外,用户函数申请对该描述符中某些事件的监听RequestEvent通过.

SocketClass、UDPSocketClass和TCPSocketClass三个类都是EventContext的子类,它们封装了TCP和UDP的部分实现,同时扩展了EventContext中的事件,但都没有改变其运行机制。

TCPListenerSocket用于监听TCP端口,当一个新连接请求到达后,该类将赋予这个新连接一个Socket对象和一个Task对象的配对。

二.服务器模块:

处理网络和协议。

主要有3个子系统:

RTSP子系统,RTP子系统以及公共服务子系统。

服务器内核:

这个子系统中的类都有一个QTSS前缀。

QTSSServer负责处理服务器的启动和关闭。

QTSSServerInterface负责保存服务器全局变量,以及收集服务器的各种统计信息。

QTSSPrefs是存储服务器偏好设定的地方。

QTSSModule,QTSSModuleInterface,和QTSSCallbacks类的唯一目的就是支持QTSS的模块API。

(1)RTSP子系统

负责解析和处理RTSP请求,以及实现QTSS模块API的RTSP部分。

其中的几个类直接对应QTSSAPI的一些元素(例如,RTSPRequestInterface类就是对应QTSS_RTSPRequestObject对象)。

每一个RTSP/TCP连接都对应一个RTSP的session.主要的类有RTSPSession,RTSPRequest,RTSPResponseStream和RTSPRequestStream.

(2)RTP子系统

负责媒体数据包的发送,根据RTCP的反馈进行服务质量控制。

主要的类有RTPSession,RTPStream和RTCPTask.

(3)公共服务子系统

负责服务器的启动/关闭,初始化参数设置以及为Module机制,跨平台的多线程和事件机制等提供支持。

DSS提供了一种称为Module的二次开发接口。

使用这个开发接口,我们可以自由扩张服务器的功能。

DSS定义了一个TCPListenerSocket类的子类RTSPListenerSocket,用于监听RTSP连接请求。

RTSPListenerSocket类做的唯一一件事就是重载了GetSessionTask函数,当客户的连接请求到达后,它创建了一个Socket对象和RTSPSession对象的配对。

RTSPSession对象是Task类的子类,是专门用于处理RTSP请求的任务类。

当client端发出Play请求时,server端的RTSPListenerSocket监听到这个请求,Run创建一个RTSPSession,这个RTSPSession被加入到任务队列中,当时间片到达时,TaskThread线程就会调用RTSPSession对象的函数,在Run函数中,维护一个RTSPSession状态机,对客户的RTSP请求做出不同的处理。

DSS,)kProcessingRequest(进入请求处理状态RTSPSession请求分析完成后,

会调用注册了“请求处理任务”(QTSS_RTSTRequest_Role)的module,而QTSSFileModule就是这样一个Module。

QTSSFileModule定义了一个分发函数QTSSFileModuleDispatch,它根据传入的任务类别和任务参数调用相应的函数。

此时传入的任务是QTSS_RTSTRequest_Role,相应的处理函数是ProcessRTSPRequest,该函数根据传入的RTSPMethod调用相应的处理函数,此时传入的method是play,所以调用函数DoPlay。

IdleTaskThread,它的Entry中不停的超时等待,查看它队列中的task是否到期,是则调用该task->

signal.

IdleTask的SetIdleTimer()里面调用IdleTaskThread->

SetIdleTimer()把该task加入它的fIdleHeap.

程序的数据流程为四部分,就是:

1,task。

而Run()方法是在Task对象获得处理该事件的时间片后运行的,应用可以通过继承Task并重写Run()方法实现自己的任务。

2,EventContext事件的触发者,当事件发生时,调用Task:

:

signal().

3,TaskThread,任务的驱动线程,对一个或者多个Task进行调度,通过调用

Task:

run()处理事件.

4,EventThread,EventContext的驱动线程,可以处理多个EventContext,发生事件时调用EventContext:

process_event(),后者将调用Task:

Signal()

流程:

注册事件。

EventContextClient,或者Task的子类向1内。

Pool的EventThread将事件放入EventContext,2.

3,EventThread调用select等待多个事件中任一个触发。

4,事件触发以后,EventThread调用EventContext:

ProcessEvent()。

5,调用Task:

signal()。

6,Task:

signal()将task放入TaskThread的队列。

7,TaskThread调度相应的Task,执行其Run()方法。

它的具体实现在各个Module中定义。

DSS的基本功能单元称为模块(module),每一个模块都是处理某一类事件的功能集合。

例如QTSSAcessModule就是鉴权授权事件的主要处理模块,类似于桌面窗口的事件处理中的事件,DSS服务器核心处理RTSP请求,定义了若干角色(role),一个角色就是一项任务,一个模块可以注册若干个角色,表示这个模块可以处理这些注册的任务。

比如一个模块注册了QTSS_RSTPPreProcess_Role,则可以调用这个Module来预处理RSTP请求。

根据不同的任务,服务器会传递不同的对象给模块,这些对象中包含有为完成这个任务所包含的一系列数据以及为向服务器传递信息而存在的数据结构。

Darwinstreamingserver的媒体存储格式hinttrack格式以及被ISO,ISMA等标准组织采纳并成为正式标准。

Hinttrack是Darwinstreamingserver的扩展,通过在媒体文件中增加hinttrack轨道,存放了一些预先生成好的媒体描述信息(SDP格式)和媒体数据打包的索引信息。

通过ISMA传输协议进行传输时,可以直接根据数据打包索引信息来打包发送,不需要对信息进行重复的分析格式组装数据包的处理过程。

普通文件可以通过一些工具添加hinttrack属性。

开源的工具有mpeg4ip,mp4info.

数据处理RTSP

Filter当RTSPRole”对封包资料做某些改变等前置处理。

首先经由“RTSPFilter

RTSP完成,开始进行对该请求封包的分析以取得各种参数并建立一个Role主要负责处理此一请求所建立的session及一个Clientsession.RTSPsession则负责串流传送阶段的维护工作。

回应。

ClientsessionRTSP连线阶段的请求/

对”对RTSP对该请求分析完毕后,server呼叫各模块中的”RTSPRouteRole象进行参数修改和设定。

他可以改变文件的处理目录。

以RTSP封包中的哪一种类型,”判断该请求属于接着呼叫”PreprocessorRole则将其若无法判别属于哪一类型,便把该请求传送到对应的函数处理此一请求,”中PreprocessorRole,RTSPRequestRole传送到””此一角色处理所有在”未定义的类型。

最后,来到“PostprocessorRole”,此角色负责统计的工作,例如存取记录等。

在处理”PreporcessorRole”或是“RTSPRequestRole”中的各模块时,可能会产生串流媒体资料。

需要产生媒体资料时,程式会呼叫Clientsession中的“QTSS_Play”物件,此物件会触发在“RTPSendPacketsRole”中的各个模块,同时进入RTPsubsystem中。

RTPsubsystem:

串流控制两部份。

在封包传送封包传送及RTCPRTPRTPsubsystem主要包括”中经由呼叫“QTSS_Write方面,“RTPSendPacketsRole”在RTPsession

每送一次封包后,把媒体资料传送到客户端。

在传送过程中,“QTSS_WriteV”或”传送封包。

在串RoleRTPSendPacketsServer等待一个时间值再继续呼叫”封包属于哪一种RTCPRTCP封包时会先判定此流控制方面,当Server接收到SR(Sourcedescription),RFC1889中定义了五种RTCP封包,分別是:

封包,items)include,DescriptionRR(Receiverdescription),SDES(SourceItems,会呼。

根据封包的种类,BYEServer及specificAPP(Applicationfunctions)RTCPProcessRole叫“”中相应的模块进行处理。

一个clientSession对应多个rtpstream.

passingAuthentication洠慥獮尠youareavaliduserofthesystem.Itdoesnotmeanyouhave

accesstotherequestedfile.Authorizationistheotherhalf,whichistheprocessofallowingthe

useraccesstotherequestedcontent.

rtspSession的流程:

当client端发出Play请求时,server端的RTSPListenerSocket监听到这个请求,Run在GetSessionTask()函数中创建一个RTSPSession,这个RTSPSession被加入到任务队列中,当signal通知数据到达时,TaskThread线程就会调用RTSPSession对象的函数,在Run函数中,维护一个RTSPSession状态机,对客户的RTSP请求做出不同的处理。

rtspSession的run函数中,

casekReadingFirstRequest:

initializedvalued

fInputStream.ReadRequest()读取数据

if(err==QTSS_RequestArrived)

fState=kHTTPFilteringRequest;

casekHTTPFilteringRequest:

fState=kHaveNonTunnelMessage;

casekReadingRequest:

if((err=fInputStream.ReadRequest())==QTSS_NoErr)…

casekHaveNonTunnelMessage:

fRequest=NEWRTSPRequest(this);

fState=kFilteringRequest;

casekFilteringRequest:

this->

SetupRequest();

//setuprtpSession

RTSPRequest:

Parse()

if(fRTPSession==NULL)

theErr=this->

CreateNewRTPSession(theMap);

fState=kRoutingRequest;

casekRoutingRequest:

if(fRequest->

SkipAuthorization())

fState=kPreprocessingRequest;

casekPreprocessingRequest:

theModule=QTSServerInterface:

GetModule

(QTSSModule:

kRTSPPreProcessorRole,fCurrentModule);

(void)theModule->

CallDispatch

(QTSS_RTSPPreProcessor_Role,&

fRoleParams);

fModuleState.isGlobalLocked=false;

在reflectorModule模块中ProcessRTSPRequest()处理

if(*theMethod==qtssAnnounceMethod)

returnDoAnnounce(inParams);

if(*theMethod==qtssDescribeMethod)

returnDoDescribe(inParams);

if(*theMethod==qtssSetupMethod)

returnDoSetup(inParams);

caseqtssPlayMethod:

returnDoPlay(inParams,(*theOutput)->

GetReflectorSession());

fState=kProcessingRequest;

if(fRequest->

HasResponseBeenSent())

{

fState=kPostProcessingRequest;

break;

}

casekPostProcessingRequest:

fState=kSendingResponse;

casekSendingResponse:

fState=kCleaningUp;

casekCleaningUp:

CleanupRequest();

fState=kReadingRequest;

在client启动播放时,先建立rtspSession,然后进入run(),

读了一个请求后,调用setupRequest,然后,clearupRequest.循环直到return出run()的while(true)函数。

在setupRequest的FindRTPSession中,会去给fRTPSession赋值。

所以在cleanupRequest中把它置为NULL。

三.关键模块分析

直播模块结构分析:

1.ReflectorSocket:

publicIdleTask,publicUDPSocket

GetIncomingData()负责接收数据

ProcessPacket(),负责把数据包填入ReflectorSender的OSQueue。

ReflectorSocketPool:

UDPSocketPair*ReflectorSocketPool:

ConstructUDPSocketPair()

returnNEWUDPSocketPair

(NEWReflectorSocket(),NEWReflectorSocket());

}

ReflectorSender:

publicUDPDemuxerTask

ReflectPackets()从它的ReflectorStream中找到ReflectorOutput,

调用SendPacketsToOutput(),里面调用WritePacket()

ReflectorOutput*theOutput=

fStream->

fOutputArray[bucketIndex][bucketMemberIndex];

classRTPSessionOutput:

publicReflectorOutput

RTPSessionOutput:

WritePacket()

{

由它的RTPSessionfClientSession找出对应的RTPStream,

RTPStream的fCookieAttrID=sStreamCookieAttr属性记录的是它对应

的reflectorStream.

判断该rtpStream对应的reflectorStream是否就是调用方的这个fstream.

QTSS_Write(*theStreamPt

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 表格模板 > 合同协议

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2