您的位置:首页 > 理论基础 > 计算机网络

live555 传输方式(TCP&UDP)

2017-11-30 17:55 721 查看
概述:live555底层支持TCP和UDP,通过RTSP交互时客户端通过SETUP请求!!!

先介绍下主要的流程:RTP包的发送是从MediaSink::startPlaying函数调用开始的,在StartPlaying函数的最后会调用函数continuePlaying。
continuePlaying函数是定义在MediaSink类中的纯虚函数,需要到特定媒体的sink子类中实现,对于H264来讲是在H264VideoRTPSink中实现的。H264VideoRTPSink:continuePlaying中会创建一个辅助类H264FUAFragmenter,用于H264的RTP打包。因为H264的RTP包,有些特殊需要进一步处理。接着调用其父类MultiFramedRTPSink::continuePlaying实现。
在函数MultiFramedRTPSink::continuePlaying中主要是调MultiFramedRTPSink::buildAndSendPacket函数。
看名字就知道MultiFramedRTPSink::buildAndSendPacket()函数将完成打包并发送工作。传递了一个True参数,表示这是第一个packet。在该函数的最后调用了MultiFramedRTPSink::packFrame() ,进一步的工作,在packFrame函数中进行,
MultiFramedRTPSink::packFrame() 将为RTP包填充数据。packFrame函数需要处理两种情况:
1).buffer中存在未发送的数据(overflow data),这时可以将调用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函数,这个函数中直接调用socket的send函数。至此关于RTP打包发送的主要流程分析就差不多了,具体细节实现,可参考源代码

TCP方式 (sendRTPOverTcP)

VLC :工具->首选项->输入/编解码器



VLC设置RTP over RTSP (TCP):SETUP 为RTP/AVP/TCP

[plain]
view plain
copy

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  
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  
11-30 09:55:22.904: I/RTSPServer_jni(801): CSeq: 3  
11-30 09:55:22.904: I/RTSPServer_jni(801): User-Agent: LIVE555 Streaming Media v2012.01.13  
11-30 09:55:22.904: I/RTSPServer_jni(801): Transport: RTP/AVP/TCP;unicast;interleaved=0-1  
11-30 09:55:22.904: I/RTSPServer_jni(801):   
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.  
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  
11-30 09:55:22.953: I/RTSPServer_jni(801): CSeq: 3  
11-30 09:55:22.953: I/RTSPServer_jni(801): Date: Thu, Nov 30 2017 01:55:22 GMT  
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  
11-30 09:55:22.953: I/RTSPServer_jni(801): Session: 0568BD35;timeout=65  

UDP方式(Groupsock::output)

VLC :工具->首选项->输入/编解码器



VLC设置默认:SETUP 为RTP/AVP

[plain]
view plain
copy

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  
11-30 10:12:55.662: I/RTSPServer_jni(800): CSeq: 3  
11-30 10:12:55.662: I/RTSPServer_jni(800): User-Agent: LIVE555 Streaming Media v2012.01.13  
11-30 10:12:55.662: I/RTSPServer_jni(800): Transport: RTP/AVP;unicast;client_port=62366-62367  
11-30 10:12:55.662: I/RTSPServer_jni(800):   
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.  
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  
11-30 10:12:55.684: I/RTSPServer_jni(800): CSeq: 3  
11-30 10:12:55.684: I/RTSPServer_jni(800): Date: Thu, Nov 30 2017 02:12:55 GMT  
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-30 10:12:55.684: I/RTSPServer_jni(800): Session: 77D628A6;timeout=65 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐