视频缩放
====

本模块提供视频细节增强的[C API接口](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/capi-videoprocessing)，通过调用本模块的接口，可以实现视频流图像内容的清晰度增强及缩放功能，处理后的数据可以用于送显、播放和录制。

典型应用场景如：视频解码 > 视频细节增强 > XComponent显示。

#### 约束与限制

1.  为保证处理能够实时响应，建议只创建一个实例。
    
2.  当前仅支持处理同时满足以下条件的视频：
    
    *   视频为SDR（Standard dynamic range）视频。
    *   视频的像素格式为NV12、NV21，输出格式与输入格式一致。
3.  本模块提供4个档位的算法，处理效果逐渐变优，但性能也会逐渐下降。
    
    | 档位 | 输入分辨率要求（单位：像素） | 输出分辨率要求（单位：像素） | 说明 |
    | :-- | :-- | :-- | :-- |
    | NONE | 
    宽：(32,2000\]
    
    高：(32,2000\]
    
     | 
    
    宽：(32,2000\]
    
    高：(32,2000\]
    
     | 仅适用于缩放场景，无清晰度增强效果。 |
    | LOW | 
    
    宽：(32,2000\]
    
    高：(32,2000\]
    
     | 
    
    宽：(32,2000\]
    
    高：(32,2000\]
    
     | 
    
    仅适用于缩放场景，等比缩放时无清晰度增强效果。
    
    缩放时会对图像进行低质量的清晰度增强，处理速度较快。
    
    该档位为默认设置。
    
     |
    | MEDIUM | 
    
    宽：(32,2000\]
    
    高：(32,2000\]
    
     | 
    
    宽：(32,2000\]
    
    高：(32,2000\]
    
     | 
    
    仅适用于缩放场景，等比缩放时无清晰度增强效果。
    
    缩放时会对图像进行中等质量的清晰度增强，处理速度适中。
    
     |
    | HIGH | 
    
    宽：\[512,2000\]
    
    高：\[512,2000\]
    
     | 
    
    宽：\[512,2000\]
    
    高：\[512,2000\]
    
     | 
    
    适用于缩放及清晰度增强场景，等比缩放时能进行清晰度增强。
    
    缩放时会对图像进行高质量的清晰度增强，处理速度相对较慢。
    
     |
    
4.  不允许在视频处理回调函数中，直接调用视频处理相关接口或其他耗时操作，请在应用自己的线程中调用。
    

#### 开发指导

具体实现可参考[示例工程](https://gitcode.com/HarmonyOS_Samples/VideoProcessing)。

#### \[h2\]在 CMake 脚本中链接动态库

target\_link\_libraries(sample PUBLIC libvideo\_processing.so)

#### \[h2\]开发步骤

1.  添加头文件。
    
    #include <ace/xcomponent/native\_interface\_xcomponent.h>
    #include <multimedia/player\_framework/native\_avformat.h>
    #include <multimedia/video\_processing\_engine/video\_processing.h>
    #include <multimedia/video\_processing\_engine/video\_processing\_types.h>
    #include <native\_window/external\_window.h>
    #include <native\_buffer/native\_buffer.h>
    
2.  （可选）创建解码实例。
    
    细节增强模块的输入可以是来自系统解码的视频流，也可以由应用自行往window填充视频数据（例如：应用内部软解后直接将数据填充到window中）。若选择系统解码器对视频文件或视频流媒体进行处理，则可以创建解码实例来作为细节增强模块的输入。
    
    // 创建Demuxer（媒体多路分解器）解析音视频信息(详见代码示例)
    OH\_AVSource\* source\_ = OH\_AVSource\_CreateWithFD(inputFd, inputFileOffset, inputFileSize);
    OH\_AVDemuxer\* demuxer\_ = OH\_AVDemuxer\_CreateWithSource(source\_);
    auto sourceFormat = std::shared\_ptr<OH\_AVFormat>(OH\_AVSource\_GetSourceFormat(source\_), OH\_AVFormat\_Destroy);
    // 创建视频解码器
    OH\_AVCodec \* decoder\_ = OH\_VideoDecoder\_CreateByMime(videoCodecMime.c\_str());
    // 配置视频信息
    OH\_AVFormat \*format = OH\_AVFormat\_Create();
    OH\_AVFormat\_SetIntValue(format, OH\_MD\_KEY\_WIDTH, videoWidth);
    OH\_AVFormat\_SetIntValue(format, OH\_MD\_KEY\_HEIGHT, videoHeight);
    OH\_AVFormat\_SetDoubleValue(format, OH\_MD\_KEY\_FRAME\_RATE, frameRate);
    OH\_AVFormat\_SetIntValue(format, OH\_MD\_KEY\_PIXEL\_FORMAT, pixelFormat);
    OH\_AVFormat\_SetIntValue(format, OH\_MD\_KEY\_ROTATION, rotation);
    int ret = OH\_VideoDecoder\_Configure(decoder\_, format);
    OH\_AVFormat\_Destroy(format);
    // 配置回调，维护视频解码器buffer队列（详见代码示例）
    OH\_VideoDecoder\_RegisterCallback(decoder\_,
            {SampleCallback::OnCodecError, SampleCallback::OnCodecFormatChange,
             SampleCallback::OnNeedInputBuffer, SampleCallback::OnNewOutputBuffer}, videoDecContext\_);
    // 准备视频解码器
    int ret = OH\_VideoDecoder\_Prepare(decoder\_);
    // 创建解码上下文
    videoDecContext\_ = new CodecUserData;
    
3.  （可选）初始化环境。
    
    一般在进程内第一次使用时调用，可提前完成部分耗时操作。
    
    VideoProcessing\_ErrorCode ret = OH\_VideoProcessing\_InitializeEnvironment();
    
4.  创建细节增强模块。
    
    应用可以通过视频处理引擎模块类型来创建细节增强模块。示例中的变量说明如下：
    
    *   videoProcessor：细节增强模块实例。
    *   VIDEO\_PROCESSING\_TYPE\_DETAIL\_ENHANCER：细节增强类型。
    *   预期返回值：VIDEO\_PROCESSING\_SUCCESS
    
    // 通过指定视频处理引擎类型创建细节增强模块实例
    VideoProcessing\_ErrorCode ret = OH\_VideoProcessing\_Create(&videoProcessor, VIDEO\_PROCESSING\_TYPE\_DETAIL\_ENHANCER);
    
5.  配置异步回调函数。
    
    // 创建回调实例
    ret = OH\_VideoProcessingCallback\_Create(&callback);
    // 绑定回调函数
    OH\_VideoProcessingCallback\_BindOnError(callback, OnError);
    OH\_VideoProcessingCallback\_BindOnState(callback, OnState);
    OH\_VideoProcessingCallback\_BindOnNewOutputBuffer(callback, OnNewOutputBuffer);
    // 注册回调函数
    ret = OH\_VideoProcessing\_RegisterCallback(videoProcessor, callback, this);
    // 回调函数声明（其中userData会传递注册回调时传入的用户数据，如：this指针）
    void OnError(OH\_VideoProcessing\* videoProcessor, VideoProcessing\_ErrorCode error, void\* userData);
    void OnState(OH\_VideoProcessing\* videoProcessor, VideoProcessing\_State state, void\* userData);
    void OnNewOutputBuffer(OH\_VideoProcessing\* videoProcessor, uint32\_t index, void\* userData);
    
6.  （可选）配置细节增强档位，当前有高中低三档及NONE可选，若不配置则默认档位为LOW档。
    
    // 创建format实例
    OH\_AVFormat\* parameter = OH\_AVFormat\_Create();
    // 指定档位
    OH\_AVFormat\_SetIntValue(parameter, VIDEO\_DETAIL\_ENHANCER\_PARAMETER\_KEY\_QUALITY\_LEVEL, VIDEO\_DETAIL\_ENHANCER\_QUALITY\_LEVEL\_HIGH);
    // 配置参数
    OH\_VideoProcessing\_SetParameter(videoProcessor, parameter);
    
7.  获取Surface。
    
    //配置算法的输入
    ret = OH\_VideoProcessing\_GetSurface(videoProcessor, inputWindow);
    // 将解码器的输出与算法的输入进行绑定，解码器输出的window分辨率即为算法输入分辨率
    OH\_VideoDecoder\_SetSurface(decoder\_,  inputWindow\_);
    
8.  设置Surface（配置送显）。
    
    // 配置算法的输出，配置的输出window的分辨率即为算法输出分辨率
    ret = OH\_VideoProcessing\_SetSurface(videoProcessor, outWindow);
    
9.  创建解码器输入输出线程。
    
    std::unique\_ptr<std::thread> videoDecInputThread\_ = std::make\_unique<std::thread>(&Player::VideoDecInputThread, this);
    std::unique\_ptr<std::thread> videoDecOutputThread\_ = std::make\_unique<std::thread>(&Player::VideoDecOutputThread, this);
    
10.  启动细节增强处理。
     
     // 启动解码
     int ret = OH\_VideoDecoder\_Start(decoder\_);
     // 启动细节增强处理
     ret = OH\_VideoProcessing\_Start(videoProcessor);
     
11.  调用[OH\_VideoProcessing\_Stop()](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/capi-video-processing-h#oh_videoprocessing_stop)停止细节增强。
     
     VideoProcessing\_ErrorCode ret = OH\_VideoProcessing\_Stop(videoProcessor);
     
12.  释放处理实例。
     
     VideoProcessing\_ErrorCode ret = OH\_VideoProcessing\_Destroy(videoProcessor)；
     videoProcessor = nullptr;
     VideoProcessing\_ErrorCode ret = OH\_VideoProcessingCallback\_Destroy(callback);
     callback = nullptr;
     
13.  释放处理资源。
     
     VideoProcessing\_ErrorCode ret = OH\_VideoProcessing\_DeinitializeEnvironment();