| |
| |
| #### 14.3 Implementation of the WHT Inversion {#h-14-03} |
| |
| |
| As previously discussed (see Sections 2 and 13), for macroblocks |
| encoded using prediction modes other than `B_PRED` and `SPLITMV`, the DC |
| values derived from the DCT transform on the 16 Y blocks are |
| collected to construct a 25th block of a macroblock (16 Y, 4 U, 4 V |
| constitute the 24 blocks). This 25th block is transformed using a |
| Walsh-Hadamard transform (WHT). |
| |
| The inputs to the inverse WHT (that is, the dequantized |
| coefficients), the intermediate "horizontally detransformed" signal, |
| and the completely detransformed residue signal are all stored as |
| arrays of 16-bit signed integers. |
| |
| Following the tradition of specifying bitstream format using the |
| decoding process, we specify the inverse WHT in the decoding process |
| using the following C-style source code: |
| |
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| void vp8_short_inv_walsh4x4_c(short *input, short *output) |
| { |
| int i; |
| int a1, b1, c1, d1; |
| int a2, b2, c2, d2; |
| short *ip = input; |
| short *op = output; |
| int temp1, temp2; |
| |
| for(i=0;i<4;i++) |
| { |
| a1 = ip[0] + ip[12]; |
| b1 = ip[4] + ip[8]; |
| c1 = ip[4] - ip[8]; |
| d1 = ip[0] - ip[12]; |
| |
| op[0] = a1 + b1; |
| op[4] = c1 + d1; |
| op[8] = a1 - b1; |
| op[12]= d1 - c1; |
| ip++; |
| op++; |
| } |
| ip = output; |
| op = output; |
| for(i=0;i<4;i++) |
| { |
| a1 = ip[0] + ip[3]; |
| b1 = ip[1] + ip[2]; |
| c1 = ip[1] - ip[2]; |
| d1 = ip[0] - ip[3]; |
| |
| a2 = a1 + b1; |
| b2 = c1 + d1; |
| c2 = a1 - b1; |
| d2 = d1 - c1; |
| |
| op[0] = (a2+3)>>3; |
| op[1] = (b2+3)>>3; |
| op[2] = (c2+3)>>3; |
| op[3] = (d2+3)>>3; |
| |
| ip+=4; |
| op+=4; |
| } |
| } |
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| {:lang="c"} |
| |
| In the case that there is only one non-zero DC value in input, the |
| inverse transform can be simplified to the following: |
| |
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| void vp8_short_inv_walsh4x4_1_c(short *input, short *output) |
| { |
| int i; |
| int a1; |
| short *op=output; |
| |
| a1 = ((input[0] + 3)>>3); |
| |
| for(i=0;i<4;i++) |
| { |
| op[0] = a1; |
| op[1] = a1; |
| op[2] = a1; |
| op[3] = a1; |
| op+=4; |
| } |
| } |
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| {:lang="c"} |
| |
| It should be noted that a conforming decoder should implement the |
| inverse transform using exactly the same rounding to achieve bit-wise |
| matching output to the output of the process specified by the above |
| C source code. |
| |
| The reference decoder WHT inversion may be found in the file |
| `idct_add.c` (Section 20.8). |
| |