RTSPClient
RTSPClient 是RTSP协议的客户端实现,用于发送RTSP请求命令
类接口:
static RTSPClient* createNew()
用于外部创建RTSPClient实例的方法,将构造方法进行了隐藏(protect);
unsigned sendXXXXCommand()
发送RTSP请求,会传入回调函数responseHandler;
responseHandler是类内部定义的一个函数指针,统一回调的格式
typedef void (responseHandler)(RTSPClient* rtspClient, int resultCode, char* resultString);
int socketNum() const
返回用于连接的socket;
staticBoolean lookupByName(UsageEnvironment& env,char const* sourceName,
RTSPClient*& resultClient)
查找sourceName指定的RTSPClient
staticBoolean parseRTSPURL(UsageEnvironment& env, char const* url,
char*& username, char*& password,NetAddress& address, portNumBits& portNum, char const** urlSuffix =NULL)
解析输入的RTSPURL,主要用于获取服务器地址NetAddress& address和端口号portNumBits& portNum,还会返回urlSuffix的指针,标识媒体名等信息;
voidsetUserAgentString(char const* userAgentName)
指定RTSP回应消息中的"User-Agent: %s\r\n"字段,类内部保存了fUserAgentHeaderStr,会将其内容替换为userAgentName;
charconst* url() const
返回初始请求服务器的url信息,即rtsp://…//...;就是parseRTSPURL中的URL,保存在fBaseURL中;
保护方法:
voidreset()
重置RTSPClient,1、关闭socket;2、重置responseBuffer的指示变量;3、清除分BaseURL等
voidsetBaseURL(char const* url)
设置请求的URL信息fBaseURL;
virtualunsigned sendRequest(RequestRecord* request)
发送请求,请求统一封装在RequestRecord;
------------------------------------------------------------------------------------------------------------------------------------------------------
内部类
RequestRecord 公开
该类封装了请求命令,只用来保存请求的信息,如命令名称、回调函数等;
RequestRecord(unsignedcseq, char const* commandName, responseHandler* handler,
MediaSession*session = NULL, MediaSubsession* subsession = NULL,
u_int32_t booleanFlags = 0,
doublestart = 0.0f, double end = -1.0f, float scale = 1.0f,
charconst* contentStr = NULL);
所有信息都在初始化时传入,之后类为每一个信息都提供了访问方法
RequestQueue 私有
该类定义了RequestRecord的队列,可以保存请求信息,还提供了一些工具方法如下
voidputAtHead(RequestRecord* request); // "request" must not be NULL
RequestRecord*findByCSeq(unsigned cseq);
---------------------------------------------------------------------------------------------------------------------------------------------------------
成员变量:
——————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
ServerMediaSession
ServerMediaSession是RTSPServer中用于表示一个媒体信息的类,内部会包含该媒体需要的子媒体ServerMediaSubsession,例如一个MP4文件既有视频也有音频,那这个ServerMediaSession就需要包含表示视频的subSession和音频的subSession。
类接口:
staticServerMediaSession* createNew(UsageEnvironment& env,
char const* streamName = NULL,
char const* info = NULL,
char const* description = NULL,
Boolean isSSM = False,
char const* miscSDPLines = NULL);
外部创建ServerMediaSession实例的方法,在Live555中对类的实例化大多采用了这种方式,在方法内部调用类的构造函数,还不知道这么做有什么用意,为什么不直接用构造函数?
staticBoolean lookupByName(UsageEnvironment& env,
char const*mediumName,
ServerMediaSession*& resultSession);
查找mediaName对应的serverMediaSession,内部是通过Medium::lookupByName(env, mediumName, medium)这个静态方法实现的,什么时候添加的?
char*generateSDPDescription();
生成媒体的SDP信息,分配的字符串内存由调用者负责释放;
关键部分
for each serverMediaSubSession {subSesssion->sdpLines()};// 产生各个子媒体的sdp描述
char const* streamName() const;
返回fStreamName,媒体名
BooleanaddSubsession(ServerMediaSubsession* subsession);
添加subSession,在ServerMediaSession内有头尾subSession的指针,可以形成单列表,
fSubsessionsTail= subsession;
subsession->fParentSession= this;
subsession->fTrackNumber =++fSubsessionCounter; // 增加count数,并将其设置为subSession的trackNameber
unsignednumSubsessions() const
返回fSubsessionCounter,在该ServerMediaSession总subSession的数目
unsignedreferenceCount() const { return fReferenceCount; }
voidincrementReferenceCount() { ++fReferenceCount; }
voiddecrementReferenceCount() { if (fReferenceCount > 0) --fReferenceCount; }
Boolean& deleteWhenUnreferenced() {return fDeleteWhenUnreferenced; } // 指示是否已经没有了引用而可以析构了
void deleteAllSubsessions(); //移除所有subSession
保护方法:
ServerMediaSession(UsageEnvironment&env, char const* streamName,
char const* info, char const* description,
Boolean isSSM, char const* miscSDPLines);
构造方法,主要初始化一些sdp需要的描述信息:fStreamName,fInfoSDPString,fDescriptionSDPString,fMiscSDPLines,fCreationTime
成员变量:
ServerMediaSubSession
ServerMediaSubSession是一个媒体流中表示子媒体的结构
类接口:
unsignedtrackNumber() const
返回表示该subSession的ID:fTrackNumber,这个值会在ServerMediaSession添加subSession时赋予;
charconst* trackId();
返回trackID字符串fTrackId:("track%d",fTrackNumber)
virtualchar const* sdpLines() = 0;
纯虚函数,需子类具体实现,返回sdp描述中的媒体信息,如
/*
m=video 0 RTP/AVP 96
c=IN IP4 0.0.0.0
b=AS:500
a=rtpmap:96 H264/90000
a=fmtp:96 packetization-mode=1;profile-level-id=4D4033;
sprop-parameter-sets=Z01AM5p0FidCAAADAAIAAAMAZR4wZUA=,aO48gA==
a=control:track1
*/
virtualvoid getStreamParameters(unsigned clientSessionId, // in
netAddressBits clientAddress, // in
Port const& clientRTPPort, // in
Port const& clientRTCPPort, // in
int tcpSocketNum, // in (-1 means use UDP,not TCP)
unsigned char rtpChannelId, // in (used ifTCP)
unsigned char rtcpChannelId, // in (used ifTCP)
netAddressBits& destinationAddress, //in out
u_int8_t& destinationTTL, // in out
Boolean& isMulticast, // out
Port& serverRTPPort, // out
Port& serverRTCPPort, // out
void*& streamToken // out
) = 0;
纯虚函数,返回各种流参数;
virtualvoid startStream(unsigned clientSessionId, void* streamToken,
TaskFunc* rtcpRRHandler,
void* rtcpRRHandlerClientData,
unsigned short& rtpSeqNum,
unsigned& rtpTimestamp,
ServerRequestAlternativeByteHandler*serverRequestAlternativeByteHandler,
void*serverRequestAlternativeByteHandlerClientData) = 0;
纯虚函数,启动流传输,即开始播放;
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
下面这些函数都只定义了接口,没有做具体实现,子类可以根据情况完成
virtualvoid pauseStream(unsigned clientSessionId, void* streamToken);
virtual void seekStream(unsigned clientSessionId, void* streamToken,double& seekNPT, double streamDuration,u_int64_t& numBytes);
// This routine is used to seek byrelative (i.e., NPT) time.
// "streamDuration", if >0.0,specifies how much data to stream, past "seekNPT". (If <=0.0, all remaining data isstreamed.)
// "numBytes" returns the size(in bytes) of the data to be streamed, or 0 if unknown or unlimited.
virtualvoid seekStream(unsigned clientSessionId, void* streamToken, char*&absStart, char*& absEnd);
// This routine is used to seek by'absolute' time.
// "absStart" should be a stringof the form "YYYYMMDDTHHMMSSZ" or"YYYYMMDDTHHMMSS.<frac>Z".
// "absEnd" should be eitherNULL (for no end time), or a string of the same form as "absStart".
// These strings may be modified in-place,or can be reassigned to a newly-allocated value (after delete[]ing theoriginal).
virtualvoid setStreamScale(unsigned clientSessionId, void* streamToken, float scale);
virtualFramedSource* getStreamSource(void* streamToken);
virtualvoid deleteStream(unsigned clientSessionId, void*& streamToken);
virtualvoid testScaleFactor(float& scale); // sets "scale" to the actualsupported scale
virtualfloat duration() const;
// returns 0 for an unbounded session (thedefault)
// returns > 0 for a bounded session
virtualvoid getAbsoluteTimeRange(char*& absStartTime, char*& absEndTime)const;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////