劉 勇
(作者單位:安徽廣播電視臺)
基于IMX6嵌入式處理器的音頻流媒體服務器的設計與實現
劉 勇
(作者單位:安徽廣播電視臺)
為了解決智能廣播發射監控系統中廣播信號采集并實時回傳問題,本文提出了一種基于IMX6嵌入式處理器的流媒體服務器的解決方案。筆者深入研究了流媒體技術以及傳輸控制協議,詳細分析了流媒體技術,并為本文的設計方案制定了最為先進的流媒體傳輸策略。本文整合了多種技術模塊:音頻采集、音頻壓縮、網絡傳輸,實現了一個完整的音頻流媒體采集、壓縮到傳輸的鏈路。值得注意的是,在音頻壓縮方面,本文采用先進的AAC音頻壓縮技術,而在網絡傳輸方面,本文實現了單播和組播兩種傳輸方式。
嵌入式;IMX6;流媒體;組播
廣播發射監測技術是廣播事業發展過程中的熱點技術,是提高工作效率和工作質量的重要技術。。智能廣播發射監控系統需要具有以下功能:廣播信號采集并實時回傳功能、廣播發射狀態監測功能、環境監測功能、供電遠程控制功能與有線無線網絡自動接入功能。這其中廣播信號采集并實時回傳功能是最重要的,而這一功能的實現依賴于先進的流媒體傳輸技術和先進的嵌入式技術。本文設計并實現了一種基于IMX6嵌入式處理器的音頻流媒體解決方案,有效地解決了廣播信號采集并實時回傳的難題。
1.1流媒體
流媒體[1]技術的定義是:將音頻、視頻或者其他多媒體文件通過流式傳輸的方法在網絡上播放。[2]不同于早先的先下載后播放的模式,通過流媒體技術播放多媒體文件并不需要預先下載媒體數據,只需要在播放開始時將少量的數據存入緩存區。
流媒體傳輸的特征是網絡數據量大,其特定的傳輸方式:流式傳輸,對傳輸的實時性要求較高,因此與傳統的網絡傳輸相比,通過Internet網絡傳輸流媒體數據具有以下特點:①流式傳輸的實現需要一定的緩存空間;②在流式傳輸之前,多媒體文件必須經過預處理;③多媒體文件通過流式傳輸需要適當的傳輸和控制協議。
1.2RTP/RTCP協議
RTP(Real-time Transport Protocol)實時傳輸協議是一種專門的網絡傳輸協議。[3]RTP傳輸協議是建立在UDP協議的基礎之上的,只能提供端到端的數據傳輸,沒有提供相應的傳輸質量保障機制。RTP協議是一種應用層協議,在發送RTP數據包之前需要先通過軟件編程對媒體文件數據包進行分組和RTP打包,然后將打包后的RTP數據發送給UDP接口,添加UDP傳輸信息和IP數據包頭,再通過Internet發送至接收端。
實時運輸控制協議RTCP(RTP Control Protocol)是RTP協議實際使用過程中不可或缺的一部分。[4]RTCP協議主要是在RFC3550和RFC3551中做出了解釋[5][6]。
RTCP協議的主要功能是:為RTP傳輸服務質量提供監視與反饋機制,對多媒體數據中不同的媒體流進行同步保證,還可以對多播組中的成員進行標識加以區分。RTCP協議同樣是UDP協議的子協議,RTCP分組主要是攜帶發送端和接收端對傳輸質量的統計信息報告。
1.3MPEG-4 AAC音頻壓縮標準
AAC編碼算法設計了大量算法模塊,使用戶可以根據編碼質量和實際應用的要求,使用不同模塊組合成復雜度不同的AAC編碼算法。其中,MPEG-4定義了三種不同復雜度的音頻編碼框架類型[7]。
(1)主配置框架(Main Profile):此框架包括了除增益控制模塊外的所有模塊,其運算復雜度和系統資源的消耗是最高的,但與此同時此種框架也可以提供最好的音質。
(2)低復雜度框架(Low Complexity Profile):此種算法框架擁有較高的適用性和性價比,比較適用于商業用途,如今最流行的Apple的iTunes音樂庫就使用了此種編碼框架。
(3)可變采樣率框架(Scalable Sampling Rate Profile):算法復雜度隨著帶寬的變化而變化,并取消了預測模塊,適用于網絡帶寬變換較大的應用場合。
本課題的總體設計方案是采用基于IMX6Q處理器的ARM嵌入式開發平臺,設計并且實現嵌入式音頻流媒體服務器的軟件應用程序。服務器系統分為3個模塊:原始音頻信號采集模塊、音頻壓縮編碼模塊、傳輸發送模塊。
2.1原始音頻信號采集模塊設計
在本系統中,將FM解調信號作為音頻輸入。聲卡則根據用戶設置參數對模擬音頻進行數字采樣,在量化之后便形成了原始音頻數據PCM流。對音頻采集的控制。ALSA中的Libasound庫提供了最高級且方便的編程接口。
數據采集函數:
snd_pcm_mmap_readi (snd_pcm_ t *pcm, void *buffer, snd_pcm_uframes_t size)
此函數具體實現了從聲卡中采集數據的任務,音頻數據采集以size為一個周期,采集數據存入緩沖區buffer,其中size=n*frames,根據MPEG編碼標準,MPEG-1 layer3的音頻壓縮每幀frames為1 152個樣點,而MPEG-4 AAC的音頻壓縮每幀frames為1 024個樣點。待一個采集周期結束后,調用fwrite()函數將buffer里的數據寫入管道緩沖區,等待下一模塊的接收。在音頻采集模塊程序設計中,預留了兩個參數設置接口,分別為采樣時間和采樣頻率。
2.2音頻壓縮編碼模塊設計
在此模塊中,采用MP3以及AAC音頻編碼技術,以滿足各種現實需求。MP3編碼技術得益于它的高壓縮率和高保真度,已經被廣泛應用于各種場合。AAC是一種獨立開發的音頻編碼技術,所以并不與MP3等早期音頻編碼技術相兼容。當AAC音頻的壓縮碼率達到96 kbps時,它便可以達到CD的音質,并且還支持5聲道編碼,比MP3更加適合于低碼率傳輸。理論上,同樣音質的AAC音頻傳輸時的帶寬占用量相較于MP3會降低1/4。為了實現多種音頻壓縮模式,并且簡化代碼編寫,本文使用添加了Libmp3lame依賴庫和Faac依賴庫的FFMPEG庫。
2.3傳輸發送模塊設計
使用Jrtplib實現RTP傳輸主要有以下流程。
(1)創建一個RTP傳輸的實例,以MyRTPSession sess為例,sess為此傳輸實例的名稱。
(2)調用RTPTransmissionParams類提供的SetPort base接口設置RTP會話要使用的本地端口號;調用RTPSessionParams類提供的SetOwnTimestampUnit接口設置時戳單元。時間戳單元的設置關系到之后時間戳增量的設置,如果設置的不恰當則會影響接收端的播放質量。時戳單元需要根據所要傳輸的媒體數據類型來確定,與媒體數據的時鐘頻率有關。根據標準規定,MPA數據類型的時鐘頻率為90000 Hz,則時戳單元就應該被設置為1/90 000。同時還需要調用SetAcceptOwnPackets接口,將其設置為true,使RTP會話被允許接受私人定義的數據類型。
(3)RTP會話創建成功后便可以開始RTP包的傳輸。首先需要調用RTPSession類提供的AddDestination()接口添加目的端口及其IP地址,同一個會話中允許添加多個目的端口。待準備工作完成后,就可以通過RTPSession類定義創建的SendPacket()接口發送RTP數據包了。SendPacket()是一個重載函數,有很多調用方法,其中最常用的一種是:SendPacket(const void *data,size_t len,uint8_ t pt,bool mark,uint32_t timestampinc)。
其中,data指針指向將要被發送的RTP包,len表示此RTP包的數據長度,pt為RTP負載類型的有效負載號。mark為標志位,取值為0或1,可以使用此標志位判斷一幀的開始或結束。
針對不同格式的壓縮音頻數據,需要對傳輸時的參數進行修改,在傳輸MP3音頻數據時,需要對負載類型加以定義并設置相關的參數。參照RFC1890標準的定義,應該選用的負載類型為MPA,有效負載號為14,時鐘頻率則為90 000 Hz,相應的時戳單元則需要設置為1/90 000,計算時間戳增量(以采樣率為48 kHz為例):
時間戳增量=(1152/48000)*(1/90000)=2160
所以參照標準,傳輸MP3音頻數據的發送函數為:
status = sess.SendPacket(buff,pksize,14,true,2160);
相比于MP3音頻的傳輸,傳輸AAC壓縮音頻數據則要復雜很多,在RFC協議中并沒有對AAC格式音頻定義負載類型,所以再次需要自己定義。參照RFC1890標準,有效負載號段96—127為動態號段,及用戶可以根據自身需求進行定義,在此將AAC的有效負載號定義為97,時鐘頻率設為90 000 Hz,相對應的時戳單元就等于1/90 000,時間戳增量的計算公式為:
時間戳增量=(1024/48000)*(1/90 000)=1920
AAC格式音頻的發送函數為:
status= sess.SendPacket(buff,pksize,14,t rue,1920)
此時雖然數據的發送函數已經設計完畢,但是目前從音頻壓縮模塊傳輸過來的AAC音頻是ADTS格式并不能直接進行RTP傳輸,需要將此種格式的AAC音頻轉化為可供RTP傳輸的特殊格式。此步驟分為兩步,第一步,去除原AAC音頻的7字節長的ADTS頭,得到純音頻壓縮流。第二步,添加AU頭,共4字節,分為AU_HEADER_LENGTH和AU_ HEADER。程序實現如下。
此段程序中,AU_HEADER_LENGTH設置為16,及AU_HEADER的長度為2個字節。AU_HEADER的前13個比特為AAC負載長度。
由于在RTP傳輸會話中,AAC的負載類型是自己定義的,第三方軟件在接收時并不能自動識別音頻格式并調用合適的解碼器,對此需要通過帶外的方式傳遞載有音頻編碼信息的SDP文件給第三方播放器(如VLC)。SDP文件的編寫規范參照RFC3016、RFC3064標準。[8][9]
在此,筆者參考各種規范,定義了用來傳輸AAC媒體流的SDP文件,并且經過實際驗證,可以通過VLC播放器打開并實現流媒體接收。
3.1硬件資源占用率測試
筆者通過Linux的TOP命令查看流媒體系統各個程序模塊的資源占用率情況(此階段,使用MP3格式作為測試格式)。進程PID3930為音頻采集模塊,PID3931為音頻編碼模塊,PID 3932 為傳輸發送模塊。可以看出,CPU占用率最高的為音頻編解碼模塊。其中音頻編碼模塊CPU占用率為44%,而其他模塊的CPU占用率都不高于1%。而在內存占用率方面,各模塊都不超過0.1%,可見此流媒體系統對硬件內存要求不高。
3.2網絡傳輸性能測試
經過網絡分析,筆者得到服務器端的數據發送速率,從在20秒內,發送速率一直維持在120Kbps~135Kbps,發送速率相對穩定。
本文采用基于IMX6Q處理器的嵌入式開發板,設計與實現了嵌入式流媒體服務器。整個系統分為3個模塊,分別是音頻采集模塊、音頻編碼模塊、網絡傳輸發送模塊。圍繞該系統的設計與實現,本文進行了以下的研究工作。
(1)在音頻編解碼技術上,本文采用了MP3以及AAC兩種音頻編碼技術,可以滿足系統在不同環境下的傳輸要求。其中對AAC壓縮編碼的支持,是本課題實現的一個亮點。
(2)在流媒體傳輸技術上,本課題不只實現了一對一的網絡傳輸,同時還可以實現組播模式,實現一對多的網絡傳輸,這是本課題實現的另一個亮點。
但是由于時間有限以及本人能力的不足,整個系統還有許多可以完善的地方。
(1)在硬件層面上,雖然IMX6Q是一種相當先進的微處理器,但是由于其他相關硬件的限制,尚不能完全發揮該處理器的性能。所以在未來的研究中,可以通過自行設計相關技術模塊,使其可以成為專業的流媒體服務器系統。
(2)在軟件層面上,本文設計的軟件系統總體分為3個模塊,但是在傳輸發送模塊由于需要添加對多種壓縮格式的支持,需要分別編寫應用程序,調用比較復雜,所以希望在后續的研究中,將此模塊進行整合,簡化程序調用方法。