91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Android音頻開發(5):音頻數據的編解碼

發布時間:2020-08-10 12:18:53 來源:網絡 閱讀:22765 作者:Jhuster 欄目:移動開發

前面四篇文章分別介紹了音頻開發必備的基礎知識、如何采集一幀音頻、如何播放一幀音頻、如何存儲和解析wav格式的文件,建議有興趣的小伙伴們先讀一讀,本文則重點關注如何對一幀音頻數據進行編碼和解碼。


1. Android 官方的 MediaCodec API


首先,我們了解一下 Android 官方提供的音頻編解碼的 API,即 MediaCodec 類,該 API 是在 Andorid 4.1 (API 16) 版本引入的,因此只能工作于 Android 4.1 以上的手機上。


1.1 MediaCodec 基本介紹


(1)提供了一套訪問 Android 底層多媒體模塊的接口,主要是音視頻的編解碼接口


(2)Android 底層多媒體模塊采用的是 OpenMax 框架,任何 Android 底層編解碼模塊的實現,都必須遵循 OpenMax 標準。Google 官方默認提供了一系列的軟件編×××:包括:OMX.google.h364.encoder,OMX.google.h364.encoder, OMX.google.aac.encoder, OMX.google.aac.decoder 等等,而硬件編解碼功能,則需要由芯片廠商依照 OpenMax 框架標準來完成,所以,一般采用不同芯片型號的手機,硬件編解碼的實現和性能是不同的


(3)Android 應用層統一由 MediaCodec API 來提供各種音視頻編解碼功能,由參數配置來決定采用何種編解碼算法、是否采用硬件編解碼加速等等


1.2 MediaCodec 核心原理


我不準備詳細介紹 MediaCodec API 的每個函數是怎么用,示例代碼大家可以在后面給出的資源鏈接中查看和學習。


這里我準備重點介紹一下 MediaCodec 的核心工作原理,因為只有搞清楚了這一點,你才會明白為什么 MediaCodec API 提供的接口是這個樣子的。


MediaCodec 使用的基本流程是:


- createEncoderByType/createDecoderByType
- configure
- start
- while(1) {
    - dequeueInputBuffer
    - queueInputBuffer
    - dequeueOutputBuffer
    - releaseOutputBuffer
}
- stop
- release


由此可以看到,Buffer 隊列的操作是其最核心的部分之一,關于 MediaCodec 的 Buffer 隊列 ,示意圖如下:

Android音頻開發(5):音頻數據的編解碼



MediaCodec 架構上采用了2個緩沖區隊列,異步處理數據,下面描述的 Client 和 MediaCodec 模塊是并行工作的(注:這里的 Client 就是指 “開發者,API 的使用者”):


(1)Client 從 input 緩沖區隊列申請 empty buffer [dequeueInputBuffer]

(2)Client 把需要編解碼的數據拷貝到 empty buffer,然后放入 input 緩沖區隊列 [queueInputBuffer] 

(3)MediaCodec 模塊從 input 緩沖區隊列取一幀數據進行編解碼處理

(4)編解碼處理結束后,MediaCodec 將原始數據 buffer 置為 empty 后放回 input 緩沖區隊列,將編解碼后的數據放入到 output 緩沖區隊列

(5)Client 從 output 緩沖區隊列申請編解碼后的 buffer [dequeueOutputBuffer]

(6)Client 對編解碼后的 buffer 進行渲染/播放

(7)渲染/播放完成后,Client 再將該 buffer 放回 output 緩沖區隊列 [releaseOutputBuffer]


MediaCodec 在架構上,其實是采用了一種基于“環形緩沖區”的“生產者-消費者”模式,它設計了 2 個基于 idx 序號的“環形緩沖區” ,注意,是 2 個,一個在 input 端, 一個在 output 端。


我曾經在 Github 上分享過一段 Linux C 代碼,名叫:“rw_queue”,就是這種環形緩沖區的簡化版,大家有興趣可以看看,地址:https://github.com/Jhuster/clib/tree/master/rw_queue


基于 idx 的環形緩沖區的總體示意圖如下,圖中,wp 代表 “寫指針”,指向的是 “empty buffer”, 而 rp 代表 “讀指針”,指向的是 “filled buffer”:


Android音頻開發(5):音頻數據的編解碼

“生產者”和“消費者”其實是共用這一個緩沖區隊列,“生產者”負責從隊列中取出未使用的 Buffer,填入數據,然后放回隊列,“消費者”則負責取出填入數據后的 Buffer,進行處理,處理結束后,再把 Buffer 標記為“空”,退回到隊列中去以供“生產者”繼續填充數據。


在 input 端,“Client”是這個環形緩沖區“生產者”,“MediaoCodec 模塊”是“消費者”。

在 output 端,“MediaoCodec 模塊”是這個環形緩沖區“生產者”,而“Client”則變成了“消費者”。


這就是其核心的工作原理,其實并不復雜,大家靜下心來,很快就能理解其中的奧妙。


1.3  參考資源


關于 MediaCodec 的示例代碼,網上其實也很多了,我就直接給出一些個人覺得不錯的鏈接,有興趣的小伙伴們可以去研究一下。


(1)Android 官方文檔: 《MediaCodec》

(2)《Android MediaCodec stuff》

(3)《HWEncoderExperiments》

(4)一些開源的播放器 Android 源碼,如 VLC、ijkplayer


2. 第三方音頻編解碼的庫


官方的 MediaCodec API 雖然支持硬件編解碼加速,但是問題和局限還是很多的,一方面是只能在 Android 4.1 以上機型上才能使用,另一方面,由于 Android 手機種類繁多,廠商對底層源碼的修改各不相同,導致 MediaCodec API 在實際使用中,會遇到很多坑,有很多兼容性的問題,因此,我們也可以考慮采用第三方的編解碼庫。


這里,我簡單推薦幾款第三方音頻編解碼庫(可以移植到 Android 平臺的),大家可以直接去官網或者項目主頁了解其詳細信息。


(1) opus 編解碼庫


很喜歡 opus,低碼率下 opus 完勝曾經優勢明顯的 HE AAC,我曾經用它實現了一款 Android 局域網的VoIP網絡電話應用:“飛鴿電話”,效果很不錯。


opus 官網地址:https://www.opus-codec.org


注:如今 Android 5.0 已經官方支持 opus 格式了,關于 Android 支持的多媒體格式列表可以查看 Android developer guide:《Supported Media Formats》


(2) Speex 編解碼庫


老牌的音頻處理庫,不僅是編解碼,還提供了包括音頻去噪、回聲消除、靜音檢測等功能,官網地址:http://www.speex.org


(3) ffmpeg


大名鼎鼎的 ffmpeg 肯定不能錯過,官網:https://www.ffmpeg.org


(4)Android AAC Encoder


一款輕量級的 Android aac 編碼庫:https://github.com/timsu/android-aac-enc


(5)opencore-amr-android


從 opencore 抽取出來的 amr 編解碼庫,地址:https://github.com/kevinho/opencore-amr-android


(6)iLBC-Android


iLBC 是著名的 WebRTC 項目的音頻編解碼模塊,iLBC-Android 是從中抽取 iLBC 模塊移植到 Android 平臺的個人項目,地址:https://github.com/lukeweber/iLBC-Android


關于第三方編解碼庫就簡單介紹到這里了,最后三個是個人項目,我沒有使用過,真心感謝這些作者的無私奉獻,另外,更多的第三方庫歡迎大家留言或者來信補充。


3. 小結


關于如何在 Android 平臺編解碼音頻數據就簡單介紹到這里了,文章中有不清楚的地方歡迎留言或者來信 lujun.hust@gmail.com 交流,或者關注我的新浪微博 @盧_俊 或者 微信公眾號 @Jhuster 獲取最新的文章和資訊。


Android音頻開發(5):音頻數據的編解碼

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

绥芬河市| 临泽县| 格尔木市| 滨海县| 舒城县| 黄骅市| 施甸县| 嘉峪关市| 大渡口区| 宁安市| 和政县| 凤冈县| 阳高县| 胶南市| 元阳县| 哈密市| 井冈山市| 西乡县| 桓仁| 北宁市| 和林格尔县| 徐州市| 桐城市| 南京市| 林甸县| 佳木斯市| 锡林浩特市| 福安市| 丹东市| 克山县| 溧水县| 镇宁| 宣恩县| 瑞昌市| 塔城市| 鹤山市| 秦皇岛市| 西昌市| 怀远县| 腾冲县| 蓬莱市|