在AV1中,有一种编码手段,类似于HEVC中的Slice,叫做Segment。segmentation技术将一帧分为若干个部分,然后对这些部分提供单独的参数。这些参数可以包含
- 量化参数(绝对值或者delta值)
- loop filter 强度(strength)
- 预测参考值信息
- 块skip信息
Segmentation
在一帧中,最多可以定义8个segment,也就是说,最多只会有8套segment参数传输到解码端,在SVT-AV1中有宏定义
#define MAX_SEGMENTS 8
同时,每一个segment都会有一个segment ID,指定当前块属于哪一个segment,在SVT-AV1代码中,关于segment的参数由一个叫SegmentationParam的结构体存储
typedef struct {
/*!< 1: 启用Segmentation 功能
* 0: 表示当前帧不使用Segmentation功能*/
uint8_t segmentation_enabled;
/*!< 1: 表示解码此帧时需要同时更新 Segmentation map
* 0: 表示直接从上一帧拿 segmentation map*/
uint8_t segmentation_update_map;
/*!< 1: 表示当前帧的segmentation map的更新是有参考了已有的segmentation map
* 0: 表示不参考已有的segmentation map,直接传一张新的map */
uint8_t segmentation_temporal_update;
/*!< 1: segment 添加新的parameter
* 0: segment 使用已有的parameter */
uint8_t segmentation_update_data;
/*!< feature data */
int16_t feature_data[MAX_SEGMENTS][SEG_LVL_MAX];
/*!< 该segment启用了哪些特性 */
int16_t feature_enabled[MAX_SEGMENTS][SEG_LVL_MAX];
/*!< qm level */
int16_t seg_qm_level[MAX_SEGMENTS][SEG_LVL_MAX];
/*!< 当前segmentation id最大值,也就是已经分配了多少个segment */
uint8_t last_active_seg_id;
/*!< 1: 先读segment id 再读 skip syntax element
* 0: 先读 skip syntax element */
uint8_t seg_id_pre_skip;
//qp-binning
int16_t variance_bin_edge[MAX_SEGMENTS];
} SegmentationParams;
这个结构体中的信息会被放到Frame Header里,这也就意味着针对每一帧,segment的划分是有存在差异的可能性的。