• Live555研究之三 RTSP Server处理请求


    RTSP Server会不断用select查询是否有socket连接,如果有则在(*handler->handlerProc)(handler->clientData, resultConditionSet) 进行处理。
    RTSPServer::RTSPClientConnection::incomingRequestHandler1()函数中,从socket读取客户端请求信息,然后解析RTSP命令,在变量fRequestBuffer中保存了RTSP请求信息:
    例如:
    OPTIONS rtsp://192.168.2.100:8554/3.ts RTSP/1.0
    CSeq: 2
    User-Agent: LibVLC/2.0.7 (LIVE555 Streaming Media v2012.12.18)

    void RTSPServer::RTSPClientConnection::incomingRequestHandler1() {
      struct sockaddr_in dummy;
      // 'from' address, meaningless in this case  
      int bytesRead = readSocket(envir(), fClientInputSocket, &fRequestBuffer[fRequestBytesAlreadySeen], fRequestBufferBytesLeft, dummy);
    handleRequestBytes(bytesRead);
    }

    Live555首先预解析请求字符串,判断请求是否符合标准。目前支持解析以下几种命令:
    OPTIONS
    GET_PARAMETER
    SET_PARAMETER
    DESCRIBE
    SETUP
    TEARDOWN
    PLAY
    PAUSE

    然后发送响应给客户端:
    例如:

    RTSP/1.0 200 OK
    CSeq: 2
    Date: Wed, Jun 19 2013 16:05:27 GMT
    Public: OPTIONS, DESCRIBE, SETUP, TEARDOWN, PLAY, PAUSE, GET_PARAMETER, SET_PARAMETER


    如果使用PLAY请求命令,Live555将调用
    void RTSPServer::RTSPClientSession
    ::handleCmd_PLAY(
      RTSPServer::RTSPClientConnection* ourClientConnection,
      ServerMediaSubsession*  subsession,
      char const* fullRequestStr)函数进行处理。

    请求数据如下:

    PLAY rtsp://192.168.2.100:8554/3.ts/ RTSP/1.0
    CSeq: 5
    User-Agent: LibVLC/2.0.7 (LIVE555 Streaming Media v2012.12.18)
    Session: E0406EAB
    Range: npt=0.000-

    首先定位流的位置,因为调试时使用的是ts流,
    void MPEG2TransportFileServerMediaSubsession
    ::seekStream(
      unsigned clientSessionId,
      void* streamToken,
      double& seekNPT,
      double streamDuration,
      u_int64_t& numBytes);

    之后就是开始播放流,

    fStreamStates[i].subsession->startStream(fOurSessionId,
       fStreamStates[i].streamToken,    
       (TaskFunc*)noteClientLiveness, this,
       rtpSeqNum, rtpTimestamp,
        RTSPServer::RTSPClientConnection::handleAlternativeRequestByte,
        ourClientConnection);

    该函数内会调用void OnDemandServerMediaSubsession::startStream(),继而调用StreamState::startPlaying()
    void OnDemandServerMediaSubsession::startStream(unsigned clientSessionId,
       void* streamToken,
        TaskFunc* rtcpRRHandler,
        void* rtcpRRHandlerClientData,
            unsigned short& rtpSeqNum,
        unsigned& rtpTimestamp,
        ServerRequestAlternativeByteHandler* serverRequestAlternativeByteHandler,
       
    void* serverRequestAlternativeByteHandlerClientData);


    在StreamState::startPlaying()中会创建一个RTCPInstance实例,并把客户端地址和端口添加到RTP和RTCPgroupsocks目的地中。再调用RTPSink::startPlaying()开始推送数据。

  • 相关阅读:
    oracleDBA-D4
    oracleDBA-D3
    oracleDBA-D2
    大数据架构学习记录
    UBUNTU 安装最新版 nodejs
    datax 单条记录超过大小限制,当前限制为:67108864
    将anaconda中已存在的虚拟环境增加到jupyterlab
    jupyter 启动python3 内核 总是出现错误 ImportError: cannot import name 'create_prompt_application'
    CDH 本地hadoop支持读写 AWS S3a
    hadoop 集群集成jupyterhub 出现的问题
  • 原文地址:https://www.cnblogs.com/ityujian/p/3145276.html
Copyright © 2020-2023  润新知