SVT-AV1帧内编码

AV1帧内预测模式AV1视频编码标准中用于减少冗余提高压缩效率关键技术之一通过利用当前帧内相邻像素相关性生成预测从而减少需要编码数据以下AV1帧内预测模式详细介绍

一 方向性帧内预测模式

AV1支持56方向帧内预测模式这些模式通过不同角度偏移模拟局部纹理具体来说

1.1 8 基础角度模式包括45,67,90,113,135,157,180,203角度

1.2 扩展角度模式每个基础角度模式两侧3补偿分布6扩展角度从而形成56方向性预测模式

二 非方向性帧内预测模式

除了方向模式AV1支持多种方向性帧内预测模式适用于平滑区域预测

DC_PRED模式通过平均顶部左侧临近重建样本生成当前预测样本

SMOOTH模式 使用沿垂直水平方向二次插值结果平均值生成预测值

SMOOTH_VSMOOTH_H模式分别沿垂直水平方向使用二次插值生成预测

Paeth预测模式根据顶部左侧左上角参考样本预测每个样本

三 其他帧内预测模式

3.1 递归滤波模式通过递归利用预测样本预测的样本特别适合预测具有明显方向纹理区域

3.2 依赖亮度色度预测模式Cfl通过一个线性模型使用相应重建亮度样本推导色度预测样本

四 帧内预测的优势

4.1 高压缩效率通过多种预测模式AV1能够灵活适应图像内容变化从而提高编码效率压缩性能

4.2 减少冗余 利用空间时间临近像素相关性减少数据冗余

五 应用场景

AV1帧内预测模式适用于各种视频内容特别是处理平滑区域具有明显方向纹理区域表现出色通过选择合适预测模式编码器能够有效压缩视频数据提升视频质量压缩比

六 SVT-AV1中的帧内预测分析

svt_av1_predict_intra_block 帧内块预测编码

svt_av1_intra_prediction_cl 帧内预测chroma luma

svt_av1_predict_intra_block_16bit 16bits深度帧内预测编码

七 函数内部详细分析

//帧内预测块生成函数

void svt_av1_predict_intra_block(

STAGE stage, //当前处理阶段ED_STAGE 表示编码块决策阶段

const BlockGeom * blk_geom, //机和信息

MacroBlockD *xd, //宏块 描述

int32_t wpx, //块宽度

int32_t hpx,//高度

TxSize tx_size,//变换尺寸

PredictionMode mode, //预测模式

int32_t angle_delta, //角度预测偏移量

int32_t use_palette, //是否使用调色板模式

PaletteInfo *palette_info, //调色板信息结构体

FilterIntraMode filter_intra_mode, //滤波帧内模式

uint8_t* top_neigh_array, //上方邻居像素数组

uint8_t* left_neigh_array, // 左侧邻居像素数组

EbPictureBufferDesc *recon_buffer, //重建图像缓冲区

int32_t col_off, //偏移

int32_t row_off, //偏移

int32_t plane, //当前处理

BlockSize bsize, //尺寸

uint32_t txb_org_x_pict, //变换在图像X坐标

uint32_t txb_org_y_pict, //变换在图像Y坐标

uint32_t bl_org_x_pict,//图像X坐标

uint32_t bl_org_y_pict,//图像Y坐标

uint32_t bl_org_x_mb,//宏块中X坐标

uint32_t bl_org_y_mb,//宏块Y坐标

SeqHeader *seq_header_ptr) //序列头信息

{

uint32_t pred_buf_x_offest; //预测缓冲区X方向偏移

uint32_t pred_buf_y_offest; //预测缓冲区Y方向偏移

if (stage == ED_STAGE) { // EncDec

pred_buf_x_offest = plane ? ((bl_org_x_pict >> 3) << 3) >> 1 : txb_org_x_pict; //色度平面需要将坐标下采样

pred_buf_y_offest = plane ? ((bl_org_y_pict >> 3) << 3) >> 1 : txb_org_y_pict; //

}

else { // MD

pred_buf_x_offest = bl_org_x_mb; //直接使用宏块坐标

pred_buf_y_offest = bl_org_y_mb;

}

//调整mi/位置 (所有平面共享相同值)

// Adjust mirow , micol ;

// All plane have the same values

uint8_t *dst; //目标缓冲区指针

int32_t dst_stride; //目标缓冲区步长

//根据平面设置目标指针步长

if (plane == 0) { //Y通道

dst = recon_buffer->buffer_y + pred_buf_x_offest + recon_buffer->org_x //X方向偏移

+ (pred_buf_y_offest + recon_buffer->org_y)*recon_buffer->stride_y;//Y方向偏移

dst_stride = recon_buffer->stride_y;//Y平面步长

}

else if (plane == 1) { //Cb通道

dst = recon_buffer->buffer_cb + (pred_buf_x_offest + //色度亚采样X偏移

recon_buffer->org_x / 2 + (pred_buf_y_offest + recon_buffer->org_y //色度亚像素采样Y偏移

2)*recon_buffer->stride_cb);

dst_stride = recon_buffer->stride_cb;//Cb平面步长

}

else {

dst = recon_buffer->buffer_cr + (pred_buf_x_offest + recon_buffer->org_x / 2 + (pred_buf_y_offest + recon_buffer->org_y / 2)*recon_buffer->stride_cr);

dst_stride = recon_buffer->stride_cr;//Cr平面步长

}

//获取变换尺寸

//CHKN const MbModeInfo *const mbmi = xd->mi[0];

const int32_t txwpx = tx_size_wide[tx_size]; //变换块宽度

const int32_t txhpx = tx_size_high[tx_size];//变换块高度

//计算当前变换块父块位置

const int32_t x = col_off << tx_size_wide_log2[0]; //X偏移

const int32_t y = row_off << tx_size_high_log2[0];//Y偏移

//调色板模式处理

if (use_palette) {

//获取调色板呀呢索引映射调色板颜色数组

const uint8_t *const map = palette_info->color_idx_map;//颜色索引映射

const uint16_t *const palette =

palette_info->pmi.palette_colors + plane * PALETTE_MAX_SIZE;//当前平面调色板

//遍历每个像素填充预测值

for (int32_t r = 0; r < txhpx; ++r)

for (int32_t c = 0; c < txwpx; ++c)

dst[r * dst_stride + c] =

(uint8_t)palette[map[(r + y) * wpx + c + x]];

//调色获取颜色值

return;//调色板模式直接返回

}

//设置宏块平面参数

//CHKN BlockSize bsize = mbmi->bsize;

struct MacroblockdPlane pd_s;

struct MacroblockdPlane * pd = &pd_s;

//设置采样参数(色度平面为1,亮度为0)

if (plane == 0)

pd->subsampling_x = pd->subsampling_y = 0;

else

pd->subsampling_x = pd->subsampling_y = 1;

//获取变换尺寸高度(以最小单元为单位)

const int32_t txw = tx_size_wide_unit[tx_size];//变换宽度单元

const int32_t txh = tx_size_high_unit[tx_size];//变换高度单元

//判断上方/左侧参考像素是否可用

const int32_t have_top = row_off || (pd->subsampling_y ? xd->chroma_up_available

: xd->up_available);//上方可用

const int32_t have_left =

col_off ||

(pd->subsampling_x ? xd->chroma_left_available : xd->left_available);//左侧可用性

//计算当前宏块图像位置

const int32_t mi_row = -xd->mb_to_top_edge >> (3 + MI_SIZE_LOG2);//宏块行位置

const int32_t mi_col = -xd->mb_to_left_edge >> (3 + MI_SIZE_LOG2);//宏块位置

const int32_t xr_chr_offset = 0;//色度X偏移调整

const int32_t yd_chr_offset = 0;//色度Y偏移量调整量

// Distance between the right edge of this prediction block to

// the frame right edge 计算当前预测右边距离

const int32_t xr = (xd->mb_to_right_edge >> (3 + pd->subsampling_x)) +

(wpx - x - txwpx) - xr_chr_offset;

//计算当前预测块底边界距离

// Distance between the bottom edge of this prediction block to

// the frame bottom edge

//判断右方下方是否可用

const int32_t yd = (xd->mb_to_bottom_edge >> (3 + pd->subsampling_y)) +

(hpx - y - txhpx) - yd_chr_offset;

const int32_t right_available =

mi_col + ((col_off + txw) << pd->subsampling_x) < xd->tile.mi_col_end;

const int32_t bottom_available =

(yd > 0) &&

(mi_row + ((row_off + txh) << pd->subsampling_y) < xd->tile.mi_row_end);

//根据醒状态获取分区类型

const PartitionType partition = from_shape_to_part[blk_geom->shape]; //blk_ptr->part;// PARTITION_NONE;//CHKN this is good enough as the avail functions need to know if VERT part is used or not mbmi->partition;

//调整色度分块尺寸

// force 4x4 chroma component block size.

bsize = svt_aom_scale_chroma_bsize(bsize, pd->subsampling_x, pd->subsampling_y);

//判断右上参考像素是否可用

const int32_t have_top_right = svt_aom_intra_has_top_right(

seq_header_ptr->sb_size, // 超级块尺寸

bsize, // 当前块尺寸

mi_row, mi_col, // 宏块位置

have_top, right_available, partition, tx_size,

row_off, col_off, // 变换块偏移

pd->subsampling_x, pd->subsampling_y); // 亚采样参数

const int32_t disable_edge_filter = !(seq_header_ptr->enable_intra_edge_filter);

//if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {

// build_intra_predictors_high(

// xd, ref, ref_stride, dst, dst_stride, mode, angle_delta,

// filter_intra_mode, tx_size, disable_edge_filter,

// have_top ? AOMMIN(txwpx, xr + txwpx) : 0,

// have_top_right ? AOMMIN(txwpx, xr) : 0,

// have_left ? AOMMIN(txhpx, yd + txhpx) : 0,

// have_bottom_left ? AOMMIN(txhpx, yd) : 0, plane);

// return;

//}

//构建帧内预测

build_intra_predictors(

xd, //宏块描述附

top_neigh_array, //上方邻居数组

left_neigh_array, //左侧邻居数组

// ref, ref_stride,

dst, dst_stride, mode, //目标换次红区以及步长

angle_delta, filter_intra_mode, tx_size, //角度偏移滤波模式变换尺寸

disable_edge_filter, //是否禁用边缘滤波

have_top ? AOMMIN(txwpx, xr + txwpx) : 0, //上方有效像素

have_top_right ? AOMMIN(txwpx, xr) : 0, //右上方有效像素

have_left ? AOMMIN(txhpx, yd + txhpx) : 0, //左侧有效像素

have_bottom_left ? AOMMIN(txhpx, yd) : 0, plane); //左下方有效像素数 当前处理通道

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值