code wiki / (root) / nx_h264_bframe_walk.nx

nx_h264_bframe_walk.nx source

↩ module page · 338 lines · 16779 B

1// nx_h264_bframe_walk.nx -- B-R2: ENTROPY-WALK the first B-slice of bframe_test.264, consuming every bit 2// (B mb_skip_run, B mb_types incl B_8x8 sub_mb_types, per-list L0/L1 ref_idx + mvd, inter CBP, residual, 3// intra-in-B). Proof of correct B syntax = all MBs parsed + reader lands at rbsp end (same bar as P-R1c). 4// No reconstruction yet (B-R3+). license_tier: ORIGINAL 5import "nx_syscalls.nx" 6import "nx_h264_bits.nx" 7import "nx_h264_sps.nx" 8import "nx_h264_pps.nx" 9import "nx_h264_nal.nx" 10import "nx_h264_slice.nx" 11import "nx_h264_mb.nx" 12import "nx_h264_mb_pred.nx" 13import "nx_h264_coeff_token.nx" 14import "nx_h264_cavlc_level.nx" 15import "nx_h264_residual.nx" 16import "nx_h264_nc.nx" 17import "nx_h264_bmb.nx" 18 19func gp(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 } 20func gn(v: i64) -> i64 { 21 let bb: *u8 = sys_mmap(28); var m: i64 = v 22 if m < 0 { sys_write(1, "-\x00" as *u8, 1); m = 0 - m } 23 let t: *u8 = sys_mmap(28); var k: i64 = 0 24 if m == 0 { t[0] = 48 as u8; k = 1 } 25 while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 } 26 var i: i64 = 0 27 while i < k { bb[i] = t[k - 1 - i]; i = i + 1 } 28 sys_write(1, bb, k); return 0 29} 30func dec_luma(br: *BitReader, lumaTC: *i64, lbW: i64, bx: i64, by: i64, maxc: i64, coeff: *i64) -> i64 { 31 var nA: i64 = 0 32 var avA: i64 = 0 33 if bx > 0 { nA = lumaTC[by * lbW + (bx - 1)]; avA = 1 } 34 var nB: i64 = 0 35 var avB: i64 = 0 36 if by > 0 { nB = lumaTC[(by - 1) * lbW + bx]; avB = 1 } 37 let nC: i64 = nx_h264_nc_luma(nA, avA, nB, avB) 38 let tc: i64 = nx_h264_residual_decode(br, maxc, nC, coeff) 39 lumaTC[by * lbW + bx] = tc 40 return tc 41} 42func dec_cac(br: *BitReader, cTC: *i64, cbW: i64, cbx: i64, cby: i64, coeff: *i64) -> i64 { 43 var nA: i64 = 0 44 var avA: i64 = 0 45 if cbx > 0 { nA = cTC[cby * cbW + (cbx - 1)]; avA = 1 } 46 var nB: i64 = 0 47 var avB: i64 = 0 48 if cby > 0 { nB = cTC[(cby - 1) * cbW + cbx]; avB = 1 } 49 let nC: i64 = nx_h264_nc_luma(nA, avA, nB, avB) 50 let tc: i64 = nx_h264_residual_decode(br, 15, nC, coeff) 51 cTC[cby * cbW + cbx] = tc 52 return tc 53} 54func read_ref(br: *BitReader, num_ref: i64) -> i64 { 55 if num_ref == 1 { return 0 } 56 if num_ref == 2 { let bb: i64 = br_read_bit(br); return 1 - bb } 57 return br_read_ue(br) 58} 59 60func main() -> i64 { 61 let szp: *i64 = sys_mmap(16) as *i64 62 let b: *u8 = sys_read_file("knowledge/staging/media/bframe_test.264\x00" as *u8, szp) 63 if (b as i64) == 0 { gp("no bframe_test.264\n\x00" as *u8); return 1 } 64 let len: i64 = szp[0] 65 gp("B-FRAME-WALK (B-R2: B-slice entropy sync)\n\x00" as *u8) 66 let offs: *i64 = sys_mmap(512 * 8) as *i64 67 let types: *i64 = sys_mmap(512 * 8) as *i64 68 let nc: i64 = nx_nal_split_annexb(b, 0, len, offs, types, 512) 69 let sps: *i64 = sys_mmap(128) as *i64 70 let pps: *i64 = sys_mmap(128) as *i64 71 var k: i64 = 0 72 while k < nc { 73 let noff: i64 = offs[k] 74 var nend: i64 = len 75 if k + 1 < nc { nend = offs[k + 1] - 3 } 76 if types[k] == 7 { let dst: *u8 = sys_mmap(nend - noff + 16); let rb: i64 = nx_h264_unescape_rbsp((b as i64 + noff + 1) as *u8, nend - noff - 1, dst); nx_h264_parse_sps(dst, rb, sps) } 77 if types[k] == 8 { let dst: *u8 = sys_mmap(nend - noff + 16); let rb: i64 = nx_h264_unescape_rbsp((b as i64 + noff + 1) as *u8, nend - noff - 1, dst); nx_h264_parse_pps(dst, rb, pps) } 78 k = k + 1 79 } 80 let W: i64 = sps[2] 81 let H: i64 = sps[3] 82 let mbW: i64 = W / 16 83 let mbH: i64 = H / 16 84 let totalMB: i64 = mbW * mbH 85 86 // find first B-slice NAL 87 let sh: *i64 = sys_mmap(64) as *i64 88 var bk: i64 = 0 - 1 89 k = 0 90 while k < nc { 91 let isSlice: i64 = (types[k] == 1) as i64 + (types[k] == 5) as i64 92 if isSlice >= 1 { if bk < 0 { 93 let noff: i64 = offs[k] 94 let hdr: i64 = b[noff] as i64 95 var nend: i64 = len 96 if k + 1 < nc { nend = offs[k + 1] - 3 } 97 let dst: *u8 = sys_mmap(nend - noff + 16) 98 let rb: i64 = nx_h264_unescape_rbsp((b as i64 + noff + 1) as *u8, nend - noff - 1, dst) 99 let br: *BitReader = sys_mmap(NX_BR_BYTES) as *BitReader 100 br_init(br, dst, rb) 101 nx_h264_parse_slice_header_br(br, hdr & 31, (hdr >> 5) & 3, sps[9], sps[11], sps[10], sps[6], pps[3], pps[6], sh) 102 if sh[8] == 1 { bk = k } 103 } } 104 k = k + 1 105 } 106 if bk < 0 { gp("no B-slice\n\x00" as *u8); sys_exit(1); return 1 } 107 108 let noff: i64 = offs[bk] 109 let hdr: i64 = b[noff] as i64 110 var nend: i64 = len 111 if bk + 1 < nc { nend = offs[bk + 1] - 3 } 112 let sl_dst: *u8 = sys_mmap(nend - noff + 16) 113 let sl_rbsp: i64 = nx_h264_unescape_rbsp((b as i64 + noff + 1) as *u8, nend - noff - 1, sl_dst) 114 let sbr: *BitReader = sys_mmap(NX_BR_BYTES) as *BitReader 115 br_init(sbr, sl_dst, sl_rbsp) 116 nx_h264_parse_slice_header_br(sbr, hdr & 31, (hdr >> 5) & 3, sps[9], sps[11], sps[10], sps[6], pps[3], pps[6], sh) 117 let num_ref_l0: i64 = sh[12] + 1 118 let num_ref_l1: i64 = sh[13] + 1 119 gp(" B-slice first_mb=\x00" as *u8); gn(sh[0]); gp(" QP=\x00" as *u8); gn(sh[7]); gp(" num_ref_l0=\x00" as *u8); gn(num_ref_l0); gp(" num_ref_l1=\x00" as *u8); gn(num_ref_l1); gp(" rbsp=\x00" as *u8); gn(sl_rbsp); gp("\n\x00" as *u8) 120 121 let lbW: i64 = mbW * 4 122 let lbH: i64 = mbH * 4 123 let lumaTC: *i64 = sys_mmap(lbW * lbH * 8) as *i64 124 let cbW: i64 = mbW * 2 125 let cbH: i64 = mbH * 2 126 let uTC: *i64 = sys_mmap(cbW * cbH * 8) as *i64 127 let vTC: *i64 = sys_mmap(cbW * cbH * 8) as *i64 128 var z: i64 = 0 129 while z < lbW * lbH { lumaTC[z] = 0; z = z + 1 } 130 z = 0 131 while z < cbW * cbH { uTC[z] = 0; vTC[z] = 0; z = z + 1 } 132 let bx4: *i64 = sys_mmap(16 * 8) as *i64 133 let by4: *i64 = sys_mmap(16 * 8) as *i64 134 bx4[0]=0; by4[0]=0; bx4[1]=1; by4[1]=0; bx4[2]=0; by4[2]=1; bx4[3]=1; by4[3]=1 135 bx4[4]=2; by4[4]=0; bx4[5]=3; by4[5]=0; bx4[6]=2; by4[6]=1; bx4[7]=3; by4[7]=1 136 bx4[8]=0; by4[8]=2; bx4[9]=1; by4[9]=2; bx4[10]=0; by4[10]=3; bx4[11]=1; by4[11]=3 137 bx4[12]=2; by4[12]=2; bx4[13]=3; by4[13]=2; bx4[14]=2; by4[14]=3; bx4[15]=3; by4[15]=3 138 139 let coeff: *i64 = sys_mmap(32 * 8) as *i64 140 let subs: *i64 = sys_mmap(8 * 8) as *i64 141 var qp: i64 = sh[7] 142 var nskip: i64 = 0 143 var ndirect: i64 = 0 144 var ninter: i64 = 0 145 var nintra: i64 = 0 146 var nmvd: i64 = 0 147 var ok: i64 = 1 148 var mbAddr: i64 = 0 149 while mbAddr < totalMB { 150 if ok == 0 { mbAddr = totalMB } else { 151 let skip_run: i64 = br_read_ue(sbr) 152 var s2: i64 = 0 153 while s2 < skip_run { 154 if mbAddr < totalMB { 155 let mbX: i64 = mbAddr % mbW 156 let mbY: i64 = mbAddr / mbW 157 var bl: i64 = 0 158 while bl < 16 { lumaTC[(mbY*4 + by4[bl]) * lbW + (mbX*4 + bx4[bl])] = 0; bl = bl + 1 } 159 var cc: i64 = 0 160 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 } 161 nskip = nskip + 1 162 mbAddr = mbAddr + 1 163 } 164 s2 = s2 + 1 165 } 166 if mbAddr < totalMB { 167 let mbX: i64 = mbAddr % mbW 168 let mbY: i64 = mbAddr / mbW 169 let bx0: i64 = mbX * 4 170 let by0: i64 = mbY * 4 171 let mb_type: i64 = br_read_ue(sbr) 172 let bt: i64 = nx_h264_bmb_kind(mb_type) 173 if bt >= 0 { 174 // ---- INTER B macroblock ---- 175 if nx_h264_bmb_is_direct(bt) == 1 { ndirect = ndirect + 1 } 176 if nx_h264_bmb_is_direct(bt) == 0 { ninter = ninter + 1 } 177 if nx_h264_bmb_is_8x8(bt) == 1 { 178 var si: i64 = 0 179 while si < 4 { subs[si] = br_read_ue(sbr); si = si + 1 } 180 // ref_idx L0 then L1 (per 8x8 sub-MB, if list used & not direct & num_ref>1) 181 if num_ref_l0 > 1 { si = 0; while si < 4 { if nx_h264_bsub_is_direct(subs[si]) == 0 { if nx_h264_mode_uses_l0(nx_h264_bsub_mode(subs[si])) == 1 { read_ref(sbr, num_ref_l0) } } si = si + 1 } } 182 if num_ref_l1 > 1 { si = 0; while si < 4 { if nx_h264_bsub_is_direct(subs[si]) == 0 { if nx_h264_mode_uses_l1(nx_h264_bsub_mode(subs[si])) == 1 { read_ref(sbr, num_ref_l1) } } si = si + 1 } } 183 // mvd L0 then L1 (per sub-partition) 184 si = 0 185 while si < 4 { 186 if nx_h264_bsub_is_direct(subs[si]) == 0 { if nx_h264_mode_uses_l0(nx_h264_bsub_mode(subs[si])) == 1 { 187 var sp: i64 = 0 188 let np: i64 = nx_h264_bsub_nparts(subs[si]) 189 while sp < np { br_read_se(sbr); br_read_se(sbr); nmvd = nmvd + 1; sp = sp + 1 } 190 } } 191 si = si + 1 192 } 193 si = 0 194 while si < 4 { 195 if nx_h264_bsub_is_direct(subs[si]) == 0 { if nx_h264_mode_uses_l1(nx_h264_bsub_mode(subs[si])) == 1 { 196 var sp: i64 = 0 197 let np: i64 = nx_h264_bsub_nparts(subs[si]) 198 while sp < np { br_read_se(sbr); br_read_se(sbr); nmvd = nmvd + 1; sp = sp + 1 } 199 } } 200 si = si + 1 201 } 202 } 203 if nx_h264_bmb_is_8x8(bt) == 0 { if nx_h264_bmb_is_direct(bt) == 0 { 204 let np: i64 = nx_h264_bmb_nparts(bt) 205 // ref_idx L0 206 if num_ref_l0 > 1 { var p: i64 = 0; while p < np { if nx_h264_mode_uses_l0(nx_h264_bmb_partmode(bt, p)) == 1 { read_ref(sbr, num_ref_l0) } p = p + 1 } } 207 if num_ref_l1 > 1 { var p: i64 = 0; while p < np { if nx_h264_mode_uses_l1(nx_h264_bmb_partmode(bt, p)) == 1 { read_ref(sbr, num_ref_l1) } p = p + 1 } } 208 // mvd L0 then L1 209 var p: i64 = 0 210 while p < np { if nx_h264_mode_uses_l0(nx_h264_bmb_partmode(bt, p)) == 1 { br_read_se(sbr); br_read_se(sbr); nmvd = nmvd + 1 } p = p + 1 } 211 p = 0 212 while p < np { if nx_h264_mode_uses_l1(nx_h264_bmb_partmode(bt, p)) == 1 { br_read_se(sbr); br_read_se(sbr); nmvd = nmvd + 1 } p = p + 1 } 213 } } 214 // CBP (inter) + residual 215 let cbp: i64 = nx_h264_decode_cbp_inter(sbr) 216 let cbpL: i64 = cbp & 15 217 let cbpC: i64 = (cbp >> 4) & 3 218 if cbp != 0 { let mqd: i64 = br_read_se(sbr); qp = (qp + mqd + 52) % 52 } 219 var bl: i64 = 0 220 while bl < 16 { 221 let abx: i64 = bx0 + bx4[bl] 222 let aby: i64 = by0 + by4[bl] 223 let i8: i64 = bl / 4 224 if ((cbpL >> i8) & 1) != 0 { dec_luma(sbr, lumaTC, lbW, abx, aby, 16, coeff) } 225 if ((cbpL >> i8) & 1) == 0 { lumaTC[aby * lbW + abx] = 0 } 226 bl = bl + 1 227 } 228 if cbpC != 0 { 229 let ucdc: *i64 = sys_mmap(8 * 8) as *i64 230 nx_h264_residual_decode_cdc(sbr, ucdc) 231 let vcdc: *i64 = sys_mmap(8 * 8) as *i64 232 nx_h264_residual_decode_cdc(sbr, vcdc) 233 if cbpC == 2 { 234 var cc: i64 = 0 235 while cc < 4 { dec_cac(sbr, uTC, cbW, mbX*2 + (cc%2), mbY*2 + (cc/2), coeff); cc = cc + 1 } 236 cc = 0 237 while cc < 4 { dec_cac(sbr, vTC, cbW, mbX*2 + (cc%2), mbY*2 + (cc/2), coeff); cc = cc + 1 } 238 } 239 } 240 if cbpC == 0 { 241 var cc: i64 = 0 242 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 } 243 } 244 } 245 if bt < 0 { 246 // ---- INTRA in B (mb_type-23) ---- 247 nintra = nintra + 1 248 let it: i64 = mb_type - 23 249 let cls: i64 = nx_h264_mb_type_class(it) 250 if cls == 1 { 251 let der: *i64 = sys_mmap(32) as *i64 252 nx_h264_i16x16_derive(it, der) 253 let cbpL: i64 = der[2] 254 let cbpC: i64 = der[1] 255 br_read_ue(sbr) 256 let mqd: i64 = br_read_se(sbr); qp = (qp + mqd + 52) % 52 257 var nA: i64 = 0 258 var avA: i64 = 0 259 if bx0 > 0 { nA = lumaTC[by0 * lbW + (bx0 - 1)]; avA = 1 } 260 var nB: i64 = 0 261 var avB: i64 = 0 262 if by0 > 0 { nB = lumaTC[(by0 - 1) * lbW + bx0]; avB = 1 } 263 let nCdc: i64 = nx_h264_nc_luma(nA, avA, nB, avB) 264 nx_h264_residual_decode(sbr, 16, nCdc, coeff) 265 var bl: i64 = 0 266 while bl < 16 { 267 let abx: i64 = bx0 + bx4[bl] 268 let aby: i64 = by0 + by4[bl] 269 if cbpL != 0 { dec_luma(sbr, lumaTC, lbW, abx, aby, 15, coeff) } 270 if cbpL == 0 { lumaTC[aby * lbW + abx] = 0 } 271 bl = bl + 1 272 } 273 if cbpC != 0 { 274 let u2: *i64 = sys_mmap(8*8) as *i64 275 nx_h264_residual_decode_cdc(sbr, u2) 276 let v2: *i64 = sys_mmap(8*8) as *i64 277 nx_h264_residual_decode_cdc(sbr, v2) 278 if cbpC == 2 { 279 var cc: i64 = 0 280 while cc < 4 { dec_cac(sbr, uTC, cbW, mbX*2 + (cc%2), mbY*2 + (cc/2), coeff); cc = cc + 1 } 281 cc = 0 282 while cc < 4 { dec_cac(sbr, vTC, cbW, mbX*2 + (cc%2), mbY*2 + (cc/2), coeff); cc = cc + 1 } 283 } 284 } 285 } 286 if cls == 0 { 287 let modes: *i64 = sys_mmap(24 * 8) as *i64 288 nx_h264_parse_inxn_predmodes(sbr, modes) 289 let cbp: i64 = nx_h264_decode_cbp_intra(sbr) 290 let cbpL: i64 = cbp & 15 291 let cbpC: i64 = (cbp >> 4) & 3 292 if cbp != 0 { let mqd: i64 = br_read_se(sbr); qp = (qp + mqd + 52) % 52 } 293 var bl: i64 = 0 294 while bl < 16 { 295 let abx: i64 = bx0 + bx4[bl] 296 let aby: i64 = by0 + by4[bl] 297 let i8: i64 = bl / 4 298 if ((cbpL >> i8) & 1) != 0 { dec_luma(sbr, lumaTC, lbW, abx, aby, 16, coeff) } 299 if ((cbpL >> i8) & 1) == 0 { lumaTC[aby * lbW + abx] = 0 } 300 bl = bl + 1 301 } 302 if cbpC != 0 { 303 let u3: *i64 = sys_mmap(8*8) as *i64 304 nx_h264_residual_decode_cdc(sbr, u3) 305 let v3: *i64 = sys_mmap(8*8) as *i64 306 nx_h264_residual_decode_cdc(sbr, v3) 307 if cbpC == 2 { 308 var cc: i64 = 0 309 while cc < 4 { dec_cac(sbr, uTC, cbW, mbX*2 + (cc%2), mbY*2 + (cc/2), coeff); cc = cc + 1 } 310 cc = 0 311 while cc < 4 { dec_cac(sbr, vTC, cbW, mbX*2 + (cc%2), mbY*2 + (cc/2), coeff); cc = cc + 1 } 312 } 313 } 314 } 315 if cls == 2 { 316 br_align(sbr) 317 var pp: i64 = 0 318 while pp < 384 { br_read_bits(sbr, 8); pp = pp + 1 } 319 } 320 if cls < 0 { ok = 0; gp(" DESYNC bad intra mb_type\n\x00" as *u8) } 321 } 322 mbAddr = mbAddr + 1 323 } 324 } 325 } 326 327 gp(" parsed MBs=\x00" as *u8); gn(mbAddr); gp("/\x00" as *u8); gn(totalMB) 328 gp(" (skip=\x00" as *u8); gn(nskip); gp(" direct=\x00" as *u8); gn(ndirect); gp(" inter=\x00" as *u8); gn(ninter); gp(" intra=\x00" as *u8); gn(nintra); gp(" mvd=\x00" as *u8); gn(nmvd); gp(")\n\x00" as *u8) 329 gp(" reader byte=\x00" as *u8); gn(sbr.byte_pos); gp("/\x00" as *u8); gn(sl_rbsp); gp(" bit=\x00" as *u8); gn(sbr.bit_pos); gp("\n\x00" as *u8) 330 if ok == 1 { if mbAddr == totalMB { if sbr.byte_pos >= sl_rbsp - 2 { 331 gp(" *** B-FRAME ENTROPY SYNC: all MBs parsed, reader at rbsp end -> B-R2 GREEN ***\n\x00" as *u8) 332 sys_exit(0) 333 return 0 334 } } } 335 gp("B-FRAME-WALK result=FAIL verdict=RED (desync)\n\x00" as *u8) 336 sys_exit(1) 337 return 1 338}