概念
RTP: Real-time Transport Protocol,实时传输协议,一般用于多媒体数据的传输。
RTCP: RTP Control Protocol,实时传输控制协议,同RTP一起用于数据传输的监视,控制功能。
RTSP: Real Time Streaming Protocol,实时流协议,用于多媒体数据流的控制,如播放,暂停等。
RTP/RTCP相对于底层传输层,和RTSP,SIP等上层协议一起可以实现视频会议,视频直播等应用
RTP/RTSP/RTCP的区别 用一句简单的话总结:RTSP发起/终结流媒体、RTP传输流媒体数据 、RTCP对RTP进行控制,同步。
UDP:
TCP:
HTTP:
SDP:
rtsp服务器配置
基本流程 rtsp服务器配置
但是有一点需要主要的
将此mkv文件复制到和上面live555MediaServer可执行文件的同一个目录,
这里不需要将媒体文件放在live555MediaServer同一个目录,具体是看执行live555MediaServer进程的所在文件夹
例如:
Download $ ~/vendor/live/mediaServer/live555MediaServer
这时视频是Download目录下的
live555MediaServer传输1080p视频
默认配置,在terminal会打印如下错误
MultiFramedRTPSink::afterGettingFrame1(): The input frame data was too large for our buffer size (100452). 27300 bytes of trailing data was dropped! Correct this by increasing "OutPacketBuffer::maxSize" to at least 127300, *before* creating this 'RTPSink'. (Current value is 100000.)
OutPacketBuffer::maxSize默认大小为100000
需要修改DynamicRTSPServer的代码
} else if (strcmp(extension, ".264") == 0) {
// Assumed to be a H.264 Video Elementary Stream file:
NEW_SMS("H.264 Video");
OutPacketBuffer::maxSize = 157300; // allow for some possibly large H.264 frames
sms->addSubsession(H264VideoFileServerMediaSubsession::createNew(env, fileName, reuseSource));
}
然后重新编译
如何使用rtp over tcp
在ffmpeg 命令中
-rtsp_transport tcp -i rtsp://192.168.0.172:8554/bb.264 ./bbo.264
在ffmpeg 代码中
if (av_stristart(filename, "rtsp", NULL)) {
av_dict_set(&o->g->format_opts, "rtsp_transport", "tcp", 0);
}
err = avformat_open_input(&ic, filename, file_iformat, &o->g->format_opts);
rtsp over http
这时候就不要使用live555MediaServer开启时打印信息中的http端口
例如
(We use port 8000 for optional RTSP-over-HTTP tunneling, or for HTTP live streaming (for indexed Transport Stream files only).)
把url的端口号换一下
if (av_stristart(filename, "rtsp", NULL)) {
av_dict_set(&o->g->format_opts, "rtsp_transport", "tcp", 0);
}
err = avformat_open_input(&ic, filename, file_iformat, &o->g->format_opts);
rtp over udp和rtp over tcp(unicast 和 mutlicat)
ffmpeg默认是rtp over udp,关于rtp over udp和rtp over tcp的区别可以看看如下文章
http://blog.csdn.net/cloume/article/details/11771403
http://wiki.yak.net/916/multicast-rtp-etc.html
ffmpeg代码分析
ffmpeg rtsp代码位置
liveformat/rtsp.c 这个是udp里面的实现
liveformat/rtspdec.c
avformat_open_input
avformat_open_input >>
rtsp_read_header >>
ff_rtsp_connect>>
ff_rtsp_setup_input_streams
rtsp连接 ff_rtsp_connect
rtsp的控制方式
RTSP_MODE_PLAIN 普通rtsp
RTSP_MODE_TUNNEL 基于HTTP
分割url:proto, auth, host ,port ,path
rtsp HTTP打开连接
ffmpeg会在http的请求报文头发送如下格式
"x-sessioncookie: %s\r\n"
"Accept: application/x-rtsp-tunnelled\r\n"
"Pragma: no-cache\r\n"
"Cache-Control: no-cache\r\n",
x-sessioncookie:只是一个随机的值
即使不看方法体也能猜出来
snprintf(sessioncookie, sizeof(sessioncookie), "%08x%08x",
av_get_random_seed(), av_get_random_seed());
rtsp tcp打开连接
简单的建立信道
rtsp 发送OPTIONS命令,获取支持的命令
rtsp 传输方式
RAW/RAW ::Support receiving plain data over UDP without any RTP encapsulation
RTP/AVP: RTP transport / audio , video , control protocol
x-pn-tng: 不懂
rtsp 发送 SETUP命令 ff_rtsp_make_setup_request()函数
status_code = 461 /* Unsupported protocol */
status_
验证c s两端的协议,必须一致(大概是怕我们乱改代码)
interleaved :
The channel identifier is defined in the Transport header with the
interleaved parameter(Section 12.39).
个人理解,tcp是一个持续的流,所以需要一个interleaved来分割包
ff_rtsp_make_setup_request
ffmpeg会执行三个动作
OPTIONS
查看支持命令
这里的live555并没有收到任何的报文信息
DESCRIBE 获取视频信息 --就是SDP报文
SETUP 建立RTP通道
rtsp_read_play
ff_read_packet
rtsp_read_packet >> ff_rtsp_fetch_packet
rtp playload格式
packetization-mode 0 : 单一NALU
单NAL单元包(Single NAL Unit Packet):负载中只包含单一的NAL单元。NAL头的类型等同于原始的NAL单元类型,也就是,1~23的范围。此种包必须只包含单个NAL单元,聚合包和分片单元都不能在这种包内使用。必须按解码顺序发送.
packetization-mode 1 : non-interleaved 非交错封包模式
用于聚合多个NAL单元为单个RTP负载。这种包存在四种版本:单时间聚合包(STAP-A),单时间聚合包(STAP-B),多时间聚合包(MTAP)带16位偏移(MTAP16),多时间聚合包(MTAP)带24位偏移(MTAP24). NAL类型号分配给STAP-A,STAP-B,MTAP16和MTAP24分别为24,25,26,27。
packetization-mode 2 : interleaved 交错封包模式
用于分割单一的NAL单元为多个RTP包,共有两个版本,FU-A和FU-B. 它们的NAL类型号分别为28,29.
分片的原因是为了传输大于64KB的NAL单元。
分片针对单个NAL单元,而不是聚合包。
FU不能嵌套。
FU的时戳设置为被分片NAL单元的NALU时间
FU-A包括一个字节的FU indicator+一个字节的FU header+FU payload
FU-B比FU-A多了一个字节的decoding order number(DON).
FU-B必须只被用在交叉包装模式下NAL分片的第一片。换句话说,在交叉包装模式,每个NALU被分片为FU-B+FU-A+FU-A+...+FU-A
ff_rtsp_fetch_packet
ff_rtsp_fetch_packet 根据lower_transport 调用不同协议read_packet的方法
执行流程
OPTIONS-> DESCRIBE->RTSP/SDP
SDP(Session Description Protocol)
SDP 会话描述协议
简单报文分析
v=0 协议版本
o=- 1476286318262307 1 IN IP4 192.168.31.194 (所有者/创建者和会话标识符)
s=H.264 Video, streamed by the LIVE555 Media Server (会话名称)
i=bb.264(会话信息)
t=0 0(会话活动时间)
a=tool:LIVE555 Streaming Media v2016.09.22
a=type:broadcast
a=control:*
a=range:npt=0-
a=x-qt-text-nam:H.264 Video, streamed by the LIVE555 Media Server
a=x-qt-text-inf:bb.264
m=video 0 RTP/AVP 96(媒体名称和传输地址)
c=IN IP4 0.0.0.0(连接信息 ― 如果包含在所有媒体中,则不需要该字段)
b=AS:500(带宽信息)
a=rtpmap:96 H264/90000
a=fmtp:96 packetization-mode=1;profile-level-id=640028;sprop-parametersets=Z2QAKKzZQHgCJ+WEAAADAAQAAAMA8Dxgxlg=,aOvjyyLA
a=control:track1
a=rtpmap
H264 编码名称
90000 时钟频率
96 dynamically assigned
"a=rtpmap" 行中的编码名称必须是 "H264".
"a=rtpmap" 行中的时钟频率必须是 90000.
packetization-mode:表示支持的封包模式.
当 packetization-mode 的值为 0 时或不存在时, 必须使用单一 NALU 单元模式.
当 packetization-mode 的值为 1 时必须使用非交错(non-interleaved)封包模式.
当 packetization-mode 的值为 2 时必须使用交错(interleaved)封包模式.
sprop-parameter-sets: SPS,PPS
这个参数可以用于传输 H.264 的序列参数集和图像参数 NAL 单元. 这个参数的值
采用 Base64 进行编码. 不同的参数集间用","号隔开
profile-level-id:
这个参数用于指示 H.264 流的 profile 类型和级别. 由 Base16(十六进制) 表示的 3 个字节. 第一个字节表示 H.264 的 Profile 类型, 第三个字节表示 H.264 的 Profile 级别:
参考资料