兼容媒體轉碼

Android 12 中引入的兼容媒體轉碼功能允許設備使用更現代、存儲效率更高的媒體格式進行視頻捕獲,例如 HEVC,同時保持與應用程序的兼容性。借助此功能,設備製造商可以默認使用 HEVC 而不是 AVC 來提高視頻質量,同時降低存儲和帶寬要求。對於啟用了兼容媒體轉碼的設備,當視頻被不支持的應用程序打開時,Android 可以自動轉換以 HEVC 或 HDR 等格式錄製的視頻(最長一分鐘)。這允許應用程序即使在設備上以較新的格式捕獲視頻時也能運行。

默認情況下,兼容媒體轉碼功能處於關閉狀態。要請求媒體轉碼,應用程序必須聲明其媒體功能。有關聲明媒體功能的更多信息,請參閱兼容的媒體轉碼的Android開發者網站。

怎麼運行的

兼容媒體轉碼功能包括兩個主要部分:

  • 在媒體框架轉換服務:這些服務從一種格式轉換到另一個文件使用硬件的低延遲和高品質的轉換。這包括轉碼 API、轉碼服務、用於自定義過濾器的 OEM 插件和硬件。有關詳細信息,請參閱架構概述
  • 兼容的媒體在媒體提供轉碼功能:該組件在媒體提供商攔截發現Apps訪問媒體文件,並提供任何原始文件或基於應用程序的聲明功能的轉碼文件。如果應用程序支持媒體文件的格式,則不需要特殊處理。如果應用程序不支持該格式,則在應用程序訪問文件時,框架會將文件轉換為舊格式,例如 AVC。

圖 1 顯示了媒體轉碼過程的概覽。

兼容媒體轉碼流程

圖1.兼容的媒體轉碼的概述。

支持的格式

兼容媒體轉碼功能支持以下格式轉換:

  • HEVC(8位),以AVC:編解碼器轉換是通過連接一個mediacodec解碼器和一個編碼器mediacode執行。
  • HDR10 +(10位),以AVC(SDR):HDR至SDR轉換是使用mediacodec實例和供應商插件鉤到解碼器的實例進行。欲了解更多信息,請參閱HDR至SDR編碼

支持的內容來源

兼容媒體轉碼功能支持設備上的由被存儲在本機OEM相機應用生成的媒體DCIM/Camera/初級外部卷文件夾中。該功能不支持輔助存儲上的媒體。不支持通過電子郵件或 SD 卡傳遞到設備的內容。

應用程序根據各種文件路徑訪問文件。下面描述了啟用或繞過轉碼的文件路徑:

  • 啟用轉碼:

    • 通過 MediaStore API 訪問應用程序
    • 通過直接文件路徑 API 訪問應用程序,包括 Java 和本機代碼
    • 通過存儲訪問框架 (SAF) 訪問應用程序
    • 通過操作系統共享表 Intents 訪問應用程序。 (僅限 MediaStore URI)
    • MTP/PTP 文件從手機傳輸到 PC
  • 繞過轉碼:

    • 通過彈出 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模塊。這為尚未更新其清單文件的應用程序啟用轉碼。一旦應用使用不受支持的格式更新其清單文件,就必須將其從強制轉碼列表中刪除。設備製造商可以提名他們的應用程序被添加或從力轉碼列表中刪除提交補丁報告bug 。 Android 團隊會定期查看列表,並可能會從列表中刪除應用。
  • 在運行時使用應用程序兼容性框架禁用支持的格式(用戶還可以在“設置”中為每個應用程序禁用此功能)。
  • 打開文件後MediaStore同時明確指定與不支持的格式openTypedAssetFileDescriptor API。

用於USB傳輸(設備到PC),代碼轉換被默認禁用但用戶可以選擇啟用使用轉換的影片AVC肘節在USB設定為如圖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

全局啟用媒體轉碼

要使用轉碼測試媒體轉碼框架或應用程序行為,您可以全局啟用或禁用兼容媒體轉碼功能。在設置>系統>開發者>媒體轉碼開發人員選項頁,將Override轉換默認切換到然後設置啟用轉碼切換為開啟關閉。如果啟用此設置,則您正在開發的應用程序以外的應用程序可能會在後台進行媒體轉碼。

查看轉碼狀態

在測試過程中,您可以使用以下 ADB shell 命令來檢查轉碼狀態,包括當前和過去的轉碼會話:

adb shell dumpsys media.transcoding

擴展視頻長度限制

出於測試目的,您可以使用以下命令擴展轉碼的一分鐘視頻長度限制。運行此命令後可能需要重新啟動。

adb shell device_config put storage_native_boot transcode_max_duration_ms <LARGE_NUMBER_IN_MS>

AOSP 來源和參考資料

以下是與兼容媒體轉碼相關的 AOSP 源代碼。

HDR 到 SDR 編碼

為了支持HDR至SDR編碼,設備製造商可以使用AOSP樣品編解碼器2.0過濾器插件位於/platform/frameworks/av/media/codec2/hidl/plugin/ 。本節介紹過濾器插件的工作原理、插件的實現方法以及插件的測試方法。

如果設備不包含支持 HDR 到 SDR 編碼的插件,則訪問 HDR 視頻的應用將獲取原始文件描述符,而不管清單中聲明的應用的媒體功能如何。

怎麼運行的

本節介紹 Codec 2.0 過濾器插件的一般行為。

背景

Android提供的之間的適配層實現編解碼器2.0接口和android.hardware.media.c2在HAL接口android::hardware::media::c2 。對於過濾器插件,AOSP 包含一個包裝器機制,將解碼器與過濾器插件包裝在一起。 MediaCodec識別這些包裹部件與過濾功能的解碼器。

概述

所述FilterWrapper類需要供應商的編解碼器,並返回包裹編解碼器回到所述media.c2適配層。該FilterWrapper類負載libc2filterplugin.so通過FilterWrapper::Plugin API和記錄可用的過濾器在插件中。在創作, FilterWrapper實例所有可用的過濾器。只有改變緩衝區的過濾器才會在啟動時啟動。

過濾插件架構

圖1.過濾器插件架構。

過濾插件接口

FilterPlugin.h接口定義了以下API揭露過濾器:

  • std::shared_ptr<C2ComponentStore>getComponentStore()

    返回C2ComponentStore包含過濾器對象。這與供應商的 Codec 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如果過濾器組件改變了緩衝區。例如,色調映射過濾器返回true如果目標傳遞函數是SDR和輸入傳遞函數是HDR(HLG或PQ)。

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