VLC 使用live555 接收数据

     对 http://blog.csdn.net/jack_incredible/article/details/7593492 略加整理和加工而成。

     下面以VLC使用live555作为数据接收端为例,讲述如何建立连接,并传递数据:


 1.  建立RTSP连接,其中可能需要账户和密码认证:

   live555.cpp/Open() -> Connect() ->

  {
    (1) RTSPClient.cpp/RTSPClient::sendOptionsCmd() -> BasicTaskScheduler0.cpp/BasicTaskScheduler0::doEventLoop() -> BasicTaskScheduler.cpp/BasicTaskScheduler::SingleStep() -> RTSPClient.cpp/RTSPClient::incomingDataHandler() -> RTSPClient()/RTSPClient::incomingDataHandler1() -> GroupsockHelper.cpp/readSocket()
   (2) RTSPClient.cpp/RTSPClient::describeWithPassword() -> RTSPClient::describeURL() -> BasicTaskScheduler0.cpp/BasicTaskScheduler0::doEventLoop() -> BasicTaskScheduler.cpp/BasicTaskScheduler::SingleStep() -> RTSPClient.cpp/RTSPClient::incomingDataHandler() -> RTSPClient()/RTSPClient::incomingDataHandler1() -> GroupsockHelper.cpp/readSocket()
 
   }

 2.  建立RTP和RTCP的Socket连接
    live555.cpp/Open() -> SessionsSetup() -> MediaSubsession.cpp/MediaSubsession::initiate() ->
   {
   (1) Groupsock.cpp/Groupsock() -> GroupsockHelper.cpp/ourIPAddress() -> writeSocket() -> sendto()!!!
   (2) RTCPInstance::createNew() -> RTCPInstance::RTCPInstance() ->
           { 
             (1)RTPInterface::startNetworkReading()
            (2)RTCPInstance::onExpire() -> RTCPInstance::onExpire1() -> rtcp_from_spec.c/OnExpire() -> RTCP.cpp/RTCPInstance::SendRTCPReport() -> RTCPInstance::sendBuiltPacket() -> RTCPInstance::sendBuiltPacket()-> RTPInterface.cpp/RTPInterface::sendPacket() -> Groupsock.cpp/Groupsock::output() -> OutputSocket::write() -> GroupsockHelper.cpp/writeSocket() -> sendto()!!!
         }
    }

    live555.cpp/Open() -> SessionsSetup() -> RTSPClient.cpp/RTSPClient::setupMediaSubsession()"发起建立连接的请求(实际上前面一步的send已经发出,这里是接收响应信息)“ ->
  {
        (1)   ...(readSocket()之类的函数???)
        (2)  BasicTaskScheduler::SingleStep() -> RTCP.cpp/RTCPInstance::incomingReportHandler1() -> RTCPInstance::incomingReportHandler1() -> RTPInterface.cpp/RTPInterface::handleRead() -> Groupsock.cpp/Groupsock::handleRead() -> GroupsockHelper.cpp/readSocket()
    }

3. 接收和读取数据到Reorder buffer然后从中提取packet,送到decoder解码

    /*****************Demux*************************/
 threads.c/thread_entry() -> input.c/Run() -> MainLoop() -> MainLoopDemux() -> demux.h/demux_Demux() -> live555.cpp/"pf"Demux() -> 
 {
      (1) FrameSource.cpp/getNextFrame()"第4个实参类型是live_track_t* afterGettingClientData,它的实际意义是变量p_sys->track[i],即第i个轨道的数据buffer地址,将它赋值给FrameSource类里的成员变量fAfterGettingClientData,第1个参数是p_sys->track[i]的    p_buffer地址,把这个地址告诉FrameSource类成员变量To,让它利用下面的函数doGetNextFrame1()来填充buffer,第3个实参StreamRead,赋值给类的成员变量fAfterGettingFunc,之后在类成员函数afterGetting()当中执行这个函数指针,即执行       StreamRead(afterGettingClientData)" -> doGetNextFrame() ->
 {
       (1) RTPInterface.cpp/startNetworkReading() ->
       (2) MultiFramedRTPSource.cpp/doGetNextFrame1() -> 在一个while循环内执 "如果nextPacket有效,即存在Packet的话,会执行到"
        {
            (1)BufferedPacket::use(),从而将接收到(链表形式)的各个packet里头的有效数据copy到上面提到的FrameSource类成员变量To,从而达到填充buffer(p_sys->track[i])的目的。
           (2)"如果条件:fCurrentPacketCompletesFrame && fReorderingBuffer->isEmpty()成立,即We have all the data that the client wants.&& " FramedSource::afterGetting() -> ...
        }
     }
    (2) BasicTaskScheduler0::doEventLoop() -> SingleStep() -> ....../*网络接收数据部分*/
  }

   /**********网络接收数据部分************************/
   BasicTaskScheduler::SingleStep() -> “利用函数指针调用“MultiFramedRTPSource::networkReadHandler() -> networkReadHandler1() ->
 {
(1)  BufferedPacket::fillInData() -> RTPInterface::handleRead() -> Groupsock::handleRead() -> GroupsockHelper.cpp/readSocket() -> recvfrom()!!!
(2)  ReorderingPacketBuffer::storePacket() ->
(3)  MultiFramedRTPSource::doGetNextFrame1() -> FramedSource::afterGetting() -> "利用函数指针调用"live555.cpp/StreamRead()
     其中传进来的第一个参数(实际就是Demux部分的afterGettingClientData)被转化为一个live_track_t的指针,其中的p_buffer域被copy到本地新建的p_block变量的p_buffer域中。p_buffer被下面的函数作为实参 -> es_out_Send() -> “利用函数指针调用“es_out_timeshift.c/Send() -> CmdExecuteSend() -> es_out_Send() -> es_out.c/EsOutSend() -> decoder.c/input_DecoderDecode() -> block.c/block_FifoPut() 把刚才这个p_block放入这个FIFO当中
    

}

/******解码线程***************/

thread_entry() -> “利用函数指针调用“input/src/Decoder.c/DecoderThread() -> "在一个死循环当中调用“block_FifoGet()


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值