code wiki / (root) / nx_h264_pmvfield.nx

nx_h264_pmvfield.nx source

↩ module page · 243 lines · 13443 B

1// nx_h264_pmvfield.nx -- decode a P-slice's per-4x4 L0 MOTION-VECTOR FIELD (gref/gmvx/gmvy) by the proven 2// P entropy walk (skip-MV derivation, P mb_types incl 8x8 sub-partitions, mvp via the grid + mvd, residual 3// decoded only to keep entropy in sync). Used to obtain the CO-LOCATED motion of the future anchor that 4// B-slice spatial-direct prediction (8.4.1.2.2) reads. The caller pre-inits the grids to -2 (undecoded). 5// genealogy_id: itu_t_h264_pslice_mv_field license_tier: ORIGINAL 6import "nx_syscalls.nx" 7import "nx_h264_bits.nx" 8import "nx_h264_mb.nx" 9import "nx_h264_mb_pred.nx" 10import "nx_h264_coeff_token.nx" 11import "nx_h264_cavlc_level.nx" 12import "nx_h264_residual.nx" 13import "nx_h264_nc.nx" 14import "nx_h264_pmb.nx" 15import "nx_h264_mvgrid.nx" 16 17func pmv_dec_luma(br: *BitReader, lumaTC: *i64, lbW: i64, bx: i64, by: i64, maxc: i64, coeff: *i64) -> i64 { 18 var nA: i64 = 0 19 var avA: i64 = 0 20 if bx > 0 { nA = lumaTC[by * lbW + (bx - 1)]; avA = 1 } 21 var nB: i64 = 0 22 var avB: i64 = 0 23 if by > 0 { nB = lumaTC[(by - 1) * lbW + bx]; avB = 1 } 24 let nC: i64 = nx_h264_nc_luma(nA, avA, nB, avB) 25 let tc: i64 = nx_h264_residual_decode(br, maxc, nC, coeff) 26 lumaTC[by * lbW + bx] = tc 27 return tc 28} 29func pmv_dec_cac(br: *BitReader, cTC: *i64, cbW: i64, cbx: i64, cby: i64, coeff: *i64) -> i64 { 30 var nA: i64 = 0 31 var avA: i64 = 0 32 if cbx > 0 { nA = cTC[cby * cbW + (cbx - 1)]; avA = 1 } 33 var nB: i64 = 0 34 var avB: i64 = 0 35 if cby > 0 { nB = cTC[(cby - 1) * cbW + cbx]; avB = 1 } 36 let nC: i64 = nx_h264_nc_luma(nA, avA, nB, avB) 37 let tc: i64 = nx_h264_residual_decode(br, 15, nC, coeff) 38 cTC[cby * cbW + cbx] = tc 39 return tc 40} 41func pmv_read_ref(sbr: *BitReader, num_ref: i64) -> i64 { 42 if num_ref == 1 { return 0 } 43 if num_ref == 2 { let bbit: i64 = br_read_bit(sbr); return 1 - bbit } 44 return br_read_ue(sbr) 45} 46 47// Walk a P-slice (sbr positioned after the slice header) filling gref/gmvx/gmvy (per-4x4, -2=undecoded 48// pre-init, -1=intra, >=0 ref). qp0 = slice QP, num_ref = num_ref_idx_l0_active. Returns reader byte_pos. 49func nx_h264_pslice_mvfield(sbr: *BitReader, qp0: i64, num_ref: i64, mbW: i64, mbH: i64, 50 gref: *i64, gmvx: *i64, gmvy: *i64) -> i64 { 51 let lbW: i64 = mbW * 4 52 let lbH: i64 = mbH * 4 53 let cbW: i64 = mbW * 2 54 let cbH: i64 = mbH * 2 55 let totalMB: i64 = mbW * mbH 56 let lumaTC: *i64 = sys_mmap(lbW * lbH * 8) as *i64 57 let uTC: *i64 = sys_mmap(cbW * cbH * 8) as *i64 58 let vTC: *i64 = sys_mmap(cbW * cbH * 8) as *i64 59 var z: i64 = 0 60 while z < lbW * lbH { lumaTC[z] = 0; z = z + 1 } 61 z = 0 62 while z < cbW * cbH { uTC[z] = 0; vTC[z] = 0; z = z + 1 } 63 let bx4: *i64 = sys_mmap(16 * 8) as *i64 64 let by4: *i64 = sys_mmap(16 * 8) as *i64 65 bx4[0]=0; by4[0]=0; bx4[1]=1; by4[1]=0; bx4[2]=0; by4[2]=1; bx4[3]=1; by4[3]=1 66 bx4[4]=2; by4[4]=0; bx4[5]=3; by4[5]=0; bx4[6]=2; by4[6]=1; bx4[7]=3; by4[7]=1 67 bx4[8]=0; by4[8]=2; bx4[9]=1; by4[9]=2; bx4[10]=0; by4[10]=3; bx4[11]=1; by4[11]=3 68 bx4[12]=2; by4[12]=2; bx4[13]=3; by4[13]=2; bx4[14]=2; by4[14]=3; bx4[15]=3; by4[15]=3 69 let coeff: *i64 = sys_mmap(32 * 8) as *i64 70 let mvp: *i64 = sys_mmap(16) as *i64 71 let refs: *i64 = sys_mmap(8 * 8) as *i64 72 let subs: *i64 = sys_mmap(8 * 8) as *i64 73 var qp: i64 = qp0 74 var ok: i64 = 1 75 var mbAddr: i64 = 0 76 while mbAddr < totalMB { 77 if ok == 0 { mbAddr = totalMB } else { 78 let skip_run: i64 = br_read_ue(sbr) 79 var s2: i64 = 0 80 while s2 < skip_run { 81 if mbAddr < totalMB { 82 let mbX: i64 = mbAddr % mbW 83 let mbY: i64 = mbAddr / mbW 84 nx_mvg_skip_mv(gref, gmvx, gmvy, lbW, lbH, mbX, mbY, mvp) 85 nx_mvg_fill(gref, gmvx, gmvy, lbW, mbX * 4, mbY * 4, 4, 4, 0, mvp[0], mvp[1]) 86 var bl: i64 = 0 87 while bl < 16 { lumaTC[(mbY*4 + by4[bl]) * lbW + (mbX*4 + bx4[bl])] = 0; bl = bl + 1 } 88 var cc: i64 = 0 89 while cc < 4 { uTC[(mbY*2 + cc/2) * cbW + (mbX*2 + cc%2)] = 0; vTC[(mbY*2 + cc/2) * cbW + (mbX*2 + cc%2)] = 0; cc = cc + 1 } 90 mbAddr = mbAddr + 1 91 } 92 s2 = s2 + 1 93 } 94 if mbAddr < totalMB { 95 let mbX: i64 = mbAddr % mbW 96 let mbY: i64 = mbAddr / mbW 97 let bx0: i64 = mbX * 4 98 let by0: i64 = mbY * 4 99 let mb_type: i64 = br_read_ue(sbr) 100 let kind: i64 = nx_h264_pmb_kind(mb_type) 101 if kind >= 0 { 102 if nx_h264_pmb_is_8x8(kind) == 1 { 103 var si: i64 = 0 104 while si < 4 { subs[si] = br_read_ue(sbr); si = si + 1 } 105 si = 0 106 while si < 4 { refs[si] = 0; si = si + 1 } 107 if num_ref > 1 { if nx_h264_pmb_codes_ref(kind) == 1 { si = 0; while si < 4 { refs[si] = pmv_read_ref(sbr, num_ref); si = si + 1 } } } 108 si = 0 109 while si < 4 { 110 let sx: i64 = bx0 + (si % 2) * 2 111 let sy: i64 = by0 + (si / 2) * 2 112 let st: i64 = subs[si] 113 var spn: i64 = nx_h264_psub_nparts(st) 114 var sp: i64 = 0 115 while sp < spn { 116 var px: i64 = sx 117 var py: i64 = sy 118 var pw: i64 = 2 119 var ph: i64 = 2 120 if st == 1 { pw = 2; ph = 1; py = sy + sp } 121 if st == 2 { pw = 1; ph = 2; px = sx + sp } 122 if st == 3 { pw = 1; ph = 1; px = sx + (sp % 2); py = sy + (sp / 2) } 123 let mvdx: i64 = br_read_se(sbr) 124 let mvdy: i64 = br_read_se(sbr) 125 nx_mvg_part_mvp(gref, gmvx, gmvy, lbW, lbH, px, py, pw, refs[si], 0, 0, mvp) 126 nx_mvg_fill(gref, gmvx, gmvy, lbW, px, py, pw, ph, refs[si], mvp[0] + mvdx, mvp[1] + mvdy) 127 sp = sp + 1 128 } 129 si = si + 1 130 } 131 } 132 if nx_h264_pmb_is_8x8(kind) == 0 { 133 let nparts: i64 = nx_h264_pmb_nparts(kind) 134 var rp: i64 = 0 135 while rp < nparts { refs[rp] = 0; rp = rp + 1 } 136 if num_ref > 1 { if nx_h264_pmb_codes_ref(kind) == 1 { rp = 0; while rp < nparts { refs[rp] = pmv_read_ref(sbr, num_ref); rp = rp + 1 } } } 137 if kind == 0 { 138 let mvdx: i64 = br_read_se(sbr) 139 let mvdy: i64 = br_read_se(sbr) 140 nx_mvg_part_mvp(gref, gmvx, gmvy, lbW, lbH, bx0, by0, 4, refs[0], 0, 0, mvp) 141 nx_mvg_fill(gref, gmvx, gmvy, lbW, bx0, by0, 4, 4, refs[0], mvp[0] + mvdx, mvp[1] + mvdy) 142 } 143 if kind == 1 { 144 let mvdx0: i64 = br_read_se(sbr) 145 let mvdy0: i64 = br_read_se(sbr) 146 nx_mvg_part_mvp(gref, gmvx, gmvy, lbW, lbH, bx0, by0, 4, refs[0], 1, 0, mvp) 147 nx_mvg_fill(gref, gmvx, gmvy, lbW, bx0, by0, 4, 2, refs[0], mvp[0] + mvdx0, mvp[1] + mvdy0) 148 let mvdx1: i64 = br_read_se(sbr) 149 let mvdy1: i64 = br_read_se(sbr) 150 nx_mvg_part_mvp(gref, gmvx, gmvy, lbW, lbH, bx0, by0 + 2, 4, refs[1], 1, 1, mvp) 151 nx_mvg_fill(gref, gmvx, gmvy, lbW, bx0, by0 + 2, 4, 2, refs[1], mvp[0] + mvdx1, mvp[1] + mvdy1) 152 } 153 if kind == 2 { 154 let mvdx0: i64 = br_read_se(sbr) 155 let mvdy0: i64 = br_read_se(sbr) 156 nx_mvg_part_mvp(gref, gmvx, gmvy, lbW, lbH, bx0, by0, 2, refs[0], 2, 0, mvp) 157 nx_mvg_fill(gref, gmvx, gmvy, lbW, bx0, by0, 2, 4, refs[0], mvp[0] + mvdx0, mvp[1] + mvdy0) 158 let mvdx1: i64 = br_read_se(sbr) 159 let mvdy1: i64 = br_read_se(sbr) 160 nx_mvg_part_mvp(gref, gmvx, gmvy, lbW, lbH, bx0 + 2, by0, 2, refs[1], 2, 1, mvp) 161 nx_mvg_fill(gref, gmvx, gmvy, lbW, bx0 + 2, by0, 2, 4, refs[1], mvp[0] + mvdx1, mvp[1] + mvdy1) 162 } 163 } 164 let cbp: i64 = nx_h264_decode_cbp_inter(sbr) 165 let cbpL: i64 = cbp & 15 166 let cbpC: i64 = (cbp >> 4) & 3 167 if cbp != 0 { let mqd: i64 = br_read_se(sbr); qp = (qp + mqd + 52) % 52 } 168 var bl: i64 = 0 169 while bl < 16 { 170 let abx: i64 = bx0 + bx4[bl] 171 let aby: i64 = by0 + by4[bl] 172 let i8: i64 = bl / 4 173 if ((cbpL >> i8) & 1) != 0 { pmv_dec_luma(sbr, lumaTC, lbW, abx, aby, 16, coeff) } 174 if ((cbpL >> i8) & 1) == 0 { lumaTC[aby * lbW + abx] = 0 } 175 bl = bl + 1 176 } 177 if cbpC != 0 { 178 let ucdc: *i64 = sys_mmap(8 * 8) as *i64 179 nx_h264_residual_decode_cdc(sbr, ucdc) 180 let vcdc: *i64 = sys_mmap(8 * 8) as *i64 181 nx_h264_residual_decode_cdc(sbr, vcdc) 182 if cbpC == 2 { 183 var cc: i64 = 0 184 while cc < 4 { pmv_dec_cac(sbr, uTC, cbW, mbX*2 + (cc%2), mbY*2 + (cc/2), coeff); cc = cc + 1 } 185 cc = 0 186 while cc < 4 { pmv_dec_cac(sbr, vTC, cbW, mbX*2 + (cc%2), mbY*2 + (cc/2), coeff); cc = cc + 1 } 187 } 188 } 189 if cbpC == 0 { var cc: i64 = 0; while cc < 4 { uTC[(mbY*2 + cc/2) * cbW + (mbX*2 + cc%2)] = 0; vTC[(mbY*2 + cc/2) * cbW + (mbX*2 + cc%2)] = 0; cc = cc + 1 } } 190 } 191 if kind < 0 { 192 // intra-in-P: mark grid -1; decode for sync 193 var gb: i64 = 0 194 while gb < 16 { let ax: i64 = bx0 + bx4[gb]; let ay: i64 = by0 + by4[gb]; gref[ay*lbW+ax] = 0 - 1; gmvx[ay*lbW+ax] = 0; gmvy[ay*lbW+ax] = 0; gb = gb + 1 } 195 let it: i64 = mb_type - 5 196 let cls: i64 = nx_h264_mb_type_class(it) 197 if cls == 1 { 198 let der: *i64 = sys_mmap(32) as *i64 199 nx_h264_i16x16_derive(it, der) 200 let cbpL: i64 = der[2] 201 let cbpC: i64 = der[1] 202 br_read_ue(sbr) 203 let mqd: i64 = br_read_se(sbr); qp = (qp + mqd + 52) % 52 204 var nA: i64 = 0 205 var avA: i64 = 0 206 if bx0 > 0 { nA = lumaTC[by0 * lbW + (bx0 - 1)]; avA = 1 } 207 var nB: i64 = 0 208 var avB: i64 = 0 209 if by0 > 0 { nB = lumaTC[(by0 - 1) * lbW + bx0]; avB = 1 } 210 let nCdc: i64 = nx_h264_nc_luma(nA, avA, nB, avB) 211 nx_h264_residual_decode(sbr, 16, nCdc, coeff) 212 var bl: i64 = 0 213 while bl < 16 { let abx: i64 = bx0 + bx4[bl]; let aby: i64 = by0 + by4[bl]; if cbpL != 0 { pmv_dec_luma(sbr, lumaTC, lbW, abx, aby, 15, coeff) } if cbpL == 0 { lumaTC[aby * lbW + abx] = 0 } bl = bl + 1 } 214 if cbpC != 0 { 215 let u2: *i64 = sys_mmap(8*8) as *i64; nx_h264_residual_decode_cdc(sbr, u2) 216 let v2: *i64 = sys_mmap(8*8) as *i64; nx_h264_residual_decode_cdc(sbr, v2) 217 if cbpC == 2 { var cc: i64 = 0; while cc < 4 { pmv_dec_cac(sbr, uTC, cbW, mbX*2 + (cc%2), mbY*2 + (cc/2), coeff); cc = cc + 1 } cc = 0; while cc < 4 { pmv_dec_cac(sbr, vTC, cbW, mbX*2 + (cc%2), mbY*2 + (cc/2), coeff); cc = cc + 1 } } 218 } 219 } 220 if cls == 0 { 221 let modes: *i64 = sys_mmap(24 * 8) as *i64 222 nx_h264_parse_inxn_predmodes(sbr, modes) 223 let cbp: i64 = nx_h264_decode_cbp_intra(sbr) 224 let cbpL: i64 = cbp & 15 225 let cbpC: i64 = (cbp >> 4) & 3 226 if cbp != 0 { let mqd: i64 = br_read_se(sbr); qp = (qp + mqd + 52) % 52 } 227 var bl: i64 = 0 228 while bl < 16 { let abx: i64 = bx0 + bx4[bl]; let aby: i64 = by0 + by4[bl]; let i8: i64 = bl / 4; if ((cbpL >> i8) & 1) != 0 { pmv_dec_luma(sbr, lumaTC, lbW, abx, aby, 16, coeff) } if ((cbpL >> i8) & 1) == 0 { lumaTC[aby * lbW + abx] = 0 } bl = bl + 1 } 229 if cbpC != 0 { 230 let u3: *i64 = sys_mmap(8*8) as *i64; nx_h264_residual_decode_cdc(sbr, u3) 231 let v3: *i64 = sys_mmap(8*8) as *i64; nx_h264_residual_decode_cdc(sbr, v3) 232 if cbpC == 2 { var cc: i64 = 0; while cc < 4 { pmv_dec_cac(sbr, uTC, cbW, mbX*2 + (cc%2), mbY*2 + (cc/2), coeff); cc = cc + 1 } cc = 0; while cc < 4 { pmv_dec_cac(sbr, vTC, cbW, mbX*2 + (cc%2), mbY*2 + (cc/2), coeff); cc = cc + 1 } } 233 } 234 } 235 if cls == 2 { br_align(sbr); var pp: i64 = 0; while pp < 384 { br_read_bits(sbr, 8); pp = pp + 1 } } 236 if cls < 0 { ok = 0 } 237 } 238 mbAddr = mbAddr + 1 239 } 240 } 241 } 242 return sbr.byte_pos 243}