有趣的地方

有趣的地方

x265中量化函数neon汇编实现分析

// uint32_t quant_c(const int16_t* coef, const int32_t quantScale, int32_t* deltaU, int16_t* qCoef, int qBits, int add, int numCoeff)
function x265_quant_neon
    mov             w9, #1  //x9的低32位 = 1
    lsl             w9, w9, w4 //w9 = 1 << qBits;
    dup             v0.2s, w9 //16bits为单位 = w9 2s ? 
    neg             w9, w4 //w4 = 0 - w9
    dup             v1.4s, w9 //v1, 4字节signed = w9
    add             w9, w9, #8 //w8 += 8
    dup             v2.4s, w9 //v2 4字节signed = w9
    dup             v3.4s, w5 //v3 4字节signed = w5 参数add
    
    mov                w11, w1 //w11 = w1 //w11 = quantScale

    lsr             w6, w6, #2 //w6 = w6 >> 2 numCoeff 参数, 一组4个系数
    eor             v4.16b, v4.16b, v4.16b //v4 = 0
    eor             w10, w10, w10 //w10 = 0;
    eor             v17.16b, v17.16b, v17.16b //v17 = 0

.loop_quant:

    ld1             {v18.4h}, [x0], #8 //coef 加载 4个系数,到v18的低64位
    //ld1             {v7.4s}, [x1], #16
    dup             v7.4s, w11 //v7 4字节为单位的signed = quantScale
    sxtl            v6.4s, v18.4h //v18 本来是16bits extern 到 32bits 存入v6

    cmlt            v5.4s, v6.4s, #0 //v5的值小于寄存器v6的值,判断v6 系数是否 > 0

    abs             v6.4s, v6.4s //求绝对值


    mul             v6.4s, v6.4s, v7.4s //系数 = 系数 * qscale  int tmplevel = abs(level) * quantScale;

    add             v7.4s, v6.4s, v3.4s //得到的结果加上偏移, tmplevel += add
    sshl            v7.4s, v7.4s, v1.4s //逻辑左移 qBits 位 

    mls             v6.4s, v7.4s, v0.s[0] //level << qBits  level <<= qBits 存入v6
    sshl            v16.4s, v6.4s, v2.4s //level << qBits >> qBits8 左移 -qBits8 >> 右移qBits8
    st1             {v16.4s}, [x2], #16 //deltaU[blockpos] = ((tmplevel - (level << qBits)) >> qBits8); 数据存入deltaU

    // numsig
    cmeq            v16.4s, v7.4s, v17.4s //v7和v17做比较,结果存储到v16, v17 = 0在这里 
    add             v4.4s, v4.4s, v16.4s //系数个数累加 
    add             w10, w10, #4 //处理了四个系数 

    // level *= sign
    eor             v16.16b, v7.16b, v5.16b //符号位通过异或  这里是相当于取反
    sub             v16.4s, v16.4s, v5.4s // 然后加1
    sqxtn           v5.4h, v16.4s //v16 4字节宽,缩小到2字节, 存储到v5
    st1             {v5.4h}, [x3], #8 //存入量化后的系数,数组 

    subs            w6, w6, #1 //w6 = w6 - 1  处理完一组4个系数
    b.ne             .loop_quant

    addv            s4, v4.4s
    mov             w9, v4.s[0]
    add             w0, w10, w9
    ret
endfunc

发表评论:

Powered By Z-BlogPHP 1.7.3

© 2018-2020 有趣的地方 粤ICP备18140861号-1 网站地图