日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

RTSP学习笔记(2)live555

發布時間:2025/3/17 编程问答 19 豆豆
生活随笔 收集整理的這篇文章主要介紹了 RTSP学习笔记(2)live555 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

為什么80%的碼農都做不了架構師?>>> ??

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

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

成員變量:

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

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

?

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;

/

轉載于:https://my.oschina.net/seanx/blog/619623

總結

以上是生活随笔為你收集整理的RTSP学习笔记(2)live555的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。