当前位置:   article > 正文

x264 arm64汇编分析 quant8x8_neon分析

x264 arm64汇编分析 quant8x8_neon分析

一 C语言实现

#define QUANT_ONE( coef, mf, f ) \

{ \

    if( (coef) > 0 ) \

        (coef) = (f + (coef)) * (mf) >> 16; \

    else \

        (coef) = - ((f - (coef)) * (mf) >> 16); \

    nz |= (coef); \

}

static int quant_8x8( dctcoef dct[64], udctcoef mf[64], udctcoef bias[64] )

{

    int nz = 0;

    for( int i = 0; i < 64; i++ )

        QUANT_ONE( dct[i], mf[i], bias[i] );

    return !!nz;

}

二 汇编实现

//quant_8x8(int16_t dct[64], uint16_t mf[64], uint16_t bias[64])

function quant_8x8_neon, export=1

     ld1 {v16.8h, v17.8h}, [x0] //从地址x0加载数据到neon寄存器v16和v17

     abs v18.8h, v16.8h //对v16中的数据进行绝对值操作,并将结果存储在v18中

     abs v19.8h, v17.8h //对v17中的数据进行绝对值操作,并将结果存储在v19中

     ld1 {v0.8h, v1.8h}, [x2], #32 //从地址x2加载数据到neon寄存v0和v1,并跳过

     ld1 {v2.8h, v3.8h}, [x1], #32 //从地址x1加载数据到neon寄存器v2和v3,并跳过

     QUANT_TWO v0.8h, v1.8h, v2, v3, v4.16b//调用自定义的QUANT_TWO函数进行量化处理

.rept 3

//重复以下操作3次

    ld1 {v16.8h, v17.8h}, [x0] //v16, v17 dct系数

    abs v18.8h, v16.8h //求绝对值

    abs v19.8h, v17.8h //求绝对值

    ld1 {v0.8h, v1.8h}, [x2], #32

    ld1 {v2.8h, v3.8h}, [x1], #32

    QUANT_TWO v0.8h, v1.8h, v2, v3, v5.16b//再次强调QUANT_TWO函数进行量化处理

//v0.8h, v1.8h 存储偏移 数据64bits

//v2.8h,v3.8h 存储mf 量化因子64bits

    orr v4.16b, v4.16b, v5.16b //将每次量化处理的结果进行或操作,并存储在x4中

.endr

    uqxtn  v0.8b, v4.8h //对v4进行位转换操作

    QUANT_END d0 //量化处理结束

endfunc

// QUANT_TWO   v0.8h,  v1.8h,  v2,  v3,  v4.16b

//QUANT_TWO   v0.8h,  v1.8h,  v2,  v3,  v5.16b

// v0 v1存储偏移数组, v2,v3 量化因子mask用来输出结果

.macro QUANT_TWO bias0 bias1 mf0_1 mf2_3 mask

   add v18.8h, v18.8h, bias0 //绝对值v18.8h 相加bias0

   add v19.8h, v19.8h, bias1 //绝对值v19.8h 相加bias1

   umull v20.4s, v18.4h, mf0_1().4h //这里的h表示 harfword, 4half word量化因子4存入 v20.4s s表示s word, 32bits ,这个也是一致

   umull2 v21.4s, v18.8h, mf0_1().8h //这里h表示harfword, 4half word, 量化因子4存入v21.4s ,v18.8h 64位4个系数 和这个乘以mf量化因子4halfword

//意思乘以之后存入v21.4s

   umull v22.4s, v19.4h, mf2_3().4h

/*mf2_3().4h 的含义是4个half word,  乘以 v19.4h 存入 v22.4s */

   umull2 v23.4s, v19.8h, mf2_3().8h

/*高4个halfword 和 系数相乘 存入 v23.4s 4个sword 32bits的数据中*/

   sshr v16.8h, v16.8h, #15

/*v16以8个16bits 为单位,向右移位15位*/

   sshr v17.8h, v17.8h, #15

/*v17也是这样操作,看起来是取符号位, 取的低64bits*/

   shrn v18.4h, v20.4s, #16

/*对寄存器 v20 进行右移操作,移动 16 位,结果的低 16 位存储在寄存器 v18 中。*/

   shrn2 v18.8h, v21.4s, #16

//上面两句话,一句话写了v18的低64bits,一句话写了高64bits,组合成一个完整的v18寄存器的值

/*对寄存器 v21 进行右移操作,移动 16 位,结果的低 16 位存储在寄存器 v18 中。*/

   shrn v19.4h, v22.4s, #16

/*对寄存器 v22 进行右移操作,移动 16 位,结果的低 16 位存储在寄存器 v19 中。*/

   shrn2 v19.8h, v23.4s, #16

/*对寄存器 v23 进行右移操作,移动 16 位,结果的低 16 位存储在寄存器 v19 中。*/

   eor v18.16b, v18.16b, v16.16b

/*对寄存器 v18 v16 进行异或操作,结果存储在寄存器 v18字节 */

   eor v19.16b, v19.16b, v17.16b

/*对寄存器 v19 v17 进行异或操作,结果存储在寄存器 v19 字节中*/

   sub v18.8h, v19.8h, v16.8h

/*v16.8h 和 v19.8h 寄存器,相减 存入 18.8h */

   sub 19.8h, v19.8h, v17.8h

/*v7.8h 和 v19.8h 寄存器,相减 存入 19.8h*/

   orr mask, v18.16b, v19.16b

/*对寄存器 v18 v19 进行或操作,结果存储在寄存器 mask */

   st1 {v18.8h, v19.8h}, [x0], #32

/*把最终的结果存入,x0的内存位置,dct 数组*/

.endm

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Gausst松鼠会/article/detail/386788
推荐阅读
相关标签
  

闽ICP备14008679号