相容媒體轉碼

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 開放原始碼計畫原始碼。

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 實作項目公開的內容不同。通常,此儲存庫僅包含 te 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 類別的詳細資料。

創作

在建立時,包裝的元件會將基礎解碼器和所有定義的篩選器例項化。

查詢和設定

包裝的元件會根據篩選器說明,將傳入參數與查詢或設定要求分開。例如,篩選器控制項參數的設定會轉送至對應的篩選器,而篩選器中受影響的參數會出現在查詢中,而非從含有未受影響參數的解碼器讀取。

查詢和設定

圖 2. 查詢和設定。

開始

在啟動時,包裝的元件會啟動解碼器和所有會變更緩衝區的篩選器。如果未啟用篩選器,包裝的元件會啟動解碼器和直通緩衝區,並將指令傳送至解碼器本身。

緩衝區處理

緩衝區處理

圖 3. 緩衝區處理。

排入已包裝解碼器的緩衝區會傳送至基礎解碼器。經過包裝的元件會透過 onWorkDone_nb() 回呼從解碼器擷取輸出緩衝區,然後將其排入篩選器中。系統會將最後一個篩選器的最終輸出緩衝區回報給用戶端。

為了讓這個緩衝區處理作業正常運作,包裝的元件必須將 C2PortBlockPoolsTuning 設為最後一個篩選器,讓架構輸出來自預期的區塊集區。

停止、重設及釋放

結束的元件會停止解碼器,以及所有已啟動的已啟用篩選器。重設和發布時,無論啟用與否,所有元件都會重設或發布。

實作範例篩選器外掛程式

如要啟用外掛程式,請按照下列步驟操作:

  1. 在程式庫中實作 FilterPlugin 介面,並拖曳到 /vendor/lib[64]/libc2filterplugin.so.
  2. 視需要為 mediacodec.te 新增其他權限。
  3. 將調整層更新至 Android 12,並重新建構 media.c2 服務。

測試外掛程式

如要測試範例外掛程式,請按照下列步驟操作:

  1. 重新建構並刷新裝置。
  2. 使用下列指令建構範例外掛程式:

    m sample-codec2-filter-plugin
    
  3. 重新安裝裝置並重新命名供應商外掛程式,方便轉碼器服務識別裝置。

    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