概念
RTP: Real-time Transport Protocol,實時傳輸協(xié)議客蹋,一般用于多媒體數(shù)據(jù)的傳輸。
RTCP: RTP Control Protocol,實時傳輸控制協(xié)議,同RTP一起用于數(shù)據(jù)傳輸?shù)谋O(jiān)視,控制功能缀辩。
RTSP: Real Time Streaming Protocol,實時流協(xié)議,用于多媒體數(shù)據(jù)流的控制踪央,如播放臀玄,暫停等。
RTP/RTCP相對于底層傳輸層畅蹂,和RTSP健无,SIP等上層協(xié)議一起可以實現(xiàn)視頻會議,視頻直播等應用
RTP/RTSP/RTCP的區(qū)別 用一句簡單的話總結(jié):RTSP發(fā)起/終結(jié)流媒體液斜、RTP傳輸流媒體數(shù)據(jù) 累贤、RTCP對RTP進行控制,同步少漆。
UDP:
TCP:
HTTP:
SDP:
rtsp服務器配置
基本流程 rtsp服務器配置
但是有一點需要主要的
將此mkv文件復制到和上面live555MediaServer可執(zhí)行文件的同一個目錄臼膏,
這里不需要將媒體文件放在live555MediaServer同一個目錄,具體是看執(zhí)行l(wèi)ive555MediaServer進程的所在文件夾
例如:
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示损,關(guān)于rtp over udp和rtp over tcp的區(qū)別可以看看如下文章
http://blog.csdn.net/cloume/article/details/11771403
http://wiki.yak.net/916/multicast-rtp-etc.html
ffmpeg代碼分析
- ffmpeg rtsp代碼位置
liveformat/rtsp.c 這個是udp里面的實現(xiàn)
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的請求報文頭發(fā)送如下格式
"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 發(fā)送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 發(fā)送 SETUP命令 ff_rtsp_make_setup_request()函數(shù)
status_code = 461 /* Unsupported protocol */
status_
驗證c s兩端的協(xié)議渗磅,必須一致(大概是怕我們亂改代碼)
interleaved :
The channel identifier is defined in the Transport header with the
interleaved parameter(Section 12.39).
個人理解,tcp是一個持續(xù)的流检访,所以需要一個interleaved來分割包
ff_rtsp_make_setup_request
- ffmpeg會執(zhí)行三個動作
OPTIONS
查看支持命令
這里的live555并沒有收到任何的報文信息
DESCRIBE 獲取視頻信息 --就是SDP報文
SETUP 建立RTP通道
rtsp_read_play
ff_read_packet
rtsp_read_packet >> ff_rtsp_fetch_packet
rtp playload格式
參考鏈接:
http://blog.rongpmcu.com/rtpxue-xi/
packetization-mode 0 : 單一NALU
單NAL單元包(Single NAL Unit Packet):負載中只包含單一的NAL單元始鱼。NAL頭的類型等同于原始的NAL單元類型,也就是脆贵,1~23的范圍医清。此種包必須只包含單個NAL單元,聚合包和分片單元都不能在這種包內(nèi)使用卖氨。必須按解碼順序發(fā)送.
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包括一個字節(jié)的FU indicator+一個字節(jié)的FU header+FU payload
FU-B比FU-A多了一個字節(jié)的decoding order number(DON).
FU-B必須只被用在交叉包裝模式下NAL分片的第一片葫盼。換句話說,在交叉包裝模式,每個NALU被分片為FU-B+FU-A+FU-A+...+FU-A
ff_rtsp_fetch_packet
ff_rtsp_fetch_packet 根據(jù)lower_transport 調(diào)用不同協(xié)議read_packet的方法
執(zhí)行流程
OPTIONS-> DESCRIBE->RTSP/SDP
SDP(Session Description Protocol)
SDP 會話描述協(xié)議簡單報文分析
v=0 協(xié)議版本
o=- 1476286318262307 1 IN IP4 192.168.31.194 (所有者/創(chuàng)建者和會話標識符)
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(媒體名稱和傳輸?shù)刂?
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
這個參數(shù)可以用于傳輸 H.264 的序列參數(shù)集和圖像參數(shù) NAL 單元. 這個參數(shù)的值
采用 Base64 進行編碼. 不同的參數(shù)集間用","號隔開profile-level-id:
這個參數(shù)用于指示 H.264 流的 profile 類型和級別. 由 Base16(十六進制) 表示的 3 個字節(jié). 第一個字節(jié)表示 H.264 的 Profile 類型, 第三個字節(jié)表示 H.264 的 Profile 級別: