在 Android 12 中推出的「相容媒體轉碼」功能,可讓裝置使用更先進、儲存空間更有效率的媒體格式 (例如 HEVC) 擷取影片,同時維持與應用程式的相容性。有了這項功能,裝置製造商就能預設使用 HEVC 而非 AVC,提升影片品質,同時降低儲存空間和頻寬需求。如果裝置已啟用相容的媒體轉碼功能,當影片由不支援該格式的應用程式開啟時,Android 會自動轉換以 HEVC 或 HDR 等格式錄製的影片 (長度上限為一分鐘)。這樣一來,即使裝置上以較新的格式擷取影片,應用程式也能正常運作。
相容媒體轉碼功能預設為關閉。如要要求媒體轉碼,應用程式必須宣告媒體功能。如要進一步瞭解如何宣告媒體功能,請參閱 Android 開發人員網站上的「相容的媒體轉碼」。
運作方式
相容媒體轉碼功能包含兩個主要部分:
- 媒體架構中的轉碼服務:這些服務會使用硬體將檔案從一種格式轉換為另一種格式,以便提供低延遲和高品質的轉換。這包括轉碼 API、轉碼服務、自訂濾鏡的 OEM 外掛程式和硬體。詳情請參閱「架構總覽」。
- 媒體供應器中的相容媒體轉碼功能:媒體供應器中的這個元件會攔截存取媒體檔案的應用程式,並根據應用程式宣告的功能提供原始檔案或轉碼檔案。如果應用程式支援媒體檔案的格式,就不需要特別處理。如果應用程式不支援該格式,則在應用程式存取檔案時,架構會將檔案轉換為舊格式,例如 AVC。
圖 1 顯示媒體轉碼程序的總覽。
圖 1. 相容媒體轉碼總覽。
支援的格式
相容的媒體轉碼功能支援下列格式轉換:
- HEVC (8 位元) 至 AVC:透過連結一個媒體編碼器解碼器和一個媒體編碼器編碼器,執行轉碼器轉換作業。
- HDR10+ (10 位元) 至 AVC (SDR):使用媒體編解碼例項和供應商外掛程式鉤子,執行 HDR 至 SDR 的轉換作業。詳情請參閱「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 守護程序會攔截應用程式對檔案的讀取存取權。如果應用程式支援較新的格式 (例如 HEVC),系統會傳回原始檔案。如果應用程式不支援該格式,系統會將檔案轉碼為舊版格式 (例如 AVC),如果有轉碼版本,則會從快取中傳回。
要求轉碼檔案
相容的媒體轉碼功能預設為停用,也就是說,如果裝置支援 HEVC,Android 不會轉碼檔案,除非應用程式在資訊清單檔案或強制轉碼清單中指定。
應用程式可以使用下列選項要求經過轉碼的素材資源:
- 在資訊清單檔案中宣告不支援的格式。詳情請參閱「在資源中宣告功能」和「在程式碼中宣告功能」。
- 將應用程式新增至 MediaProvider 模組中的強制轉碼清單。這可讓未更新資訊清單檔案的應用程式進行轉碼。一旦應用程式更新資訊清單檔案,但使用不支援的格式,就必須從強制轉碼清單中移除。裝置製造商可以提交修補程或回報錯誤,將自家應用程式加入或移除強制轉碼清單。Android 團隊會定期審查這份清單,並可能從清單中移除應用程式。
- 在執行時使用應用程式相容性架構停用支援的格式 (使用者也可以在「設定」中為每個應用程式停用這項功能)。
- 使用
MediaStore
開啟檔案,並透過openTypedAssetFileDescriptor
API 明確指定不支援的格式。
對於 USB 傳輸 (裝置到電腦),系統預設會停用轉碼功能,但使用者可以選擇在「USB 偏好設定」畫面中使用「將影片轉換為 AVC」切換按鈕啟用轉碼功能,如圖 3 所示。
圖 3. 切換至 USB 偏好設定畫面,啟用媒體轉碼功能。
要求轉碼檔案的限制
為避免轉碼要求長時間鎖定系統資源,要求轉碼工作階段的應用程式會受到以下限制:
- 連續 10 個工作階段
- 總放送時間為三分鐘
如果應用程式超出所有這些限制,架構會傳回原始檔案描述元。
裝置需求
如要支援相容的媒體轉碼功能,裝置必須符合下列規定:
- 裝置預設在原生相機應用程式中啟用 HEVC 編碼
- (支援 HDR 到 SDR 轉碼的裝置) 裝置支援 HDR 影片擷取功能
為確保裝置在媒體轉碼時的效能,必須最佳化影片硬體和儲存空間的讀/寫存取效能。如果媒體轉碼器的設定優先順序等於 1
,則轉碼器必須以盡可能高的總處理量運作。我們建議轉碼效能至少達到 200 fps。如要測試硬體效能,請在 frameworks/av/media/libmediatranscoding/transcoder/benchmark
中執行媒體轉碼器基準測試。
驗證
如要驗證相容的媒體轉碼功能,請執行下列 CTS 測試:
android.media.mediatranscoding.cts
android.mediaprovidertranscode.cts
全域啟用媒體轉碼
如要測試媒體轉碼架構或應用程式轉碼行為,您可以全面啟用或停用相容的媒體轉碼功能。在「設定」>「系統」>「開發人員」>「媒體轉碼」開發人員選項頁面中,將「覆寫轉碼預設值」切換鈕設為「開啟」,然後將「啟用轉碼」切換鈕設為「開啟」或「關閉」。如果啟用這項設定,除了您正在開發的應用程式之外,其他應用程式可能會在背景執行媒體轉碼。
查看轉碼狀態
在測試期間,您可以使用下列 ADB 殼層指令,檢查轉碼狀態,包括目前和過去的轉碼工作階段:
adb shell dumpsys media.transcoding
放寬影片長度限制
為了測試,您可以使用下列指令,延長轉碼的影片長度限制為一分鐘。執行這項指令後,可能需要重新啟動。
adb shell device_config put storage_native_boot transcode_max_duration_ms <LARGE_NUMBER_IN_MS>
Android 開放原始碼計畫來源和參考資料
以下是與相容媒體轉碼相關的 Android 開放原始碼計畫原始碼。
Transcoding System 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 影片的應用程式會取得原始檔案描述元,而不會取得資訊清單中宣告的應用程式媒體功能。
運作方式
本節說明編解碼器 2.0 濾鏡外掛程式的一般行為。
背景
Android 在 android::hardware::media::c2
中提供 Codec 2.0 介面與 android.hardware.media.c2
HAL 介面之間的適應層實作項目。針對篩選器外掛程式,AOSP 包含包裝函式機制,可將解碼器與篩選器外掛程式包裝在一起。MediaCodec
會將這些包裝的元件視為具有篩選功能的解碼器。
總覽
FilterWrapper
類別會採用供應商編解碼,並將包裝的編解碼傳回至 media.c2
轉譯層。FilterWrapper
類別會透過 FilterWrapper::Plugin
API 載入 libc2filterplugin.so
,並記錄外掛程式提供的可用篩選器。建立時,FilterWrapper
會將所有可用的篩選器例項化。只有會變更緩衝區的篩選器會在開始時啟動。
圖 4. 篩選器外掛程式架構。
篩選器外掛程式介面
FilterPlugin.h
介面定義了以下 API,用於公開篩選器:
std::shared_ptr<C2ComponentStore>getComponentStore()
傳回包含篩選器的
C2ComponentStore
物件。這與供應商的編碼器 2.0 實作項目公開的內容不同。通常,這個儲存庫只會包含FilterWrapper
類別使用的篩選器。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
類別。
創作
在建立時,包裝的元件會將基礎解碼器和所有定義的篩選器例項化。
查詢和設定
經過包裝的元件會根據篩選器說明,將傳入的參數與查詢或設定要求分開。舉例來說,篩選器控制項參數的設定會傳送至對應的篩選器,而篩選器的受影響參數會顯示在查詢中 (而不是從具有不受影響參數的解碼器讀取)。
圖 5. 查詢和設定。
開始
在啟動時,包裝的元件會啟動解碼器和所有會變更緩衝區的篩選器。如果未啟用篩選器,則包裝的元件會啟動解碼器和直通緩衝區,並將指令傳送至解碼器本身。
緩衝區處理
圖 6. 緩衝處理。
排入包裝解碼器的緩衝區會傳送至基礎解碼器。經過包裝的元件會透過 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