• 沒有找到結果。

RTP 檔頭架構

二、 Java 多媒體系統

2.5 Java Socket & Real-Time Transport Protocol

2.5.2 Real-Time Transport Protocol

2.5.2.1 RTP 檔頭架構

RTP 封包包含一個檔頭以及在檔頭後面的負載資料,RTP 封包的檔頭格式 在RFC3550,根據[4],中有明確定義,而負載資料格式的切割方式,則根據負 載資料不同而有不同的定義,以下為介紹RTP 封包的檔頭資訊。

The RTP version number (V): 2bits,指出RTP的版本為何,在此RFC3550把此 值設定為2。

Padding (P): 1bits,指出封包的結尾有無padding data,padding data可以被用 於各種加密演算法。

Extension (X): 1 bit,指出延伸標頭是否存在,若存在則表除了 RTP 固定的檔 頭,還放了額外的檔頭資訊。

CSRC Count (CC): 4 bits,RTP packet 是由幾個來源所組成的。

Marker (M): 1 bit.指出此資料流的邊界,當設定為1時表此資料流已達邊界。

Payload Type (PT): 7 bits,是表示為一個索引,此索引指向多媒體設定檔的表,

指出payload data的格式。

Sequence Number: 16 bits,此數值指出此封包的位置,數值起始值是隨機產生,

隨著封包增加逐次加一。藉由這個數字,接收端可以偵測出遺失封包,以及將順 序錯誤的封包進行重新排列。

Timestamp: 32 bits,伺服端會根據取樣時間在每個封包上加上一個時間戳記,

使得接收端能得知何時必須處理此封包,當接收端接收的封包已逾時,則此封包 將被丟棄。

SSRC: 32 bits,辨別同步來源(Synchronization source),當此數值為零,表示此 payload就為其資料來源,若不為零則表其資料來源為mixer。

CSRC: 最多16項,每項32 bits,指出payload的來源。

圖 2-19 RTP data-packet header format.

第三章 Java多媒體系統動態分析

多媒體資料處理系統,必須由建立數個子系統方塊而組成。其所包括的子系 統如下,擷取裝置管理、媒體資料來源、影音來源之分流、影音壓縮處理、影音 整合與RTP封包建立和傳送(系統建立之細節請參考第二章)。

本論文依子系統的程式功能建立數個thread,如圖3-1。每個thread彼此間 會透過同步機制,互相溝通與合作,傳遞每個子系統所處理完成的媒體資料,並 將媒體資料包裝為RTP封包傳遞至接收端。

以下,會依序說明,各個thread的功能、thread的建構流程、thread之間是 以何種機制達成溝通與資料分享以及整個系統程式執行的細部運作。

圖3-1 Thread建立流程 3.1各個Thread的功能介紹

(1)Audio方面

RequestThread(A):執行開啟mike的程序,或是其它對mike的要求,如關

閉mike。

DirectSound PushThread(A):將mike所擷取的音訊資料放入子系統:「媒體資料 來源」的暫存器,接著將暫存器的音訊資料放入parser內的 暫存器。

SourceThread(A):將parser內的音訊資料取出,交由BasicFilterModule做資料壓 縮的處理,並且將完成壓縮的資料放入多工器內的暫存器。

RawBufferStreamThread(A):將多工器存的音訊資料交給RTPSession,建立RTP 封包,將封包交由接著由下層的UDP送出。

(2)Video方面

VFWRequestThread(V):執行開啟camera的程序,或是其它對camera的要求,

如關閉camera。

PushThread(V):將camera所擷取的影像資料放入子系統:「媒體資料來源」的暫 存器。

VFWTransferDataThread(V):將媒體資料來源的暫存器內所存的影像資料寫入 parser的暫存器。

SourceThread(V):將parser內的影像資料取出,交由BasicFilterModule做資料壓 縮的處理,並且將完成壓縮的資料放入多工器內的暫存器。

RawBufferStream Thread(V): 將多工器所存的影像資料交給RTPSession,建立 RTP封包,將封包交由接著由下層的UDP送出。

3.2 Threads建立的流程

由圖3-1Thread建立的流程,以下依序說明其建立流程以及thread所處理的 暫存器。

(1)1、2和3 thread的建立

程式Main thread開始執行,建立媒體資料來源,DataSource物件,此物件 會包函擷取裝置的路徑和管理影音來源的物件。接著呼叫DataSource物件的 connect( )函式,此時會分別建立RequestThread(A)、VFWRequestThread(V) 和DirectSoundPushThread (A)。

在建立RequestThread(A)之前,最主要必須為設置存放擷取資料的暫存器 大小,暫存器大小的設置與音訊來源有關,程序如下:

1.計算frameSize=取樣位元 X 通道數 / 8

2. 暫存器的大小=取樣率 X frameSize X 預設轉衝器長度(50) / 1000 以表格2-1音訊格式為例:

暫存器的大小=48000 X 4 X 50/1000=9600 (byte) 上例表示每一次擷取的資料量為9600 (byte)。

當建立RequestThread(A)時,RequestThread(A)會進入待命狀態,但由於 此thread設立了request旗標,其預設為0,唯有當request旗標大於0時,run( ) 函式裡,判斷式條件成立才能對mike改變狀態。但由於request旗標此時為0,因 此,此thread雖為待命狀態,只有當收到旗標狀態變更的通知,並且判斷式條件 成立,此thread才能對mike改變狀態。在此會先建立DirectSound

PushThread(A),由於未呼叫start( )函式,此時為初始狀態。

VFW RequestThread(V)設立vfwRequest旗標,其預設為-1,唯有當 vfwRequest旗標大於或等於0時,此thread才會進入到執行狀態,但由於

vfwRequest旗標此時為-1,因此此thread會放出執行權,並且進入封鎖狀態,但 由於它呼叫為sleep( )函式,因此當設立的時間到時,它會再次醒來,但若還有 其它thread也在競爭執行權時,就可能超過預定的等待時間才醒來。醒來後同樣 會再次檢查vfwRequest旗標。在此設置此暫存器的大小是依影像大小而決定,

以表格2-1影像格式為例:每次擷取的資料量為28800(byte)。

(2)4和5thread的建立

Main thread呼叫realizeProcessor( )函式,會建立RealizeWorkThread物 件,此thread會進入執行狀態,執行以下程序:呼叫doRealize( )函式,當呼叫此 函式時,會建立BasicFilterModule物件(處理媒體資料壓縮)和呼叫connectMux( ) 函式,建立RTPSyncBufferMux物件(多工器),初始多工器的輸入端時,會建立 兩個RawBufferSourceStream物件,此物件是媒體(A/V)輸入資料存放的地方。

當 建 立 RawBufferSourceStream 物 件 的 同 時 , 會 依 序 建 立 RawBufferStreamThread(A)和RawBufferStreamThread(V),此兩個thread都會 進入初始狀態,直到Main thread建立了RTPSessionMgr物件和SendStream物件 (所存放的媒體資料將會封成RTP封包),執行SendStream.start( )函式時(請參考 2.3.4節),此兩個thread才會呼叫start()函式才會進入待命狀態,。

由於RealizeWorkThread的run( )函式並非迴圈,當上面程序都執行完成 後,此thread會進入結束狀態,此thread會佔用記憶體位置,Java提供自動回收 廢棄不用的記憶體(automatic garbage collection),也提供記憶體回收執行緒 (garbage-collector thread),會自動回收程式不再使用的記憶體。

(3)6、7、8和9 thread的建立

最後必須要求實際的媒體資料輸入,因此會建立PrefetchWorkThread,此 thread會進入執行狀態,接著呼叫doPrefetch( )函式,接著執行以下程

序:BasicSourceModule.doStart( ),其會呼叫RawBufferParser.start( )函式,接 著會呼叫PushBufferStream陣列內的VFWSourceStream.start( )函式與

DirectSoundStream.start( )函式。

當呼叫VFWSourceStream.start( )函式時,則會建立PushThread(V),此 thread會進入待命狀態,當thread取得執行權,進入執行狀態,開始執行時會先 睡0.01秒,醒來後會呼叫yield( )函式,此函式目的是要達到公平的排程。緊接 著會建立VFWTransferDataThread(V),此thread會進入執行狀態,會先檢查

bufferQ(在此bufferQ泛指儲存資料的暫存器)是否存有資料,若無資料,則會進 入鎖定狀態,等待0.25秒,醒來後一樣會再檢查bufferQ。建立上面兩個thread 的同時,會送出vfwRequest=1,改變VFW RequestThread(V)旗標的狀態,此 thread會開啟camera。

當呼叫DirectSoundStream.start( )函式,會先送出request旗標為3至 RequestThread(A),此thread則會開啟mike。接著會呼叫DirectSound PushThread(A).start(),此thread會進入待命狀態。

接著會依據有多少影音tracks而建立相同數目的SourceThread,在此會有 SourceThread(A)和SourceThread(V),並且都會進入等待狀態,當thread取得 執行權進入執行狀態,當檢查bufferQ為不可讀時,則此thread會進入封鎖狀態,

直到此thread收到解開封鎖的通告,此thread才會再進入執行狀態。

由於PrefetchWorkThread的run函式並非迴圈,當上面程序都執行完成後,

此thread會進入結束狀態。

3.3 Thread之間的資料分享與溝通

本論文所使用的排程機制為3.6.5節所提:自定排程,對各個thread用wait( ) 函式保留執行權。處理媒體資料的各個子系統,當各自要處理媒體資料時,都會 將媒體資料存在各自的暫存器,因此thread就必須做為每個暫存器之間的橋樑,

負責將媒體資料自暫存器讀出,或是將媒體資料放入暫存器。

子系統內的暫存器,其所扮演的角色就是thread能否執行的條件式,若 thread無法執行任務時,子系統內的暫存器就會扮演管理thread的角色,直到收 到此thread可執行條件成立的通告,就會解開對此thread的管理,而此thread就 會鎖住此暫存器,而執行資料讀出或放入的任務。

由上可知,本論文是利用子系統內的暫存器,做為每個thread互相制衡的機 制,同時每個子系統也必須各自完成,處理媒體的任務。以上Java thread的相

關知識請參考3.6節。

3.3.1 子系統介紹和Thread所屬之類別物件 (1) 子系統介紹

在"3.6 Java thread"會提到,同一個類別可產生多個thread,圖3-3為介紹 每個thread是包含在哪些類別,並且說明子系統所擁有的暫存器內容。

(a)

(b)

(c) (d)

圖3-3 (a)音訊來源(b)影像來源(c)影音分流(d)多工器輸入來源

在3.2節,有說明每一次mike所抓取的資料大小,在DirectSoundStream物 件內會有一bufferQ物件的暫存器,且為FIFO的特性,此暫存器擁有一個queue,

queue儲存大小與3.2節所計算的資料量大小相同。VFWSourceStream物件內會 有一bufferQ物件的暫存器,且為FIFO的特性,此暫存器擁有八個queue,每個 queue儲存大小與擷取的影像資料量有關,如表格2-1其大小為28800(byte)。

在RawBufferParser物件內的bufferQ物件的暫存器所擁有的queue的數量:

音訊方面為1,影像為1,兩者大小設置都與前者相同。BasicMuxModule物件內 的bufferQ物件的暫存器同樣具有FIFO的特性,其所擁有的queue的數量,影音 皆為5,每個queue儲存大小皆為1456(byte)。

媒 體 資 料 來 源 DataSource 物 件 會 包 含 DirectSoundStream 物 件 和 VFWSourceStream物件。VFWSourceStream物件會將擷取到的影像資料放入暫 存 器 中 , 其 過 程 為 VFWRequestThread(V) 負 責 管 理 camera , 當

VFWRequestThread (V)開啟camera,PushThread(V)將擷取的影像資料存入暫 存器中。VFWTransferDataThread(V)會將暫存器中的影像資料取出,接著放入 RawBufferParser物件的暫存器,在以上過程中,我們會發現暫存器是由後兩個 thread所共用的,因此當thread要放入或讀出資料時,都必須注意資料同步的問 題。

由上圖3-3,除了VFWSourceStream物件內包含數個thread,要注意資料 同步的問題之外,每個物件之間,資料的傳遞則是靠著thread之間的溝通,主要 是每個物件都有提供一個機制能讓thread成為等待區,此機制能夠幫助thread間 的通訊。

3.3.2 Thread的設計原理與制衡

依thread所處理的媒體資料特性,分別以處理音訊和影像資料的thread來加 以探討。Java虛擬機對作業系統來說,也是一支程式,Java虛擬機會自作業系統 取得執行權,接著將執行權分給各個thread使用。在此系統中,所有的thread的 run( )函式都是無窮迴圈,除非main thread完全結束,否則各個thread都會依排 程機制繼續執行。

在此,我們必須先了解一件事,在此的9個thread(包含處理影像和音訊)都 為無窮迴圈,每一個thread都是相同的優先度,在任何時間每個thread都是有權 利競爭執行權,除了處在封鎖狀態的thread是無法競爭。Thread會進入封鎖狀

在此,我們必須先了解一件事,在此的9個thread(包含處理影像和音訊)都 為無窮迴圈,每一個thread都是相同的優先度,在任何時間每個thread都是有權 利競爭執行權,除了處在封鎖狀態的thread是無法競爭。Thread會進入封鎖狀

相關文件