1. 程式人生 > >live555 傳輸方式(TCP&UDP)

live555 傳輸方式(TCP&UDP)

概述:live555底層支援TCP和UDP,通過RTSP互動時客戶端通過SETUP請求!!!

先介紹下主要的流程:RTP包的傳送是從MediaSink::startPlaying函式呼叫開始的,在StartPlaying函式的最後會呼叫函式continuePlaying

continuePlaying函式是定義在MediaSink類中的純虛擬函式,需要到特定媒體的sink子類中實現,對於H264來講是在H264VideoRTPSink中實現的。H264VideoRTPSinkcontinuePlaying中會建立一個輔助類H264FUAFragmenter,用於H264RTP打包。因為

H264RTP包,有些特殊需要進一步處理。接著呼叫其父類MultiFramedRTPSink::continuePlaying實現。

在函式MultiFramedRTPSink::continuePlaying中主要是調MultiFramedRTPSink::buildAndSendPacket函式。

看名字就知道MultiFramedRTPSink::buildAndSendPacket()函式將完成打包併發送工作。傳遞了一個True引數,表示這是第一個packet。在該函式的最後呼叫了MultiFramedRTPSink::packFrame() 進一步的工作,在packFrame函式中進行

,

MultiFramedRTPSink::packFrame()將為RTP包填充資料。packFrame函式需要處理兩種情況:
1).buffer
存在未傳送的資料(overflowdata),這時可以將呼叫afterGettingFrame1函式進行後續處理工作。2).buffer不存在資料,這時需要呼叫source上的getNextFrame函式獲取資料getNextFrame呼叫時,引數中有兩個回撥用函式:afterGettingFrame函式將在獲取到資料後呼叫,其中只是簡單的呼叫了afterGettingFrame1函式而已;ourHandleClosure函式將在資料已經處理完畢時呼叫,如檔案結束。可以看出,兩種情況下最後都是要呼叫

afterGettingFrame1函式

afterGettingFrame1函式的複雜之處在於處理frame的分片,若一個frame大於TCP/UDP有效載荷(程式中定義為1448個位元組),就必需分片了。最簡單的情況就是一個packet(RTP)中最多隻充許一個frame,即一個RTP包中存在一個frame或者frame的一個分片,H264就是這樣處理的:方法是將剩餘的資料記錄為buffer的溢位部分。下次呼叫packFrame函式時,直接從溢位部分複製到packet中。不過應該注意,一個frame的大小不能超過buffer的大小(預設為60000),否則會真的溢位,那就應該考慮增加buffer大小了。

處理完相關分片資訊,將會呼叫函式MultiFramedRTPSink::sendPacketIfNecessary()來發送資料包。sendPacketIfNecessary()函式處理一些傳送的細節,packet中含有Frame則呼叫RTPInterface::sendPacket函式傳送packet。並將下一次RTP的傳送操作加入到任務排程器中:nextTask() = envir().taskScheduler().

scheduleDelayedTask。函式引數中傳遞了sendNext函式指標。sendNext函式又呼叫了buildAndSendPacket函式,輪迴了。。。!

最後來看下RTPInterface::sendPacket函式。若是使用UDP方式傳送,將呼叫Groupsock::output函式,可以實現組播功能。groupsock只實現了UDP傳送功能,當用TCP方式傳送時呼叫sendRTPOverTcP函式,這個函式中直接呼叫socketsend函式。至此關於RTP打包傳送的主要流程分析就差不多了,具體細節實現,可參考原始碼


TCP方式 (sendRTPOverTcP

VLC :工具->首選項->輸入/編解碼器

VLC設定RTP over RTSP (TCP):SETUP 為RTP/AVP/TCP

  1. 11-30 09:55:22.878: I/RTSPServer_jni(801): [live555android.cpp:551 jint Java_com_eques_device_ui_hardware_RTSPJNI_ReadVideoData(JNIEnv*, jobject, jbyteArray, jint)]: <ycs>video ! packet->insize 1363  
  2. 11-30 09:55:22.904: I/RTSPServer_jni(801): [RTSPServer.cpp:919 void RTSPServer::RTSPClientConnection::handleRequestBytes(int)]: RTSPClientConnection[0x5557a458]::handleRequestBytes() read 162 new bytes:SETUP rtsp://192.168.0.100:8554/1/trackID=1 RTSP/1.0  
  3. 11-30 09:55:22.904: I/RTSPServer_jni(801): CSeq: 3  
  4. 11-30 09:55:22.904: I/RTSPServer_jni(801): User-Agent: LIVE555 Streaming Media v2012.01.13  
  5. 11-30 09:55:22.904: I/RTSPServer_jni(801): Transport: RTP/AVP/TCP;unicast;interleaved=0-1  
  6. 11-30 09:55:22.904: I/RTSPServer_jni(801):   
  7. 11-30 09:55:22.904: I/RTSPServer_jni(801): [RTSPServer.cpp:1012 void RTSPServer::RTSPClientConnection::handleRequestBytes(int)]: parseRTSPRequestString() succeeded, returning cmdName "SETUP", urlPreSuffix "1", urlSuffix "trackID=1", CSeq "3", Content-Length 0, with 0 bytes following the message.  
  8. 11-30 09:55:22.953: I/RTSPServer_jni(801): [RTSPServer.cpp:1153 void RTSPServer::RTSPClientConnection::handleRequestBytes(int)]: sending response: RTSP/1.0 200 OK  
  9. 11-30 09:55:22.953: I/RTSPServer_jni(801): CSeq: 3  
  10. 11-30 09:55:22.953: I/RTSPServer_jni(801): Date: Thu, Nov 30 2017 01:55:22 GMT  
  11. 11-30 09:55:22.953: I/RTSPServer_jni(801): Transport: RTP/AVP/TCP;unicast;destination=192.168.0.105;source=192.168.0.100;interleaved=0-1  
  12. 11-30 09:55:22.953: I/RTSPServer_jni(801): Session: 0568BD35;timeout=65  


UDP方式(Groupsock::output

VLC :工具->首選項->輸入/編解碼器

VLC設定預設:SETUP 為RTP/AVP

  1. 11-30 10:12:55.662: I/RTSPServer_jni(800): [RTSPServer.cpp:919 void RTSPServer::RTSPClientConnection::handleRequestBytes(int)]: RTSPClientConnection[0x55d6e008]::handleRequestBytes() read 166 new bytes:SETUP rtsp://192.168.0.100:8554/1/trackID=1 RTSP/1.0  
  2. 11-30 10:12:55.662: I/RTSPServer_jni(800): CSeq: 3  
  3. 11-30 10:12:55.662: I/RTSPServer_jni(800): User-Agent: LIVE555 Streaming Media v2012.01.13  
  4. 11-30 10:12:55.662: I/RTSPServer_jni(800): Transport: RTP/AVP;unicast;client_port=62366-62367  
  5. 11-30 10:12:55.662: I/RTSPServer_jni(800):   
  6. 11-30 10:12:55.662: I/RTSPServer_jni(800): [RTSPServer.cpp:1012 void RTSPServer::RTSPClientConnection::handleRequestBytes(int)]: parseRTSPRequestString() succeeded, returning cmdName "SETUP", urlPreSuffix "1", urlSuffix "trackID=1", CSeq "3", Content-Length 0, with 0 bytes following the message.  
  7. 11-30 10:12:55.684: I/RTSPServer_jni(800): [RTSPServer.cpp:1153 void RTSPServer::RTSPClientConnection::handleRequestBytes(int)]: sending response: RTSP/1.0 200 OK  
  8. 11-30 10:12:55.684: I/RTSPServer_jni(800): CSeq: 3  
  9. 11-30 10:12:55.684: I/RTSPServer_jni(800): Date: Thu, Nov 30 2017 02:12:55 GMT  
  10. 11-30 10:12:55.684: I/RTSPServer_jni(800): Transport: RTP/AVP;unicast;destination=192.168.0.105;source=192.168.0.100;client_port=62366-62367;server_port=6970-6971  
  11. 11-30 10:12:55.684: I/RTSPServer_jni(800): Session: 77D628A6;timeout=65