ASessionDescription::parse

    xiaoxiao2021-03-25  65

      安卓N版本ASessionDescription::parse函数原文:

    bool ASessionDescription::parse(const void *data, size_t size) { //先把mTracks和mFormats里的内容清空 mTracks.clear(); mFormats.clear(); //向mTracks里添加一个元素Attribs() //Attribs是类型为KeyedVector<AString,AString>的容器 //向mFormats容器里添加一个元素AString("[root]") //mFormats是类型为Vector<AString>的容器 mTracks.push(Attribs()); mFormats.push(AString("[root]")); //将指定缓冲区里的内容拷贝到desc对象里 AString desc((const char *)data, size); //循环解析拷贝到desc对象里的内容 //内容是按行划分的 size_t i = 0; for (;;) { //从内容的位置i开始查找"\n"的位置 //返回位置i后最先出现的"\n"的位置eolPos ssize_t eolPos = desc.find("\n", i); if (eolPos < 0) { //如果eolPos的值小于0,说明位置i后没有"\n"了 //即到达了结尾,跳出循环 break; } AString line; if ((size_t)eolPos > i && desc.c_str()[eolPos - 1] == '\r') { // We accept both '\n' and '\r\n' line endings, if it's // the latter, strip the '\r' as well. //如果(size_t)eolPos > i,则说明 //desc.c_str()[i,eolPos - 1]是新的一行内容不包括desc.c_str()[eolPos] //因为desc.c_str()[eolPos] == '\n' //如果desc.c_str()[eolPos - 1] == '\r'则将该字符去掉 //只将desc.c_str()[i,eolPos - 1 - 1]里的内容拷贝进line里 line.setTo(desc, i, eolPos - i - 1); } else { line.setTo(desc, i, eolPos - i); } if (line.empty()) { //如果line内容为空 //则迭代进行下一次循环 //将i的位置设置到下一行的首位置 i = eolPos + 1; continue; } if (line.size() < 2 || line.c_str()[1] != '=') { //如果line.size() < 2 或者 line.c_str()[1] != '=' //则说明这是一无效的行 //返回false结束循环 //有效一行的格式是:如"a=*****" return false; } ALOGI("%s", line.c_str()); switch (line.c_str()[0]) { case 'v': { //如果该行内容首字符为'v' //则判断该行内容是否为"v=0" //如果不是则说明该行是一个无效的行返回false if (strcmp(line.c_str(), "v=0")) { return false; } break; } case 'a': case 'b': { //解析该行内容首字符为'a'和'b'的情况 //解析出一对儿key和value AString key, value; //查找key和value的分割符":"的位置colonPos //一般情况下line.str()[0,colonPos-1]为key //line.str()[colonPos]为":" //line.str()[colonPos+1,line.size()-1] ssize_t colonPos = line.find(":", 2); if (colonPos < 0) { //如果colonPos < 0 //说明该行没有key和value的分割符":" //即该行就是key,将line赋值给key key = line; } else { //如果colonPos > 0 //则说明存在key和value的分割符":" //line.str()[colonPos]为":" //将包含key的内容line.str()[0,colonPos-1]赋值到key里 //通过函数key.setTo(line, 0, colonPos)完成 key.setTo(line, 0, colonPos); if (key == "a=fmtp" || key == "a=rtpmap" || key == "a=framesize") { //分析key为 "a=fmtp" "a=rtpmap" "a=framesize"的情况 //从该行内容里从key和value的分割符":"位置colonPos后查找" "的位置 //对应该种情况,从分隔符":"的位置colonPos开始查找" "的位置spacePos ssize_t spacePos = line.find(" ", colonPos + 1); if (spacePos < 0) { //如果spacePos < 0说明分隔符":"后没有" "的位置 //该行是无效的行,返回false return false; } //重新设置key, //此时key为line.strz()[0,spacePos-1] key.setTo(line, 0, spacePos); //将" "的位置赋值给colonPos colonPos = spacePos; } //line.strz()[colonPos + 1,line.size()-1]为value value.setTo(line, colonPos + 1, line.size() - colonPos - 1); } key.trim(); value.trim(); ALOGV("adding '%s' => '%s'", key.c_str(), value.c_str()); //将解析出来的一对儿key和value添加到mTracks后一个元素所表示的容器里 mTracks.editItemAt(mTracks.size() - 1).add(key, value); break; } case 'm': { ALOGV("new section '%s'", AString(line, 2, line.size() - 2).c_str()); //处理该行首字符为'm'的情况 //向mTracks容器添加一个类型为Attribs的元素 //将line.str()[2,line.size() - 1]里的内容添加到mFormats容器里 mTracks.push(Attribs()); mFormats.push(AString(line, 2, line.size() - 2)); break; } default: { //处理该行首字符为其他字符的情况 AString key, value; //从该行查找"="字符的位置 ssize_t equalPos = line.find("="); //line.str()[0,equalPos]为key //line.str()[equalPos+1,line.size() -1]为value key = AString(line, 0, equalPos + 1); value = AString(line, equalPos + 1, line.size() - equalPos - 1); key.trim(); value.trim(); ALOGV("adding '%s' => '%s'", key.c_str(), value.c_str()); mTracks.editItemAt(mTracks.size() - 1).add(key, value); break; } } //迭代解析下一行 i = eolPos + 1; } return true; }

      小结:   ASessionDescription::parse函数的功能就是根据内容格式解析出对应的key和value并用相应的数据结构存储起来。

      给出一个会话例子:   

    Example: C->S: DESCRIBE rtsp://server.example.com/fizzle/foo RTSP/1.0 CSeq: 312 Accept: application/sdp, application/rtsl, application/mheg S->C: RTSP/1.0 200 OK CSeq: 312 Date: 23 Jan 1997 15:35:06 GMT Content-Type: application/sdp Content-Length: 376 v=0 o=mhandley 2890844526 2890842807 IN IP4 126.16.64.4 s=SDP Seminar i=A Seminar on the session description protocol u=http://www.cs.ucl.ac.uk/staff/M.Handley/sdp.03.ps e=mjh@isi.edu (Mark Handley) c=IN IP4 224.2.17.12/127 t=2873397496 2873404696 a=recvonly m=audio 3456 RTP/AVP 0 m=video 2232 RTP/AVP 31 m=whiteboard 32416 UDP WB a=orient:portrait
    转载请注明原文地址: https://ju.6miu.com/read-39448.html

    最新回复(0)