基于ffmpeg的rtsp拉流代碼分析流水賬

概念

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);

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 級別:

參考資料

用實例分析H264 RTP payload

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末贫导,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子蟆盹,更是在濱河造成了極大的恐慌孩灯,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,692評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件逾滥,死亡現(xiàn)場離奇詭異峰档,居然都是意外死亡,警方通過查閱死者的電腦和手機寨昙,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,482評論 3 392
  • 文/潘曉璐 我一進店門讥巡,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人舔哪,你說我怎么就攤上這事欢顷。” “怎么了捉蚤?”我有些...
    開封第一講書人閱讀 162,995評論 0 353
  • 文/不壞的土叔 我叫張陵抬驴,是天一觀的道長。 經(jīng)常有香客問我缆巧,道長布持,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,223評論 1 292
  • 正文 為了忘掉前任陕悬,我火速辦了婚禮题暖,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘墩莫。我一直安慰自己芙委,他們只是感情好,可當我...
    茶點故事閱讀 67,245評論 6 388
  • 文/花漫 我一把揭開白布狂秦。 她就那樣靜靜地躺著灌侣,像睡著了一般。 火紅的嫁衣襯著肌膚如雪裂问。 梳的紋絲不亂的頭發(fā)上侧啼,一...
    開封第一講書人閱讀 51,208評論 1 299
  • 那天牛柒,我揣著相機與錄音,去河邊找鬼痊乾。 笑死皮壁,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的哪审。 我是一名探鬼主播蛾魄,決...
    沈念sama閱讀 40,091評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼湿滓!你這毒婦竟也來了滴须?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,929評論 0 274
  • 序言:老撾萬榮一對情侶失蹤叽奥,失蹤者是張志新(化名)和其女友劉穎扔水,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體朝氓,經(jīng)...
    沈念sama閱讀 45,346評論 1 311
  • 正文 獨居荒郊野嶺守林人離奇死亡魔市,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,570評論 2 333
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了赵哲。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片待德。...
    茶點故事閱讀 39,739評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖誓竿,靈堂內(nèi)的尸體忽然破棺而出磅网,到底是詐尸還是另有隱情,我是刑警寧澤筷屡,帶...
    沈念sama閱讀 35,437評論 5 344
  • 正文 年R本政府宣布涧偷,位于F島的核電站,受9級特大地震影響毙死,放射性物質(zhì)發(fā)生泄漏燎潮。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,037評論 3 326
  • 文/蒙蒙 一扼倘、第九天 我趴在偏房一處隱蔽的房頂上張望确封。 院中可真熱鬧,春花似錦再菊、人聲如沸爪喘。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,677評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽秉剑。三九已至,卻和暖如春稠诲,著一層夾襖步出監(jiān)牢的瞬間侦鹏,已是汗流浹背诡曙。 一陣腳步聲響...
    開封第一講書人閱讀 32,833評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留略水,地道東北人价卤。 一個月前我還...
    沈念sama閱讀 47,760評論 2 369
  • 正文 我出身青樓,卻偏偏與公主長得像渊涝,于是被迫代替她去往敵國和親慎璧。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,647評論 2 354

推薦閱讀更多精彩內(nèi)容