| // Copyright 2011 The Go Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style |
| // license that can be found in the LICENSE file. |
| |
| package vp8 |
| |
| // This file implements the predicition functions, as specified in chapter 12. |
| // |
| // For each macroblock (of 1x16x16 luma and 2x8x8 chroma coefficients), the |
| // luma values are either predicted as one large 16x16 region or 16 separate |
| // 4x4 regions. The chroma values are always predicted as one 8x8 region. |
| // |
| // For 4x4 regions, the target block's predicted values (Xs) are a function of |
| // its previously-decoded top and left border values, as well as a number of |
| // pixels from the top-right: |
| // |
| // a b c d e f g h |
| // p X X X X |
| // q X X X X |
| // r X X X X |
| // s X X X X |
| // |
| // The predictor modes are: |
| // - DC: all Xs = (b + c + d + e + p + q + r + s + 4) / 8. |
| // - TM: the first X = (b + p - a), the second X = (c + p - a), and so on. |
| // - VE: each X = the weighted average of its column's top value and that |
| // value's neighbors, i.e. averages of abc, bcd, cde or def. |
| // - HE: similar to VE except rows instead of columns, and the final row is |
| // an average of r, s and s. |
| // - RD, VR, LD, VL, HD, HU: these diagonal modes ("Right Down", "Vertical |
| // Right", etc) are more complicated and are described in section 12.3. |
| // All Xs are clipped to the range [0, 255]. |
| // |
| // For 8x8 and 16x16 regions, the target block's predicted values are a |
| // function of the top and left border values without the top-right overhang, |
| // i.e. without the 8x8 or 16x16 equivalent of f, g and h. Furthermore: |
| // - There are no diagonal predictor modes, only DC, TM, VE and HE. |
| // - The DC mode has variants for macroblocks in the top row and/or left |
| // column, i.e. for macroblocks with mby == 0 || mbx == 0. |
| // - The VE and HE modes take only the column top or row left values; they do |
| // not smooth that top/left value with its neighbors. |
| |
| // nPred is the number of predictor modes, not including the Top/Left versions |
| // of the DC predictor mode. |
| const nPred = 10 |
| |
| const ( |
| predDC = iota |
| predTM |
| predVE |
| predHE |
| predRD |
| predVR |
| predLD |
| predVL |
| predHD |
| predHU |
| predDCTop |
| predDCLeft |
| predDCTopLeft |
| ) |
| |
| func checkTopLeftPred(mbx, mby int, p uint8) uint8 { |
| if p != predDC { |
| return p |
| } |
| if mbx == 0 { |
| if mby == 0 { |
| return predDCTopLeft |
| } |
| return predDCLeft |
| } |
| if mby == 0 { |
| return predDCTop |
| } |
| return predDC |
| } |
| |
| var predFunc4 = [...]func(*Decoder, int, int){ |
| predFunc4DC, |
| predFunc4TM, |
| predFunc4VE, |
| predFunc4HE, |
| predFunc4RD, |
| predFunc4VR, |
| predFunc4LD, |
| predFunc4VL, |
| predFunc4HD, |
| predFunc4HU, |
| nil, |
| nil, |
| nil, |
| } |
| |
| var predFunc8 = [...]func(*Decoder, int, int){ |
| predFunc8DC, |
| predFunc8TM, |
| predFunc8VE, |
| predFunc8HE, |
| nil, |
| nil, |
| nil, |
| nil, |
| nil, |
| nil, |
| predFunc8DCTop, |
| predFunc8DCLeft, |
| predFunc8DCTopLeft, |
| } |
| |
| var predFunc16 = [...]func(*Decoder, int, int){ |
| predFunc16DC, |
| predFunc16TM, |
| predFunc16VE, |
| predFunc16HE, |
| nil, |
| nil, |
| nil, |
| nil, |
| nil, |
| nil, |
| predFunc16DCTop, |
| predFunc16DCLeft, |
| predFunc16DCTopLeft, |
| } |
| |
| func predFunc4DC(z *Decoder, y, x int) { |
| sum := uint32(4) |
| for i := 0; i < 4; i++ { |
| sum += uint32(z.ybr[y-1][x+i]) |
| } |
| for j := 0; j < 4; j++ { |
| sum += uint32(z.ybr[y+j][x-1]) |
| } |
| avg := uint8(sum / 8) |
| for j := 0; j < 4; j++ { |
| for i := 0; i < 4; i++ { |
| z.ybr[y+j][x+i] = avg |
| } |
| } |
| } |
| |
| func predFunc4TM(z *Decoder, y, x int) { |
| delta0 := -int32(z.ybr[y-1][x-1]) |
| for j := 0; j < 4; j++ { |
| delta1 := delta0 + int32(z.ybr[y+j][x-1]) |
| for i := 0; i < 4; i++ { |
| delta2 := delta1 + int32(z.ybr[y-1][x+i]) |
| z.ybr[y+j][x+i] = uint8(clip(delta2, 0, 255)) |
| } |
| } |
| } |
| |
| func predFunc4VE(z *Decoder, y, x int) { |
| a := int32(z.ybr[y-1][x-1]) |
| b := int32(z.ybr[y-1][x+0]) |
| c := int32(z.ybr[y-1][x+1]) |
| d := int32(z.ybr[y-1][x+2]) |
| e := int32(z.ybr[y-1][x+3]) |
| f := int32(z.ybr[y-1][x+4]) |
| abc := uint8((a + 2*b + c + 2) / 4) |
| bcd := uint8((b + 2*c + d + 2) / 4) |
| cde := uint8((c + 2*d + e + 2) / 4) |
| def := uint8((d + 2*e + f + 2) / 4) |
| for j := 0; j < 4; j++ { |
| z.ybr[y+j][x+0] = abc |
| z.ybr[y+j][x+1] = bcd |
| z.ybr[y+j][x+2] = cde |
| z.ybr[y+j][x+3] = def |
| } |
| } |
| |
| func predFunc4HE(z *Decoder, y, x int) { |
| s := int32(z.ybr[y+3][x-1]) |
| r := int32(z.ybr[y+2][x-1]) |
| q := int32(z.ybr[y+1][x-1]) |
| p := int32(z.ybr[y+0][x-1]) |
| a := int32(z.ybr[y-1][x-1]) |
| ssr := uint8((s + 2*s + r + 2) / 4) |
| srq := uint8((s + 2*r + q + 2) / 4) |
| rqp := uint8((r + 2*q + p + 2) / 4) |
| apq := uint8((a + 2*p + q + 2) / 4) |
| for i := 0; i < 4; i++ { |
| z.ybr[y+0][x+i] = apq |
| z.ybr[y+1][x+i] = rqp |
| z.ybr[y+2][x+i] = srq |
| z.ybr[y+3][x+i] = ssr |
| } |
| } |
| |
| func predFunc4RD(z *Decoder, y, x int) { |
| s := int32(z.ybr[y+3][x-1]) |
| r := int32(z.ybr[y+2][x-1]) |
| q := int32(z.ybr[y+1][x-1]) |
| p := int32(z.ybr[y+0][x-1]) |
| a := int32(z.ybr[y-1][x-1]) |
| b := int32(z.ybr[y-1][x+0]) |
| c := int32(z.ybr[y-1][x+1]) |
| d := int32(z.ybr[y-1][x+2]) |
| e := int32(z.ybr[y-1][x+3]) |
| srq := uint8((s + 2*r + q + 2) / 4) |
| rqp := uint8((r + 2*q + p + 2) / 4) |
| qpa := uint8((q + 2*p + a + 2) / 4) |
| pab := uint8((p + 2*a + b + 2) / 4) |
| abc := uint8((a + 2*b + c + 2) / 4) |
| bcd := uint8((b + 2*c + d + 2) / 4) |
| cde := uint8((c + 2*d + e + 2) / 4) |
| z.ybr[y+0][x+0] = pab |
| z.ybr[y+0][x+1] = abc |
| z.ybr[y+0][x+2] = bcd |
| z.ybr[y+0][x+3] = cde |
| z.ybr[y+1][x+0] = qpa |
| z.ybr[y+1][x+1] = pab |
| z.ybr[y+1][x+2] = abc |
| z.ybr[y+1][x+3] = bcd |
| z.ybr[y+2][x+0] = rqp |
| z.ybr[y+2][x+1] = qpa |
| z.ybr[y+2][x+2] = pab |
| z.ybr[y+2][x+3] = abc |
| z.ybr[y+3][x+0] = srq |
| z.ybr[y+3][x+1] = rqp |
| z.ybr[y+3][x+2] = qpa |
| z.ybr[y+3][x+3] = pab |
| } |
| |
| func predFunc4VR(z *Decoder, y, x int) { |
| r := int32(z.ybr[y+2][x-1]) |
| q := int32(z.ybr[y+1][x-1]) |
| p := int32(z.ybr[y+0][x-1]) |
| a := int32(z.ybr[y-1][x-1]) |
| b := int32(z.ybr[y-1][x+0]) |
| c := int32(z.ybr[y-1][x+1]) |
| d := int32(z.ybr[y-1][x+2]) |
| e := int32(z.ybr[y-1][x+3]) |
| ab := uint8((a + b + 1) / 2) |
| bc := uint8((b + c + 1) / 2) |
| cd := uint8((c + d + 1) / 2) |
| de := uint8((d + e + 1) / 2) |
| rqp := uint8((r + 2*q + p + 2) / 4) |
| qpa := uint8((q + 2*p + a + 2) / 4) |
| pab := uint8((p + 2*a + b + 2) / 4) |
| abc := uint8((a + 2*b + c + 2) / 4) |
| bcd := uint8((b + 2*c + d + 2) / 4) |
| cde := uint8((c + 2*d + e + 2) / 4) |
| z.ybr[y+0][x+0] = ab |
| z.ybr[y+0][x+1] = bc |
| z.ybr[y+0][x+2] = cd |
| z.ybr[y+0][x+3] = de |
| z.ybr[y+1][x+0] = pab |
| z.ybr[y+1][x+1] = abc |
| z.ybr[y+1][x+2] = bcd |
| z.ybr[y+1][x+3] = cde |
| z.ybr[y+2][x+0] = qpa |
| z.ybr[y+2][x+1] = ab |
| z.ybr[y+2][x+2] = bc |
| z.ybr[y+2][x+3] = cd |
| z.ybr[y+3][x+0] = rqp |
| z.ybr[y+3][x+1] = pab |
| z.ybr[y+3][x+2] = abc |
| z.ybr[y+3][x+3] = bcd |
| } |
| |
| func predFunc4LD(z *Decoder, y, x int) { |
| a := int32(z.ybr[y-1][x+0]) |
| b := int32(z.ybr[y-1][x+1]) |
| c := int32(z.ybr[y-1][x+2]) |
| d := int32(z.ybr[y-1][x+3]) |
| e := int32(z.ybr[y-1][x+4]) |
| f := int32(z.ybr[y-1][x+5]) |
| g := int32(z.ybr[y-1][x+6]) |
| h := int32(z.ybr[y-1][x+7]) |
| abc := uint8((a + 2*b + c + 2) / 4) |
| bcd := uint8((b + 2*c + d + 2) / 4) |
| cde := uint8((c + 2*d + e + 2) / 4) |
| def := uint8((d + 2*e + f + 2) / 4) |
| efg := uint8((e + 2*f + g + 2) / 4) |
| fgh := uint8((f + 2*g + h + 2) / 4) |
| ghh := uint8((g + 2*h + h + 2) / 4) |
| z.ybr[y+0][x+0] = abc |
| z.ybr[y+0][x+1] = bcd |
| z.ybr[y+0][x+2] = cde |
| z.ybr[y+0][x+3] = def |
| z.ybr[y+1][x+0] = bcd |
| z.ybr[y+1][x+1] = cde |
| z.ybr[y+1][x+2] = def |
| z.ybr[y+1][x+3] = efg |
| z.ybr[y+2][x+0] = cde |
| z.ybr[y+2][x+1] = def |
| z.ybr[y+2][x+2] = efg |
| z.ybr[y+2][x+3] = fgh |
| z.ybr[y+3][x+0] = def |
| z.ybr[y+3][x+1] = efg |
| z.ybr[y+3][x+2] = fgh |
| z.ybr[y+3][x+3] = ghh |
| } |
| |
| func predFunc4VL(z *Decoder, y, x int) { |
| a := int32(z.ybr[y-1][x+0]) |
| b := int32(z.ybr[y-1][x+1]) |
| c := int32(z.ybr[y-1][x+2]) |
| d := int32(z.ybr[y-1][x+3]) |
| e := int32(z.ybr[y-1][x+4]) |
| f := int32(z.ybr[y-1][x+5]) |
| g := int32(z.ybr[y-1][x+6]) |
| h := int32(z.ybr[y-1][x+7]) |
| ab := uint8((a + b + 1) / 2) |
| bc := uint8((b + c + 1) / 2) |
| cd := uint8((c + d + 1) / 2) |
| de := uint8((d + e + 1) / 2) |
| abc := uint8((a + 2*b + c + 2) / 4) |
| bcd := uint8((b + 2*c + d + 2) / 4) |
| cde := uint8((c + 2*d + e + 2) / 4) |
| def := uint8((d + 2*e + f + 2) / 4) |
| efg := uint8((e + 2*f + g + 2) / 4) |
| fgh := uint8((f + 2*g + h + 2) / 4) |
| z.ybr[y+0][x+0] = ab |
| z.ybr[y+0][x+1] = bc |
| z.ybr[y+0][x+2] = cd |
| z.ybr[y+0][x+3] = de |
| z.ybr[y+1][x+0] = abc |
| z.ybr[y+1][x+1] = bcd |
| z.ybr[y+1][x+2] = cde |
| z.ybr[y+1][x+3] = def |
| z.ybr[y+2][x+0] = bc |
| z.ybr[y+2][x+1] = cd |
| z.ybr[y+2][x+2] = de |
| z.ybr[y+2][x+3] = efg |
| z.ybr[y+3][x+0] = bcd |
| z.ybr[y+3][x+1] = cde |
| z.ybr[y+3][x+2] = def |
| z.ybr[y+3][x+3] = fgh |
| } |
| |
| func predFunc4HD(z *Decoder, y, x int) { |
| s := int32(z.ybr[y+3][x-1]) |
| r := int32(z.ybr[y+2][x-1]) |
| q := int32(z.ybr[y+1][x-1]) |
| p := int32(z.ybr[y+0][x-1]) |
| a := int32(z.ybr[y-1][x-1]) |
| b := int32(z.ybr[y-1][x+0]) |
| c := int32(z.ybr[y-1][x+1]) |
| d := int32(z.ybr[y-1][x+2]) |
| sr := uint8((s + r + 1) / 2) |
| rq := uint8((r + q + 1) / 2) |
| qp := uint8((q + p + 1) / 2) |
| pa := uint8((p + a + 1) / 2) |
| srq := uint8((s + 2*r + q + 2) / 4) |
| rqp := uint8((r + 2*q + p + 2) / 4) |
| qpa := uint8((q + 2*p + a + 2) / 4) |
| pab := uint8((p + 2*a + b + 2) / 4) |
| abc := uint8((a + 2*b + c + 2) / 4) |
| bcd := uint8((b + 2*c + d + 2) / 4) |
| z.ybr[y+0][x+0] = pa |
| z.ybr[y+0][x+1] = pab |
| z.ybr[y+0][x+2] = abc |
| z.ybr[y+0][x+3] = bcd |
| z.ybr[y+1][x+0] = qp |
| z.ybr[y+1][x+1] = qpa |
| z.ybr[y+1][x+2] = pa |
| z.ybr[y+1][x+3] = pab |
| z.ybr[y+2][x+0] = rq |
| z.ybr[y+2][x+1] = rqp |
| z.ybr[y+2][x+2] = qp |
| z.ybr[y+2][x+3] = qpa |
| z.ybr[y+3][x+0] = sr |
| z.ybr[y+3][x+1] = srq |
| z.ybr[y+3][x+2] = rq |
| z.ybr[y+3][x+3] = rqp |
| } |
| |
| func predFunc4HU(z *Decoder, y, x int) { |
| s := int32(z.ybr[y+3][x-1]) |
| r := int32(z.ybr[y+2][x-1]) |
| q := int32(z.ybr[y+1][x-1]) |
| p := int32(z.ybr[y+0][x-1]) |
| pq := uint8((p + q + 1) / 2) |
| qr := uint8((q + r + 1) / 2) |
| rs := uint8((r + s + 1) / 2) |
| pqr := uint8((p + 2*q + r + 2) / 4) |
| qrs := uint8((q + 2*r + s + 2) / 4) |
| rss := uint8((r + 2*s + s + 2) / 4) |
| sss := uint8(s) |
| z.ybr[y+0][x+0] = pq |
| z.ybr[y+0][x+1] = pqr |
| z.ybr[y+0][x+2] = qr |
| z.ybr[y+0][x+3] = qrs |
| z.ybr[y+1][x+0] = qr |
| z.ybr[y+1][x+1] = qrs |
| z.ybr[y+1][x+2] = rs |
| z.ybr[y+1][x+3] = rss |
| z.ybr[y+2][x+0] = rs |
| z.ybr[y+2][x+1] = rss |
| z.ybr[y+2][x+2] = sss |
| z.ybr[y+2][x+3] = sss |
| z.ybr[y+3][x+0] = sss |
| z.ybr[y+3][x+1] = sss |
| z.ybr[y+3][x+2] = sss |
| z.ybr[y+3][x+3] = sss |
| } |
| |
| func predFunc8DC(z *Decoder, y, x int) { |
| sum := uint32(8) |
| for i := 0; i < 8; i++ { |
| sum += uint32(z.ybr[y-1][x+i]) |
| } |
| for j := 0; j < 8; j++ { |
| sum += uint32(z.ybr[y+j][x-1]) |
| } |
| avg := uint8(sum / 16) |
| for j := 0; j < 8; j++ { |
| for i := 0; i < 8; i++ { |
| z.ybr[y+j][x+i] = avg |
| } |
| } |
| } |
| |
| func predFunc8TM(z *Decoder, y, x int) { |
| delta0 := -int32(z.ybr[y-1][x-1]) |
| for j := 0; j < 8; j++ { |
| delta1 := delta0 + int32(z.ybr[y+j][x-1]) |
| for i := 0; i < 8; i++ { |
| delta2 := delta1 + int32(z.ybr[y-1][x+i]) |
| z.ybr[y+j][x+i] = uint8(clip(delta2, 0, 255)) |
| } |
| } |
| } |
| |
| func predFunc8VE(z *Decoder, y, x int) { |
| for j := 0; j < 8; j++ { |
| for i := 0; i < 8; i++ { |
| z.ybr[y+j][x+i] = z.ybr[y-1][x+i] |
| } |
| } |
| } |
| |
| func predFunc8HE(z *Decoder, y, x int) { |
| for j := 0; j < 8; j++ { |
| for i := 0; i < 8; i++ { |
| z.ybr[y+j][x+i] = z.ybr[y+j][x-1] |
| } |
| } |
| } |
| |
| func predFunc8DCTop(z *Decoder, y, x int) { |
| sum := uint32(4) |
| for j := 0; j < 8; j++ { |
| sum += uint32(z.ybr[y+j][x-1]) |
| } |
| avg := uint8(sum / 8) |
| for j := 0; j < 8; j++ { |
| for i := 0; i < 8; i++ { |
| z.ybr[y+j][x+i] = avg |
| } |
| } |
| } |
| |
| func predFunc8DCLeft(z *Decoder, y, x int) { |
| sum := uint32(4) |
| for i := 0; i < 8; i++ { |
| sum += uint32(z.ybr[y-1][x+i]) |
| } |
| avg := uint8(sum / 8) |
| for j := 0; j < 8; j++ { |
| for i := 0; i < 8; i++ { |
| z.ybr[y+j][x+i] = avg |
| } |
| } |
| } |
| |
| func predFunc8DCTopLeft(z *Decoder, y, x int) { |
| for j := 0; j < 8; j++ { |
| for i := 0; i < 8; i++ { |
| z.ybr[y+j][x+i] = 0x80 |
| } |
| } |
| } |
| |
| func predFunc16DC(z *Decoder, y, x int) { |
| sum := uint32(16) |
| for i := 0; i < 16; i++ { |
| sum += uint32(z.ybr[y-1][x+i]) |
| } |
| for j := 0; j < 16; j++ { |
| sum += uint32(z.ybr[y+j][x-1]) |
| } |
| avg := uint8(sum / 32) |
| for j := 0; j < 16; j++ { |
| for i := 0; i < 16; i++ { |
| z.ybr[y+j][x+i] = avg |
| } |
| } |
| } |
| |
| func predFunc16TM(z *Decoder, y, x int) { |
| delta0 := -int32(z.ybr[y-1][x-1]) |
| for j := 0; j < 16; j++ { |
| delta1 := delta0 + int32(z.ybr[y+j][x-1]) |
| for i := 0; i < 16; i++ { |
| delta2 := delta1 + int32(z.ybr[y-1][x+i]) |
| z.ybr[y+j][x+i] = uint8(clip(delta2, 0, 255)) |
| } |
| } |
| } |
| |
| func predFunc16VE(z *Decoder, y, x int) { |
| for j := 0; j < 16; j++ { |
| for i := 0; i < 16; i++ { |
| z.ybr[y+j][x+i] = z.ybr[y-1][x+i] |
| } |
| } |
| } |
| |
| func predFunc16HE(z *Decoder, y, x int) { |
| for j := 0; j < 16; j++ { |
| for i := 0; i < 16; i++ { |
| z.ybr[y+j][x+i] = z.ybr[y+j][x-1] |
| } |
| } |
| } |
| |
| func predFunc16DCTop(z *Decoder, y, x int) { |
| sum := uint32(8) |
| for j := 0; j < 16; j++ { |
| sum += uint32(z.ybr[y+j][x-1]) |
| } |
| avg := uint8(sum / 16) |
| for j := 0; j < 16; j++ { |
| for i := 0; i < 16; i++ { |
| z.ybr[y+j][x+i] = avg |
| } |
| } |
| } |
| |
| func predFunc16DCLeft(z *Decoder, y, x int) { |
| sum := uint32(8) |
| for i := 0; i < 16; i++ { |
| sum += uint32(z.ybr[y-1][x+i]) |
| } |
| avg := uint8(sum / 16) |
| for j := 0; j < 16; j++ { |
| for i := 0; i < 16; i++ { |
| z.ybr[y+j][x+i] = avg |
| } |
| } |
| } |
| |
| func predFunc16DCTopLeft(z *Decoder, y, x int) { |
| for j := 0; j < 16; j++ { |
| for i := 0; i < 16; i++ { |
| z.ybr[y+j][x+i] = 0x80 |
| } |
| } |
| } |