x264代码剖析(十六):核心算法之宏块编码中的量化编码

简介: <h1 style="text-align:center"><strong>x264<span style="font-family:宋体">代码剖析(十六):核心算法之宏块编码中的量化编码</span></strong></h1> <p> </p> <p>        为了进一步节省图像的传输码率,需要对图像进行压缩,通常采用变换编码及量化来消除图像中的相关性以减少图像编码的动态范

x264代码剖析(十六):核心算法之宏块编码中的量化编码

 

        为了进一步节省图像的传输码率,需要对图像进行压缩,通常采用变换编码及量化来消除图像中的相关性以减少图像编码的动态范围。本文主要介绍量化的相关内容,并给出x264中量化编码的代码分析。

 

1、量化编码

 

        量化过程就是根据图像的动态范围大小确定量化参数,既保留图像必要的细节,又可以减少码流。在图像编码中,变换编码和量化从原理上讲是两个独立的过程。但在H.264中,将两个过程中的乘法合二为一,并进一步采用整数运算,减少编解码的运算量,提高图像压缩的实时性,这些措施对峰值信噪比(PSNR)的影响很小,一般低于0.02dB,可不计。下面给出编码器中变换编码及量化过程的流程。




        下面给出毕厚杰著作的《新一代视频压缩编码标准——H.264/AVC(第二版)》中量化的相关理论知识,仅供学习参考。




2、量化源码分析

 

        量化的相关函数大都位于common/quant.c中,主要包括以下函数:

x264_quant_init():初始化量化和反量化相关的汇编函数

quant_4x4():对4x4DCT残差矩阵进行量化

QUANT_ONE():完成一个DCT系数的量化工作

quant_4x4x4():对44x4DCT残差矩阵进行量化

 

        下面对这些函数进行深入分析。


2.1x264_quant_init()函数

 

        量化模块的初始化函数是x264_quant_init()。该函数对x264_quant_function_t结构体中的函数指针进行了赋值。X264运行的过程中只要调用x264_quant_function_t的函数指针就可以完成相应的功能。对应的代码分析如下:

 

/******************************************************************/
/******************************************************************/
/*
======Analysed by RuiDong Fang
======Csdn Blog:http://blog.csdn.net/frd2009041510
======Date:2016.03.25
 */
/******************************************************************/
/******************************************************************/

/************====== 量化 ======************/
/*
功能:量化初始化,x264_quant_init()被x264_encoder_open()函数调用
*/
void x264_quant_init( x264_t *h, int cpu, x264_quant_function_t *pf )
{
    /*===== 量化=====*/
	pf->quant_8x8 = quant_8x8;	/////////////////针对8x8DCT的量化
    pf->quant_4x4 = quant_4x4;	/////////////////量化4x4=16个
    pf->quant_4x4x4 = quant_4x4x4;	/////////////////处理4个4x4的块

	/////////////////Intra16x16中,16个DC系数Hadamard变换后对的它们量化
    pf->quant_4x4_dc = quant_4x4_dc;	
    pf->quant_2x2_dc = quant_2x2_dc;

	/*===== 反量化=====*/
    pf->dequant_4x4 = dequant_4x4;	/////////////////反量化4x4=16个
    pf->dequant_4x4_dc = dequant_4x4_dc;	/////////////////
    pf->dequant_8x8 = dequant_8x8;	/////////////////处理4个4x4的块针对8x8DCT的反量化

	/////////////////Intra16x16中,16个DC系数Hadamard变换后对的它们反量化
    pf->idct_dequant_2x4_dc = idct_dequant_2x4_dc;
    pf->idct_dequant_2x4_dconly = idct_dequant_2x4_dconly;

	//色度
    pf->optimize_chroma_2x2_dc = optimize_chroma_2x2_dc;
    pf->optimize_chroma_2x4_dc = optimize_chroma_2x4_dc;

    pf->denoise_dct = x264_denoise_dct;
    pf->decimate_score15 = x264_decimate_score15;
    pf->decimate_score16 = x264_decimate_score16;
    pf->decimate_score64 = x264_decimate_score64;

    pf->coeff_last4 = x264_coeff_last4;
    pf->coeff_last8 = x264_coeff_last8;
    pf->coeff_last[  DCT_LUMA_AC] = x264_coeff_last15;
    pf->coeff_last[ DCT_LUMA_4x4] = x264_coeff_last16;
    pf->coeff_last[ DCT_LUMA_8x8] = x264_coeff_last64;
    pf->coeff_level_run4 = x264_coeff_level_run4;
    pf->coeff_level_run8 = x264_coeff_level_run8;
    pf->coeff_level_run[  DCT_LUMA_AC] = x264_coeff_level_run15;
    pf->coeff_level_run[ DCT_LUMA_4x4] = x264_coeff_level_run16;

#if HIGH_BIT_DEPTH
#if HAVE_MMX
    INIT_TRELLIS( sse2 );
    if( cpu&X264_CPU_MMX2 )
    {
#if ARCH_X86
        pf->denoise_dct = x264_denoise_dct_mmx;
        pf->decimate_score15 = x264_decimate_score15_mmx2;
        pf->decimate_score16 = x264_decimate_score16_mmx2;
        pf->decimate_score64 = x264_decimate_score64_mmx2;
        pf->coeff_last8 = x264_coeff_last8_mmx2;
        pf->coeff_last[  DCT_LUMA_AC] = x264_coeff_last15_mmx2;
        pf->coeff_last[ DCT_LUMA_4x4] = x264_coeff_last16_mmx2;
        pf->coeff_last[ DCT_LUMA_8x8] = x264_coeff_last64_mmx2;
        pf->coeff_level_run8 = x264_coeff_level_run8_mmx2;
        pf->coeff_level_run[  DCT_LUMA_AC] = x264_coeff_level_run15_mmx2;
        pf->coeff_level_run[ DCT_LUMA_4x4] = x264_coeff_level_run16_mmx2;
#endif
        pf->coeff_last4 = x264_coeff_last4_mmx2;
        pf->coeff_level_run4 = x264_coeff_level_run4_mmx2;
        if( cpu&X264_CPU_LZCNT )
            pf->coeff_level_run4 = x264_coeff_level_run4_mmx2_lzcnt;
    }
    if( cpu&X264_CPU_SSE2 )
    {
        pf->quant_4x4 = x264_quant_4x4_sse2;
        pf->quant_4x4x4 = x264_quant_4x4x4_sse2;
        pf->quant_8x8 = x264_quant_8x8_sse2;
        pf->quant_2x2_dc = x264_quant_2x2_dc_sse2;
        pf->quant_4x4_dc = x264_quant_4x4_dc_sse2;
        pf->dequant_4x4 = x264_dequant_4x4_sse2;
        pf->dequant_8x8 = x264_dequant_8x8_sse2;
        pf->dequant_4x4_dc = x264_dequant_4x4dc_sse2;
        pf->denoise_dct = x264_denoise_dct_sse2;
        pf->decimate_score15 = x264_decimate_score15_sse2;
        pf->decimate_score16 = x264_decimate_score16_sse2;
        pf->decimate_score64 = x264_decimate_score64_sse2;
        pf->coeff_last8 = x264_coeff_last8_sse2;
        pf->coeff_last[ DCT_LUMA_AC] = x264_coeff_last15_sse2;
        pf->coeff_last[DCT_LUMA_4x4] = x264_coeff_last16_sse2;
        pf->coeff_last[DCT_LUMA_8x8] = x264_coeff_last64_sse2;
        pf->coeff_level_run8 = x264_coeff_level_run8_sse2;
        pf->coeff_level_run[ DCT_LUMA_AC] = x264_coeff_level_run15_sse2;
        pf->coeff_level_run[DCT_LUMA_4x4] = x264_coeff_level_run16_sse2;
        if( cpu&X264_CPU_LZCNT )
        {
            pf->coeff_last4 = x264_coeff_last4_mmx2_lzcnt;
            pf->coeff_last8 = x264_coeff_last8_sse2_lzcnt;
            pf->coeff_last[ DCT_LUMA_AC] = x264_coeff_last15_sse2_lzcnt;
            pf->coeff_last[DCT_LUMA_4x4] = x264_coeff_last16_sse2_lzcnt;
            pf->coeff_last[DCT_LUMA_8x8] = x264_coeff_last64_sse2_lzcnt;
            pf->coeff_level_run8 = x264_coeff_level_run8_sse2_lzcnt;
            pf->coeff_level_run[ DCT_LUMA_AC] = x264_coeff_level_run15_sse2_lzcnt;
            pf->coeff_level_run[DCT_LUMA_4x4] = x264_coeff_level_run16_sse2_lzcnt;
        }
    }
    if( cpu&X264_CPU_SSSE3 )
    {
        pf->quant_4x4 = x264_quant_4x4_ssse3;
        pf->quant_4x4x4 = x264_quant_4x4x4_ssse3;
        pf->quant_8x8 = x264_quant_8x8_ssse3;
        pf->quant_2x2_dc = x264_quant_2x2_dc_ssse3;
        pf->quant_4x4_dc = x264_quant_4x4_dc_ssse3;
        pf->denoise_dct = x264_denoise_dct_ssse3;
        pf->decimate_score15 = x264_decimate_score15_ssse3;
        pf->decimate_score16 = x264_decimate_score16_ssse3;
        pf->decimate_score64 = x264_decimate_score64_ssse3;
        INIT_TRELLIS( ssse3 );
    }
    if( cpu&X264_CPU_SSE4 )
    {
        pf->quant_2x2_dc = x264_quant_2x2_dc_sse4;
        pf->quant_4x4_dc = x264_quant_4x4_dc_sse4;
        pf->quant_4x4 = x264_quant_4x4_sse4;
        pf->quant_4x4x4 = x264_quant_4x4x4_sse4;
        pf->quant_8x8 = x264_quant_8x8_sse4;
    }
    if( cpu&X264_CPU_AVX )
    {
        pf->denoise_dct = x264_denoise_dct_avx;
    }
    if( cpu&X264_CPU_XOP )
    {
        pf->dequant_4x4_dc = x264_dequant_4x4dc_xop;
        if( h->param.i_cqm_preset != X264_CQM_FLAT )
        {
            pf->dequant_4x4 = x264_dequant_4x4_xop;
            pf->dequant_8x8 = x264_dequant_8x8_xop;
        }
    }
    if( cpu&X264_CPU_AVX2 )
    {
        pf->quant_4x4 = x264_quant_4x4_avx2;
        pf->quant_4x4_dc = x264_quant_4x4_dc_avx2;
        pf->quant_8x8 = x264_quant_8x8_avx2;
        pf->quant_4x4x4 = x264_quant_4x4x4_avx2;
        pf->dequant_4x4 = x264_dequant_4x4_avx2;
        pf->dequant_8x8 = x264_dequant_8x8_avx2;
        pf->dequant_4x4_dc = x264_dequant_4x4dc_avx2;
        pf->denoise_dct = x264_denoise_dct_avx2;
        if( cpu&X264_CPU_LZCNT )
            pf->coeff_last[DCT_LUMA_8x8] = x264_coeff_last64_avx2_lzcnt;
    }
#endif // HAVE_MMX
#else // !HIGH_BIT_DEPTH
#if HAVE_MMX
    INIT_TRELLIS( sse2 );
    if( cpu&X264_CPU_MMX )
    {
#if ARCH_X86
        pf->dequant_4x4 = x264_dequant_4x4_mmx;
        pf->dequant_4x4_dc = x264_dequant_4x4dc_mmx2;
        pf->dequant_8x8 = x264_dequant_8x8_mmx;
        if( h->param.i_cqm_preset == X264_CQM_FLAT )
        {
            pf->dequant_4x4 = x264_dequant_4x4_flat16_mmx;
            pf->dequant_8x8 = x264_dequant_8x8_flat16_mmx;
        }
        pf->denoise_dct = x264_denoise_dct_mmx;
#endif
    }

    if( cpu&X264_CPU_MMX2 )
    {
        pf->quant_2x2_dc = x264_quant_2x2_dc_mmx2;
#if ARCH_X86
        pf->quant_4x4 = x264_quant_4x4_mmx2;
        pf->quant_8x8 = x264_quant_8x8_mmx2;
        pf->quant_4x4_dc = x264_quant_4x4_dc_mmx2;
        pf->decimate_score15 = x264_decimate_score15_mmx2;
        pf->decimate_score16 = x264_decimate_score16_mmx2;
        pf->decimate_score64 = x264_decimate_score64_mmx2;
        pf->coeff_last[  DCT_LUMA_AC] = x264_coeff_last15_mmx2;
        pf->coeff_last[ DCT_LUMA_4x4] = x264_coeff_last16_mmx2;
        pf->coeff_last[ DCT_LUMA_8x8] = x264_coeff_last64_mmx2;
        pf->coeff_level_run[  DCT_LUMA_AC] = x264_coeff_level_run15_mmx2;
        pf->coeff_level_run[ DCT_LUMA_4x4] = x264_coeff_level_run16_mmx2;
#endif
        pf->coeff_last4 = x264_coeff_last4_mmx2;
        pf->coeff_last8 = x264_coeff_last8_mmx2;
        pf->coeff_level_run4 = x264_coeff_level_run4_mmx2;
        pf->coeff_level_run8 = x264_coeff_level_run8_mmx2;
        if( cpu&X264_CPU_LZCNT )
        {
            pf->coeff_last4 = x264_coeff_last4_mmx2_lzcnt;
            pf->coeff_last8 = x264_coeff_last8_mmx2_lzcnt;
            pf->coeff_level_run4 = x264_coeff_level_run4_mmx2_lzcnt;
            pf->coeff_level_run8 = x264_coeff_level_run8_mmx2_lzcnt;
        }
    }

    if( cpu&X264_CPU_SSE2 )
    {
        pf->quant_4x4_dc = x264_quant_4x4_dc_sse2;
        pf->quant_4x4 = x264_quant_4x4_sse2;
        pf->quant_4x4x4 = x264_quant_4x4x4_sse2;
        pf->quant_8x8 = x264_quant_8x8_sse2;
        pf->dequant_4x4 = x264_dequant_4x4_sse2;
        pf->dequant_4x4_dc = x264_dequant_4x4dc_sse2;
        pf->dequant_8x8 = x264_dequant_8x8_sse2;
        if( h->param.i_cqm_preset == X264_CQM_FLAT )
        {
            pf->dequant_4x4 = x264_dequant_4x4_flat16_sse2;
            pf->dequant_8x8 = x264_dequant_8x8_flat16_sse2;
        }
        pf->optimize_chroma_2x2_dc = x264_optimize_chroma_2x2_dc_sse2;
        pf->denoise_dct = x264_denoise_dct_sse2;
        pf->decimate_score15 = x264_decimate_score15_sse2;
        pf->decimate_score16 = x264_decimate_score16_sse2;
        pf->decimate_score64 = x264_decimate_score64_sse2;
        pf->coeff_last[ DCT_LUMA_AC] = x264_coeff_last15_sse2;
        pf->coeff_last[DCT_LUMA_4x4] = x264_coeff_last16_sse2;
        pf->coeff_last[DCT_LUMA_8x8] = x264_coeff_last64_sse2;
        pf->coeff_level_run[ DCT_LUMA_AC] = x264_coeff_level_run15_sse2;
        pf->coeff_level_run[DCT_LUMA_4x4] = x264_coeff_level_run16_sse2;
        if( cpu&X264_CPU_LZCNT )
        {
            pf->coeff_last[ DCT_LUMA_AC] = x264_coeff_last15_sse2_lzcnt;
            pf->coeff_last[DCT_LUMA_4x4] = x264_coeff_last16_sse2_lzcnt;
            pf->coeff_last[DCT_LUMA_8x8] = x264_coeff_last64_sse2_lzcnt;
            pf->coeff_level_run[ DCT_LUMA_AC] = x264_coeff_level_run15_sse2_lzcnt;
            pf->coeff_level_run[DCT_LUMA_4x4] = x264_coeff_level_run16_sse2_lzcnt;
        }
    }

    if( cpu&X264_CPU_SSSE3 )
    {
        pf->quant_2x2_dc = x264_quant_2x2_dc_ssse3;
        pf->quant_4x4_dc = x264_quant_4x4_dc_ssse3;
        pf->quant_4x4 = x264_quant_4x4_ssse3;
        pf->quant_4x4x4 = x264_quant_4x4x4_ssse3;
        pf->quant_8x8 = x264_quant_8x8_ssse3;
        pf->optimize_chroma_2x2_dc = x264_optimize_chroma_2x2_dc_ssse3;
        pf->denoise_dct = x264_denoise_dct_ssse3;
        pf->decimate_score15 = x264_decimate_score15_ssse3;
        pf->decimate_score16 = x264_decimate_score16_ssse3;
        pf->decimate_score64 = x264_decimate_score64_ssse3;
        INIT_TRELLIS( ssse3 );
        pf->coeff_level_run4 = x264_coeff_level_run4_ssse3;
        pf->coeff_level_run8 = x264_coeff_level_run8_ssse3;
        pf->coeff_level_run[ DCT_LUMA_AC] = x264_coeff_level_run15_ssse3;
        pf->coeff_level_run[DCT_LUMA_4x4] = x264_coeff_level_run16_ssse3;
        if( cpu&X264_CPU_LZCNT )
        {
            pf->coeff_level_run4 = x264_coeff_level_run4_ssse3;
            pf->coeff_level_run8 = x264_coeff_level_run8_ssse3;
            pf->coeff_level_run[ DCT_LUMA_AC] = x264_coeff_level_run15_ssse3_lzcnt;
            pf->coeff_level_run[DCT_LUMA_4x4] = x264_coeff_level_run16_ssse3_lzcnt;
        }
    }

    if( cpu&X264_CPU_SSE4 )
    {
        pf->quant_4x4_dc = x264_quant_4x4_dc_sse4;
        pf->quant_4x4 = x264_quant_4x4_sse4;
        pf->quant_8x8 = x264_quant_8x8_sse4;
        pf->optimize_chroma_2x2_dc = x264_optimize_chroma_2x2_dc_sse4;
    }

    if( cpu&X264_CPU_AVX )
    {
        pf->dequant_4x4_dc = x264_dequant_4x4dc_avx;
        if( h->param.i_cqm_preset != X264_CQM_FLAT )
        {
            pf->dequant_4x4 = x264_dequant_4x4_avx;
            pf->dequant_8x8 = x264_dequant_8x8_avx;
        }
        pf->optimize_chroma_2x2_dc = x264_optimize_chroma_2x2_dc_avx;
        pf->denoise_dct = x264_denoise_dct_avx;
    }

    if( cpu&X264_CPU_XOP )
    {
        if( h->param.i_cqm_preset != X264_CQM_FLAT )
        {
            pf->dequant_4x4 = x264_dequant_4x4_xop;
            pf->dequant_8x8 = x264_dequant_8x8_xop;
        }
    }

    if( cpu&X264_CPU_AVX2 )
    {
        pf->quant_4x4 = x264_quant_4x4_avx2;
        pf->quant_4x4_dc = x264_quant_4x4_dc_avx2;
        pf->quant_8x8 = x264_quant_8x8_avx2;
        pf->quant_4x4x4 = x264_quant_4x4x4_avx2;
        pf->dequant_4x4 = x264_dequant_4x4_avx2;
        pf->dequant_8x8 = x264_dequant_8x8_avx2;
        pf->dequant_4x4_dc = x264_dequant_4x4dc_avx2;
        if( h->param.i_cqm_preset == X264_CQM_FLAT )
        {
            pf->dequant_4x4 = x264_dequant_4x4_flat16_avx2;
            pf->dequant_8x8 = x264_dequant_8x8_flat16_avx2;
        }
        pf->decimate_score64 = x264_decimate_score64_avx2;
        pf->denoise_dct = x264_denoise_dct_avx2;
        if( cpu&X264_CPU_LZCNT )
        {
            pf->coeff_last[DCT_LUMA_8x8] = x264_coeff_last64_avx2_lzcnt;
            pf->coeff_level_run[ DCT_LUMA_AC] = x264_coeff_level_run15_avx2_lzcnt;
            pf->coeff_level_run[DCT_LUMA_4x4] = x264_coeff_level_run16_avx2_lzcnt;
        }
    }
#endif // HAVE_MMX

#if HAVE_ALTIVEC
    if( cpu&X264_CPU_ALTIVEC )
    {
        pf->quant_2x2_dc = x264_quant_2x2_dc_altivec;
        pf->quant_4x4_dc = x264_quant_4x4_dc_altivec;
        pf->quant_4x4 = x264_quant_4x4_altivec;
        pf->quant_8x8 = x264_quant_8x8_altivec;

        pf->dequant_4x4 = x264_dequant_4x4_altivec;
        pf->dequant_8x8 = x264_dequant_8x8_altivec;
    }
#endif

#if HAVE_ARMV6
    if( cpu&X264_CPU_ARMV6 )
    {
        pf->coeff_last4 = x264_coeff_last4_arm;
        pf->coeff_last8 = x264_coeff_last8_arm;
    }
#endif
#if HAVE_ARMV6 || ARCH_AARCH64
    if( cpu&X264_CPU_NEON )
    {
        pf->quant_2x2_dc   = x264_quant_2x2_dc_neon;
        pf->quant_4x4      = x264_quant_4x4_neon;
        pf->quant_4x4_dc   = x264_quant_4x4_dc_neon;
        pf->quant_4x4x4    = x264_quant_4x4x4_neon;
        pf->quant_8x8      = x264_quant_8x8_neon;
        pf->dequant_4x4    = x264_dequant_4x4_neon;
        pf->dequant_4x4_dc = x264_dequant_4x4_dc_neon;
        pf->dequant_8x8    = x264_dequant_8x8_neon;
        pf->coeff_last[ DCT_LUMA_AC] = x264_coeff_last15_neon;
        pf->coeff_last[DCT_LUMA_4x4] = x264_coeff_last16_neon;
        pf->coeff_last[DCT_LUMA_8x8] = x264_coeff_last64_neon;
        pf->denoise_dct = x264_denoise_dct_neon;
        pf->decimate_score15 = x264_decimate_score15_neon;
        pf->decimate_score16 = x264_decimate_score16_neon;
        pf->decimate_score64 = x264_decimate_score64_neon;
    }
#endif
#if ARCH_AARCH64
    if( cpu&X264_CPU_ARMV8 )
    {
        pf->coeff_last4 = x264_coeff_last4_aarch64;
        pf->coeff_last8 = x264_coeff_last8_aarch64;
        pf->coeff_level_run4 = x264_coeff_level_run4_aarch64;
    }
    if( cpu&X264_CPU_NEON )
    {
        pf->coeff_level_run8 = x264_coeff_level_run8_neon;
        pf->coeff_level_run[  DCT_LUMA_AC] = x264_coeff_level_run15_neon;
        pf->coeff_level_run[ DCT_LUMA_4x4] = x264_coeff_level_run16_neon;
    }
#endif

#if HAVE_MSA
    if( cpu&X264_CPU_MSA )
    {
        pf->quant_4x4      = x264_quant_4x4_msa;
        pf->quant_4x4_dc   = x264_quant_4x4_dc_msa;
        pf->quant_4x4x4    = x264_quant_4x4x4_msa;
        pf->quant_8x8      = x264_quant_8x8_msa;
        pf->dequant_4x4    = x264_dequant_4x4_msa;
        pf->dequant_4x4_dc = x264_dequant_4x4_dc_msa;
        pf->dequant_8x8    = x264_dequant_8x8_msa;
        pf->coeff_last[DCT_LUMA_4x4] = x264_coeff_last16_msa;
        pf->coeff_last[DCT_LUMA_8x8] = x264_coeff_last64_msa;
    }
#endif
#endif // HIGH_BIT_DEPTH
    pf->coeff_last[DCT_LUMA_DC]     = pf->coeff_last[DCT_CHROMAU_DC]  = pf->coeff_last[DCT_CHROMAV_DC] =
    pf->coeff_last[DCT_CHROMAU_4x4] = pf->coeff_last[DCT_CHROMAV_4x4] = pf->coeff_last[DCT_LUMA_4x4];
    pf->coeff_last[DCT_CHROMA_AC]   = pf->coeff_last[DCT_CHROMAU_AC]  =
    pf->coeff_last[DCT_CHROMAV_AC]  = pf->coeff_last[DCT_LUMA_AC];
    pf->coeff_last[DCT_CHROMAU_8x8] = pf->coeff_last[DCT_CHROMAV_8x8] = pf->coeff_last[DCT_LUMA_8x8];

    pf->coeff_level_run[DCT_LUMA_DC]     = pf->coeff_level_run[DCT_CHROMAU_DC]  = pf->coeff_level_run[DCT_CHROMAV_DC] =
    pf->coeff_level_run[DCT_CHROMAU_4x4] = pf->coeff_level_run[DCT_CHROMAV_4x4] = pf->coeff_level_run[DCT_LUMA_4x4];
    pf->coeff_level_run[DCT_CHROMA_AC]   = pf->coeff_level_run[DCT_CHROMAU_AC]  =
    pf->coeff_level_run[DCT_CHROMAV_AC]  = pf->coeff_level_run[DCT_LUMA_AC];
}

 

       其中, x264_quant_function_t的定义如下:


typedef struct
{
    int (*quant_8x8)  ( dctcoef dct[64], udctcoef mf[64], udctcoef bias[64] );
    int (*quant_4x4)  ( dctcoef dct[16], udctcoef mf[16], udctcoef bias[16] );
    int (*quant_4x4x4)( dctcoef dct[4][16], udctcoef mf[16], udctcoef bias[16] );
    int (*quant_4x4_dc)( dctcoef dct[16], int mf, int bias );
    int (*quant_2x2_dc)( dctcoef dct[4], int mf, int bias );

    void (*dequant_8x8)( dctcoef dct[64], int dequant_mf[6][64], int i_qp );
    void (*dequant_4x4)( dctcoef dct[16], int dequant_mf[6][16], int i_qp );
    void (*dequant_4x4_dc)( dctcoef dct[16], int dequant_mf[6][16], int i_qp );

    void (*idct_dequant_2x4_dc)( dctcoef dct[8], dctcoef dct4x4[8][16], int dequant_mf[6][16], int i_qp );
    void (*idct_dequant_2x4_dconly)( dctcoef dct[8], int dequant_mf[6][16], int i_qp );

    int (*optimize_chroma_2x2_dc)( dctcoef dct[4], int dequant_mf );
    int (*optimize_chroma_2x4_dc)( dctcoef dct[8], int dequant_mf );

    void (*denoise_dct)( dctcoef *dct, uint32_t *sum, udctcoef *offset, int size );

    int (*decimate_score15)( dctcoef *dct );
    int (*decimate_score16)( dctcoef *dct );
    int (*decimate_score64)( dctcoef *dct );
    int (*coeff_last[14])( dctcoef *dct );
    int (*coeff_last4)( dctcoef *dct );
    int (*coeff_last8)( dctcoef *dct );
    int (*coeff_level_run[13])( dctcoef *dct, x264_run_level_t *runlevel );
    int (*coeff_level_run4)( dctcoef *dct, x264_run_level_t *runlevel );
    int (*coeff_level_run8)( dctcoef *dct, x264_run_level_t *runlevel );

#define TRELLIS_PARAMS const int *unquant_mf, const uint8_t *zigzag, int lambda2,\
                       int last_nnz, dctcoef *coefs, dctcoef *quant_coefs, dctcoef *dct,\
                       uint8_t *cabac_state_sig, uint8_t *cabac_state_last,\
                       uint64_t level_state0, uint16_t level_state1
    int (*trellis_cabac_4x4)( TRELLIS_PARAMS, int b_ac );
    int (*trellis_cabac_8x8)( TRELLIS_PARAMS, int b_interlaced );
    int (*trellis_cabac_4x4_psy)( TRELLIS_PARAMS, int b_ac, dctcoef *fenc_dct, int psy_trellis );
    int (*trellis_cabac_8x8_psy)( TRELLIS_PARAMS, int b_interlaced, dctcoef *fenc_dct, int psy_trellis );
    int (*trellis_cabac_dc)( TRELLIS_PARAMS, int num_coefs );
    int (*trellis_cabac_chroma_422_dc)( TRELLIS_PARAMS );
} x264_quant_function_t;


 

2.2quant_4x4()函数

 

        quant_4x4()用于对4x4DCT残差矩阵进行量化,quant_4x4()循环16次调用了QUANT_ONE()完成了量化工作。并且将DCT系数值,MF值,bias偏移值直接传递给了该宏。对应的代码分析如下:

 

/************====== 4x4的DCT残差矩阵的量化 ======************/
/*
功能:quant_4x4()用于对4x4的DCT残差矩阵进行量化
*/
static int quant_4x4( dctcoef dct[16], udctcoef mf[16], udctcoef bias[16] )//输入输出都是dct[16]
{
    int nz = 0;
    for( int i = 0; i < 16; i++ )//循环16个元素
        QUANT_ONE( dct[i], mf[i], bias[i] );
    return !!nz;
}

 

        其中,QUANT_ONE()完成了一个DCT系数的量化工作,从QUANT_ONE()的定义可以看出,它实现了上文提到的H.264标准中的量化公式。它的定义如下:

 

/************====== QUANT_ONE() ======************/
/*
功能:量化1个元素
*/
#define QUANT_ONE( coef, mf, f ) \
{ \
    if( (coef) > 0 ) \
        (coef) = (f + (coef)) * (mf) >> 16; \
    else \
        (coef) = - ((f - (coef)) * (mf) >> 16); \
    nz |= (coef); \
}

 

2.3quant_4x4x4()函数

 

        quant_4x4x4()用于对44x4DCT残差矩阵进行量化。该函数的定义位于common\quant.c,从quant_4x4x4()的定义可以看出,该函数相当于调用了4quant_4x4()函数。对应的代码分析如下:


/************====== 4个4x4的DCT残差矩阵的量化 ======************/
/*
功能:quant_4x4x4()用于对4个4x4的DCT残差矩阵进行量化,从quant_4x4x4()的定义可以看出,该函数相当于调用了4次quant_4x4()函数。
*/
static int quant_4x4x4( dctcoef dct[4][16], udctcoef mf[16], udctcoef bias[16] )//输入输出都是dct[4][16] 
{
    int nza = 0;
    for( int j = 0; j < 4; j++ )//处理4个
    {
        int nz = 0;
        for( int i = 0; i < 16; i++ )
            QUANT_ONE( dct[j][i], mf[i], bias[i] );//量化
        nza |= (!!nz)<<j;
    }
    return nza;
}


大笑至此,x264中量化的重点函数就分析完毕了。


目录
相关文章
|
13天前
|
算法
分享一些提高二叉树遍历算法效率的代码示例
这只是简单的示例代码,实际应用中可能还需要根据具体需求进行更多的优化和处理。你可以根据自己的需求对代码进行修改和扩展。
|
24天前
|
算法 测试技术 开发者
在Python开发中,性能优化和代码审查至关重要。性能优化通过改进代码结构和算法提高程序运行速度,减少资源消耗
在Python开发中,性能优化和代码审查至关重要。性能优化通过改进代码结构和算法提高程序运行速度,减少资源消耗;代码审查通过检查源代码发现潜在问题,提高代码质量和团队协作效率。本文介绍了一些实用的技巧和工具,帮助开发者提升开发效率。
27 3
|
23天前
|
分布式计算 Java 开发工具
阿里云MaxCompute-XGBoost on Spark 极限梯度提升算法的分布式训练与模型持久化oss的实现与代码浅析
本文介绍了XGBoost在MaxCompute+OSS架构下模型持久化遇到的问题及其解决方案。首先简要介绍了XGBoost的特点和应用场景,随后详细描述了客户在将XGBoost on Spark任务从HDFS迁移到OSS时遇到的异常情况。通过分析异常堆栈和源代码,发现使用的`nativeBooster.saveModel`方法不支持OSS路径,而使用`write.overwrite().save`方法则能成功保存模型。最后提供了完整的Scala代码示例、Maven配置和提交命令,帮助用户顺利迁移模型存储路径。
|
1月前
|
存储 缓存 算法
如何通过优化算法和代码结构来提升易语言程序的执行效率?
如何通过优化算法和代码结构来提升易语言程序的执行效率?
|
1月前
|
搜索推荐
插入排序算法的讲解和代码
【10月更文挑战第12天】插入排序是一种基础的排序算法,理解和掌握它对于学习其他排序算法以及数据结构都具有重要意义。你可以通过实际操作和分析,进一步深入了解插入排序的特点和应用场景,以便在实际编程中更好地运用它。
|
29天前
|
缓存 分布式计算 监控
优化算法和代码需要注意什么
【10月更文挑战第20天】优化算法和代码需要注意什么
18 0
|
1月前
|
算法 Java 测试技术
数据结构 —— Java自定义代码实现顺序表,包含测试用例以及ArrayList的使用以及相关算法题
文章详细介绍了如何用Java自定义实现一个顺序表类,包括插入、删除、获取数据元素、求数据个数等功能,并对顺序表进行了测试,最后还提及了Java中自带的顺序表实现类ArrayList。
23 0
|
2月前
|
机器学习/深度学习 存储 算法
经典算法代码
这段代码展示了多个经典算法,包括:穷举法解决“百钱买百鸡”问题;递推法计算“猴子吃桃”问题;迭代法求解斐波那契数列及折纸高度超越珠峰的问题。同时,还提供了希尔排序算法实现及披萨票务订购系统和汉诺塔问题的链表存储解决方案。每部分通过具体案例解释了算法的应用场景与实现方法。
31 3
|
3月前
|
人工智能 算法 数据可视化
DBSCAN密度聚类算法(理论+图解+python代码)
DBSCAN密度聚类算法(理论+图解+python代码)
下一篇
无影云桌面