code wiki / _hdl_build / nx_h264_iframe.nx

nx_h264_iframe.nx source

↩ module page · 496 lines · 20764 B

1// nx_h264_iframe.nx -- reusable CAVLC I-slice -> YUV420 decode driver (STEP 3 core for the cam poster). 2// Lifts the proven full-frame reconstruction from nx_h264_decode_frame.nx into a callable function that 3// takes an already-extracted, de-emulated IDR slice RBSP + parsed SPS/PPS + output planes, decodes every 4// macroblock (I_4x4 / I_16x16 / I_PCM), and reconstructs Y/U/V. Two engineering fixes vs the original main: 5// (1) uses CODED MB dims (mbW=sps[4]+1, mbH=sps[5]+1) so non-16-aligned crops (e.g. 1080) decode fully; 6// (2) HOISTS all per-call scratch out of the recon kernels (the toolchain's sys_mmap has no munmap; a 7// per-MB mmap would exhaust the kernel map_count on a full-HD frame) -> bounded, constant map count. 8// Deblocking is intentionally omitted here (a downscaled poster averages block edges away); add for full res. 9// LIB (no main). license_tier: ORIGINAL genealogy_id: itu_t_h264_islice_cavlc_recon (lifted from decode_frame) 10import "nx_syscalls.nx" 11import "nx_h264_bits.nx" 12import "nx_h264_slice.nx" 13import "nx_h264_mb.nx" 14import "nx_h264_mb_pred.nx" 15import "nx_h264_coeff_token.nx" 16import "nx_h264_cavlc_level.nx" 17import "nx_h264_residual.nx" 18import "nx_h264_nc.nx" 19import "nx_h264_zigzag.nx" 20import "nx_h264_hadamard.nx" 21import "nx_h264_dequant.nx" 22import "nx_h264_idct.nx" 23import "nx_h264_intra16.nx" 24import "nx_h264_intra.nx" 25import "nx_h264_chroma_pred.nx" 26import "nx_h264_chroma.nx" 27 28// shared recon scratch layout (i64 offsets into one buffer; recon calls are strictly sequential) 29const SC_PRED: i64 = 0 // 256 (i16 pred) / 64 (chroma) 30const SC_TOP: i64 = 256 // up to 16 31const SC_LEFT: i64 = 288 // up to 16 32const SC_SCAN: i64 = 320 // 16 33const SC_RAST: i64 = 336 // 16 34const SC_DQ: i64 = 352 // 16 35const SC_DCY: i64 = 368 // 16 (I16 luma DC scaled) 36const SC_NA: i64 = 384 // 6 37const SC_CC: i64 = 392 // 4 38const SC_DCC: i64 = 400 // 4 39const SC_IDCT: i64 = 408 // 16 words: nx_idct4x4 scratch, hoisted 2026-08-01 (SC_WORDS=512, so 408+16 fits) 40const SC_WORDS: i64 = 512 41 42func scp(sc: *i64, off: i64) -> *i64 { return ((sc as i64) + off * 8) as *i64 } 43 44// decode one luma 4x4 residual block (nC neighbour context). bx,by absolute 4x4 coords. 45func dec_luma(br: *BitReader, lumaTC: *i64, lbW: i64, bx: i64, by: i64, maxc: i64, coeff: *i64) -> i64 { 46 var nA: i64 = 0 47 var avA: i64 = 0 48 if bx > 0 { nA = lumaTC[by * lbW + (bx - 1)]; avA = 1 } 49 var nB: i64 = 0 50 var avB: i64 = 0 51 if by > 0 { nB = lumaTC[(by - 1) * lbW + bx]; avB = 1 } 52 let nC: i64 = nx_h264_nc_luma(nA, avA, nB, avB) 53 let tc: i64 = nx_h264_residual_decode(br, maxc, nC, coeff) 54 lumaTC[by * lbW + bx] = tc 55 return tc 56} 57 58func dec_chroma_ac(br: *BitReader, cTC: *i64, cbW: i64, cbx: i64, cby: i64, coeff: *i64) -> i64 { 59 var nA: i64 = 0 60 var avA: i64 = 0 61 if cbx > 0 { nA = cTC[cby * cbW + (cbx - 1)]; avA = 1 } 62 var nB: i64 = 0 63 var avB: i64 = 0 64 if cby > 0 { nB = cTC[(cby - 1) * cbW + cbx]; avB = 1 } 65 let nC: i64 = nx_h264_nc_luma(nA, avA, nB, avB) 66 let tc: i64 = nx_h264_residual_decode(br, 15, nC, coeff) 67 cTC[cby * cbW + cbx] = tc 68 return tc 69} 70 71func chroma_qpc(qpL: i64, cqo: i64) -> i64 { 72 var q: i64 = qpL + cqo 73 if q < 0 { q = 0 } 74 if q > 51 { q = 51 } 75 return nx_h264_chroma_qp(q) 76} 77 78// I_16x16 luma DC -> scaled dcY[16] written into sc[SC_DCY..]. 79func i16_dc_scale_h(dcblk: *i64, qp: i64, sc: *i64) -> i64 { 80 let dcras: *i64 = scp(sc, SC_SCAN) 81 nx_h264_inv_zigzag4x4(dcblk, dcras) 82 nx_h264_hadamard4x4(dcras) 83 let na: *i64 = scp(sc, SC_NA) 84 na[0]=10; na[1]=11; na[2]=13; na[3]=14; na[4]=16; na[5]=18 85 let dcY: *i64 = scp(sc, SC_DCY) 86 let ls: i64 = 16 * na[qp % 6] 87 let sh6: i64 = qp / 6 88 var qi: i64 = 0 89 while qi < 16 { 90 var v: i64 = 0 91 if qp >= 36 { v = (dcras[qi] * ls) << (sh6 - 6) } 92 if qp < 36 { v = asr(dcras[qi] * ls + (1 << (5 - sh6)), 6 - sh6) } 93 dcY[qi] = v 94 qi = qi + 1 95 } 96 return 0 97} 98 99func recon_i16_luma_h(yf: *u8, W: i64, px: i64, py: i64, predMode: i64, sc: *i64, acstore: *i64, qp: i64) -> i64 { 100 var aT: i64 = 0 101 if py > 0 { aT = 1 } 102 var aL: i64 = 0 103 if px > 0 { aL = 1 } 104 let top: *i64 = scp(sc, SC_TOP) 105 let left: *i64 = scp(sc, SC_LEFT) 106 var k: i64 = 0 107 while k < 16 { 108 var tv: i64 = 0 109 if aT == 1 { tv = yf[(py-1)*W + px + k] as i64 } 110 top[k] = tv 111 var lv: i64 = 0 112 if aL == 1 { lv = yf[(py+k)*W + px - 1] as i64 } 113 left[k] = lv 114 k = k + 1 115 } 116 var tl: i64 = 0 117 if aT == 1 { if aL == 1 { tl = yf[(py-1)*W + px - 1] as i64 } } 118 let pred: *i64 = scp(sc, SC_PRED) 119 nx_intra16x16_pred_full(predMode, top, left, tl, aT, aL, pred) 120 let scan: *i64 = scp(sc, SC_SCAN) 121 let dq: *i64 = scp(sc, SC_DQ) 122 let dcY: *i64 = scp(sc, SC_DCY) 123 let rast: *i64 = scp(sc, SC_RAST) 124 var br: i64 = 0 125 while br < 4 { 126 var bc: i64 = 0 127 while bc < 4 { 128 let r: i64 = br * 4 + bc 129 var z: i64 = 0 130 while z < 16 { scan[z] = acstore[r*16 + z]; z = z + 1 } 131 nx_h264_inv_zigzag4x4(scan, rast) 132 nx_h264_dequant4x4(rast, qp, dq) 133 dq[0] = dcY[r] 134 nx_idct4x4_s(dq, scp(sc, SC_IDCT)) 135 var py4: i64 = 0 136 while py4 < 4 { 137 var px4: i64 = 0 138 while px4 < 4 { 139 var val: i64 = pred[(br*4 + py4)*16 + (bc*4 + px4)] + dq[py4*4 + px4] 140 if val < 0 { val = 0 } 141 if val > 255 { val = 255 } 142 yf[(py + br*4 + py4)*W + (px + bc*4 + px4)] = val as u8 143 px4 = px4 + 1 144 } 145 py4 = py4 + 1 146 } 147 bc = bc + 1 148 } 149 br = br + 1 150 } 151 return 0 152} 153 154func recon_i4_block_h(yf: *u8, W: i64, bpx: i64, bpy: i64, mode: i64, aT: i64, aL: i64, aTL: i64, aTR: i64, coeffscan: *i64, qp: i64, sc: *i64) -> i64 { 155 let top: *i64 = scp(sc, SC_TOP) 156 let left: *i64 = scp(sc, SC_LEFT) 157 var k: i64 = 0 158 while k < 4 { 159 var tv: i64 = 0 160 if aT == 1 { tv = yf[(bpy-1)*W + bpx + k] as i64 } 161 top[k] = tv 162 var lv: i64 = 0 163 if aL == 1 { lv = yf[(bpy+k)*W + bpx - 1] as i64 } 164 left[k] = lv 165 k = k + 1 166 } 167 k = 0 168 while k < 4 { 169 var tv: i64 = top[3] 170 if aTR == 1 { tv = yf[(bpy-1)*W + bpx + 4 + k] as i64 } 171 if aT == 0 { tv = 0 } 172 top[4 + k] = tv 173 k = k + 1 174 } 175 var tl: i64 = 0 176 if aTL == 1 { tl = yf[(bpy-1)*W + bpx - 1] as i64 } 177 let pred: *i64 = scp(sc, SC_PRED) 178 nx_intra4x4_pred_full(mode, top, left, tl, aT, aL, pred) 179 let rast: *i64 = scp(sc, SC_RAST) 180 nx_h264_inv_zigzag4x4(coeffscan, rast) 181 let dq: *i64 = scp(sc, SC_DQ) 182 nx_h264_dequant4x4(rast, qp, dq) 183 nx_idct4x4(dq) 184 var yy: i64 = 0 185 while yy < 4 { 186 var xx: i64 = 0 187 while xx < 4 { 188 var val: i64 = pred[yy*4 + xx] + dq[yy*4 + xx] 189 if val < 0 { val = 0 } 190 if val > 255 { val = 255 } 191 yf[(bpy + yy)*W + (bpx + xx)] = val as u8 192 xx = xx + 1 193 } 194 yy = yy + 1 195 } 196 return 0 197} 198 199func recon_chroma_comp_h(cf: *u8, cW: i64, cpx: i64, cpy: i64, predMode: i64, cdc: *i64, acstore: *i64, qpc: i64, availT: i64, availL: i64, sc: *i64) -> i64 { 200 let top: *i64 = scp(sc, SC_TOP) 201 let left: *i64 = scp(sc, SC_LEFT) 202 var k: i64 = 0 203 while k < 8 { 204 var tv: i64 = 0 205 if availT == 1 { tv = cf[(cpy-1)*cW + cpx + k] as i64 } 206 top[k] = tv 207 var lv: i64 = 0 208 if availL == 1 { lv = cf[(cpy+k)*cW + cpx - 1] as i64 } 209 left[k] = lv 210 k = k + 1 211 } 212 var tl: i64 = 0 213 if availT == 1 { if availL == 1 { tl = cf[(cpy-1)*cW + cpx - 1] as i64 } } 214 let pred: *i64 = scp(sc, SC_PRED) 215 nx_intra_chroma_pred(predMode, top, left, tl, availT, availL, pred) 216 let cc: *i64 = scp(sc, SC_CC) 217 var di: i64 = 0 218 while di < 4 { cc[di] = cdc[di]; di = di + 1 } 219 let dcC: *i64 = scp(sc, SC_DCC) 220 nx_h264_chroma_dc_scale(cc, qpc, dcC) 221 let scan: *i64 = scp(sc, SC_SCAN) 222 let rast: *i64 = scp(sc, SC_RAST) 223 let dq: *i64 = scp(sc, SC_DQ) 224 var by: i64 = 0 225 while by < 2 { 226 var bx: i64 = 0 227 while bx < 2 { 228 let blk: i64 = by*2 + bx 229 var z: i64 = 0 230 while z < 16 { scan[z] = acstore[blk*16 + z]; z = z + 1 } 231 nx_h264_inv_zigzag4x4(scan, rast) 232 nx_h264_dequant4x4(rast, qpc, dq) 233 dq[0] = dcC[blk] 234 nx_idct4x4_s(dq, scp(sc, SC_IDCT)) 235 var yy: i64 = 0 236 while yy < 4 { 237 var xx: i64 = 0 238 while xx < 4 { 239 var val: i64 = pred[(by*4+yy)*8 + (bx*4+xx)] + dq[yy*4 + xx] 240 if val < 0 { val = 0 } 241 if val > 255 { val = 255 } 242 cf[(cpy + by*4 + yy)*cW + (cpx + bx*4 + xx)] = val as u8 243 xx = xx + 1 244 } 245 yy = yy + 1 246 } 247 bx = bx + 1 248 } 249 by = by + 1 250 } 251 return 0 252} 253 254// Decode a single CAVLC I-slice (all MBs) into yf/uf/vf. Caller: mbW=sps[4]+1, mbH=sps[5]+1 (coded); 255// yf sized (mbW*16)*(mbH*16), uf/vf sized (mbW*8)*(mbH*8); planes pre-zeroed by caller. 256// Returns 1 iff all MBs parsed and the reader landed at the rbsp end; else 0 (desync / partial). 257func nx_h264_decode_iframe(sl_dst: *u8, sl_rbsp: i64, ntype: i64, sps: *i64, pps: *i64, yf: *u8, uf: *u8, vf: *u8, mbW: i64, mbH: i64) -> i64 { 258 let W: i64 = mbW * 16 259 let cpW: i64 = mbW * 8 260 let lbW: i64 = mbW * 4 261 let lbH: i64 = mbH * 4 262 let cbW: i64 = mbW * 2 263 let cbH: i64 = mbH * 2 264 let sbr: *BitReader = sys_mmap(NX_BR_BYTES) as *BitReader 265 br_init(sbr, sl_dst, sl_rbsp) 266 let sh: *i64 = sys_mmap(64) as *i64 267 nx_h264_parse_slice_header_br(sbr, ntype & 31, (ntype >> 5) & 3, sps[9], sps[11], sps[10], sps[6], pps[3], pps[6], sh) 268 var qp: i64 = sh[7] 269 270 // hoisted state (allocate ONCE) 271 let sc: *i64 = sys_mmap(SC_WORDS * 8) as *i64 272 let lumaTC: *i64 = sys_mmap(lbW * lbH * 8) as *i64 273 let i4m: *i64 = sys_mmap(lbW * lbH * 8) as *i64 274 let decoded: *i64 = sys_mmap(lbW * lbH * 8) as *i64 275 let uTC: *i64 = sys_mmap(cbW * cbH * 8) as *i64 276 let vTC: *i64 = sys_mmap(cbW * cbH * 8) as *i64 277 var z: i64 = 0 278 while z < lbW * lbH { lumaTC[z] = 0; i4m[z] = 2; decoded[z] = 0; z = z + 1 } 279 z = 0 280 while z < cbW * cbH { uTC[z] = 0; vTC[z] = 0; z = z + 1 } 281 let acstore: *i64 = sys_mmap(16 * 16 * 8) as *i64 282 let ucstore: *i64 = sys_mmap(4 * 16 * 8) as *i64 283 let vcstore: *i64 = sys_mmap(4 * 16 * 8) as *i64 284 let coeff: *i64 = sys_mmap(32 * 8) as *i64 285 let der: *i64 = sys_mmap(32 * 8) as *i64 286 let dcblk: *i64 = sys_mmap(16 * 8) as *i64 287 let ucdc: *i64 = sys_mmap(8 * 8) as *i64 288 let vcdc: *i64 = sys_mmap(8 * 8) as *i64 289 let modes: *i64 = sys_mmap(24 * 8) as *i64 290 let bx4: *i64 = sys_mmap(16 * 8) as *i64 291 let by4: *i64 = sys_mmap(16 * 8) as *i64 292 bx4[0]=0; by4[0]=0; bx4[1]=1; by4[1]=0; bx4[2]=0; by4[2]=1; bx4[3]=1; by4[3]=1 293 bx4[4]=2; by4[4]=0; bx4[5]=3; by4[5]=0; bx4[6]=2; by4[6]=1; bx4[7]=3; by4[7]=1 294 bx4[8]=0; by4[8]=2; bx4[9]=1; by4[9]=2; bx4[10]=0; by4[10]=3; bx4[11]=1; by4[11]=3 295 bx4[12]=2; by4[12]=2; bx4[13]=3; by4[13]=2; bx4[14]=2; by4[14]=3; bx4[15]=3; by4[15]=3 296 297 var ok: i64 = 1 298 var mbAddr: i64 = 0 299 let totalMB: i64 = mbW * mbH 300 while mbAddr < totalMB { 301 let mbX: i64 = mbAddr % mbW 302 let mbY: i64 = mbAddr / mbW 303 let mb_type: i64 = nx_h264_mb_parse_itype(sbr) 304 if mb_type < 0 { ok = 0; mbAddr = totalMB } 305 if ok == 1 { if mb_type > 25 { ok = 0; mbAddr = totalMB } } 306 if ok == 1 { 307 let cls: i64 = nx_h264_mb_type_class(mb_type) 308 309 if cls == 2 { 310 // I_PCM: byte-align, consume 384 raw samples (pixels not reconstructed -> rare), neighbours=16 311 br_align(sbr) 312 var pp: i64 = 0 313 while pp < 384 { br_read_bits(sbr, 8); pp = pp + 1 } 314 var bl: i64 = 0 315 while bl < 16 { lumaTC[(mbY*4 + by4[bl]) * lbW + (mbX*4 + bx4[bl])] = 16; bl = bl + 1 } 316 var cc: i64 = 0 317 while cc < 4 { 318 uTC[(mbY*2 + cc/2) * cbW + (mbX*2 + cc%2)] = 16 319 vTC[(mbY*2 + cc/2) * cbW + (mbX*2 + cc%2)] = 16 320 cc = cc + 1 321 } 322 } 323 324 if cls == 1 { 325 nx_h264_i16x16_derive(mb_type, der) 326 let cbpL: i64 = der[2] 327 let cbpC: i64 = der[1] 328 let chroma_pred: i64 = br_read_ue(sbr) 329 let mqd: i64 = br_read_se(sbr) 330 qp = (qp + mqd + 52) % 52 331 let bx0: i64 = mbX * 4 332 let by0: i64 = mbY * 4 333 var nA: i64 = 0 334 var avA: i64 = 0 335 if bx0 > 0 { nA = lumaTC[by0 * lbW + (bx0 - 1)]; avA = 1 } 336 var nB: i64 = 0 337 var avB: i64 = 0 338 if by0 > 0 { nB = lumaTC[(by0 - 1) * lbW + bx0]; avB = 1 } 339 let nCdc: i64 = nx_h264_nc_luma(nA, avA, nB, avB) 340 nx_h264_residual_decode(sbr, 16, nCdc, dcblk) 341 z = 0 342 while z < 256 { acstore[z] = 0; z = z + 1 } 343 var bl: i64 = 0 344 while bl < 16 { 345 let abx: i64 = bx0 + bx4[bl] 346 let aby: i64 = by0 + by4[bl] 347 let r: i64 = by4[bl] * 4 + bx4[bl] 348 i4m[aby * lbW + abx] = 2 349 if cbpL != 0 { 350 dec_luma(sbr, lumaTC, lbW, abx, aby, 15, coeff) 351 z = 0 352 while z < 15 { acstore[r*16 + 1 + z] = coeff[z]; z = z + 1 } 353 } 354 if cbpL == 0 { lumaTC[aby * lbW + abx] = 0 } 355 decoded[aby * lbW + abx] = 1 356 bl = bl + 1 357 } 358 i16_dc_scale_h(dcblk, qp, sc) 359 recon_i16_luma_h(yf, W, mbX * 16, mbY * 16, der[0], sc, acstore, qp) 360 z = 0 361 while z < 4 { ucdc[z] = 0; vcdc[z] = 0; z = z + 1 } 362 z = 0 363 while z < 64 { ucstore[z] = 0; vcstore[z] = 0; z = z + 1 } 364 if cbpC != 0 { 365 nx_h264_residual_decode_cdc(sbr, ucdc) 366 nx_h264_residual_decode_cdc(sbr, vcdc) 367 if cbpC == 2 { 368 var cc: i64 = 0 369 while cc < 4 { 370 dec_chroma_ac(sbr, uTC, cbW, mbX*2 + (cc%2), mbY*2 + (cc/2), coeff) 371 z = 0 372 while z < 15 { ucstore[cc*16 + 1 + z] = coeff[z]; z = z + 1 } 373 cc = cc + 1 374 } 375 cc = 0 376 while cc < 4 { 377 dec_chroma_ac(sbr, vTC, cbW, mbX*2 + (cc%2), mbY*2 + (cc/2), coeff) 378 z = 0 379 while z < 15 { vcstore[cc*16 + 1 + z] = coeff[z]; z = z + 1 } 380 cc = cc + 1 381 } 382 } 383 } 384 if cbpC == 0 { 385 var cc: i64 = 0 386 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 } 387 } 388 var qpi16: i64 = qp + pps[9] 389 if qpi16 < 0 { qpi16 = 0 } 390 if qpi16 > 51 { qpi16 = 51 } 391 let qpc16: i64 = nx_h264_chroma_qp(qpi16) 392 var caT16: i64 = 0 393 if mbY > 0 { caT16 = 1 } 394 var caL16: i64 = 0 395 if mbX > 0 { caL16 = 1 } 396 recon_chroma_comp_h(uf, cpW, mbX*8, mbY*8, chroma_pred, ucdc, ucstore, qpc16, caT16, caL16, sc) 397 recon_chroma_comp_h(vf, cpW, mbX*8, mbY*8, chroma_pred, vcdc, vcstore, qpc16, caT16, caL16, sc) 398 } 399 400 if cls == 0 { 401 nx_h264_parse_inxn_predmodes(sbr, modes) 402 let cbp: i64 = nx_h264_decode_cbp_intra(sbr) 403 let cbpL: i64 = cbp & 15 404 let cbpC: i64 = (cbp >> 4) & 3 405 if cbp != 0 { let mqd: i64 = br_read_se(sbr); qp = (qp + mqd + 52) % 52 } 406 let bx0: i64 = mbX * 4 407 let by0: i64 = mbY * 4 408 var bl: i64 = 0 409 while bl < 16 { 410 let abx: i64 = bx0 + bx4[bl] 411 let aby: i64 = by0 + by4[bl] 412 let bpx: i64 = mbX * 16 + bx4[bl] * 4 413 let bpy: i64 = mbY * 16 + by4[bl] * 4 414 var avAm: i64 = 0 415 if abx > 0 { if decoded[aby*lbW + abx - 1] == 1 { avAm = 1 } } 416 var avBm: i64 = 0 417 if aby > 0 { if decoded[(aby-1)*lbW + abx] == 1 { avBm = 1 } } 418 var predMode: i64 = 2 419 if avAm == 1 { if avBm == 1 { 420 let ma: i64 = i4m[aby*lbW + abx - 1] 421 let mbb: i64 = i4m[(aby-1)*lbW + abx] 422 predMode = ma 423 if mbb < ma { predMode = mbb } 424 } } 425 var mode: i64 = predMode 426 if modes[bl] >= 0 { 427 let rem: i64 = modes[bl] 428 if rem < predMode { mode = rem } 429 if rem >= predMode { mode = rem + 1 } 430 } 431 i4m[aby*lbW + abx] = mode 432 let i8: i64 = bl / 4 433 z = 0 434 while z < 16 { coeff[z] = 0; z = z + 1 } 435 if ((cbpL >> i8) & 1) != 0 { 436 dec_luma(sbr, lumaTC, lbW, abx, aby, 16, coeff) 437 } 438 if ((cbpL >> i8) & 1) == 0 { lumaTC[aby*lbW + abx] = 0 } 439 var aT: i64 = 0 440 if avBm == 1 { aT = 1 } 441 var aL: i64 = 0 442 if avAm == 1 { aL = 1 } 443 var aTL: i64 = 0 444 if abx > 0 { if aby > 0 { if decoded[(aby-1)*lbW + abx - 1] == 1 { aTL = 1 } } } 445 var aTR: i64 = 0 446 if aby > 0 { if abx + 1 < lbW { if decoded[(aby-1)*lbW + abx + 1] == 1 { aTR = 1 } } } 447 recon_i4_block_h(yf, W, bpx, bpy, mode, aT, aL, aTL, aTR, coeff, qp, sc) 448 decoded[aby*lbW + abx] = 1 449 bl = bl + 1 450 } 451 z = 0 452 while z < 4 { ucdc[z] = 0; vcdc[z] = 0; z = z + 1 } 453 z = 0 454 while z < 64 { ucstore[z] = 0; vcstore[z] = 0; z = z + 1 } 455 if cbpC != 0 { 456 nx_h264_residual_decode_cdc(sbr, ucdc) 457 nx_h264_residual_decode_cdc(sbr, vcdc) 458 if cbpC == 2 { 459 var cc: i64 = 0 460 while cc < 4 { 461 dec_chroma_ac(sbr, uTC, cbW, mbX*2 + (cc%2), mbY*2 + (cc/2), coeff) 462 z = 0 463 while z < 15 { ucstore[cc*16 + 1 + z] = coeff[z]; z = z + 1 } 464 cc = cc + 1 465 } 466 cc = 0 467 while cc < 4 { 468 dec_chroma_ac(sbr, vTC, cbW, mbX*2 + (cc%2), mbY*2 + (cc/2), coeff) 469 z = 0 470 while z < 15 { vcstore[cc*16 + 1 + z] = coeff[z]; z = z + 1 } 471 cc = cc + 1 472 } 473 } 474 } 475 if cbpC == 0 { 476 var cc: i64 = 0 477 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 } 478 } 479 var qpi4: i64 = qp + pps[9] 480 if qpi4 < 0 { qpi4 = 0 } 481 if qpi4 > 51 { qpi4 = 51 } 482 let qpc4: i64 = nx_h264_chroma_qp(qpi4) 483 var caT4: i64 = 0 484 if mbY > 0 { caT4 = 1 } 485 var caL4: i64 = 0 486 if mbX > 0 { caL4 = 1 } 487 recon_chroma_comp_h(uf, cpW, mbX*8, mbY*8, modes[16], ucdc, ucstore, qpc4, caT4, caL4, sc) 488 recon_chroma_comp_h(vf, cpW, mbX*8, mbY*8, modes[16], vcdc, vcstore, qpc4, caT4, caL4, sc) 489 } 490 491 mbAddr = mbAddr + 1 492 } 493 } 494 if ok == 1 { if mbAddr == totalMB { if sbr.byte_pos >= sl_rbsp - 2 { return 1 } } } 495 return 0 496}