流媒体Live555学习(二)

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()

重置RTSPClient1、关闭socket2、重置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);

---------------------------------------------------------------------------------------------------------------------------------------------------------

成员变量:

公开

static unsigned responseBufferSize;

 响应字符串的缓冲区大小

私有

portNumBits fTunnelOverHTTPPortNum;

HTTP的传输端口,为0,否则使用HTTP通信

int fInputSocketNum, fOutputSocketNum;

通信socket,一般inputoutput使用同一个socket

netAddressBits fServerAddress;

服务端地址

char* fBaseURL;

初始请求URL

unsigned char fTCPStreamIdCount;

// used for (optional) RTP/TCP

char* fLastSessionId;

 

unsigned fSessionTimeoutParameter;

 // optionally set in response "Session:" headers

char* fResponseBuffer;

服务器回应字符串缓存

unsigned

fResponseBytesAlreadySeen, fResponseBufferBytesLeft;

回应字符串的读取标识,已读数和剩余空间

RequestQueue fRequestsAwaitingConnection, fRequestsAwaitingHTTPTunneling, fRequestsAwaitingResponse;

请求信息队列


——————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————

ServerMediaSession

 

ServerMediaSessionRTSPServer中用于表示一个媒体信息的类,内部会包含该媒体需要的子媒体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数,并将其设置为subSessiontrackNameber

unsignednumSubsessions() const

返回fSubsessionCounter,在该ServerMediaSessionsubSession的数目

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需要的描述信息:fStreamNamefInfoSDPStringfDescriptionSDPStringfMiscSDPLinesfCreationTime

 

成员变量:

ServerMediaSubsession* fSubsessionsHead;

指向subSession列表头

ServerMediaSubsession* fSubsessionsTail;

指向subSesssion列表尾

unsigned fSubsessionCounter;

serverMediaSessionsubSession总数

char* fStreamName;

媒体流名称

char* fInfoSDPString;

i= <info>

char* fDescriptionSDPString;

a=x-qt-text-nam: line

char* fMiscSDPLines;

 

struct timeval fCreationTime;

用于构造sessionID// o= <session id>

unsigned fReferenceCount;

该媒体流被客户端的连接数

Boolean fDeleteWhenUnreferenced;

标识是否已经没有客户端连接从而可以释放

 

ServerMediaSubSession

 

ServerMediaSubSession是一个媒体流中表示子媒体的结构

 

类接口:

unsignedtrackNumber() const

返回表示该subSessionIDfTrackNumber,这个值会在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;

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

 

保护方法:

ServerMediaSubsession(UsageEnvironment&env);

构造函数,什么都没有做;

charconst* rangeSDPLine() const;

返回sdp中的区间信息:"a=range:"

ServerMediaSession* fParentSession;

所属的媒体流ServerMediaSession

netAddressBits fServerAddressForSDP;

服务器地址

portNumBits fPortNumForSDP;

服务器端口

 

私有成员:

ServerMediaSubsession* fNext;

指向下一个subSession,从而形成列表

unsigned fTrackNumber;

serverMediaSession为该subSession指定的id

char const* fTrackId;

id字符串,"track:id"

 


你可能感兴趣的:(流媒体Live555学习(二))