DSP

live555学习阶段二之二SDP流程(H264)

2019-07-13 18:34发布

LIVE555 采用 标准的DSP 标准作为文件的描述, 其说明在前文《LIVE555阶段一之二SDP协议描述》. 客户端链接进来,请求获取我多媒体资源的数据的描述的时候, live555  采用读取一小段文件分析生成多媒体信息并且传输出去。 void RTSPServer::RTSPClientConnection ::handleCmd_DESCRIBE(char const* urlPreSuffix, char const* urlSuffix, char const* fullRequestStr) handleCmd_DESCRIBE 函数 处理客户端的 “多媒体资源描述信息” 请求函数。

一: 匹配选择已经注册过的多媒体资源。

session = fOurServer.lookupServerMediaSession(urlTotalSuffix);urlTotalSuffix 为 RTSP 链接请求的文件。 根据这个文件的名称,搜索之前注册的多媒体。

二:动态生成多媒体文件的描述信息SDP 

sdpDescription = session->generateSDPDescription(); 那么重点 就是 详细分析 二:动态生成多媒体文件的描述信息SDP  generateSDPDescription 函数 要想获取完整的SDP描述 ,有两种方式 1.必须要先对文件进行解析。 2.直接写死不在动态生成。 live555 采用分析文件的形式。 就必须涉及到SINK 、SourceFrame 类的相关。

2.1 因此 首先要 创建  FramedSource* inputSource。

FramedSource* inputSource = createNewStreamSource(0, estBitrate);

2.2 其次 创建 RTPSink* dummyRTPSink

RTPSink* dummyRTPSink = createNewRTPSink(dummyGroupsock, rtpPayloadType, inputSource);

2.3当 inputSource 和 dummyRTPSink 都创建成功后。 就开始调用 setSDPLinesFromRTPSink函数开始分析。

2.3.1 获取媒体流类型  

char const* mediaType = rtpSink->sdpMediaType();

 2.3.2 获取媒体数据负载类型

unsigned char rtpPayloadType = rtpSink->rtpPayloadType();

2.3.3 获取多媒体类型负载类型描述rtpmap

char* rtpmapLine = rtpSink->rtpmapLine();

2.3.4. 获取多媒体类型起始和结束时间

 char const* rangeLine = rangeSDPLine();

2.3.5. 获取多媒体类型的 a=fmtp: 数据(这里是核心,涉及文件的读取解析)

char const* auxSDPLine = getAuxSDPLine(rtpSink, inputSource);
该函数为基类 OnDemandServerMediaSubsession 中的 定义的虚函数 其调用关系如下
H264视频文件 中则有 H264VideoFileServerMediaSubsession 实现解析功能. 2.3.5.1 启动数据读取解析 这里以后可以改写为 双线程通信的机制 一个进行循环等待 一个进行解析放入共享内存里面。
fDummyRTPSink->startPlaying(*inputSource, afterPlayingDummy, this);
等待FrameSoure 读取解析编码SPS PPS的输出
2.3.5.2 检测等待数据是否解析成功 checkForAuxSDPLine(this);

2.3.6. 数据组合生成最终SDP描述

sprintf(sdpLines, sdpFmt, 那么 getAuxSDPLine其流程如下
则第二节 动态生成多媒体文件的描述信息SDP的的整体流程如下

三:将SDP 描述 作为返回消息的附带内容

snprintf((char*)fResponseBuffer, sizeof fResponseBuffer,     "RTSP/1.0 200 OK CSeq: %s "     "%s"     "Content-Base: %s/ "     "Content-Type: application/sdp "     "Content-Length: %d "     "%s",     fCurrentCSeq,     dateHeader(),     rtspURL,     sdpDescriptionSize,     sdpDescription);   } while (0);

四: 返回客户端 数据

send(fClientOutputSocket, (char const*)fResponseBuffer, strlen((char*)fResponseBuffer), 0);