视频服务HDR Vivid 还原色彩,让所见成“真”

时间:2022-11-16 15:07:45

如今,视频正在以一种前所未有的方式渗入日常生活,是当下人们记录生活最热门的方式。所以,用户对视频的画质要求越来越高,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 最新技术资讯~