• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# ROI视频编码
2
3<!--Kit: AVCodec Kit-->
4<!--Subsystem: Multimedia-->
5<!--Owner: @xhjgc-->
6<!--Designer: @dpy2650--->
7<!--Tester: @cyakee-->
8<!--Adviser: @zengyawen-->
9
10## 基础概念
11
12ROI视频编码是在现有的硬件编码基础上开放的高级能力,允许开发者自主指定ROI区域,并通过调整ROI区域码率分配优化编码效果。
13- ROI区域:ROI(Region of Interest)一般是指视频中引人注目的区域,比如直播中的人脸区域等。
14- ROI编码:允许对画面中的ROI区域分配更高的码率,同时适当降低背景等非ROI区域码率,从而在有限带宽条件下提升整体视觉体验。
15
16## 适用场景
17
18具备明显ROI区域的视频编码场景,例如:
19- **直播场景**:人脸或商品一般是受关注的重点区域,通过ROI编码能够有效提升该区域的主观清晰度。
20- **监控场景**:车牌或人脸一般是受关注的重点区域,通过ROI编码能够保留更清晰的有效信息。
21
22## 约束和限制
23
24- **支持的平台**:Kirin9000及以后。
25- **支持的系统**:OpenHarmony6.0及以后。
26- **支持的编码器**:H264 8bit硬件编码、H265 8bit硬件编码、H265 10bit硬件编码。
27- **支持的码控模式**:VBR、CBR、SQR。
28- **支持的编码模式**:Surface模式、Buffer模式。
29- 同一帧最多支持配置6个ROI区域,并且总ROI面积不能超过图片面积的1/5。
30- 本模块仅提供底层ROI编码能力,不包括ROI区域检测功能。
31
32## 接口介绍
33
34ROI编码接口支持开发者通过字符串形式下发配置参数,参数需满足"Top1,Left1-Bottom1,Right1=Offset1;Top2,Left2-Bottom2,Right2=Offset2;"的格式。<br>
35- Top、Left、Bottom、Right分别指定对应ROI区域上、左、下、右边界。
36- Offset指定deltaQp并且"=Offset"可以省略,省略时使用默认参数(deltaQp=-3)。
37- 多个ROI参数之间通过";"连接,所有参数均为整数。
38- 使用前请确保传入参数有效,并尽量避免多个ROI区域之间产生交叠。
39
40|配置参数 |语义 |格式 |
41|------- |------- |------- |
42|OH_MD_KEY_VIDEO_ENCODER_ROI_PARAMS |ROI参数 |String|
43
44**注意**
451. 为了便于使用,ROI参数支持随帧下发并实时生效,开发者无需进行能力查询或配置全局开关。
462. 如果底层硬编不支持ROI编码能力,编码器会忽略ROI参数,进行普通编码。
473. deltaQp有效范围[-51,51],编码器会在块级QP的基础上叠加deltaQp,然后Clip到[minQp,maxQp]范围内得到最终QP。
484. 不通过OH_MD_KEY_VIDEO_ENCODER_ROI_PARAMS下发参数时,该帧会复用历史ROI信息进行编码。
495. 通过OH_MD_KEY_VIDEO_ENCODER_ROI_PARAMS传入空字符串,可以主动关闭ROI编码并清空历史ROI信息,进行普通编码。
506. 通过OH_MD_KEY_VIDEO_ENCODER_ROI_PARAMS传入的字符串无法解析出任何有效ROI信息时,ROI编码不生效并清空历史ROI信息,转为普通编码。
517. 如果设置的ROI总面积超过1/5图片大小,ROI编码不生效并清空历史ROI信息,转为普通编码。
528. 如果输入的有效ROI参数超过6个,超过的ROI参数将被忽略。
539. 如果多个ROI区域产生交叠,仅第一个ROI参数会在交叠区域生效。
54
55## 开发指导
56
57基础编码功能请参考[视频编码](video-encoding.md)开发指南,下面仅针对ROI编码做具体说明。
58
59### Surface模式
60
61
621. 调用OH_VideoEncoder_RegisterParameterCallback()接口注册随帧通路回调。
63
64    ```c++
65    // 1. 编码输入参数回调OH_VideoEncoder_OnNeedInputParameter实现。
66    static void OnNeedInputParameter(OH_AVCodec *codec, uint32_t index, OH_AVFormat *parameter, void *userData)
67    {
68        /**
69        * 配置两个ROI区域,并指定对应的deltaQp。
70        * ROI1左上角坐标(0, 0),右下角坐标(64, 128),调节QP-4。
71        * ROI2左上角坐标(200, 100),右下角坐标(400, 300),调节QP+3。
72        **/
73        const char *roiInfo = "0,0-128,64=-4;100,200-300,400=3";
74        OH_AVFormat_SetStringValue(parameter, OH_MD_KEY_VIDEO_ENCODER_ROI_PARAMS, roiInfo);
75        OH_VideoEncoder_PushInputParameter(codec, index);
76    }
77    // 2. 注册随帧参数回调。
78    OH_VideoEncoder_OnNeedInputParameter inParaCb = OnNeedInputParameter;
79    OH_VideoEncoder_RegisterParameterCallback(videoEnc, inParaCb, nullptr); // nullptr:用户特定数据userData为空。
80    ```
81
82### Buffer模式
83
841. 调用OH_AVBuffer_SetParameter()接口配置随帧参数。
85
86    ```c++
87    void OnNeedInputBuffer(OH_AVCodec *codec, uint32_t index, OH_AVBuffer *buffer, void *userData)
88    {
89        /**
90        * 配置两个ROI区域,并指定对应的deltaQp。
91        * ROI1左上角坐标(0, 0),右下角坐标(64, 128),调节QP-4。
92        * ROI2左上角坐标(200, 100),右下角坐标(400, 300),调节QP+3。
93        **/
94        const char *roiInfo = "0,0-128,64=-4;100,200-300,400=3";
95        OH_AVFormat *parameter = OH_AVBuffer_GetParameter(buffer);
96        OH_AVFormat_SetStringValue(parameter, OH_MD_KEY_VIDEO_ENCODER_ROI_PARAMS, roiInfo);
97        OH_AVBuffer_SetParameter(buffer, parameter);
98        OH_AVFormat_Destroy(parameter);
99
100        inQueue.Enqueue(std::make_shared<CodecBufferInfo>(index, buffer));
101    }
102    ```