視頻服務HDR Vivid 還原色彩,讓所見成「真」

  • 2022 年 11 月 16 日
  • 筆記

如今,視頻正在以一種前所未有的方式滲入日常生活,是當下人們記錄生活最熱門的方式。所以,用戶對視頻的畫質要求越來越高,App想要吸引更多的用戶,擁有視頻畫質新技術的強力支撐很關鍵。

HDR(High-Dynamic Range)就是一種提高影像亮度和對比度的處理技術。它可以將每個暗部的細節變亮,增加對比度,豐富更多細節色彩,讓電影、圖片都能呈現出極佳的效果,在觀影時更接近真實環境中的視覺感受。但是傳統的HDR技術存在標準不統一,終端呈現效果參差不齊,製作難度大,缺少超高清片源等桎梏。

HMS Core視頻服務HDR Vivid能力不但解決了HDR的問題,而且可以呈現豐富的色彩及層次,更加強烈的影像縱深感及細節,讓畫面更加的趨近真實世界,力求實現人眼「所見即所得」的效果。HDR Vivid SDK提供的HDR Vivid視頻圖像的OETF、Tonemapping、HDR2SDR等能力,助力您快速構建HDR Vivid視頻的播放、分享特性,幫助您向用戶提供HDR Vivid視頻媒體體驗。HDR Ability SDK提供的屏幕亮度相關能力,獲得更好的HDR視頻播放體驗,可以單獨集成,也可以和HDR Vivid SDK配合使用。

開發準備

  1. 在開發應用前需要在華為開發者聯盟網站上註冊成為開發者並完成實名認證,具體方法請參見帳號註冊認證

  2. 集成HMS Core SDK

針對Android Studio開發環境,華為提供了Maven倉集成方式的HMS Core SDK包。在開始開發前,您需要將HMS Core SDK集成到您的Android Studio開發環境中。

  1. 配置混淆腳本

4. 添加權限

應用開發

1. 準備工作

檢查設備是否具有HDR Vivid片源硬件解碼能力。如果以下函數返回true,則說明設備具有HDR Vivid片源硬件解碼能力。

public boolean isSupportDecode() {
    // 獲取MediaCodec在設備上的支持信息
    MediaCodecList mcList = new MediaCodecList(MediaCodecList.ALL_CODECS);
    MediaCodecInfo[] mcInfos = mcList.getCodecInfos();


    for (MediaCodecInfo mci : mcInfos) {
        // 過濾掉編碼器
        if (mci.isEncoder()) {
            continue;
        }
        String[] types = mci.getSupportedTypes();
        String typesArr = Arrays.toString(types);
        // 過濾非HEVC解碼器
        if (!typesArr.contains("hevc")) {
            continue;
        }
        for (String type : types) {
            // 判斷解碼器是否支持HEVC 10Bit的解碼
            MediaCodecInfo.CodecCapabilities codecCapabilities = mci.getCapabilitiesForType(type);
            for (MediaCodecInfo.CodecProfileLevel codecProfileLevel : codecCapabilities.profileLevels) {
                if (codecProfileLevel.profile == HEVCProfileMain10
                    || codecProfileLevel.profile == HEVCProfileMain10HDR10
                    || codecProfileLevel.profile == HEVCProfileMain10HDR10Plus) {
                    // 返回支持
                    return true;
                }
            }
        }
    }
    // 返回不支持
    return false;
}

從視頻中解析視頻信息,包括:分辨率、轉換函數、色彩空間、顏色格式。存放到自定義變量中,如:VideoInfo。

public class VideoInfo {
    private int width;
    private int height;
    private int tf;
    private int colorSpace;
    private int colorFormat;
    private long durationUs;
}

創建SurfaceView,用於SDK處理後渲染畫面。

// surface_view為布局文件layout中定義
SurfaceView surfaceView = (SurfaceView) view.findViewById(R.id.surface_view);

創建線程,從視頻中解析視頻流,具體請參見示例代碼

2. 渲染轉碼

2.1創建並初始化HdrVividRender實例。

HdrVividRender hdrVividRender = new HdrVividRender();
hdrVividRender.init();

2.2設置視頻源的分辨率、光電轉換函數。

// 設置視頻源的光電轉換函數
hdrVividRender.setTransFunc(2);
// 設置視頻源的分辨率
hdrVividRender.setInputVideoSize(3840, 2160);

說明:Android平台下只支持渲染輸入模式場景。

2.3設置輸出的亮度值(可選)。

hdrVividRender.setBrightness(700);

2.4創建輸入Surface。當輸入模式為渲染模式時,需要調用該接口創建輸入Surface,並將該Surface作為configure的inputSurface參數傳入。

Surface inputSurface = hdrVividRender.createInputSurface();

2.5設置輸出參數。

2.5.1設置渲染的Surface的大小(渲染輸出模式需要設置)。

// surfaceView為視頻播放窗口
hdrVividRender.setOutputSurfaceSize(surfaceView.getWidth(), surfaceView.getHeight());

2.5.2設置輸出Buffer的色彩空間(轉碼輸出模式時設置,可選,如果不設置,默認為BT.709)。

hdrVividRender.setColorSpace(HdrVividRender.COLORSPACE_P3);

2.5.3設置輸出Buffer的顏色格式(轉碼輸出模式時設置,可選,如果不設置,默認為R8G8B8A8)。

hdrVividRender.setColorFormat(HdrVividRender.COLORFORMAT_R8G8B8A8);

2.6輸出模式為渲染模式時,需要調用如下接口:

hdrVividRender.configure(inputSurface, new HdrVividRender.InputCallback() {
    @Override
    public int onGetDynamicMetaData(HdrVividRender hdrVividRender, long pts) {
        // 設置靜態元數據,需要從視頻源中獲取。
        HdrVividRender.StaticMetaData lastStaticMetaData = new HdrVividRender.StaticMetaData();
        hdrVividRender.setStaticMetaData(lastStaticMetaData);
        // 設置動態元數據,從視頻源中獲取。
        ByteBuffer dynamicMetaData = ByteBuffer.allocateDirect(10);
        hdrVividRender.setDynamicMetaData(20000, dynamicMetaData);
        return 0;
    }
}, surfaceView.getHolder().getSurface(), null);

2.7輸出模式為轉碼模式時,需要調用如下接口:

hdrVividRender.configure(inputSurface, new HdrVividRender.InputCallback() {
    @Override
    public int onGetDynamicMetaData(HdrVividRender hdrVividRender, long pts) {
        // 設置靜態元數據,需要從視頻源中獲取。
        HdrVividRender.StaticMetaData lastStaticMetaData = new HdrVividRender.StaticMetaData();
        hdrVividRender.setStaticMetaData(lastStaticMetaData);
        // 設置動態元數據,從視頻源中獲取。
        ByteBuffer dynamicMetaData = ByteBuffer.allocateDirect(10);
        hdrVividRender.setDynamicMetaData(20000, dynamicMetaData);
        return 0;
    }
}, null, new HdrVividRender.OutputCallback() {
    @Override
    public void onOutputBufferAvailable(HdrVividRender hdrVividRender, ByteBuffer byteBuffer,
        HdrVividRender.BufferInfo bufferInfo) {
            // App處理緩衝Buffer數據邏輯
    }
});

說明:如果不使用new HdrVividRender.OutputCallback()異步處理返回Buffer數據,可以通過read方法主動獲取。例如:hdrVividRender.read(new BufferInfo(), 10); // 10為時間戳,由App決定具體時間戳。

2.8啟動處理流程。

hdrVividRender.start();

2.9停止處理流程。

hdrVividRender.stop();

2.10釋放資源。

hdrVividRender.release();
hdrVividRender = null;

說明:

渲染輸出模式,當Surface大小改變時,需要調用setOutputSurfaceSize重新設置輸出Surface的大小。

渲染輸出模式,當Surface銷毀重新創建時(前後台切換),如果HdrVividRender實例沒有銷毀,需要調用setOutputSurface接口設置新的輸出Surface。

3. HDR能力配置

HDR能力接口類HdrAbility,可用於HDR Vivid SDK對HDR Vivid視頻進行渲染轉碼處理過程中,進行亮度調節。

3.1初始化亮度調節功能。

HdrAbility.init(getApplicationContext());

3.2打開設備的HDR能力,屏幕的峰值亮度會增加。

HdrAbility.setHdrAbility(true);

3.3設置輸出視頻圖像數據的白點的備選的最大峰值亮度。

HdrAbility.setBrightness(600);

3.4打開視頻圖層高亮顯示能力。

HdrAbility.setHdrLayer(surfaceView, true);

3.5設置字幕/彈幕圖層高亮顯示能力。

HdrAbility.setCaptionsLayer(captionView, 1.5f);

了解更多詳情>>

訪問華為開發者聯盟官網
獲取開發指導文檔
華為移動服務開源倉庫地址:GitHubGitee

關注我們,第一時間了解 HMS Core 最新技術資訊~