nx_h264_mc_luma.nx source
↩ module page · 83 lines · 4644 B
1// nx_h264_mc_luma.nx -- H.264 luma quarter-pel motion-compensated interpolation (spec 8.4.2.2.1).
2// Half-pel = 6-tap (1,-5,20,20,-5,1); quarter-pel = bilinear average of integer/half-pel samples;
3// center (2,2) = 6-tap on the UNROUNDED horizontal half-pel intermediates ((.+512)>>10). Edge
4// samples are clamped (full-sample padding). Given a reference plane + integer pos (x,y) + frac
5// (xf,yf in 0..3), returns one predicted luma sample.
6// genealogy_id: itu_t_h264_sec8_4_2_2_1_luma_interp
7// lineage_id: sixtap_halfpel + bilinear_quarterpel + center_2pass
8// license_tier: ORIGINAL
9import "nx_syscalls.nx"
10
11func mc_clip1(v: i64) -> i64 { if v < 0 { return 0 } if v > 255 { return 255 } return v }
12func mc_tap6(a: i64, b: i64, c: i64, d: i64, e: i64, f: i64) -> i64 {
13 return a - 5 * b + 20 * c + 20 * d - 5 * e + f
14}
15// clamped integer sample access
16func mc_rc(ref: *u8, W: i64, H: i64, x: i64, y: i64) -> i64 {
17 var xx: i64 = x
18 if xx < 0 { xx = 0 }
19 if xx > W - 1 { xx = W - 1 }
20 var yy: i64 = y
21 if yy < 0 { yy = 0 }
22 if yy > H - 1 { yy = H - 1 }
23 return ref[yy * W + xx] as i64
24}
25// unrounded horizontal 6-tap at (x,y): half-pel between (x,y) and (x+1,y)
26func mc_hc(ref: *u8, W: i64, H: i64, x: i64, y: i64) -> i64 {
27 return mc_tap6(mc_rc(ref,W,H,x-2,y), mc_rc(ref,W,H,x-1,y), mc_rc(ref,W,H,x,y),
28 mc_rc(ref,W,H,x+1,y), mc_rc(ref,W,H,x+2,y), mc_rc(ref,W,H,x+3,y))
29}
30// unrounded vertical 6-tap at (x,y): half-pel between (x,y) and (x,y+1)
31func mc_vc(ref: *u8, W: i64, H: i64, x: i64, y: i64) -> i64 {
32 return mc_tap6(mc_rc(ref,W,H,x,y-2), mc_rc(ref,W,H,x,y-1), mc_rc(ref,W,H,x,y),
33 mc_rc(ref,W,H,x,y+1), mc_rc(ref,W,H,x,y+2), mc_rc(ref,W,H,x,y+3))
34}
35func mc_halfH(ref: *u8, W: i64, H: i64, x: i64, y: i64) -> i64 { return mc_clip1((mc_hc(ref,W,H,x,y) + 16) >> 5) }
36func mc_halfV(ref: *u8, W: i64, H: i64, x: i64, y: i64) -> i64 { return mc_clip1((mc_vc(ref,W,H,x,y) + 16) >> 5) }
37// center half-pel (2,2): 6-tap (vertical) on unrounded horizontal intermediates
38func mc_halfHV(ref: *u8, W: i64, H: i64, x: i64, y: i64) -> i64 {
39 let j1: i64 = mc_tap6(mc_hc(ref,W,H,x,y-2), mc_hc(ref,W,H,x,y-1), mc_hc(ref,W,H,x,y),
40 mc_hc(ref,W,H,x,y+1), mc_hc(ref,W,H,x,y+2), mc_hc(ref,W,H,x,y+3))
41 return mc_clip1((j1 + 512) >> 10)
42}
43
44// one luma sample at integer (x,y) + quarter-pel frac (xf,yf), each 0..3.
45func nx_h264_mc_luma_sample(ref: *u8, W: i64, H: i64, x: i64, y: i64, xf: i64, yf: i64) -> i64 {
46 if xf == 0 { if yf == 0 { return mc_rc(ref,W,H,x,y) } } // G
47 // pure horizontal row (yf==0)
48 if yf == 0 {
49 let bb: i64 = mc_halfH(ref,W,H,x,y)
50 if xf == 2 { return bb } // b
51 if xf == 1 { return (mc_rc(ref,W,H,x,y) + bb + 1) >> 1 } // a
52 return (mc_rc(ref,W,H,x+1,y) + bb + 1) >> 1 // c (xf==3)
53 }
54 // pure vertical col (xf==0)
55 if xf == 0 {
56 let hh: i64 = mc_halfV(ref,W,H,x,y)
57 if yf == 2 { return hh } // h
58 if yf == 1 { return (mc_rc(ref,W,H,x,y) + hh + 1) >> 1 } // d
59 return (mc_rc(ref,W,H,x,y+1) + hh + 1) >> 1 // n (yf==3)
60 }
61 // center column (xf==2)
62 if xf == 2 {
63 let j: i64 = mc_halfHV(ref,W,H,x,y)
64 if yf == 2 { return j } // j
65 if yf == 1 { return (mc_halfH(ref,W,H,x,y) + j + 1) >> 1 } // f
66 return (j + mc_halfH(ref,W,H,x,y+1) + 1) >> 1 // q (yf==3)
67 }
68 // center row (yf==2)
69 if yf == 2 {
70 let j: i64 = mc_halfHV(ref,W,H,x,y)
71 if xf == 1 { return (mc_halfV(ref,W,H,x,y) + j + 1) >> 1 } // i
72 return (j + mc_halfV(ref,W,H,x+1,y) + 1) >> 1 // k (xf==3)
73 }
74 // true diagonals (xf in {1,3}, yf in {1,3})
75 let bxy: i64 = mc_halfH(ref,W,H,x,y) // b (x+0.5, y)
76 let bxy1: i64 = mc_halfH(ref,W,H,x,y+1) // s (x+0.5, y+1)
77 let vxy: i64 = mc_halfV(ref,W,H,x,y) // h (x, y+0.5)
78 let vx1y: i64 = mc_halfV(ref,W,H,x+1,y) // m (x+1, y+0.5)
79 if xf == 1 { if yf == 1 { return (bxy + vxy + 1) >> 1 } } // e
80 if xf == 3 { if yf == 1 { return (bxy + vx1y + 1) >> 1 } } // g
81 if xf == 1 { if yf == 3 { return (vxy + bxy1 + 1) >> 1 } } // p
82 return (vx1y + bxy1 + 1) >> 1 // r (3,3)
83}