• 沒有找到結果。

一、 緒論

1.2 研究動機

近幾年來,Java蓬勃發展,其跨平台的特性以及優異的物件導向語法,Java 是非常適合用來發展系統、開發應用程式的語言。Java在多媒體串流上,有提供 相關的套件,如Java Media Framework(JMF)為Sun與IBM合力制定的一個開 放性與具可擴充性的多媒體處理API,其提供上層應用程式或Applet,是一種處 理多媒體串流的一致性介面。JMF提供大部份標準的媒體編碼影音格式,但未包 含MPEG4和H.264,但Apple推出QuickTime for Java的API 彌補JMF的不足,

使得Java在多媒體方面的支援更加強大。

由於以上種種因素,我們對於Java 在多媒體上的支援倍感興趣,Java 在多 媒體方面釋出以下幾種套件:Java Media Framework、Java 3D、Java 2D…等。

其中Java Media Framework(JMF)套件可以做得到的功能相當的多,如擷取影 音檔案、http 檔案下載和播放,也可以做到傳輸串流媒體,JMF 算是相當完整 的多媒體套件。藉此本論文將會探討JMF 對處理多媒體資料和即時傳輸所提供 的套件,以及程式如何實際建立與執行。

第二章 Java 多媒體系統

Codec.open( )

BasicMuxModule RTPSyncBufferMux

RTPSession RTPSinkStream

A B C D

A: Get multimedia format of hardware support.

B: Tell User &User choice media format.

C: Tell User what media format they can use to transmit streaming data & User choice media format.

D: User tell Program what information of client . information

building System

System Architecture

1 2 3 4

Processor

圖 2-1 媒體資料處理系統

圖 2-1 中,藍色方塊是描述使用者介面(UI)的建構流程,其表示傳送端的系 統程式與本地端使用者之間的互動;建構子系統的同時必須向使用者取得建構子 系統所需的訊息。綠色的子系統方塊主要為處理媒體資料和傳送串流媒體至遠方

用戶端。圖 2-1 中,information:代表建立子系統時,所必須自 UI 取得的相關 取裝置的位置、支援哪些影音格式。JMF 套件有提供 query mechanism(請參考 2.4.1),以得知擷取裝置的資訊,因此必須執行 CaptureDeviceManager.

getDeviceList( )函式,取得包含擷取裝置的相關資訊之物件:CaptureDeviceInfo (包含 VFWDeviceQuery)物件,CaptureDeviceInfo 物件內容主要為:裝置名稱、

裝置位置、此裝置所支援的格式、音訊的取樣率與影像的大小。

表格 2-1 舉出 CaptureDeviceInfo 的部分內容:

表格 2-1 擷取裝置資訊 音訊之相關資訊(CaptureDeviceInfo)

裝置名稱

(MediaLocator)

DirectSoundCapture : dsound://

音訊格式/

取樣率

LINEAR, 48000.0 Hz, 16-bit, Stereo, LittleEndian, Signed

影像之相關資訊(VFWDeviceQuery) 裝置名稱

(MediaLocator)

vfw:Microsoft WDM Image Capture (Win32):0 : vfw://0

影像格式 /影像大小

YUV Video Format: Size =java.awt.Dimension[width=160,heig ht=120], MaxDataLength = 28800

RGB, 160x120, Length=57600, 24-bit

當此階段無法取得CaptureDeviceInfo物件時,判定無可以使用的擷取裝置時,會 顯示"No capture devices found in JMF registry!"的對話視窗。

2.2.2 系統支援之影音格式

圖 2-2,B 之方塊中,其主要為建立一對話視窗,將系統有支援的影音格式 告知使用者(本地端),使用者可依其需求選擇影音格式、音訊取樣率與影像大 小。對話視窗顯示兩資訊:音訊和影像資訊。在音訊方面,必須呼叫

CaptureDeviceInfo.getFormat( )函式,取得一存有音訊格式型態的陣列,此陣 列包含擷取裝置所支援的輸出音訊格式目錄。將此目錄裡的資訊一一抽出,做為 建立音訊的訊息對話視窗,告知使用者可選用的音訊格式。

在影像方面,必須呼叫VFWDeviceQuery.getFormat( )函式,取得一存有影 像格式型態的陣列,此陣列包含擷取裝置所支援的輸出影像格式目錄。同樣將此 目錄裡的資訊一一抽出,做為建立影像的訊息對話視窗,告知使用者可選用的影 像格式。如下圖 2-3:

圖 2-3 裝置支援格式

當使用者完成選定影音格式的動作後,其相關資訊(圖 2-1 的虛線 1)會用來做 DataSource 物件的初始與建立(2.3.1 節會說明此物件的功能)。

2.2.3 影音編碼格式選項

由圖 2-1 中,經由使用者選定擷取裝置輸出的媒體格式,建立DataSource

物件,接著會選用適當的parser,同時建立 processor(以上流程在 2.3.2 節說 明)。當 parser 選定後,會依 parser 輸出的內容格式(content type)找出相對應 的多工器,此多工器的輸入影音格式會成為建立C 之方塊時所需的資訊(圖 2-1 的虛線 2)。圖 2-2,C 之方塊中,主要為告知使用者,影音編碼的傳輸格式(也 就是多工器的輸入影音格式)有哪一些,由使用者選定後,影音資料將來會壓縮 為使用者所選定的影音編碼格式(圖 2-1 的虛線 3)。

以下為取得影音編碼格式選項的程序:

(1)找出 JMF 支援的多工器

執行pluginManager.getPlugInList (,,5)函式(請參考 2.4.1),取得所有確定 存在的多工器,總共有 10 個。如下圖 2-4:

圖 2-4 JMF 所支援的多工器 (2)建立 ContentDescriptor 物件

執行processor.getSupportedContentDescriptors ( )函式(請參考 2.4.1 節),此函式會取得媒體資料格式。前面有提到,在此主要處理擷取裝置的影音 資料,因此此函式所取得的影音資料的內容型別(content type)為 raw,此時意 味著所取得的影音資料為未經過壓縮處理的媒體資料。利用前面所取的內容型別 加上".rtp",接著建立 ContentDescriptor 物件,其包含內容型別為"raw.rtp",

意謂著經處理後的媒體資訊是要送至網際網路。

(3)找尋適當的多工器

1.執行 processor.setContentDescriptor(contentDescriptor)函式,設定此時 processor 的輸出內容型別為"raw.rtp",此函式會詢問 PlugInManager,因此會 呼叫PlugInManager.getPlugInList(,contentDescriptor, 5)函式,詢問在所有多 工器中是否有內容型別為"raw.rtp"的多工器。以下為找尋適當多工器的過程:

將"raw.rtp"轉為某一整數。而所有的多工器會將它的輸出格式(含有各自的 內容型別)轉為整數,接著依序與"raw.rtp"所對應的整數做比對,直到找到多工 器的內容型別與此整數互相符合,在此所找到的多工器是

com.sun.media.Multiplexer.RTPSyncBufferMux,此多工器是負責處理要送至 網際網路上的媒體資料。

2.執行 RTPSyncBufferMux.setInputFormat(input[],TrackID)函式,input[ ] 為一陣列,其存放processor 的輸出媒體格式:codec 的列表;TrackID 為音訊或 影像的TrackID。此函式會將 RTPSyncBufferMux 所能提供的媒體輸入格式與 RTP Payload Type 作比對,互相符合的格式資訊會存入陣列中,接著利用所得 到的資訊建立影音編碼格式選項的對話視窗,如圖 2-5。

影音編碼格式選項的對話視窗,其告知傳輸端使用者下面資訊:

影像編碼格式選項:h263/rtp 和 jpeg/rtp。

音訊編碼格式選項: dvi/rtp、mpegaudio/rtp、ulaw/rtp、gsm/rtp、g723/rtp。

圖 2-5 顯示 Video 編碼格式 2.2.4 取得用戶端資訊

圖 2-2,D 之方塊中,其主要為建立一取得用戶端資訊的對話視窗。對話視 窗要求傳送端的使用者,輸入使用者所要傳送的目的地之IP 位址、port,當使 用者輸入資訊後,會執行使用者所輸入接收端的IP Address、Port 是否正確的 檢查程序,若有錯誤則會顯示通知使用者”有錯誤的”的對話視窗,並且對話視窗 不會再往下一頁跳,仍是在原先的視窗等待使用者重新輸入資訊。圖 2-1 中,我 們可知,使用者所輸入的資訊是將來要建立RTPSession 所需的資訊((圖 2-1 的 虛線 4))。

transmit

DataSource(A/V)

BasicSourceModule RawBufferParser

BasicFilterModule Codec.open( )

BasicMuxModule RTPSyncBufferMux

RTPSession RTPSinkStream System

Processor

1 2 3 4

2.3 子系統之建構流程

圖 2-6 處理媒體之子系統建構流程

2.3.1 影音來源

藉由UI 所傳遞的資訊(圖 2-6 的虛線 1):影音資料格式和影音來源位置,建 立管理影音資料的DataSource 物件,如圖 2-6,必須執行下面函式(請參考 2.4.1):

JMFUtils.createCaptureDataSource(audioDeviceName, getAudioFormat( ), videoDeviceName, getVideoFormat( )),其函式利用已知的裝置名稱和影音媒體 格式,建立DataSource 物件,如表格 2-2。

表格 2-2 DataSource 物件 DataSource

streams:PushBufferStream[2]

Connect()

DataSource 物件內的 PushBufferStream 陣列,會有存有管理影像資料和音 訊資料的物件,分別是VFWSourceStream 和 DirectSoundStream 物件。

connect( )函式與 thread 的建立有關,請參考 3.2 節。

2.3.2 影音分流

有了影音資料的來源,我們必須利用DataSource 物件作為引數,建立圖 2-6 中的Processor,接著必須執行 Manager.createProcessor(DataSource)函式。媒 體資料將會輸入Processor,經過各個處理媒體資料的元件,執行相關資料處理 的程序。當媒體資料傳遞至Processor,則必須將影音資料執行影音分流的處理,

因此必須執行以下程序,(1)找出適當的 parser(解多工器),執行影音分流的處理 (2)建立 BasicSourceModule 物件,此物件作為媒體資料壓縮處理的來源。

(1)找出適當的 parser。DataSource 物件包含媒體的內容型別,由於影音來 源自擷取裝置,因此內容型別為raw,藉由此內容型別找出相對應的 parser。首 先建立ContentDescriptor 物件,其包函媒體的內容型別 (raw),接著執行 PlugInManager.getPlugInList(ContentDescriptor, ,1)函式,此函式會找尋所有 JMF 有支援的 parsers(圖 2-7),最後將內容型別 (raw)和所有 parsers 的輸入的 格式都轉為數值,接著開始互相比對,互相符合者就是我們所要使用的parser,

在此為RawBufferParser,接著建構 RawBufferParser 物件,此 parser 是負責 處理未經過處理的媒體資料。

圖 2-7 JMF 支援的 parsers

(2)建立 BasicSourceModule 物件。利用上述的 parser 和 DataSource 物件 以引數的形式,呼叫BasicSourceModule(DataSource, parser),建立

BasicSourceModule 物件,此物件負責將音訊或影像資料送至處理壓縮媒體資料 的子系統,請參考 3.4 節。

當Processor 已得到關於媒體資料的資訊,確定資料的格式與位置,

Processor 的狀態應該轉變為 Configured 的狀態(請參考 2.4.1 節)。因此必須呼 叫configureProcessor ( )函式,主要執行下面程序:執行 parser 的 getTracks( ) 函式,會依track 的數量建立相同數量的 RawBufferParser$FrameTrack 物件:

BufferTransferHandler,此物件將會分別抽出音訊和影像的媒體資料,負責將 媒體資料送入parser。

最後必須要對DataSource 物件設置負責資料傳遞的 BufferTransferHandler,分別下面函式:

VFWSourceStream.setTransferHandler(RawBufferParser$FrameTrack)、

DirectSoundStream.setTransferHandler(RawBufferParser$FrameTrack),

BufferTransferHandler 是負責將媒體資料自 DataSource 物件抓入 Parser 內的 暫存器,實際資料的搬運細節請參考 3.4。

2.3.3 影音壓縮

欲將媒體資料以串流的傳輸方式傳送至用戶端前,必須將未處理的媒體資料 壓縮,轉換為能進行即時串流傳輸的媒體格式。由 2.2.3 節,自UI 取得影音編 碼格式的資訊,由此資訊選擇所要使用的Codec,Codec 以引數的形式建立 BasicFilterModule 物件,此物件是負責將未經處理的媒體資料交由 encoder 處 理,編碼完成後的媒體資料會送入多工器,由多工器將媒體資料送至

RTPSession。

因此必須將Processor 狀態由 Configured 更新為 Realized(請參考 2.4.1),

更新Processor 狀態必須執行 realizeProcessor( )函式,此函式會建立 RealizeWorkThread 物件,此 thread 進入待命狀態,當開始執行時會呼叫 doRealize( )函式,來執行以下兩個程序:1.建立 BasicFilterModule 物件,2.建立 多工器。

1.Codec 以引數的形式建立 BasicFilterModule 物件,如表格 2-3。

表格 2-3 BasicFilterModule 物件 BasicFilterModule

codec:Codec

ic:BasicInputConnector oc:BasicOutputConnector

表格 2-3 中ic 為媒體資料輸入 BasicFilterModule 的路徑,oc 為自

BasicFilterModule 輸出的路徑,ic 和 oc 是輸入/出 BasicFilterModul 的連結器,

它的內部會定義 buffer 和媒體輸入/出的格式。接著呼叫 BasicFilterModule.

doRealize( )函式,此函式會執行 codec.open( )函式,對 encoder 作初始。

表格 2-4 Picture Formats Supported FRAME

FORMAT

Width height nativeformat

SQCIF 128 96 0

QCIF (PAL) 176 144 1

CIF (PAL) 352 288 2

在此以H.263 為例,表格 2-4 中,提供 3 種影像格式,藉由影像資料欲壓縮 的影像格式(大小)決定 nativeformat 參數值,初始 h.263 的 encoder。由 2.2.2 節,自UI 取得擷取的影像大小的資訊,接著對影像大小的資訊作一簡單的檢驗

在此以H.263 為例,表格 2-4 中,提供 3 種影像格式,藉由影像資料欲壓縮 的影像格式(大小)決定 nativeformat 參數值,初始 h.263 的 encoder。由 2.2.2 節,自UI 取得擷取的影像大小的資訊,接著對影像大小的資訊作一簡單的檢驗

相關文件