[live555] testRTSPClient.cpp DESCRIBE (后续处理) 二

摘要

DESCRIBE 请求收到返回SDP 就会根据SDP 创建rtp socket

轮询处理handleResponseBytes

在上一篇testRTSPClient中,已经走到

  handleResponseBytes(bytesRead);//处理reponse 数据

主要处理了
1. 解析返回的response 数据
2. 根据返回response, 后续进一步处理(即回调函数continueAfterDESCRIBE() 等)
3. 根据返回response,OK 就会进行下一步的请求发送 (DESCRIBE–>SETUP)

具体code:

void RTSPClient::handleResponseBytes(int newBytesRead) {

    //parse reponse code

    while ((request = fRequestsAwaitingResponse.dequeue()) != NULL) {
        //.... 判断是否是当前request
            if (request->cseq() == cseq) {
              foundRequest = request;
              break;
            }
    }

    //SETUP GET_PARAMETER TEAR_DOWN PLAY 请求reponse 处理 
    //......
    //返回成功回调
    if (responseSuccess) {
        if (responseCode == 200) {
          resultString = numBodyBytes > 0 ? strDup(bodyStart)
          :strDup(publicParamsStr);
        //...
        }
        //在DESCRIBE请求之后就是 continueAfterDESCRIBE回调
        (*foundRequest->handler())(this, resultCode, resultString);
    }

这里的cseq是根据RTSP 服务器返回的会话中提取
foundRequest通过fRequestsAwaitingResponse 队列获取,而在send 第一创建 request的时候,会放入队列中

unsigned RTSPClient::sendRequest(RequestRecord* request) {
//...
fRequestsAwaitingResponse.enqueue(request);
}

可以看出来RequestQueue 是一个单链表

void RTSPClient::RequestQueue::enqueue(RequestRecord* request) {
  if (fTail == NULL) {
    fHead = request;
  } else {
    fTail->next() = request;
  }
  fTail = request;
}

回调continueAfterDESCRIBE 函数

  1. 根据返回的DESCRIBE消息 ,本地创建MediaSession
  2. 发起SETUP请求
void continueAfterDESCRIBE(RTSPClient* rtspClient, int resultCode, char* resultString) {
  do {
    UsageEnvironment& env = rtspClient->envir(); // alias
    StreamClientState& scs = ((ourRTSPClient*)rtspClient)->scs; // alias
    char* const sdpDescription = resultString;

    // Create a media session object from this SDP description:
    scs.session = MediaSession::createNew(env, sdpDescription);

    // SETUP请求发起
    scs.iter = new MediaSubsessionIterator(*scs.session);
    setupNextSubsession(rtspClient);
    return;
  } while (0);

}

创建MediaSession

创建MediaSession,作用就是解析sdpDescription 消息,获取信息
用wireshark解析如下图
sdp
wireshark 解析log地址
上面标记了MIME Type H264 告诉客户端解码用H264

Boolean MediaSession::initializeWithSDP(char const* sdpDescription) {
      //....
          if (subsession->parseSDPAttribute_rtpmap(sdpLine)) continue;
    //....解析获取解码方式H264
}

setupNextSubsession 做了两件事情

  1. 创建socket 发送报文 即RTP
  2. 发起SETUP请求

void setupNextSubsession(RTSPClient* rtspClient) {
  UsageEnvironment& env = rtspClient->envir(); // alias
  StreamClientState& scs = ((ourRTSPClient*)rtspClient)->scs; // alias

  scs.subsession = scs.iter->next();
  if (scs.subsession != NULL) {
    if (!scs.subsession->initiate()) {//创建RTP socket
    //....
    } else {
      // Continue setting up this subsession, by sending a RTSP "SETUP" command:
      rtspClient->sendSetupCommand(*scs.subsession, continueAfterSETUP
      , False, REQUEST_STREAMING_OVER_TCP); 
    }
    return;
  }
}

创建 RTP socket
scs.subsession->initiate()

Boolean MediaSubsession::initiate(int useSpecialRTPoffset) {
    //创建RTP socket
    fRTPSocket = new Groupsock(env(), tempAddr, fSourceFilterAddr, fClientPortNum);
    //创建 RTCP socket
    fRTCPSocket = new Groupsock(env(), tempAddr, fSourceFilterAddr, rtcpPortNum);

    // Try to use a big receive buffer for RTP - at least 0.1 second of
    // specified bandwidth and at least 50 KB
    unsigned rtpBufSize = fBandwidth * 25 / 2; // 1 kbps * 0.1 s = 12.5 bytes
    if (rtpBufSize < 50 * 1024){
      rtpBufSize = 50 * 1024;
      increaseReceiveBufferTo(env(), fRTPSocket->socketNum(), rtpBufSize);
    }


    // Create "fRTPSource" and "fReadSource":
    if (!createSourceObjects(useSpecialRTPoffset)) break;
}

需要根据解析的解码方式创建不同的解码

Boolean MediaSubsession::createSourceObjects(int useSpecialRTPoffset) {

    if (strcmp(fCodecName, "H264") == 0) {
        fReadSource = fRTPSource
          = H264VideoRTPSource::createNew(env(), fRTPSocket,//根据socket 作为数据入口
                          fRTPPayloadFormat,
                          fRTPTimestampFrequency);
    }

}

然后就是SETUP发起流程


  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值