H264解析Demo12去块滤波
Posted 叮咚咕噜
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了H264解析Demo12去块滤波相关的知识,希望对你有一定的参考价值。
框架结构
一帧的所有宏块的在重建完成解码像素之后,针对整个slice操作的,所以去块滤波的操作需要放在slice的解析中,对整个一帧数据
for (int idx = 0; idx < m_max_mb_number; idx++)
{
m_macroblocks[idx]->Deblock_macroblock();
}
1、获取当前是否为上边沿和左边沿宏块
2、获取slice heder中的标志位,确定当前slice是否需要进行去块滤波
3、分别进行垂直和水平方向的滤波
//<去块滤波><1>针对每个宏块的去块滤波
int CMacroblock::Deblock_macroblock()
{
int width_in_mb = m_slice->m_sps_active->Get_pic_width_in_mbs();
int height_in_mb = m_slice->m_sps_active->Get_pic_height_in_mbs();
int total_filter_strength = 0, filter_strength_arr[16] = { 0 };
bool filterLeftMbEdgeFlag = (m_mb_idx % width_in_mb != 0); //<去块滤波><1>是否是最左边的宏块
bool filterTopMbEdgeFlag = (m_mb_idx >= width_in_mb); //<去块滤波><1>不是上边沿应该要被滤波
//<去块滤波><1>不需要进行去块滤波的操作
if (m_slice->m_sliceHeader->m_disable_deblocking_filter_idc == 1)
{
return kPARSING_ERROR_NO_ERROR;
}
m_mb_alpha_c0_offset = m_slice->m_sliceHeader->m_slice_alpha_c0_offset; //<去块滤波><1>判断每条边界是否需要滤波的一个判断条件所需要的数据
m_mb_beta_offset = m_slice->m_sliceHeader->m_slice_beta_offset;
// Vertical filtering luma 1、垂直方向的滤波
// Horizontal filtering luma 2、水平方向的滤波
return kPARSING_ERROR_NO_ERROR;
}
计算滤波强度
参考标准文档8.7.2.1,下面只是针对帧内预测编码的情况,最左边的边沿对应的滤波强度为4,非最左边的边沿为3
//<去块滤波><2>计算滤波强度:edge边界序号 strength这条边沿的滤波强度数组 标准文档8.7.2.1
int CMacroblock::get_filtering_strength(int edge, int strength[16])
{
int total_strength = 0;
for (int idx = 0; idx < 16; idx++)
{
strength[idx] = (edge == 0) ? 4 : 3; //<去块滤波><2>只针对帧内预测edge == 0为宏块的边沿
total_strength += strength[idx];
}
return total_strength;
}
获取参考像素
下图中虚线表示的边沿1,左边是0,后面是2和3,;参考像素为第一列子宏块的4个和第二列子宏块的4个
//<去块滤波><5>
/*获取边沿上参考像素的值:pixel_arr读取到的参考数据的值
*target_mb_idx:左侧或者上边宏块序号
*edge:第几个边沿
*pix_idx:边沿的第几个像素
*/
int CMacroblock::get_edge_pixel_item(int dir, int target_mb_idx, int edge, int pix_idx, int luma, int pixel_arr[8])
{
CMacroblock *target = NULL;
int neighbor_blk_idx = -1, blk_idx = pix_idx / 4, pix_pos = pix_idx % 4;//<去块滤波><5>blk_idx当前宏块所处的子块从上至下的序号 pix_pos像素在当前子块中的位置
/*
For luma:
pix_idx ranges [0,15], so blk_idx means the block index the pixel belongs to, and pix_pos means the pixel index in the sub block.
*/
if (edge)// Internal Filtering
{
target = this;
neighbor_blk_idx = edge - 1; //<去块滤波><5>edge是从16*16宏块的最左边边沿开始的
}
else
{
target = m_slice->Get_macroblock_at_index(target_mb_idx);
neighbor_blk_idx = 3;
}
if (luma)
{
if (!dir) // Vertical
{
for (int idx = 0; idx < 4; idx++)
{
pixel_arr[idx] = target->m_reconstructed_block[blk_idx][neighbor_blk_idx][pix_pos][idx];
}
for (int idx = 4; idx < 8; idx++)
{
pixel_arr[idx] = m_reconstructed_block[blk_idx][edge][pix_pos][idx-4];
}
}
else //Horizontal
{
for (int idx = 0; idx < 4; idx++)
{
pixel_arr[idx] = target->m_reconstructed_block[neighbor_blk_idx][blk_idx][idx][pix_pos];
}
for (int idx = 4; idx < 8; idx++)
{
pixel_arr[idx] = m_reconstructed_block[edge][blk_idx][idx - 4][pix_pos];
}
}
}
return kPARSING_ERROR_NO_ERROR;
}
以上是关于H264解析Demo12去块滤波的主要内容,如果未能解决你的问题,请参考以下文章