Android 12 中推出的相容媒體轉碼功能,可讓裝置使用更現代化且節省儲存空間的媒體格式 (例如 HEVC) 進行錄影,同時維持與應用程式的相容性。有了這項功能,裝置製造商就能預設使用 HEVC 而非 AVC,提升影片品質,同時降低儲存空間和頻寬需求。如果裝置已啟用相容的媒體轉碼功能,當影片由不支援該格式的應用程式開啟時,Android 會自動轉換以 HEVC 或 HDR 等格式錄製的影片 (長度上限為一分鐘)。這樣一來,即使裝置上拍攝的影片採用較新的格式,應用程式仍可正常運作。
相容的媒體轉碼功能預設為關閉。若要要求媒體轉碼,應用程式必須宣告其媒體功能。如要進一步瞭解如何宣告媒體功能,請參閱 Android 開發人員網站上的「相容的媒體轉碼」。
運作方式
相容媒體轉碼功能包含兩個主要部分:
- 媒體架構中的轉碼服務:這些服務會使用硬體將檔案從一種格式轉換為另一種格式,以便提供低延遲和高品質的轉換。這包括轉碼 API、轉碼服務、自訂篩選器的 OEM 外掛程式和硬體。詳情請參閱「架構總覽」。
- 媒體供應器中的相容媒體轉碼功能:媒體供應器中的這個元件會攔截存取媒體檔案的應用程式,並根據應用程式宣告的功能提供原始檔案或轉碼檔案。如果應用程式支援媒體檔案格式,就不需要進行特殊處理。如果應用程式不支援該格式,則在應用程式存取檔案時,架構會將檔案轉換為舊版格式,例如 AVC。
圖 1 顯示媒體轉碼程序的總覽。
圖 1. 相容媒體轉碼總覽。
支援的格式
相容的媒體轉碼功能支援下列格式轉換:
- HEVC (8 位元) 至 AVC:透過連結一個媒體編碼器解碼器和一個媒體編碼器編碼器,執行轉碼器轉換作業。
- HDR10+ (10 位元) 到 AVC (SDR):HDR 到 SDR 轉換是使用 mediacodec 執行個體執行,而廠商外掛程式會掛接到解碼器執行個體。詳情請參閱「HDR 至 SDR 編碼」。
支援的內容來源
相容的媒體轉碼功能支援原生原始設備製造商 (OEM) 相機應用程式產生的裝置端媒體,儲存在主要外部磁碟區的 DCIM/Camera/
資料夾中。這項功能不支援次要儲存空間中的媒體。
系統不支援透過電子郵件或 SD 卡傳送至裝置的內容。
應用程式會根據各種檔案路徑存取檔案。以下說明啟用或略過轉碼功能的檔案路徑:
已啟用轉碼功能:
- 透過 MediaStore API 存取應用程式
- 透過直接檔案路徑 API (包括 Java 和原生程式碼) 存取應用程式
- 透過儲存空間存取架構 (SAF) 存取應用程式
- 透過 OS 分享表單意圖存取應用程式。(僅限 MediaStore URI)
- 從手機傳輸至電腦的 MTP/PTP 檔案
已略過轉碼:
- 透過彈出 SD 卡的方式,將檔案從裝置中移除
- 使用鄰近分享或藍牙傳輸等選項,將檔案從裝置傳輸到裝置。
新增用於轉碼的自訂檔案路徑
裝置製造商可選擇在 DCIM/
目錄下新增用於媒體轉碼的檔案路徑。DCIM/
目錄以外的路徑都會遭拒。您可能需要新增這類檔案路徑,才能符合電信業者規定或當地法規。
如要新增檔案路徑,請使用轉碼路徑執行階段資源疊加層 (RRO) config_supported_transcoding_relative_paths
。以下是如何新增檔案路徑的範例:
<string-array name="config_supported_transcoding_relative_paths" translatable="false">
<item>DCIM/JCF/</item>
</string-array>
如要驗證已設定的檔案路徑,請使用:
adb shell dumpsys activity provider com.google.android.providers.media.module/com.android.providers.media.MediaProvider | head -n 20
架構總覽
本節將說明媒體轉碼功能的架構。
圖 2. 媒體轉碼架構。
媒體轉碼架構由下列元件組成:
- MediaTranscodingManager 系統 API:可讓用戶端與 MediaTranscoding 服務通訊的介面。MediaProvider 模組會使用這個 API。
- MediaTranscodingService:原生服務,可管理用戶端連線、排定轉碼要求,以及管理
TranscodingSessions
的記錄。 - MediaTranscoder:執行轉碼作業的原生程式庫。這個程式庫是以媒體架構 NDK 為基礎,與模組相容。
相容的媒體轉碼功能會記錄服務和媒體轉碼器的轉碼指標。用戶端和服務端程式碼位於 MediaProvider 模組中,可讓您及時修正錯誤和更新。
檔案存取權
相容的媒體轉碼以使用者空間中的檔案系統 (FUSE) 檔案系統為基礎,該系統是用於限定範圍儲存空間。FUSE 可讓 MediaProvider 模組在使用者空間檢查檔案作業,並根據政策限制檔案存取權,進而允許、拒絕或遮蓋存取。
當應用程式嘗試存取檔案時,FUSE Daemon 會攔截應用程式中的檔案讀取權限。如果應用程式支援較新的格式 (例如 HEVC),便會傳回原始檔案。如果應用程式不支援此格式,檔案會轉碼成舊版格式 (例如 AVC),或是如果有轉碼版本,則會從快取傳回。
要求轉碼檔案
相容的媒體轉碼功能預設為停用。也就是說,如果裝置支援 HEVC,則除非在資訊清單檔案或強制轉碼清單中指定的應用程式,否則 Android 不會轉碼檔案。
應用程式可以使用下列選項要求經過轉碼的素材資源:
- 在資訊清單檔案中宣告不支援的格式。詳情請參閱在資源中宣告功能和在程式碼中宣告功能。
- 將應用程式新增至 MediaProvider 模組中的強制轉碼清單。這可讓未更新資訊清單檔案的應用程式進行轉碼。一旦應用程式更新資訊清單檔案,但使用不支援的格式,就必須從強制轉碼清單中移除。裝置製造商可以提交修補程或回報錯誤,指定要將哪些應用程式加入或移除強制轉碼清單。Android 團隊會定期審查清單,且可能會將應用程式從清單中移除。
- 在執行時使用應用程式相容性架構,停用支援的格式 (使用者也可以在「設定」中為每個應用程式停用這項功能)。
- 使用
MediaStore
開啟檔案,同時使用openTypedAssetFileDescriptor
API 明確指定不支援的格式。
如果是 USB 傳輸 (裝置對電腦),轉碼功能預設為停用,但使用者可以選擇透過「USB Preferences」設定畫面,使用「Convert videos to AVC」切換功能來啟用轉碼功能 (如圖 3 所示)。
圖 3. 切換即可啟用「USB 偏好設定」畫面中的媒體轉碼。
要求轉碼檔案的限制
為避免轉碼要求長時間鎖定系統資源,要求轉碼工作階段的應用程式會受到以下限制:
- 連續 10 個工作階段
- 總執行時間為 3 分鐘
如果應用程式超出上述所有限制,架構會傳回原始檔案描述元。
裝置需求
如要支援相容的媒體轉碼功能,裝置必須符合下列需求:
- 裝置預設在原生相機應用程式中啟用 HEVC 編碼
- (支援 HDR 到 SDR 轉碼的裝置) 裝置支援 HDR 影片擷取功能
為確保裝置在媒體轉碼時的效能,必須最佳化影片硬體和儲存空間的讀取/寫入存取效能。當媒體轉碼器設定優先順序等於 1
時,轉碼器必須以最高的處理量運作。我們建議轉碼效能至少達到 200 fps。如要測試硬體效能,請在 frameworks/av/media/libmediatranscoding/transcoder/benchmark
中執行媒體轉碼器基準測試。
驗證
如要驗證相容媒體轉碼功能,請執行下列 CTS 測試:
android.media.mediatranscoding.cts
android.mediaprovidertranscode.cts
全域啟用媒體轉碼
如要測試媒體轉碼架構或應用程式轉碼行為,您可以全面啟用或停用相容的媒體轉碼功能。在「設定」>「系統」>「開發人員」>「媒體轉碼」開發人員選項頁面中,將「覆寫轉碼預設值」切換鈕設為「on」,然後將「啟用轉碼功能」切換鈕設為「on」或「off」。啟用這項設定後,除了您正在開發的應用程式以外,可能會在背景執行媒體轉碼。
檢查轉碼狀態
在測試期間,您可以使用下列 ADB 殼層指令,檢查轉碼狀態,包括目前和過去的轉碼工作階段:
adb shell dumpsys media.transcoding
延長影片長度限制
為了測試,您可以使用下列指令,延長轉碼的影片長度限制為一分鐘。執行這個指令後,可能需要重新啟動。
adb shell device_config put storage_native_boot transcode_max_duration_ms <LARGE_NUMBER_IN_MS>
Android 開放原始碼計畫的來源和參考資料
以下是與相容媒體轉碼相關的 Android 開放原始碼計畫原始碼。
轉碼系統 API (僅供 MediaProvider 使用)
ApplicationMediaCapabilities API
frameworks/base/apex/media/framework/java/android/media/ApplicationMediaCapabilities.java
MediaTranscoding 服務
frameworks/av/services/mediatranscoding/
frameworks/av/media/libmediatranscoding/
原生 MediaTranscoder
frameworks/av/media/libmediatranscoding/transcoder
MediaTranscoder 適用的 HDR 範例外掛程式
MediaProvider 檔案攔截和轉碼程式碼
MediaTranscoder 基準
frameworks/av/media/libmediatranscoding/transcoder/benchmark
CTS 測試
cts/tests/tests/mediatranscoding/
HDR 到 SDR 編碼
如要支援 HDR 到 SDR 的編碼,裝置製造商可以使用位於 /platform/frameworks/av/media/codec2/hidl/plugin/
的 AOSP 樣本編解碼器 2.0 濾鏡外掛程式。本節說明篩選器外掛程式的運作方式、如何實作外掛程式,以及如何測試外掛程式。
如果裝置未納入支援 HDR 至 SDR 編碼的外掛程式,則存取 HDR 影片的應用程式會取得原始檔案描述元,而不會受到資訊清單中宣告的應用程式媒體功能影響。
運作方式
本節說明 Codec 2.0 篩選器外掛程式的一般行為。
背景
Android 在 android::hardware::media::c2
中提供 Codec 2.0 介面與 android.hardware.media.c2
HAL 介面之間的適應層實作項目。針對篩選器外掛程式,Android 開放原始碼計畫提供包裝函式機制,可將解碼器與篩選器外掛程式一併包裝。MediaCodec
會將這些包裝的元件視為具有篩選功能的解碼器。
總覽
FilterWrapper
類別會採用供應商轉碼器,並將經過包裝的轉碼器傳回 media.c2
調整層。FilterWrapper
類別會透過 FilterWrapper::Plugin
API 載入 libc2filterplugin.so
,並記錄外掛程式提供的可用篩選器。建立時,FilterWrapper
會執行個體化所有可用的篩選器。只有在開始時,才會啟動修改緩衝區的篩選器。
圖 1. 篩選器外掛程式架構。
篩選外掛程式介面
FilterPlugin.h
介面定義了以下 API,用於公開篩選器:
std::shared_ptr<C2ComponentStore>getComponentStore()
傳回包含篩選器的
C2ComponentStore
物件。這與供應商的編碼器 2.0 實作項目公開的內容不同。通常,此儲存庫僅包含 teFilterWrapper
類別使用的篩選器。bool describe(C2String name, Descriptor *desc)
除了
C2ComponentStore
提供的篩選器外,還可使用其他篩選器。定義如下:controlParam
:用於控制篩選器行為的參數。例如,對於 HDR 到 SDR 色調的對應元素,控制參數就是目標傳輸函式。affectedParams
:受篩選作業影響的參數。例如,針對 HDR 到 SDR 色調對應工具,受影響的參數是色彩切面。
bool isFilteringEnabled(const std::shared_ptr<C2ComponentInterface> &intf)
如果篩選器元件更改緩衝區,則傳回
true
。舉例來說,如果目標轉乘函式為 SDR,而輸入傳輸函式為 HDR (HLG 或 PQ),則色調對應篩選器會傳回true
。
FilterWrapper 詳細資料
本節將說明 FilterWrapper
類別的詳細資料。
創作
在建立時,包裝的元件會將基礎解碼器和所有定義的篩選器例項化。
查詢和設定
包裝的元件會根據篩選器說明,將傳入參數與查詢或設定要求分開。例如,篩選器控制項參數的設定會轉送至對應的篩選器,而篩選器中受影響的參數會出現在查詢中,而非從含有未受影響參數的解碼器讀取。
圖 2. 查詢和設定。
開始
在啟動時,包裝的元件會啟動解碼器和所有會變更緩衝區的篩選器。如果未啟用篩選器,包裝的元件會啟動解碼器和直通緩衝區,並將指令傳送至解碼器本身。
緩衝區處理
圖 3. 緩衝區處理。
排入已包裝解碼器的緩衝區會傳送至基礎解碼器。經過包裝的元件會透過 onWorkDone_nb()
回呼從解碼器擷取輸出緩衝區,然後將其排入篩選器中。系統會將最後一個篩選器的最終輸出緩衝區回報給用戶端。
為了讓這個緩衝區處理作業正常運作,包裝的元件必須將 C2PortBlockPoolsTuning
設為最後一個篩選器,讓架構輸出來自預期的區塊集區。
停止、重設及釋放
結束的元件會停止解碼器,以及所有已啟動的已啟用篩選器。重設和發布時,無論啟用與否,所有元件都會重設或發布。
實作範例篩選器外掛程式
如要啟用外掛程式,請按照下列步驟操作:
- 在程式庫中實作
FilterPlugin
介面,並拖曳到/vendor/lib[64]/libc2filterplugin.so.
- 視需要為
mediacodec.te
新增其他權限。 - 將調整層更新至 Android 12,並重新建構
media.c2
服務。
測試外掛程式
如要測試範例外掛程式,請按照下列步驟操作:
- 重新建構並刷新裝置。
使用下列指令建構範例外掛程式:
m sample-codec2-filter-plugin
重新安裝裝置並重新命名供應商外掛程式,方便轉碼器服務識別裝置。
adb root adb remount adb reboot adb wait-for-device adb root adb remount adb push /out/target/<...>/lib64/sample-codec2-filter-plugin.so \ /vendor/lib64/libc2filterplugin.so adb push /out/target/<...>/lib/sample-codec2-filter-plugin.so \ /vendor/lib/libc2filterplugin.so adb reboot