安卓多媒體開發框架中,從音頻采集,視頻采集,到音視頻處理,音視頻播放顯示分別有哪些常用的框架?分成六章,這里一次幫你總結完。
音視頻的主要流程是錄制、處理、編解碼和播放顯示。本文也遵循這個流程展開,多媒體框架有視頻驅動框架V4L2/UVC,顯示驅動框架DRM,音視頻處理框架openMAX,播放框架EXoplayer,以及顯示渲染框架VLC等。
在一些大廠,一般和多媒體工程師和影像工程師進行區分,影像負責音視頻的采集和處理;多媒體負責音視頻的編解碼和顯示渲染;驅動和底層系統工程師負責提供底層的系統支持,以及框架內部的適配。
因為本人上下層都有涉獵,所以更加系統的把從多媒體的底層到上層,更為全面的角度審視這些多媒體框架。
本文是開源方案第二章,流媒體框架GStreamer之后單獨一張補充,主要原因是做流媒體這一塊的核心業務和流程和本地多媒體有蠻多差異。
有博友已經催更到朋友圈,所以做個說明:
最近同時面對工作和出差,身體抵抗力有所下降,每次寫文章都忙到12點以后,考慮到健康狀況,所以更新頻率降低,恢復之后就繼續安排上。因為文章皆為原創,同時為了保證質量,計劃優先穩定在兩周一更的頻率。
一、多媒體框架綜述
個人覺得通過上層到應用側,通過JAVA API可以串聯整個音視頻的流程,更容易進行理解。
Android的多媒體框架同樣也遵循這些流程,音視頻解析/解碼/播放/錄制相關核心服務架構和流程有:
MediaExtractor/MediaCodec/MediaRecorder/MediaPlayerService/libstagefright/OpenMAX 等,使用它們從而完成音視頻的采集、處理、編碼、封包、mp4輸出到最終的播放。
再具體一點,安卓相機的業務實現流程是:在收集數據之前,對Camera設置一些參數;然后設置PreviewCallback;之后獲取到Camera的原始NV21數據;再創建一個H264Encoder類,在里面進行編碼操作,并將編碼后的數據存儲到文件;結束編碼的時候將相關的資源釋放掉。這部分內容之后以高通為例,單獨展開來說。
本文是對上一章《庫》的補充,庫和框架側重不同。
庫是一組可以重復使用的代碼,提供了一些特定的功能,程序員可以在自己的程序中調用這些功能。比如在音視頻多媒體系統開發中,庫可能只負責音視頻的編解碼(如 FFmpeg)、音視頻處理(如OpenCV)或視頻渲染(如 OpenGL ES)等某個特定的功能模塊。
框架則是提供了一整套的架構和機制,通過提供了大量的預定義代碼和可復用組件?從而實現一個完整的解決方案,框架會負責從音視頻數據的獲取、解碼、處理到最終的顯示渲染等整個流程的管理和組織。程序員是在這個框架的基礎上實現自己的應用邏輯。
二、OpenMAX多媒體框架
OpenMAX(OMX)一個多媒體應用程序的框架標準,Android系統默認已經集成。
框架的特點是提供標準化的音視頻處理API接口,便于集成和擴展;
因為其跨平臺和標準化特點,在需要優化視頻處理性能的時候,最常應用于嵌入式系統和移動設備中的音視頻處理中。
程序員通過調用OpenMAX API來管理編解碼器、設置編解碼參數、發送編解碼命令等。也可以發送音視頻數據到編解碼器進行處理,并接收處理后的數據。這些API通常通過JNI在Java層和Native層之間進行調用。
2.1框架分層
OMX的三個主要層次是DL(開發層)、IL(集成層)和AL(應用層)。
IL層在Android中是最常用的,IL層滿足了操作系統到硬件的差異和多媒體應用的差異,IL提供了與硬件編解碼器交互的接口。
硬件多媒體編解碼框架,定義標準化接口對接 DSP/GPU 加速組件,提升編解碼效率,如 MediaCodec
底層實現依賴此標準。
IL層主要實現了各種組件,組件是IL層實現的核心內容,通過輸入端口消耗buffer,通過輸出端口填充buffer,由此多組件相連接可以構成流式處理。
IL層對上層給AL層等框架層調用,也可以給應用程序直接調用;對下層可以調用DL層的接口,也可也直接調用各種codec實現。
OpenMAX IL層接口示例:
(1)組件加載與卸載接口:OMX_GetHandle
、OMX_FreeHandle
(2)組件控制與配置接口:OMX_SetParameter
、OMX_GetParameter
、OMX_SendCommand
(3)組件間通信接口:OMX_SetupTunnel
、OMX_UseBuffer
2.2使用流程
使用OpenMAX框架音視頻開發的流程,和整體安卓多媒體的開發流程一致,主要包括以下幾點:
(1)創建OpenMAX組件,使用OpenMAX IL API創建編解碼器、源、解復用器等組件的實例。
(2)配置組件,設置組件的參數,如輸入輸出格式、緩沖區大小等。
(3)連接組件將不同的組件通過隧道化方式連接起來,形成處理流。
(4)發送數據,將音視頻數據發送到編解碼器進行處理。
(5)接收和處理結果,接收編解碼器處理后的數據,并進行后續處理(如渲染、存儲等)。
(6)資源釋放,在處理完成后,釋放組件和相關資源。
2.3在安卓系統應用
openmaxIL可以以插件的形式加入到android系統中,從而可以再Android系統的編解碼開發、播放器組件以及中間件開發中都發揮作用。作為安卓系統的多媒體開發人員,對此毫不陌生。
(1)編解碼器開發和管理。
通過OpenMAX IL層,音視頻和圖像編解碼器能夠與多媒體框架進行交互,提供統一的接口來支持編解碼功能。Android系統通過OpenMAX IL層封裝了硬件編解碼器的功能,使得上層應用能夠透明地利用硬件加速能力進行音視頻編解碼,從而提高接口處理效率。
(2)構成播放器組件。
在Android中,如NuPlayer或AwesomePlayer等播放器框架就使用了OpenMAX來管理編解碼器、源、輸出、解復用器demux等組件。
使用OpenMAX的組件化設計,播放器可以靈活地組合不同的模塊,靈活實現音視頻數據的解碼、渲染和輸出。
(3)實現多媒體中間件接口。
OpenMAX AL層提供了應用程序和多媒體中間件之間的標準化接口。應用開發著只需關注標準化的功能實現,差異化交給下層。
在Android中這有助于多媒體中間件與上層應用之間的集成,不同的廠商都熱衷于設計和完成自己的中間件,比如編解碼器庫、圖形庫或者平臺庫等。
三、音視頻采集框架
V4L2(Video for Linux 2)在Android音視頻開發中的應用主要集中在視頻采集和處理方面。V4L2是Linux內核中用于視頻設備的一個API框架,旨在提供對視頻捕捉、輸出和處理設備的支持。
V4L2和UVC的驅動基礎我們在之前的文章中已經分享過,本文更加關注框架層應用。
https://mp.weixin.qq.com/s/puaNQrfn1KFNe0uSN9SmKQ
https://mp.weixin.qq.com/s/JG2XDjI1E2jEU6fDlQZCCw
3.1V4L2的使用
在linux中使用V4L2,使用open()
函數打開視頻設備文件/dev/videoX
,使用ioctl()
函數進行設置和處理視頻幀。
在Android中使用V4L2,只需要在內核配置菜單中選擇Video capture adapters”,確保V4L2驅動被選中并編譯進內核,之后按照V4L2提供的API來訪問和控制視頻設備,使用ioctl等系統調用設置和處理視頻幀。使用v4l2-ctl等命令行工具來調試和測試V4L2設備信息。通過logcat等工具來查看調試信息。
在驅動開發中,V4L2可以作為攝像頭、視頻采集卡等設備的驅動框架。驅動工程師根據V4L2的規范來編寫或修改驅動程序,使設備能夠在Android系統上正常工作。
在系統開發中,通過V4L2以直接與Android設備上的攝像頭硬件進行交互,實現視頻幀的捕獲。系統工程師可以使用V4L2接口來開發特定的視頻采集應用,如安防監控軟件、實時視頻流傳輸軟件等。
在應用開發中,比如視頻編輯軟件、實時視頻特效軟件時,可以通過V4L2與GPU或其他硬件加速技術結合使用,提高處理效率。
3.2UVC的使用
在Linux音視頻開發中,UVC是USB視頻類驅動框架,標準化USB攝像頭在Linux內核中的協議實現?,主要用在處理USB攝像頭和視頻輸入設備時。在Linux系統中,UVC設備通常會被識別為/dev/videoX
(X為設備編號)的文件。
使用UVC簡化了視頻采集的流程,Linux系統能夠直接識別和使用USB攝像頭,而無需安裝額外的驅動程序。同樣UVC攝像頭通常支持多種視頻格式和分辨率,所以UVC更容易應用于快捷視頻接入的場景。
在視頻監控中,UVC攝像頭可以通過Linux系統實現視頻的捕獲、編碼和傳輸,滿足遠程監控和管理的需求。
在視頻會議和實時通訊應用中,UVC攝像頭能夠提供清晰的視頻畫面,支持語音通話和視頻通話。
3.3音頻采集?Oboe?
Android SDK 提供了兩套音頻采集的 API 接口: MediaRecorder 和 AudioRecord。
而Android NDK則可以通過OpenSL ES 、AAudio和Oboe完成音頻采集。
Oboe是Android 團隊開發的 C++ 音頻框架,封裝 AAudio
和 OpenSL ES
,支持高性能、低延遲音頻采集與播放,用于構建高性能的音頻應用程序,比如實時音頻分析工具Audio Analyze就是使用的該框架。
更多資料:
https://github.com/google/oboe/blob/main/docs/FullGuide.md
https://github.com/googlearchive/android-audio-high-performance/
四、顯示驅動框架
DRM(Direct Rendering Manager)是Linux內核顯示渲染框架,管理GPU資源分配與多屏合成調度。Linux DRM聚焦圖形硬件的高效利用,而Android DRM側重內容安全。
DRM的驅動基礎我們在之前的文章中已經分享過,本文更加關注框架層應用。
4.1、Linux系統中的DRM框架
DRM是Linux內核中管理GPU的核心框架,其開發使用可分為:內核層和應用層開發。
最終的應用也比較廣泛,在嵌入式系統,DRM驅動實現多屏顯示(如HDMI+LVDS);圖形服務器中,利用DRM直接訪問GPU進行窗口合成,避免X Server的間接渲染開銷。
(1)內核層開發,通過drm_driver
結構體注冊GPU驅動,實現drm_crtc
(顯示控制器)、drm_plane
(圖層)、drm_framebuffer
(幀緩沖區)等核心對象的生命周期管理。
(2)內核層開發,使用KMS
(Kernel Mode Setting)API進行顯示模式配置(如分辨率、刷新率),通過GEM
(Graphics Execution Manager)管理顯存分配與跨進程共享。
(3)內核層開發,調試工具鏈包括:modetest
:測試顯示模式與幀緩沖操作;drm_info
:查詢GPU設備信息;apitrace
:跟蹤OpenGL/Vulkan調用。
(4)用戶層開發,則通過libdrm
庫調用ioctl
接口,或者結合GBM(Generic Buffer Management)或EGL實現GPU加速渲染。
4.2Android系統中的DRM框架
Android的DRM框架主要用于數字版權保護,包括DRM引擎和播放器集成,比如ExoPlayer通過DefaultDrmSessionManager與DRM服務器通信。
最終的應用有流媒體保護和企業應用,比如Netflix使用Widevine L1級保護4K內容,密鑰通過安全通道傳輸;Android for Work通過DRM限制企業數據訪問權限,防止數據泄露。
五、多媒體播放框架
Android 媒體框架通過 MediaPlayer
類來控制音視頻的播放,MediaPlayer
會將解碼后的視頻幀輸出到指定的 Surface
上進行顯示。而具體的顯示渲染則依賴于 SurfaceView
或 TextureView
等視圖組件。
綜合來說,Stagefright作為早期框架已被取代,NuPlayer集成于系統但擴展性有限,ExoPlayer則是開發的推薦選擇,尤其在需要流媒體支持和高度定制的場景。
5.1Stagefright和NuPlayer
Stagefright和NuPlayer是Android系統中用于多媒體編解碼與播放的底層框架,主要處理音頻、視頻的解析、解碼和渲染。它通過OpenMAX接口與硬件編解碼器交互,支持H.264、MP3等主流格式,Stagefright應用在Android 2.0至5.1版本,Android 5.1后被NuPlayer取代。
關鍵組件中,AwesomePlayer是核心播放器模塊,管理音視頻同步與渲染。MediaExtractor負責解析媒體文件,分離音視頻流。OMXCodec則基于OpenMAX的編解碼器,支持硬件加速。
Android中的Stagefright框架,包括Video Playback流程、與OpenMAX的運作、選擇Video Decoder、Video Buffer傳輸、Video Rendering以及Audio Playback流程。Stagefright使用OpenMAX進行編解碼,并通過AudioPlayer處理audio部分,實現Video與Audio的同步。
Stagefright | NuPlayer | |
---|---|---|
API | 通過MediaPlayer 類調用, | 通過MediaPlayer 類調用 |
使用 | 直接使用MediaPlayer 或MediaCodec 等高級API,底層由Stagefright處理編解碼與渲染 | 基于StagefrightPlayer 基礎類開發 |
流媒體支持 | 僅本地播放 | 支持HTTP Live、RTSP等流媒體協議 |
5.2ExoPlayer
ExoPlayer是谷歌開源播放框架,支持自定義渲染邏輯、自適應流(DASH/HLS)及 DRM 加密播放,可擴展性強于 MediaPlayer
,ExoPlayer是構建在MediaPlayer之上的庫,用于替代 Android 原生的 MediaPlayer
,提供了更強大的功能和性能,當然也更復雜。
六、顯示渲染框架
在音視頻多媒體系統開發中,顯示和渲染框架通常是指那些提供了一整套架構和機制,這些框架通常會包含多個模塊,負責從音視頻數據的解碼、處理到最終的顯示,顯示和渲染基本在一個框架中實現。
6.1VLC和SDL
VLC 是一個非常流行的開源多媒體播放器,它背后也有一個強大的多媒體處理框架。
VLC 框架內部有自己的一套機制來處理音視頻的顯示和渲染。它支持多種視頻輸出模塊,可以根據不同的平臺和需求選擇合適的輸出方式,例如在 Windows 上可以使用 Direct3D 進行視頻渲染,在 Linux 上可以使用 X11 等。
FFmpeg +SDL 構成一個簡單的顯示和渲染框架。
FFmpeg 負責音視頻的解碼等工作,而 SDL (Simple DirectMedia Layer)則負責將解碼后的視頻幀渲染到屏幕上。SDL 提供了跨平臺的多媒體處理功能,包括音頻播放和視頻顯示。
這種組合比較輕量級,適合一些對性能要求不是特別高,但需要快速實現音視頻播放和顯示的場景。由于 FFmpeg 和 SDL 都是開源的,也具有很好的可定制性。
6.2渲染視圖組件
組件的使用,通過使用 MediaPlayer
類加載音視頻文件;通過 SurfaceView
或 TextureView
將視頻幀渲染到屏幕上,ImageView
則用于顯示靜態圖像;使用 MediaCodec
進行音視頻的解碼,然后通過 OpenGL ES 或其他圖形庫進行自定義渲染。ExoPlayer 更是支持自定義渲染器,可以通過實現 Renderer
接口來實現自定義的音視頻渲染邏輯。GLSurfaceView
則用于實現復雜的 3D 圖形渲染比如游戲、AR 等場景。
總結
看到這里還不幫忙點個贊和關注,十分感謝!VX :森哥談成像技術,更新更及時哦。
本文根據博主工作經驗,匯總了影像系統從上到下,程序員都會用到的哪些開源框架。
掌握這些,有助于更好的分析問題以及查漏補缺,成為多媒體領域的全棧工程師。
本文是開源方案第二章,流媒體框架GStreamer之后單獨一張補充,主要原因是做流媒體這一塊的核心業務和流程和本地多媒體有蠻多差異。
本文只做簡單的梳理,如有學習需要可以參考其更多資料。