《電子技術(shù)應(yīng)用》
您所在的位置:首頁 > 通信與網(wǎng)絡(luò) > 設(shè)計應(yīng)用 > 基于Live555的流媒體服務(wù)器設(shè)計與實現(xiàn)
基于Live555的流媒體服務(wù)器設(shè)計與實現(xiàn)
2014年微型機與應(yīng)用第18期
許華濱1,2,謝維波1,,2,,黃 奕1,2
1.華僑大學(xué) 信息科學(xué)與工程學(xué)院,,福建 廈門 361021; 2.華僑大學(xué) 廈門軟件園 嵌入式技術(shù)開放實驗室,福建 廈門 361008
摘要: 針對傳統(tǒng)監(jiān)控系統(tǒng)的不足已不能滿足現(xiàn)代人對監(jiān)控視頻內(nèi)容的要求,,提出了一種解決方案并對其進行闡述,說明如何在Linux系統(tǒng)下,,以IP網(wǎng)絡(luò)攝像頭為數(shù)據(jù)源,,結(jié)合開源Live555庫實現(xiàn)流媒體服務(wù)器的方法,其中涉及了視頻數(shù)據(jù)的獲取,、編碼,、流化以及傳輸?shù)饶K。流媒體服務(wù)器的實現(xiàn)解決了多路客戶訪問攝像頭的負載問題,,同時若與圖像處理算法結(jié)合可提供特殊的視頻監(jiān)控內(nèi)容以滿足應(yīng)用需求,。
Abstract:
Key words :

  摘  要: 針對傳統(tǒng)監(jiān)控系統(tǒng)的不足已不能滿足現(xiàn)代人對監(jiān)控視頻內(nèi)容的要求,提出了一種解決方案并對其進行闡述,說明如何在Linux系統(tǒng)下,,以IP網(wǎng)絡(luò)攝像頭為數(shù)據(jù)源,,結(jié)合開源Live555庫實現(xiàn)流媒體服務(wù)器的方法,其中涉及了視頻數(shù)據(jù)的獲取,、編碼,、流化以及傳輸?shù)饶K。流媒體服務(wù)器的實現(xiàn)解決了多路客戶訪問攝像頭的負載問題,,同時若與圖像處理算法結(jié)合可提供特殊的視頻監(jiān)控內(nèi)容以滿足應(yīng)用需求,。

  關(guān)鍵詞RTSP;流媒體服務(wù)器,;Live555,;網(wǎng)絡(luò)監(jiān)控

0 引言

  隨著圖像處理的發(fā)展,構(gòu)建一個良好的視頻圖像處理應(yīng)用平臺越來越重要,。目前的攝像頭對多路訪問的負載能力非常有限,,并且現(xiàn)在人們對監(jiān)控內(nèi)容的要求已不僅僅停留在原始視頻上,而大多更希望能夠?qū)崟r監(jiān)控經(jīng)過特殊處理的視頻數(shù)據(jù),。為了滿足這一需求,,以IP攝像頭作為數(shù)據(jù)源,PC端搭建流媒體服務(wù)器供多路客戶進行實時監(jiān)控的模式是一個很好的解決方案,,這樣既能減少攝像頭負載能力的限制,,同時又能滿足圖像處理后的監(jiān)控需求。本文設(shè)計的流媒體服務(wù)器[1]架設(shè)在Linux操作系統(tǒng)的PC上,,采用RTSP協(xié)議[2]進行實時傳輸以供客戶訪問,。

  服務(wù)器首先登錄訪問IP攝像頭,匹配通過后IP攝像頭返回捕捉的視頻數(shù)據(jù)給服務(wù)器,,當(dāng)客戶端通過鏈接向服務(wù)器發(fā)送訪問請求后,,服務(wù)器開始向客戶端傳送實時視頻數(shù)據(jù),供客戶進行實時監(jiān)控,。

1 IPC數(shù)據(jù)獲取及存儲

  網(wǎng)絡(luò)攝像機對于人們來說較為重要的是如何獲取其視頻源數(shù)據(jù),,而海康威視的網(wǎng)絡(luò)攝像機為人們提供了二次開發(fā)的接口以方便對IPC的功能應(yīng)用進行擴展,。下面對IPC視頻數(shù)據(jù)獲取流程進行介紹,。

  由于在IPC端已經(jīng)有設(shè)定好的賬戶與密碼,因此用戶在訪問此IPC時就需要通過NET_DVR_Login_V30函數(shù)來進行注冊:NET_DVR_Login_V30(IP地址,,端口,,賬號,密碼,,&struDeviceInfo),,IP攝像頭匹配正確后才有訪問權(quán)限。

  該流程中,啟動數(shù)據(jù)流的接收是通過調(diào)用NET_DVR_RealPlay_V30來實現(xiàn)的,。該函數(shù)中有一項參數(shù)可用來設(shè)置數(shù)據(jù)回調(diào)函數(shù),,每當(dāng)有碼流數(shù)據(jù)到達時,便會跳轉(zhuǎn)到這個已設(shè)置的數(shù)據(jù)回調(diào)函數(shù)中,,在數(shù)據(jù)回調(diào)函數(shù)中需要對接收到的數(shù)據(jù)流進行判斷,,若為系統(tǒng)頭則進行一些設(shè)置,若為碼流數(shù)據(jù)則可將其存入緩沖區(qū)內(nèi),。其流程示意圖如圖1所示,。

001.jpg

  在圖1中,判斷流數(shù)據(jù)為系統(tǒng)頭時需要進行一些設(shè)置,,其中就包括了解碼回調(diào)函數(shù)的設(shè)置,。解碼回調(diào)函數(shù)的作用是當(dāng)碼流數(shù)據(jù)存入緩沖區(qū)達一幀時會跳轉(zhuǎn)到該函數(shù)中,此時在解碼回調(diào)函數(shù)內(nèi)部便可對完整的一幀數(shù)據(jù)進行操作,。

  在解碼回調(diào)函數(shù)內(nèi)獲取到的是YV12格式幀數(shù)據(jù),,而由于所選擇的是x264編碼器,其輸入源規(guī)范為YUV格式,,因此必須在解碼回調(diào)函數(shù)內(nèi)將其轉(zhuǎn)為YUV格式后才可供x264進行編碼,,之后就可以將其儲入緩沖區(qū)內(nèi)。本次開發(fā)過程中以循環(huán)緩沖區(qū)和鏈表的方式存取數(shù)據(jù),。

2 圖像編碼模塊

  前面提到,,H264編碼使用的是x264編碼器,x264提供了一些開發(fā)接口,,但仍需進一步封裝,,其設(shè)計流程如下:

 ?。?)初始化EncoderInit函數(shù):在其內(nèi)部設(shè)置初始化結(jié)構(gòu)體,,調(diào)用x264_param_default及x264_encoder_open進行編碼器初始化,并開辟存放編碼前后圖像存儲空間,。

 ?。?)編碼實現(xiàn)Encode_frame函數(shù):將原始YUV420P格式數(shù)據(jù)傳給x264_encoder_encode函數(shù)進行編碼得到nal數(shù)組,其后循環(huán)調(diào)用x264_nal_encode函數(shù)逐一將編碼后nal封裝成NAL單元并寫入輸出緩存區(qū)中,,完成一幀圖像數(shù)據(jù)的編碼,。

3 流媒體服務(wù)器模塊

  服務(wù)器結(jié)合開源Live555庫進行設(shè)計,提供對外實時播放,。Live555是一個為流媒體提供解決方案的跨平臺的C++開源項目,,它包括了四個基本庫,分別是:UsageEnvironment,、BasicUsageEnvironment,、Groupsock和LiveMedia[4]。其中LiveMedia庫是最為核心的,它包含了對應(yīng)各種不同流媒體類型的數(shù)據(jù)源類Source,、數(shù)據(jù)接收類Sink,、會話類Session及RTSPServe等。

  TaskScheduler實例是整個程序的任務(wù)調(diào)度器[5],,它通過doEventLoop()方法實現(xiàn)程序的循環(huán)結(jié)構(gòu),,并在循環(huán)中進行任務(wù)調(diào)度。

  3.1 服務(wù)器的建立及響應(yīng)

  程序流程如下:

 ?。?)建立任務(wù)調(diào)度器

  TaskScheduler*scheduler=BasicTaskScheduler::createNew()

 ?。?)建立程序運行環(huán)境

  _env=BasicUsageEnvironment::createNew(*scheduler)

  (3)創(chuàng)建RTSP服務(wù)器綁定端口號

  RTSPServer*rtspServer=RTSPServer::createNew(*_env,,9554)

 ?。?)創(chuàng)建服務(wù)器媒體對象:創(chuàng)建ServerMediaSession實例。

 ?。?)進入事件循環(huán)

  _env->taskScheduler().doEventLoop()

  服務(wù)器采用的是事件驅(qū)動機制,,在這個循環(huán)中,doEventLoop()主要負責(zé)三件事:監(jiān)聽客戶端請求并進行響應(yīng),、對事件發(fā)生進行處理,、對延時任務(wù)進行調(diào)度。

  RTSP協(xié)議應(yīng)用于C/S模式,,它本身并不傳輸數(shù)據(jù),,而只負責(zé)實現(xiàn)連接、播放,、停止等操作,,數(shù)據(jù)的傳輸則交由RTP協(xié)議來進行[6]。服務(wù)器與客戶端建立連接時是通過響應(yīng)客戶端發(fā)送的OPTION,、DESCRIBE,、SETUP、PLAY,、TERADOWN等請求來進行交互連接的[7],。常用的交互方法作用如下:

  OPTION:C向S端獲取可提供的交互方法

  DESCRIBE:要求得到S端提供的媒體初始化信息(SDP)

  SETUP:確定傳輸模式并提醒S端建立會話

  PLAY:C向S發(fā)送播放請求

  TERADOWN:C向S發(fā)送關(guān)閉請求

  服務(wù)器對客戶端的具體響應(yīng)情況如下:

  (1)服務(wù)器端在收到客戶端發(fā)送的DESCRIBE請求時,,相應(yīng)的處理函數(shù)根據(jù)流媒體名查找或創(chuàng)建ServerMediaSession,,生成SDP信息作為返回響應(yīng)此請求。

 ?。?)服務(wù)器端收到SETUP請求時,,相應(yīng)處理函數(shù)會對SETUP請求的傳輸頭解析,獲取流媒體發(fā)送傳輸參數(shù),,將這些參數(shù)組裝成響應(yīng)消息返回給客戶端,。期間subsession調(diào)用CreatNew()生成Source數(shù)據(jù)源實例及RTPSink數(shù)據(jù)接收實例,。

  (3)服務(wù)器端收到PLAY請求時,,RTPSink數(shù)據(jù)接收實例會開始向Source數(shù)據(jù)源索取圖像數(shù)據(jù),,并將索取到的數(shù)據(jù)打包成RTP包發(fā)送出去。此時,,當(dāng)RTPSink開始索取數(shù)據(jù)時,,就啟動了對一幀圖像數(shù)據(jù)的流化。

  3.2 流化過程

  當(dāng)Sink向Source索取數(shù)據(jù)時服務(wù)器內(nèi)便啟動了流化,,數(shù)據(jù)由Source流向Sink,,最終再發(fā)送出去。但這一過程中經(jīng)過了多個節(jié)點傳遞才到達Sink端,,這是因為最初的Source視頻數(shù)據(jù)如果直接傳給Sink端,,便無法直接進行流式傳輸,因此需要經(jīng)過中間多個節(jié)點對視頻數(shù)據(jù)進行“加工”才能滿足流式傳輸?shù)囊?。下面是一個示例:

  ′source1′->′source2′(a filter)->′source3′(a filter)->′sink′

  filters接收到數(shù)據(jù)后也作為后者的source,。對于本文H264格式的流媒體來說,圖像數(shù)據(jù)經(jīng)各節(jié)點傳遞過程如下:

  WebcamFrameSource(自定義節(jié)點)->H264VideoStreamParser->H264VideoStreamFramer->H264FUAFragmenter->H264 VideoRTPSink

  WebcamFrameSource中H264編碼的視頻數(shù)據(jù)傳給H264VideoStreamParser,,并由它分解為多個NAL單元,,然后經(jīng)H264VideoStreamFramer處理后由H264FUAFragmenter進行RTP封包,最后H264VideoRTPSink負責(zé)形成RTP包頭并發(fā)送數(shù)據(jù),。

  在這個過程中,,WebcamFrameSource類是創(chuàng)建的,后面的H264VideoStreamFramer類,、H264FUAFragmenter類,、H264VideoRTPSink類都是由Live555庫定義好了的,所創(chuàng)建的WebcamFrameSource類負責(zé)將前期的YUV幀數(shù)據(jù)從緩沖區(qū)取出進行H264編碼,,然后將編碼好的視頻數(shù)據(jù)傳給下一個節(jié)點即可,。

  3.3 服務(wù)器內(nèi)數(shù)據(jù)獲取與打包發(fā)送

  在Live555中MediaSource類是所有Source的基類,對各種流媒體格式類型及編碼的支持都是通過這個類的派生類來實現(xiàn)的,,F(xiàn)rameSource派生自MediaSource,,并且內(nèi)部定義了一個虛函數(shù)doGetNextFrame(),用來讓其子類實現(xiàn)各自媒體格式的幀獲取,。若要自定義Source的來源,則可以通過自定義一個派生自FrameSource的類來實現(xiàn),。前面提到的WebcamFrameSource就是繼承自FrameSource類用來實現(xiàn)數(shù)據(jù)源獲取的,。

  doGetNextFrame()是FrameSource的虛函數(shù),Sink實例在向Source實例索取數(shù)據(jù)時,,會重復(fù)循環(huán)層層調(diào)用doGetNextFrame()來獲取實時數(shù)據(jù)源,,獲取過程就是將前期的YUV幀數(shù)據(jù)從緩沖區(qū)取出進行H264編碼,,并將編碼完成的數(shù)據(jù)間接地傳遞給Sink的緩沖區(qū),最后再調(diào)用FramedSource::afterGetting()函數(shù)來通知Sink端作處理,。具體流程如圖2所示,。

002.jpg

  數(shù)據(jù)獲取后交由PackFrame()等函數(shù)進行打包,最后進行發(fā)送,。若無數(shù)據(jù),,則繼續(xù)向Source數(shù)據(jù)源進行索取,循環(huán)之前的步驟,。

4 實驗結(jié)果

003.jpg

  實驗結(jié)果如圖3所示,,左側(cè)PC為基于Linux的RTSP服務(wù)器,負責(zé)將IPC拍攝到的視頻實時傳送,;右側(cè)PC以及手機都作為客戶端,,通過RTSP服務(wù)器提供的URL進行鏈接,進而實時播放,。

5 結(jié)論

  本文對IPC數(shù)據(jù)源的獲取方法,、編碼流程、服務(wù)器內(nèi)部數(shù)據(jù)流化及數(shù)據(jù)源類WebcamFrameSource的設(shè)計進行了說明,。使用IPC通過路由器將數(shù)據(jù)傳送至服務(wù)器,,服務(wù)器端進行實時傳送并提供相應(yīng)的URL鏈接供客戶端使用??蛻舳丝墒褂肰LC等支持RTSP協(xié)議的視頻軟件進行實時監(jiān)控,。

  參考文獻

  [1] 杜嘩.流媒體技術(shù)的原理和應(yīng)用[J].光盤技術(shù),2008(7):9-11.

  [2] SCHULZRINNE A,, RAO R,, Columbia University, et al. RFC2326-Real time streaming protocol(RTSP)[S].1998.

  [3] 樊珊.基于RTP的H264視頻傳輸技術(shù)的研究[D].濟南:山東大學(xué),,2008.

  [4] 樊承澤,,陳蜀宇,楊新華.基于網(wǎng)絡(luò)計算機的流媒體播放器的研究與實現(xiàn)[J].計算機技術(shù)與發(fā)展,,2010,,20(4):195-198.

  [5] 茅炎菲,忠東.基于RTSP協(xié)議網(wǎng)絡(luò)監(jiān)控系統(tǒng)的研究與實現(xiàn)[J].計算機工程與設(shè)計,,2011,,32(7):2523-2530.

  [6] 王彥麗,陳明,,陳華,,等.基于RTP/RTCP的數(shù)字視頻監(jiān)控系統(tǒng)的設(shè)計與實現(xiàn)[J].計算機工程與科學(xué),2009,,31(3):58-60.

  [7] 王路幫.RTSP協(xié)議及其分布式應(yīng)用框架[J].安徽職業(yè)技術(shù)學(xué)院學(xué)報,,2006,,5(1):4-6.


此內(nèi)容為AET網(wǎng)站原創(chuàng),未經(jīng)授權(quán)禁止轉(zhuǎn)載,。