Android音視頻多媒體開源框架基礎大全

安卓多媒體開發框架中,從音頻采集,視頻采集,到音視頻處理,音視頻播放顯示分別有哪些常用的框架?分成六章,這里一次幫你總結完。

音視頻的主要流程是錄制、處理、編解碼和播放顯示。本文也遵循這個流程展開,多媒體框架有視頻驅動框架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_GetHandleOMX_FreeHandle

(2)組件控制與配置接口:OMX_SetParameterOMX_GetParameterOMX_SendCommand

(3)組件間通信接口:OMX_SetupTunnelOMX_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++ 音頻框架,封裝 AAudioOpenSL 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 上進行顯示。而具體的顯示渲染則依賴于 SurfaceViewTextureView 等視圖組件。

綜合來說,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的同步。

StagefrightNuPlayer
API通過MediaPlayer類調用,通過MediaPlayer類調用
使用直接使用MediaPlayerMediaCodec等高級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 類加載音視頻文件;通過 SurfaceViewTextureView 將視頻幀渲染到屏幕上,ImageView則用于顯示靜態圖像;使用 MediaCodec 進行音視頻的解碼,然后通過 OpenGL ES 或其他圖形庫進行自定義渲染。ExoPlayer 更是支持自定義渲染器,可以通過實現 Renderer 接口來實現自定義的音視頻渲染邏輯。GLSurfaceView 則用于實現復雜的 3D 圖形渲染比如游戲、AR 等場景。

在這里插入圖片描述

總結

看到這里還不幫忙點個贊和關注,十分感謝!VX :森哥談成像技術,更新更及時哦。

本文根據博主工作經驗,匯總了影像系統從上到下,程序員都會用到的哪些開源框架。

掌握這些,有助于更好的分析問題以及查漏補缺,成為多媒體領域的全棧工程師。
在這里插入圖片描述

本文是開源方案第二章,流媒體框架GStreamer之后單獨一張補充,主要原因是做流媒體這一塊的核心業務和流程和本地多媒體有蠻多差異。

本文只做簡單的梳理,如有學習需要可以參考其更多資料。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/83641.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/83641.shtml
英文地址,請注明出處:http://en.pswp.cn/web/83641.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

安卓上架華為應用市場、應用寶、iosAppStore上架流程,保姆級記錄(1)

上架前請準備好apk、備案、軟著、企業開發者賬號!!!其余準備好app相關的截圖、介紹、測試賬號,沒講解明白的評論區留言~ 華為應用市場 1、登錄賬號 打開 華為開發者平臺 https://developer.huawei.com/consumer/cn/ 2.登錄企…

【Docker】docker 常用命令

目錄 一、鏡像管理 二、容器操作 三、網絡管理 四、存儲卷管理 五、系統管理 六、Docker Compose 常用命令 一、鏡像管理 命令參數解說示例說明docker pull鏡像名:標簽docker pull nginx:alpine拉取鏡像(默認從 Docker Hub)docker images-a&#x…

OSPF域內路由

簡介 Router-LSA Router-LSA(Router Link State Advertisement)是OSPF(Open Shortest Path First)協議中的一種鏈路狀態通告(LSA),它由OSPF路由器生成,用于描述路由器自身的鏈路狀態…

torch 高維矩陣乘法分析,一文說透

文章目錄 簡介向量乘法二維矩陣乘法三維矩陣乘法廣播 高維矩陣乘法開源 簡介 一提到矩陣乘法,大家對于二維矩陣乘法都很了解,即 A 矩陣的行乘以 B 矩陣的列。 但對于高維矩陣乘法可能就不太清楚,不知道高維矩陣乘法是怎么在計算。 建議使用…

瑞薩RA-T系列芯片馬達類工程TCM加速化設置

本篇介紹在使用RA8-T系列芯片,建立馬達類工程應用時,如何將電流環部分的指令和變量設置到TCM單元,以提高電流環執行速度,從而提高系統整體的運行性能,在伺服和高端工業領域有很高的實用價值。本文以RA8T1為范例&#x…

獲取Unity節點路徑

解決目的: 避免手動拼寫節點路徑的時候,出現路徑錯誤導致獲取不到節點的情況。解決效果: 添加如下腳本之后,將自動復制路徑到剪貼板中,在代碼中通過 ctrlv 粘貼路徑代碼如下: public class CustomMenuItems…

Docker 安裝 Oracle 12C

鏡像 https://docker.aityp.com/image/docker.io/truevoly/oracle-12c:latest docker pull swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/truevoly/oracle-12c:latest docker tag swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/truevoly/oracle-12c:latest d…

Linux內核網絡協議注冊與初始化:從proto_register到tcp_v4_init_sock的深度解析

一、協議注冊:proto_register的核心使命 在Linux網絡協議棧中,proto_register是協議初始化的基石,主要完成三項關鍵任務: Slab緩存創建(內存管理核心) prot->slab = kmem_cache_create_usercopy(prot->name, prot->obj_size, ...); if (prot->twsk_prot) pr…

GD32 MCU的真隨機數發生器(TRNG)

GD32 MCU的真隨機數發生器(TRNG) 文章目錄 GD32 MCU的真隨機數發生器(TRNG)一、定義與核心特征二、物理機制:量子與經典隨機性三、生成方法四、應用場景五、與偽隨機數的對比六、局限性?? 七、物理熵源原理?? 八、硬件實現流程(以GD32F450 GD32L233為例)8.1. **初始…

Vulkan學習筆記6—渲染呈現

一、渲染循環核心 while (!glfwWindowShouldClose(window)) {glfwPollEvents();helloTriangleApp.drawFrame(); // 繪制幀} 在 Vulkan 中渲染幀包含一組常見的步驟 等待前一幀完成(vkWaitForFences) 從交換鏈獲取圖像(vkAcquireNextImageKH…

React第六十二節 Router中 createStaticRouter 的使用詳解

前言 createStaticRouter 是 React Router 專為 服務端渲染(SSR) 設計的 API,用于在服務器端處理路由匹配和數據加載。它在構建靜態 HTML 響應時替代了客戶端的 BrowserRouter,確保 SSR 和客戶端 Hydration 的路由狀態一致。 一…

qt 雙緩沖案例對比

雙緩沖 1.雙緩沖原理 單緩沖:在paintEvent中直接繪制到屏幕,繪制過程被用戶看到 雙緩沖:先在redrawBuffer繪制到緩沖區,然后一次性顯示完整結果 代碼結構 單緩沖:所有繪制邏輯在paintEvent中 雙緩沖:繪制…

華為云AI開發平臺ModelArts

華為云ModelArts:重塑AI開發流程的“智能引擎”與“創新加速器”! 在人工智能浪潮席卷全球的2025年,企業擁抱AI的意愿空前高漲,但技術門檻高、流程復雜、資源投入巨大的現實,卻讓許多創新構想止步于實驗室。數據科學家…

ParaGraphX [特殊字符]

https://github.com/stevechampion1/paragraphx 一個基于 JAX 的、為 CPU/GPU 加速而生的超高性能圖算法庫。 ParaGraphX 是一個實驗性的 Python 庫,旨在利用 JAX 的即時編譯 (JIT) 和大規模并行計算能力,為經典的圖算法提供驚人的性能提升。我們的目標…

如何用4 種可靠的方法更換 iPhone(2025 年指南)

Apple 每年都會發布新版本的 iPhone。升級到新 iPhone 是一種令人興奮的體驗,但轉移所有寶貴數據的想法有時會讓人感到畏懼。幸運的是,我們準備了 4 種有效的更換 iPhone 的方法,讓你可以毫不費力地更換到你的新 iPhone。 此外,您…

GitLab 拉取變慢的原因及排查方法

前言:在軟件開發的快節奏世界里,高效協作與快速交付是制勝關鍵。然而,當開發團隊興高采烈地投入工作,卻發現從GitLab拉取代碼的速度慢如蝸牛,那種沮喪感簡直能瞬間澆滅熱情。在分布式開發環境中,這種情況時…

落水人員目標檢測數據集(貓臉碼客第253期)

落水人員目標檢測:科技守護生命之舟 一、背景與意義 隨著人類海洋活動和水上活動的日益頻繁,海上與水域安全事故頻發。每年都會開展大量的海上救援行動,以搜救數以萬計的落難人員。在水上活動區域,如水庫、河道等,溺…

JAVA_強制類型轉換:

類型范圍大的變量,不可以直接賦值給類型變量小的變量 需要進行強制類型轉換: 想要完成類型范圍大的變量傳給類型范圍小的變量需要先創建一個新的變量(類型與方法的形參類型要相同)。將類型范圍大的變量前面加上(轉換類…

打卡第44天:無人機數據集分類

重復以下內容 作業: kaggle找到一個圖像數據集,用cnn網絡進行訓練并且用grad-cam做可視化 進階: 并拆分成多個文件 import os import torch import torch.nn as nn import torch.optim as optim from torch.utils.data import DataLoader,…

個人網站大更新,還是有個總站比較好

個人網站大更新,還是有個總站比較好 放棄了所有框架,用純htmlcssjs擼了個網站,這回可以想改啥改啥了。 選擇了黑紫作為主色調,暫時看著還算可以。 為什么不用那些框架了 幾個原因: 嘗試用vuepress、vitepress、not…