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去块滤波的主要内容,如果未能解决你的问题,请参考以下文章

十八去块滤波器

h.264 去块滤波

H.264---去块效应滤波

H264解析Demo10变换量化_3_反变换

Codecs系列HEVC标准:环路滤波技术之Deblocking

H264解析Demo10变换量化_2_反量化