Android多媒體開發介紹

Android多媒體開發介紹

一、       多媒體架構

基於第三方PacketVideo公司的OpenCORE來實現,支持所有通用的音頻/視頻/靜態圖像格式,包括:MPEG4、H.264、MP3、AAC、AMR、JPG、PNG、GIF等。從功能上分爲兩部分,一是音/視頻的回放(PlayBack),二是音視頻的紀錄(Recorder)。

CODEC(編解碼器)使用OpenMAX 1L interface接口進行擴展,可以方便地支持hardware / software codecplug-ins。

Open Core多媒體框架有一套通用可擴展的接口針對第三方的多媒體遍解碼器,輸入/出設備等等 。

多媒體文件的播放、下載,包括3GPP, MPEG-4,AAC and MP3containers

流媒體文件的下載、實時播放,包括:3GPP, HTTP and RTSP/RTP

動態視頻和靜態圖像的編解碼,如:MPEG-4, H.263 and AVC(H.264), JPEG

語音編碼格式:AMR-NB and AMR-WB

音樂編碼格式:MP3, AAC, AAC+

視頻和圖像格式:3GP、MPEG-4 and JPEG

視頻會議:基於H324-M standard

 

二、       Media Framework名詞解釋

1.    OpenCore介紹

OpenCoreAndroid多媒體框架的核心,所有Android平臺的音視頻採集,播放的操作都是通過它來實現。通過Open Core程序員可以方便快速的開發出想要的多媒體應用程序,例如:音視頻的採集,回放,視頻會議,實時的流媒體播放等等應用。

2.    OpenCore代碼結構

OpenCore的代碼在Android代碼的External/Opencore目錄中。這個目錄是OpenCore的根目錄,其中包含的子目錄如下所示:

Ø  android:這裏面是一個上層的庫,它實現了一個爲Android使用的音視頻採集,播放的接口,和DRM數字版權管理的接口實現。

Ø  baselibs:包含數據結構和線程安全等內容的底層庫

Ø  codecs_v2:音視頻的編解碼器,基於OpenMAX實現

Ø  engines:核心部分,多媒體引擎的實現

Ø  extern_libs_v2:包含了khronos的OpenMAX的頭文件

Ø  fileformats:文件格式的解析(parser)工具

Ø  nodes:提供一些PVMF的NODE,主要是編解碼和文件解析方面的。

Ø  oscl:操作系統兼容庫

Ø  pvmi:輸入輸出控制的抽象接口

Ø  protocols:主要是與網絡相關的RTSP、RTP、HTTP等協議的相關內容

Ø  pvcommon:pvcommon庫文件的Android.mk文件,沒有源文件。

Ø  pvplayer:pvplayer庫文件的Android.mk文件,沒有源文件。

Ø  pvauthor:pvauthor庫文件的Android.mk文件,沒有源文件。

Ø  tools_v2:編譯工具以及一些可註冊的模塊。

3.    OpenMax介紹

Ø  OpenMAX是Khronos制定的API,Khronos也是OpenGL的制定者。

Ø  OpenMAX是無授權費、跨平臺的應用程序接口API,通過媒體加速組件能夠在開發、集成和編程環節中實現跨多操作系統和處理器硬件平臺,提供全面的流媒體編解碼器和應用程序便攜化。

Ø  在架構底層上爲多媒體codec和數據處理定義了一套統一的編程接口(OpenMAX IL API),對多媒體數據的處理功能進行系統級抽象,爲用戶屏蔽了底層細節。因此多媒體應用程序和多媒體框架通過 OpenMAX IL可以以一種統一方式來使用codec和其他多媒體數據處理功能,具有了跨越軟硬件平臺的移植性。

Ø  OpenMax在系統中的位置





Ø  OpenMax層次

  OpenMAX AL(Appliction Layer)

OpenMAX AL API 在應用程序和多媒體中間件之間提供了一個標準化接口,多媒體中間件提供服務以實現被期待的 API 功能。 AL向多媒體接口提供應用冊便攜性。

  OpenMAXIL(Integration Layer)

OpenMAX IL 作爲音頻,視頻和圖像編解碼器,能與多媒體編解碼器交互,並以統一的行爲支持組件(例如資源和皮膚)。編解碼器供應商必須寫私有的或者封閉的接口集成進移動設備。IL的目的是使用特徵集合爲編解碼器提供一個系統抽象,爲解決多個不同媒體系統之間輕便性的問題。

  OpenMAXDL(Development Layer)

OpenMAX DL 定義了一個API,它是音/視頻和圖像功能的集合。硅供應商能夠在一個新的處理器上實現並優化其,然後編解碼供應商使用其來編寫更廣泛的編解碼器功能。它包括音頻信號的處理功能,如FFT和filter;圖像原始處理,如顏色空間轉換和視頻原始處理,以實現例如MPEG-4、H.264、MP3、AAC和JPEG等編解碼器的優化。 OpenMAX通過iDL 和aDL來支持加速, iDL使用OpenMAX IL結構,aDL向OpenMAX DL API增加了異步接口。

 

三、       Media Framework架構

1. Camcorder Framework

 

2. Audio Software Overview

 

3. SurfaceFlinger

Ø  Android中的圖形系統採用Client/Server架構。Server (即SurfaceFlinger)主要由c++代碼編寫而成。Client端代碼分爲兩部分,一部分是由Java提供的供應用使用的api,另一部分則是由c++寫成的底層實現。

Ø  Java View及其子類(如TextView, Button)要畫在surface上。每個surface創建一個Canvas對象 (但屬性時常改變),用來管理view在surface上的繪圖操作,如畫點畫線。每個canvas對象對應一個bitmap,存儲畫在surface上的內容。

Ø  每個Surface通常對應兩個buffer,一個front buffer, 一個back buffer。其中,back buffer就是canvas繪圖時對應的bitmap,繪畫總是在back buffer上,需要更新時,則將back buffer和front buffer互換。

Ø  SurfaceFlinger—High-LevelOverView


Ø  Java Surface (frameworks/base/core/java/android/view/Surface.java)。該對象被應用間接調用(通過SurfaceView,ViewRoot等), 應用需要創建surface,(並同時創建canvas), 將圖形繪製到這個對象上,並最終投遞到屏幕上。

Ø  C++ Surface(frameworks/base/libs/ui/Surface.cpp。 這個對象被Java Surface通過Jni 調用,實現Java Surface 的功能。

Ø   ISurface (以及其派生類BnSurface)。這個對象是應用和server之間的接口。C++ Surface創建這個ISurface (BnSurface)併發送命令,如更新surface內容到屏幕上。Server端接受這個命令並執行相應操作。

 

四、       Media API

Android提供Media API給開發人員使用:MediaPlayer、MediaRecorder、Android MediaAPIs。

1.    MediaPlayer

提供的基本接口如下:

Public Methods

static MediaPlayercreate(Context context, Uri uri)

Convenience method to createa MediaPlayer for a given Uri.  

int getCurrentPosition()

Gets the current playbackposition.    

int getDuration()

Gets the duration of thefile.    

int getVideoHeight()

Returns the height of thevideo.   

int getVideoWidth()

Returns the width of thevideo.   

boolean isPlaying()

Checks whether theMediaPlayer is playing.    

void pause()

Pauses playback.    

void prepare()

Prepares the player forplayback, synchronously.    

void prepareAsync()

Prepares the player forplayback, asynchronously.    

void release()

Releases resourcesassociated with this MediaPlayer object.   

void reset()

Resets the MediaPlayer toits uninitialized state.    

void seekTo(int msec)

Seeks to specified timeposition.   

void setAudioStreamType(intstreamtype)

Sets the audio stream typefor this MediaPlayer.   

void setDataSource(Stringpath)

Sets the data source(file-path or http/rtsp URL) to use.        

voidsetDisplay(SurfaceHolder sh)

Sets the SurfaceHolder touse for displaying the video portion of the media.    

void setVolume(floatleftVolume, float rightVolume)

Sets the volume on thisplayer.

void start()

Starts or resumesplayback.    

void stop()

Stops playback afterplayback has been stopped or paused.

可以看出MediaPlayer類提供了一個多媒體播放器的基本操作,播放,暫停,停止,設置音量等等。

2.    MediaPlayer結構

MediaPlayer JNI

代碼位置 /frameworks/base/media/jni

MediaPlayer (Native)

代碼位置/frameworks/base/media/libmedia

MediaPlayerService (Server)

代碼位置/frameworks/base/media/libmediaplayerservice

MediaPlayerService HostProcess

代碼位置/frameworks/base/media/mediaserver/main_mediaserver.cpp

PVPlayer

代碼位置 /external/opencore/android/

3.    MediaPlayer調用

4.    Media Recorder

提供的基本接口如下:

Public Method:

void prepare()

Prepares the recorder tobegin capturing and encoding data.    

void release()

Releases resourcesassociated with this MediaRecorder object.    

void reset()

Restarts the MediaRecorderto its idle state.    

void setAudioEncoder(intaudio_encoder)

Sets the audio encoder to beused for recording.    

void setAudioSource(intaudio_source)

Sets the audio source to beused for recording.    

void setOutputFile(Stringpath)

Sets the path of the outputfile to be produced.    

void setOutputFormat(intoutput_format)

Sets the format of theoutput file produced during recording.    

voidsetPreviewDisplay(Surface sv)

Sets a Surface to show apreview of recorded media (video).   

void start()

Begins capturing andencoding data to the file specified with setOutputFile().    

void stop()

Stops recording.

 

五、       Android音頻

 

 

 

 


 

Android Framework的音頻子系統中,每一個音頻流對應着一個AudioTrack類的一個實例,每個AudioTrack會在創建時註冊到AudioFlinger中,由AudioFlinger把所有的AudioTrack進行混合(Mixer),然後輸送到AudioHardware中進行播放。AudioTrack和AudioFlinger的通信機制通常,AudioTrack和AudioFlinger並不在同一個進程中,它們通過android中的binder機制建立聯繫。

 

 

1、Android音頻處理的基本接口

 

在Android開發中,根據不同的場景,出於衝突處理策略的考慮,開發者需要利用不同的接口來進行音頻資源的播放。

AudioManager爲上層應用提供了聲音設置管理接口.

AudioService爲所有的音頻相關的設置提供服務。他定義了了一個AudioSystemThread 的類,用來監控音頻控制相關的信號,當有請求時,它會通過調用AudioSystem 的接口實現音頻的控制,這裏的消息處理是異步的。此外在AudioService還抽象出了一套發送音頻控制信號的接口爲AudioManager提供支持。 

AudioSystem提供了音頻系統的基本類型定義,以及基本操作的接口。

  對於音調,可以通過ToneGenerator來播放;ToneGenerator提供了對DTMF音(ITU-T Q.23),以及呼叫監督音(3GPP TS 22.001)、專用音(3GPP TS 31.111)中規定的音頻的支持,根據呼叫狀態和漫遊狀態,該文件產生的音頻路徑爲下行音頻或者傳輸給揚聲器或耳機。

對於提示音,可以通過Ringtone來播放;Ringtone和RingtoneManager爲鈴聲、提示音、鬧鐘等提供了快速播放,以及管理接口。實質是對媒體播放器提供了一個簡單的封裝。

  對於遊戲中的音頻資源,可以通過SoundPool來播放。

對於錄音功能,則需要通過MediaRecorder和AudioRecord等來進行音頻記錄。

除了這些直接的音頻類外,對於音量調節、音頻設備的管理等,Android還提供了相關的類來處理。

AudioManager通過音頻服務,爲上層提供了音量和鈴聲模式控制的接口,鈴聲模式控制包括揚聲器、耳機、藍牙等是否打開,麥克風是否靜音等。在開發多媒體應用時會經常用到AudioManager,關於Android AudioManager音量控制流程。

SoundPool能夠播放音頻流的組合音,這對遊戲應用而言顯然非常有用。SoundPool可以從APK包中的資源文件或者文件系統中的文件將音頻資源加載到內存中。在底層的實現上,SoundPool通過媒體播放服務可以將音頻資源解碼爲一個16bit的單聲道或者立體聲的PCM流,這使得應用避免了在回放過程中進行解碼造成的延遲。除了回放過程中延遲小的優點外,SoundPool還能夠對一定數量的音頻流進行同時播放。當要播放的音頻流數量超過SoundPool所設定的最大值時,SoundPool將會停止已播放的一條低優先級的音頻流。SoundPool最大播放音頻流數量的設置,可以避免CPU過載和影響UI體驗。

Android平臺中關於音頻的播放還有另一種方式是MediaPlayer。MediaPlayer的特點是同一時間卻只能播放一個,適合較長但是對時間要求不高的情況。

 

2、MediaServer分析

  MediaServer是整個android中media部分的核心和靈魂。幾乎所有與多媒體播放相關的內容都放在這裏。包括了音視頻的編解碼以及顯示輸出。

1. 先初始化AudioFlinger

其初始化通過AudioFlinger的父類BindService創建唯一的AudioFlinger實例。

2. 然後初始化MediaPlayerService和CameraService

3. 最後初始化AudioPolicyService

 

3、AudioPolicyService 和AudioPolicyManager分析

AudioPolicyService是Android音頻系統的兩大服務之一,另一個服務是AudioFlinger,這兩大服務都在系統啓動時有 MediaSever加載。

AudioPolicyService主要完成以下任務:

l  JAVA應用層通過JNI,經由IAudioPolicyService接口,訪問AudioPolicyService提供的服務

l  輸入輸出設備的連接狀態

l  系統的音頻策略(strategy)的切換

l  音量/音頻參數的設置

AudioPolicyManager

   AudioPolicyService的很大一部分管理工作都是在AudioPolicyManager中完成的。包括音量管理,音頻策略(strategy)管理,輸入輸出設備管理。

通過AudioPolicyService的 AudioCommandThread,最終會將設置應用到AudioFlinger的相應的Track中。

 

4、 AudioFlinger分析

AudioFlinger負責管理每個音軌AudioTrack及RecordTrack,主音量控制,每種聲音流的屬性設置,設備控制,音效控制。AudioFlinger是android中的一個service,在android啓動時就已經被加載。

播放線程實際上是MixerThread的一個實例,會把該線程中的各個Track進行混合,必要時還要進行ReSample(重採樣)的動作,轉換爲統一的採樣率(44.1K),然後通過音頻系統的AudioHardware層輸出音頻數據。

SRC[Sample Rate Converter,採樣頻率轉換] SRC的作用就是改變信號的採樣率,低採樣率往高採樣率轉換時就是一個重採樣的過程,重採樣對象不再是原始信號,而是這個低採樣率的信號,因爲採樣率不夠需要插入更多的採樣點以達到需要的採樣率和採樣大小。

三種平臺的音頻架構對比

一、android平臺

 

 

  Android使用的是爲智能終端專門制定的ALSA(AdvancedLinux Sound Architecture,高級Linux聲音架構)框架。

從Android的音頻架構及流程分析,由於其驅動庫位於核心層,也就意味着音頻設備廠商、用戶無法象PC平臺那樣安裝驅動來改善音質。我們在實際的應用中也能感受到,Android設備音質普遍偏差。音質出現偏差一個主要的問題是處在SRC這裏。低採樣率往高採樣率轉換時就是一個重採樣的過程,重採樣對象不再是原始信號,而是這個低採樣率的信號,因爲採樣率不夠需要插入更多的採樣點以達到需要的採樣率和採樣大小

理論上SRC可以通過更換算法來實現音質提升,但卻不太現實,SRC需要大量的浮點運算的資源,即便有了高質量的SRC算法,其運算也是以犧牲設備性能和耗電量爲代價的,實用性差。

二、windowsphone平臺

 

通用音頻架構(UAA

UAA分爲獨佔模式和共享模式,它最大程度的降低了音頻設備驅動對系統穩定性的影響,而且還能夠增加信號處理流程的透明度,處理環節可以得到控制,在理論上說,它可以實現更加優秀的音質,也能非常顯著的提升系統響應速度,大幅減低延時

應用程式在一般情況下都是走Shared Mode(共享模式)那條路徑,這個路徑被稱作通道,根據上面關於共享模式的介紹,所有的聲音訊號都會轉送至Audio Engine(音效引擎)部分,有軟件混音動作,就可能會經過SRC,使得聲音出現偏差。而當應用程序發出使用獨佔模式的需求後,系統會切斷共享模式這一條路徑,聲音訊號就會直接送達Kernel Mode最後到達底層的音頻設備後輸出,音頻設備在此時也會完全100%配合獨佔模式送來的音頻格式進行處理。

三、iOS平臺

我們再把目光投向iOS,iOS非常封閉,我們甚至無法獲知其架構的具體構成,但iOS設備不存在硬件設備多樣性的問題,因此要實現更好音質也會更加簡單。iOS可以實現針對性的開發和改良,以實現更好的音質。實際情況也是如此,目前爲止,還沒有一款Android設備的音質可以媲美任意一款iOS設備,這種差距,我們認爲不是來自硬件,而是操作系統。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章