code wiki / (root) / nx_hevc_dec.nx

nx_hevc_dec.nx source

↩ module page · 602 lines · 67201 B

1// nx_hevc_dec.nx -- SOVEREIGN HEVC decoder (combined), RUNG 3b-2: CABAC running on the real slice. 2// Integrates R1 parse + R2 CABAC + R3a headers + R3b-1 contexts: full PPS + full slice_segment_header -> 3// byte-aligned CABAC start + SliceQpY, init engine+contexts, then decode the first CTB's sao() + the first 4// split_cu_flag of the coding_quadtree. This is the entry point the CU/TU/residual rungs (R3b-3..5) extend. 5// No third party. Usage: nx_hevc_dec <in.mkv> license_tier: ORIGINAL 6import "nx_syscalls.nx" 7const K_MAGIC_32768: i64 = 32768 8const K_MAGIC_32767: i64 = 32767 9const K_MAGIC_8388608: i64 = 8388608 10const K_MAGIC_8192: i64 = 8192 11const K_MAGIC_1024: i64 = 1024 12const K_MAGIC_99999: i64 = 99999 13 14func pe(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} return sys_write(1,s,n) } 15func pn(v: i64) -> i64 { var m: i64=v; if m<0{m=0-m} let b: *u8=sys_mmap(32); var i: i64=32; if m==0{i=i-1;b[i]=(48 as u8)} while m>0{let q: i64=m/10; i=i-1; b[i]=((48+(m-q*10)) as u8); m=q} if v<0{i=i-1;b[i]=(45 as u8)} return sys_write(1,((b as i64)+i) as *u8,32-i) } 16func parse_nums(s: *u8, out: *i64) -> i64 { var n: i64=0; var i: i64=0; var cur: i64=0; var has: i64=0; var neg: i64=0; while s[i]!=(0 as u8){ let c: i64=s[i] as i64; if c>=48 { if c<=57 {cur=cur*10+(c-48);has=1} else { if has==1{if neg==1{cur=0-cur} out[n]=cur;n=n+1;cur=0;has=0;neg=0} } } else { if c==45 {neg=1} else { if has==1{if neg==1{cur=0-cur} out[n]=cur;n=n+1;cur=0;has=0;neg=0} } } i=i+1 } if has==1{if neg==1{cur=0-cur} out[n]=cur;n=n+1} return n } 17func clip3(lo: i64, hi: i64, v: i64) -> i64 { if v<lo {return lo} if v>hi {return hi} return v } 18func vlen(b0: i64) -> i64 { if (b0&0x80)!=0{return 1} if (b0&0x40)!=0{return 2} if (b0&0x20)!=0{return 3} if (b0&0x10)!=0{return 4} if (b0&0x08)!=0{return 5} if (b0&0x04)!=0{return 6} if (b0&0x02)!=0{return 7} return 8 } 19func rid(b: *u8, i: i64, lo: *i64) -> i64 { let L: i64=vlen(b[i] as i64); var v: i64=0; var k: i64=0; while k<L {v=(v<<8)|(b[i+k] as i64); k=k+1} lo[0]=L; return v } 20func rsz(b: *u8, i: i64, lo: *i64) -> i64 { let L: i64=vlen(b[i] as i64); var v: i64=(b[i] as i64)&(0xff>>L); var k: i64=1; while k<L {v=(v<<8)|(b[i+k] as i64); k=k+1} lo[0]=L; return v } 21func ruint(b: *u8, o: i64, len: i64) -> i64 { var v: i64=0; var k: i64=0; while k<len {v=(v<<8)|(b[o+k] as i64); k=k+1} return v } 22func deemul(src: *u8, off: i64, len: i64, nhdr: i64, out: *u8) -> i64 { var rn: i64=0; var z: i64=0; var s: i64=off+nhdr; while s<off+len { let c: i64=src[s] as i64; if z>=2 { if c==3 {z=0} else {out[rn]=c as u8;rn=rn+1; if c==0{z=z+1}else{z=0}} } else {out[rn]=c as u8;rn=rn+1; if c==0{z=z+1}else{z=0}} s=s+1 } return rn } 23// de-emul that also records epos[rn] = EBSP source offset (relative to payload start off+nhdr) for each RBSP byte rn (for WPP entry-point mapping) 24func deemul_ep(src: *u8, off: i64, len: i64, nhdr: i64, out: *u8, epos: *i64) -> i64 { var rn: i64=0; var z: i64=0; var s: i64=off+nhdr; while s<off+len { let c: i64=src[s] as i64; var sk: i64=0; if z>=2 { if c==3 {sk=1} } if sk==1 {z=0} else {out[rn]=c as u8; epos[rn]=s-(off+nhdr); rn=rn+1; if c==0{z=z+1}else{z=0}} s=s+1 } return rn } 25// RBSP bit reader (for headers) hs[0]=ptr hs[1]=bitpos hs[2]=len 26func hbit(hs: *i64) -> i64 { let p: *u8=hs[0] as *u8; let bp: i64=hs[1]; hs[1]=bp+1; return ((p[bp>>3] as i64)>>(7-(bp&7)))&1 } 27func hb(hs: *i64, n: i64) -> i64 { var v: i64=0; var i: i64=0; while i<n {v=(v<<1)|hbit(hs); i=i+1} return v } 28func hue(hs: *i64) -> i64 { var lz: i64=0; while hbit(hs)==0 {lz=lz+1; if lz>40{return 0}} if lz==0{return 0} return ((1<<lz)-1)+hb(hs,lz) } 29func hse(hs: *i64) -> i64 { let k: i64=hue(hs); if (k&1)==1 {return (k+1)/2} return 0-(k/2) } 30func ceil_log2(n: i64) -> i64 { var k: i64=0; var v: i64=1; while v<n {v=v*2; k=k+1} return k } 31// short_term_ref_pic_set (7.3.7): parse one RPS, store NumDeltaPocs[idx] in ndp, return it. idx==numStr => slice's inline RPS. 32func parse_strps(bs: *i64, idx: i64, numStr: i64, ndp: *i64) -> i64 { 33 var interpred: i64=0; if idx!=0 {interpred=hb(bs,1)} 34 if interpred==1 { 35 var refidx: i64=idx-1; if idx==numStr {refidx=idx-1-hue(bs)} 36 hb(bs,1); hue(bs) // delta_rps_sign, abs_delta_rps_minus1 37 let nd: i64=ndp[refidx]; var cnt: i64=0; var j: i64=0 38 while j<=nd { let used: i64=hb(bs,1); if used==1 {cnt=cnt+1} else { if hb(bs,1)==1 {cnt=cnt+1} } j=j+1 } 39 ndp[idx]=cnt; return cnt 40 } else { 41 let nneg: i64=hue(bs); let npos: i64=hue(bs) 42 var i: i64=0; while i<nneg {hue(bs); hb(bs,1); i=i+1} 43 i=0; while i<npos {hue(bs); hb(bs,1); i=i+1} 44 ndp[idx]=nneg+npos; return nneg+npos 45 } 46} 47// CABAC engine cab[0]=range cab[1]=offset cab[2]=ptr cab[3]=bitpos cab[4]=len*8 48func cbit(cab: *i64) -> i64 { let bp: i64=cab[3]; if bp>=cab[4] {cab[3]=bp+1; return 0} let p: *u8=cab[2] as *u8; cab[3]=bp+1; return ((p[bp>>3] as i64)>>(7-(bp&7)))&1 } 49func cinit(cab: *i64, data: *u8, bitstart: i64, bytelen: i64) -> i64 { cab[2]=data as i64; cab[3]=bitstart; cab[4]=bytelen*8; cab[0]=510; var o: i64=0; var k: i64=0; while k<9 {o=(o<<1)|cbit(cab); k=k+1} cab[1]=o; return 0 } 50func crenorm(cab: *i64) -> i64 { while cab[0]<256 {cab[0]=cab[0]<<1; cab[1]=(cab[1]<<1)|cbit(cab)} return 0 } 51func cdec(cab: *i64, ctx: *i64, k: i64, rlps: *i64, tlps: *i64, tmps: *i64) -> i64 { let ps: i64=ctx[2*k]; let mps: i64=ctx[2*k+1]; let lps: i64=rlps[ps*4+((cab[0]>>6)&3)]; cab[0]=cab[0]-lps; var bin: i64=0; if cab[1]>=cab[0] { bin=1-mps; cab[1]=cab[1]-cab[0]; cab[0]=lps; if ps==0{ctx[2*k+1]=1-mps} ctx[2*k]=tlps[ps] } else { bin=mps; ctx[2*k]=tmps[ps] } crenorm(cab); return bin } 52func cbyp(cab: *i64) -> i64 { cab[1]=(cab[1]<<1)|cbit(cab); if cab[1]>=cab[0] {cab[1]=cab[1]-cab[0]; return 1} return 0 } 53func ctxi(ctx: *i64, k: i64, iv: i64, qp: i64) -> i64 { let sl: i64=(iv>>4)*5-45; let of: i64=((iv&15)<<3)-16; let pre: i64=clip3(1,126,((sl*clip3(0,51,qp))>>4)+of); if pre<=63 {ctx[2*k]=63-pre; ctx[2*k+1]=0} else {ctx[2*k]=pre-64; ctx[2*k+1]=1} return 0 } 54// bypass truncated-rice value, cMax 55func tr_bypass(cab: *i64, cMax: i64) -> i64 { var v: i64=0; while v<cMax { if cbyp(cab)==0 {return v} v=v+1 } return cMax } 56// decode via a packed decoder-state: dec[0]=cab dec[1]=ctx dec[2..4]=rlps/tlps/tmps dec[5]=maxtb dec[6]=mintb dec[7]=maxhi dec[8]=stop 57func cdecD(dec: *i64, k: i64) -> i64 { return cdec(dec[0] as *i64, dec[1] as *i64, k, dec[2] as *i64, dec[3] as *i64, dec[4] as *i64) } 58// up-right diagonal scan of an SxS block into sx[],sy[] (H.265 6.5.3) 59func diag_scan(S: i64, sx: *i64, sy: *i64) -> i64 { var i: i64=0; var x: i64=0; var y: i64=0; var stop: i64=0; while stop==0 { while y>=0 { if x<S { if y<S { sx[i]=x; sy[i]=y; i=i+1 } } y=y-1; x=x+1 } y=x; x=0; if i>=S*S {stop=1} } return i } 60// scan-order dispatch (6.5.3/4/5): scanIdx 0=up-right diagonal, 1=horizontal (row-major), 2=vertical (col-major). 61func gen_scan(S: i64, scanIdx: i64, sx: *i64, sy: *i64) -> i64 { 62 if scanIdx==1 { var i: i64=0; var y: i64=0; while y<S { var x: i64=0; while x<S { sx[i]=x; sy[i]=y; i=i+1; x=x+1 } y=y+1 } return i } 63 if scanIdx==2 { var i: i64=0; var x: i64=0; while x<S { var y: i64=0; while y<S { sx[i]=x; sy[i]=y; i=i+1; y=y+1 } x=x+1 } return i } 64 return diag_scan(S, sx, sy) 65} 66// sig_coeff_flag ctxInc (H.265 9.3.4.2.5). map = 4x4 ctxIdxMap. returns ctxInc into the SIG context block (luma 0-26, chroma 27-43). 67func sig_ctxinc(xC: i64, yC: i64, log2: i64, cIdx: i64, scanIdx: i64, csbfR: i64, csbfB: i64, map: *i64) -> i64 { 68 if log2==2 { let v: i64=map[(yC<<2)+xC]; if cIdx==0 {return v} return 27+v } 69 if xC+yC==0 { if cIdx==0 {return 0} return 27 } 70 let xP: i64=xC&3; let yP: i64=yC&3; let prev: i64=csbfR+2*csbfB; var s: i64=0 71 if prev==0 { if xP+yP==0 {s=2} else { if xP+yP<3 {s=1} else {s=0} } } else { if prev==1 { if yP==0 {s=2} else { if yP==1 {s=1} else {s=0} } } else { if prev==2 { if xP==0 {s=2} else { if xP==1 {s=1} else {s=0} } } else {s=2} } } 72 if cIdx==0 { if (xC>>2)+(yC>>2)>0 {s=s+3} if log2==3 { if scanIdx==0 {s=s+9} else {s=s+15} } else {s=s+21} return s } 73 if log2==3 {s=s+9} else {s=s+12} return 27+s 74} 75// coeff_abs_level_remaining: Golomb-Rice (prefix unary of 1s) + Rice (prefix<=3) or EGk suffix (bypass). 76func coeff_rem(cab: *i64, rice: i64) -> i64 { 77 var pfx: i64=0; var dn: i64=0; while dn==0 { if cbyp(cab)==1 {pfx=pfx+1; if pfx>=32 {dn=1}} else {dn=1} } 78 if pfx<=3 { var s: i64=0; var k: i64=0; while k<rice {s=(s<<1)|cbyp(cab); k=k+1} return (pfx<<rice)+s } 79 let len: i64=pfx-3+rice; var s: i64=0; var k: i64=0; while k<len {s=(s<<1)|cbyp(cab); k=k+1} return (((1<<(pfx-3))+2)<<rice)+s 80} 81// residual_coding (R3b-5): last_sig position + coded_sub_block_flag + sig_coeff_flag + level coding (greater1/2/sign/remaining). returns numSig. 82func residual_sig(dec: *i64, log2: i64, cIdx: i64, predModeIntra: i64) -> i64 { 83 let cab: *i64=dec[0] as *i64; let ctx: *i64=dec[1] as *i64; let rl: *i64=dec[2] as *i64; let tl: *i64=dec[3] as *i64; let tm: *i64=dec[4] as *i64; let map: *i64=dec[10] as *i64 84 let sbW: i64=1<<(log2-2) 85 var scanIdx: i64=0 86 if log2==2 { if predModeIntra>=6 { if predModeIntra<=14 {scanIdx=2} } if predModeIntra>=22 { if predModeIntra<=30 {scanIdx=1} } } 87 if log2==3 { if cIdx==0 { if predModeIntra>=6 { if predModeIntra<=14 {scanIdx=2} } if predModeIntra>=22 { if predModeIntra<=30 {scanIdx=1} } } } 88 let scbx: *i64=sys_mmap(8*256) as *i64; let scby: *i64=sys_mmap(8*256) as *i64; gen_scan(sbW, scanIdx, scbx, scby) 89 let s4x: *i64=sys_mmap(8*16) as *i64; let s4y: *i64=sys_mmap(8*16) as *i64; gen_scan(4, scanIdx, s4x, s4y) 90 let cMax: i64=(log2<<1)-1; var coffx: i64=15; var cshx: i64=log2-2 91 if cIdx==0 { coffx=3*(log2-2)+((log2-1)>>2); cshx=(log2+1)>>2 } 92 var lxp: i64=0; var dn: i64=0; while dn==0 { if lxp>=cMax {dn=1} else { if cdec(cab,ctx,23+coffx+(lxp>>cshx),rl,tl,tm)==0 {dn=1} else {lxp=lxp+1} } } 93 var lyp: i64=0; dn=0; while dn==0 { if lyp>=cMax {dn=1} else { if cdec(cab,ctx,41+coffx+(lyp>>cshx),rl,tl,tm)==0 {dn=1} else {lyp=lyp+1} } } 94 var lastX: i64=lxp; if lxp>3 { let nb: i64=(lxp>>1)-1; var sf: i64=0; var k: i64=0; while k<nb {sf=(sf<<1)|cbyp(cab); k=k+1} lastX=(1<<nb)*(2+(lxp&1))+sf } 95 var lastY: i64=lyp; if lyp>3 { let nb: i64=(lyp>>1)-1; var sf: i64=0; var k: i64=0; while k<nb {sf=(sf<<1)|cbyp(cab); k=k+1} lastY=(1<<nb)*(2+(lyp&1))+sf } 96 if scanIdx==2 { let tt: i64=lastX; lastX=lastY; lastY=tt } 97 let lsbX: i64=lastX>>2; let lsbY: i64=lastY>>2 98 var lastSB: i64=0; var t1: i64=0; while t1<sbW*sbW { if scbx[t1]==lsbX { if scby[t1]==lsbY {lastSB=t1; t1=sbW*sbW} } t1=t1+1 } 99 let lpx: i64=lastX&3; let lpy: i64=lastY&3 100 var lastSP: i64=0; var t2: i64=0; while t2<16 { if s4x[t2]==lpx { if s4y[t2]==lpy {lastSP=t2; t2=16} } t2=t2+1 } 101 let csbf: *i64=sys_mmap(8*256) as *i64; var z: i64=0; while z<sbW*sbW {csbf[z]=0; z=z+1} 102 let sdh: i64=dec[14]; let Nt: i64=1<<log2; let coeffOut: *i64=dec[15] as *i64; dec[16]=log2 103 var zc: i64=0; while zc<Nt*Nt {coeffOut[zc]=0; zc=zc+1} 104 let sigN: *i64=sys_mmap(8*24) as *i64; let g1: *i64=sys_mmap(8*24) as *i64; let sgn: *i64=sys_mmap(8*24) as *i64 105 var totalSig: i64=0; var totalAbs: i64=0; var maxLvl: i64=0; var lastC1: i64=1; var firstSb: i64=1 106 var i: i64=lastSB 107 while i>=0 { 108 let xS: i64=scbx[i]; let yS: i64=scby[i]; var infer: i64=0; var coded: i64=0 109 if i<lastSB { if i>0 { var cR: i64=0; if xS+1<sbW {cR=csbf[yS*sbW+(xS+1)]} var cB: i64=0; if yS+1<sbW {cB=csbf[(yS+1)*sbW+xS]} var cof: i64=0; if cIdx!=0 {cof=2} coded=cdec(cab,ctx,59+cof+(cR|cB),rl,tl,tm); infer=1 } else {coded=1} } else {coded=1} 110 csbf[yS*sbW+xS]=coded 111 if coded==1 { 112 var cR2: i64=0; if xS+1<sbW {cR2=csbf[yS*sbW+(xS+1)]} 113 var cB2: i64=0; if yS+1<sbW {cB2=csbf[(yS+1)*sbW+xS]} 114 var nsig: i64=0 115 if i==lastSB { sigN[0]=lastSP; nsig=1 } 116 var nstart: i64=15; if i==lastSB {nstart=lastSP-1} 117 var n: i64=nstart 118 while n>=0 { let xC: i64=(xS<<2)+s4x[n]; let yC: i64=(yS<<2)+s4y[n]; var sig: i64=0 119 let _sci: i64=sig_ctxinc(xC,yC,log2,cIdx,scanIdx,cR2,cB2,map); var _dec: i64=0 120 if n>0 { sig=cdec(cab,ctx,63+_sci,rl,tl,tm); _dec=1 } else { if infer==1 {sig=1} else {sig=cdec(cab,ctx,63+_sci,rl,tl,tm); _dec=1} } 121 if _dec==1 { if dec[45]==88 { if dec[46]==16 { if cIdx==0 { pe("SIG ctx=" as *u8);pn(_sci);pe(" sig=" as *u8);pn(sig);pe("\n" as *u8) } } } } 122 if sig==1 { if nsig<24 {sigN[nsig]=n} nsig=nsig+1; infer=0 } n=n-1 } 123 totalSig=totalSig+nsig 124 var ctxSet: i64=2; if i==0 {ctxSet=0} if cIdx>0 {ctxSet=0} 125 if firstSb==0 { if lastC1==0 {ctxSet=ctxSet+1} } 126 firstSb=0 127 var c1: i64=1; var ng1: i64=nsig; if ng1>8 {ng1=8}; var firstG1: i64=0-1; var kk: i64=0 128 while kk<ng1 { var cinc: i64=ctxSet*4+c1; if cIdx>0 {cinc=cinc+16} let _pr: i64=cab[0]; let _po: i64=cab[1]; let _pb: i64=cab[3]; let f: i64=cdec(cab,ctx,107+cinc,rl,tl,tm); g1[kk]=f; pe("B " as *u8);pn(dec[45]);pe(" " as *u8);pn(dec[46]);pe(" " as *u8);pn(cIdx);pe(" g1 " as *u8);pn(f);pe("\n" as *u8) if dec[45]==88 { if dec[46]==16 { if cIdx==0 { pe("G1OFF inc=" as *u8);pn(cinc);pe(" rng=" as *u8);pn(_pr);pe(" off=" as *u8);pn(_po);pe(" bp=" as *u8);pn(_pb);pe("\n" as *u8) } } } if f==1 { if firstG1<0 {firstG1=kk} c1=0 } else { if c1>0 { if c1<3 {c1=c1+1} } } kk=kk+1 } 129 lastC1=c1 130 var g2: i64=0; if firstG1>=0 { var ci2: i64=ctxSet; if cIdx>0 {ci2=4+ctxSet} g2=cdec(cab,ctx,131+ci2,rl,tl,tm); pe("B " as *u8);pn(dec[45]);pe(" " as *u8);pn(dec[46]);pe(" " as *u8);pn(cIdx);pe(" g2 " as *u8);pn(g2);pe("\n" as *u8) } 131 var signHidden: i64=0; if sdh==1 { if nsig>0 { if sigN[0]-sigN[nsig-1]>3 {signHidden=1} } } 132 var ks: i64=0; while ks<nsig { var rd: i64=1; if signHidden==1 { if ks==nsig-1 {rd=0} } if rd==1 { sgn[ks]=cbyp(cab); pe("B " as *u8);pn(dec[45]);pe(" " as *u8);pn(dec[46]);pe(" " as *u8);pn(cIdx);pe(" sg " as *u8);pn(sgn[ks]);pe("\n" as *u8) } else {sgn[ks]=0} ks=ks+1 } 133 var rice: i64=0; var kl: i64=0; var sbSum: i64=0 134 while kl<nsig { var baseLevel: i64=1; if kl<ng1 {baseLevel=baseLevel+g1[kl]} if kl==firstG1 {baseLevel=baseLevel+g2} 135 var thresh: i64=1; if kl<ng1 { if kl==firstG1 {thresh=3} else {thresh=2} } 136 var level: i64=baseLevel 137 if baseLevel==thresh { let rem: i64=coeff_rem(cab,rice); pe("B " as *u8);pn(dec[45]);pe(" " as *u8);pn(dec[46]);pe(" " as *u8);pn(cIdx);pe(" rm " as *u8);pn(rem);pe("\n" as *u8) level=baseLevel+rem; if level>(3<<rice) { if rice<4 {rice=rice+1} } } 138 totalAbs=totalAbs+level; if level>maxLvl {maxLvl=level}; sbSum=sbSum+level 139 let nn2: i64=sigN[kl]; let xC2: i64=(xS<<2)+s4x[nn2]; let yC2: i64=(yS<<2)+s4y[nn2]; var sv: i64=level; if sgn[kl]==1 {sv=0-level} 140 coeffOut[yC2*Nt+xC2]=sv 141 if dec[45]==88 { if dec[46]==16 { if cIdx==0 { pe("MYLVL kl=" as *u8);pn(kl);pe(" pos=" as *u8);pn(yC2*Nt+xC2);pe(" base=" as *u8);pn(baseLevel);pe(" lvl=" as *u8);pn(level);pe(" sgn=" as *u8);pn(sgn[kl]);pe(" rice=" as *u8);pn(rice);pe(" sbk=" as *u8);pn(i);pe("\n" as *u8) } } } 142 kl=kl+1 } 143 if signHidden==1 { if nsig>0 { let nn3: i64=sigN[nsig-1]; let xC3: i64=(xS<<2)+s4x[nn3]; let yC3: i64=(yS<<2)+s4y[nn3]; if (sbSum&1)==1 {coeffOut[yC3*Nt+xC3]=0-coeffOut[yC3*Nt+xC3]} } } 144 } 145 i=i-1 146 } 147 return totalSig 148} 149// Exp-Golomb order-0 (bypass): HEVC EGk counts leading ONES terminated by a 0, then lz suffix bits -> 2^lz-1+suffix 150func eg0(cab: *i64) -> i64 { var lz: i64=0; var dn: i64=0; while dn==0 { if cbyp(cab)==1 {lz=lz+1; if lz>=31 {dn=1}} else {dn=1} } var v: i64=0; var k: i64=0; while k<lz {v=(v<<1)|cbyp(cab); k=k+1} return (1<<lz)-1+v } 151// transform_tree (intra 2Nx2N) WITH reconstruction (R6b-2): split_transform_flag + cbf_cb/cbf_cr + cbf_luma, 152// then at each leaf TU: derive refs from the frame buffer -> predict(IntraPredModeY) -> +IDCT residual -> store. 153// Chroma residuals decoded for CABAC sync (luma-only reconstruction here). dec[8]=#cbf1 luma TUs, dec[11]=#zero TUs. 154// NOTE: the 4:2:0 log2==2 (4x4-luma) chroma-at-parent special case is deferred (does not arise in a 64x64/MaxTb32 CTU). 155func xtree(dec: *i64, log2: i64, depth: i64, cbfcb: i64, cbfcr: i64, x0: i64, y0: i64) -> i64 { 156 let maxtb: i64=dec[5]; let mintb: i64=dec[6]; let maxhi: i64=dec[7] 157 var split: i64=0; var mh: i64=maxhi; if dec[38]==1 {mh=maxhi+1} 158 if log2>maxtb { split=1 } else { if dec[38]==1 { if depth==0 {split=1} else { if log2<=mintb {split=0} else { if depth>=mh {split=0} else {split=cdecD(dec,9+(5-log2))} } } } else { if log2<=mintb { split=0 } else { if depth>=mh { split=0 } else { split=cdecD(dec, 9+(5-log2)) } } } } 159 var ncb: i64=0; var ncr: i64=0 160 if log2>2 { if depth==0 { ncb=cdecD(dec,14+depth); ncr=cdecD(dec,14+depth) } else { if cbfcb==1 {ncb=cdecD(dec,14+depth)} if cbfcr==1 {ncr=cdecD(dec,14+depth)} } } else { ncb=cbfcb; ncr=cbfcr } 161 if split==1 { let h: i64=1<<(log2-1); xtree(dec,log2-1,depth+1,ncb,ncr,x0,y0); xtree(dec,log2-1,depth+1,ncb,ncr,x0+h,y0); xtree(dec,log2-1,depth+1,ncb,ncr,x0,y0+h); xtree(dec,log2-1,depth+1,ncb,ncr,x0+h,y0+h); if log2==3 { if ncb==1 {residual_sig(dec,2,1,dec[43]); recon_chroma(dec,4,1,x0>>1,y0>>1,dec[43],1)} else {recon_chroma(dec,4,1,x0>>1,y0>>1,dec[43],0)} if ncr==1 {residual_sig(dec,2,2,dec[43]); recon_chroma(dec,4,2,x0>>1,y0>>1,dec[43],1)} else {recon_chroma(dec,4,2,x0>>1,y0>>1,dec[43],0)} } } else { 162 var cbfl: i64=0; if depth==0 { cbfl=cdecD(dec,13) } else { cbfl=cdecD(dec,12) } 163 var anycbf: i64=0; if cbfl==1 {anycbf=1} if ncb==1 {anycbf=1} if ncr==1 {anycbf=1} 164 if anycbf==1 { if dec[12]==1 { if dec[13]==0 { var pfx: i64=0; if cdecD(dec,19)==1 { pfx=1; var d2: i64=0; while d2==0 { if pfx>=5 {d2=1} else { if cdecD(dec,20)==0 {d2=1} else {pfx=pfx+1} } } } var cq: i64=pfx; if pfx>=5 {cq=5+eg0(dec[0] as *i64)} var sgnq: i64=0; if cq>0 {sgnq=cbyp(dec[0] as *i64)} var dval: i64=cq; if sgnq==1 {dval=0-cq} let q: i64=dec[39]+dval; let qy: i64=((q+76)%64)-12; dec[27]=qy+12; dec[39]=qy; dec[13]=1 } } } 165 let N: i64=1<<log2; let frame: *i64=dec[17] as *i64; let fw: i64=dec[18]; let fh: i64=dec[19] 166 let mgg: *i64=dec[31] as *i64; let modeY: i64=mgg[(y0>>2)*dec[33]+(x0>>2)] 167 let refL: *i64=sys_mmap(8*520) as *i64; let refT: *i64=sys_mmap(8*520) as *i64; let cpr: *i64=sys_mmap(16) as *i64 168 derive_refs(frame, fw, fh, x0, y0, N, refL, refT, cpr) 169 smooth_refs(refL, refT, cpr, N, modeY) 170 let predb: *i64=dec[26] as *i64; predict_tu(predb, N, modeY, refL, refT, cpr[0], dec[28] as *i64, dec[29] as *i64, 1) 171 let coeffbuf: *i64=dec[15] as *i64 172 dec[45]=x0; dec[46]=y0 173 if cbfl==1 { residual_sig(dec, log2, 0, modeY); dequant(coeffbuf, N, dec[27], 10, dec[20] as *i64); var matN: *i64=dec[23] as *i64; if N==4 {matN=dec[44] as *i64} if N==8 {matN=dec[21] as *i64} if N==16 {matN=dec[22] as *i64} itransform(coeffbuf, N, matN, 10, dec[25] as *i64) } else { var zz: i64=0; while zz<N*N {coeffbuf[zz]=0; zz=zz+1} } 174 var rr: i64=0; while rr<N { var cc: i64=0; while cc<N { frame[(y0+rr)*fw+(x0+cc)]=clip3(0,1023,predb[rr*N+cc]+coeffbuf[rr*N+cc]); cc=cc+1 } rr=rr+1 } 175 let bVm2: *i64=dec[55] as *i64; let bHm2: *i64=dec[56] as *i64; let gw4m: i64=dec[57]; let gx0: i64=x0>>2; let gy0: i64=y0>>2; let gn: i64=N>>2; var mi: i64=0; while mi<gn { bVm2[(gy0+mi)*gw4m+gx0]=1; bHm2[gy0*gw4m+(gx0+mi)]=1; mi=mi+1 } 176 if log2>2 { let lc: i64=log2-1; let cN2: i64=1<<lc; if ncb==1 {residual_sig(dec,lc,1,dec[43]); recon_chroma(dec,cN2,1,x0>>1,y0>>1,dec[43],1)} else {recon_chroma(dec,cN2,1,x0>>1,y0>>1,dec[43],0)} if ncr==1 {residual_sig(dec,lc,2,dec[43]); recon_chroma(dec,cN2,2,x0>>1,y0>>1,dec[43],1)} else {recon_chroma(dec,cN2,2,x0>>1,y0>>1,dec[43],0)} } 177 if cbfl==1 {dec[8]=dec[8]+1} else {dec[11]=dec[11]+1} 178 } 179 return 0 180} 181 182// ---- R6 reconstruction helpers (verified in nx_hevc_pred/idct/recon) ---- 183func ilog2(n: i64) -> i64 { var l: i64=0; var v: i64=n; while v>1 {v=v>>1; l=l+1} return l } 184func build_dct(gN: *i64, N: i64, gHalf: *i64, oddC: *i64) -> i64 { let H: i64=N/2; var j: i64=0; while j<H { var nn: i64=0; while nn<H { gN[(2*j)*N+nn]=gHalf[j*H+nn]; gN[(2*j)*N+(N-1-nn)]=gHalf[j*H+nn]; gN[(2*j+1)*N+nn]=oddC[j*H+nn]; gN[(2*j+1)*N+(N-1-nn)]=0-oddC[j*H+nn]; nn=nn+1 } j=j+1 } return 0 } 185func dequant(coeff: *i64, N: i64, qP: i64, bd: i64, lsc: *i64) -> i64 { let bs: i64=bd+ilog2(N)-5; let ls: i64=lsc[qP%6]; let sh: i64=qP/6; let ad: i64=1<<(bs-1); var i: i64=0; while i<N*N { coeff[i]=clip3(0-K_MAGIC_32768,K_MAGIC_32767,((coeff[i]*16*ls<<sh)+ad)>>bs); i=i+1 } return 0 } 186func itransform(coeff: *i64, N: i64, mat: *i64, bd: i64, tmp: *i64) -> i64 { var c: i64=0; while c<N { var r: i64=0; while r<N { var s: i64=0; var k: i64=0; while k<N {s=s+mat[k*N+r]*coeff[k*N+c]; k=k+1} tmp[r*N+c]=clip3(0-K_MAGIC_32768,K_MAGIC_32767,(s+64)>>7); r=r+1 } c=c+1 } let b2: i64=20-bd; let a2: i64=1<<(b2-1); var r2: i64=0; while r2<N { var c2: i64=0; while c2<N { var s: i64=0; var k: i64=0; while k<N {s=s+mat[k*N+c2]*tmp[r2*N+k]; k=k+1} coeff[r2*N+c2]=(s+a2)>>b2; c2=c2+1 } r2=r2+1 } return 0 } 187func predict_planar(pred: *i64, N: i64, refL: *i64, refT: *i64, refTR: i64, refBL: i64) -> i64 { let sh: i64=ilog2(N)+1; var y: i64=0; while y<N { var x: i64=0; while x<N { pred[y*N+x]=((N-1-x)*refL[y]+(x+1)*refTR+(N-1-y)*refT[x]+(y+1)*refBL+N)>>sh; x=x+1 } y=y+1 } return 0 } 188func predict_dc(pred: *i64, N: i64, refL: *i64, refT: *i64, cIdx: i64) -> i64 { var s: i64=0; var k: i64=0; while k<N {s=s+refT[k]+refL[k]; k=k+1} let dc: i64=(s+N)>>(ilog2(N)+1); var i: i64=0; while i<N*N {pred[i]=dc; i=i+1} if cIdx==0 { if N<32 { pred[0]=(refL[0]+2*dc+refT[0]+2)>>2; var x2: i64=1; while x2<N {pred[x2]=(refT[x2]+3*dc+2)>>2; x2=x2+1} var y2: i64=1; while y2<N {pred[y2*N]=(refL[y2]+3*dc+2)>>2; y2=y2+1} } } return 0 } 189func predict_angular(pred: *i64, N: i64, mode: i64, refL: *i64, refT: *i64, corner: i64, angT: *i64, invT: *i64, lf: i64) -> i64 { 190 let angle: i64=angT[mode-2]; let B: i64=2*N; let ref: *i64=sys_mmap(8*(4*N+16)) as *i64 191 if mode>=18 { 192 ref[B]=corner; var x: i64=0; while x<2*N {ref[B+1+x]=refT[x]; x=x+1} 193 if angle<0 { let inv: i64=invT[mode-11]; let lim: i64=(N*angle)>>5; var xx: i64=0-1; while xx>=lim { let idx: i64=(0-1)+((xx*inv+128)>>8); if idx<0 {ref[B+xx]=corner} else {ref[B+xx]=refL[idx]} xx=xx-1 } } 194 var y: i64=0; while y<N { let iIdx: i64=((y+1)*angle)>>5; let iFact: i64=((y+1)*angle)&31; var x2: i64=0; while x2<N { if iFact!=0 {pred[y*N+x2]=((32-iFact)*ref[B+x2+iIdx+1]+iFact*ref[B+x2+iIdx+2]+16)>>5} else {pred[y*N+x2]=ref[B+x2+iIdx+1]} x2=x2+1 } y=y+1 } 195 if mode==26 { if lf==1 { if N<32 { var yb: i64=0; while yb<N { pred[yb*N]=clip3(0,1023,refT[0]+((refL[yb]-corner)>>1)); yb=yb+1 } } } } 196 } else { 197 ref[B]=corner; var x: i64=0; while x<2*N {ref[B+1+x]=refL[x]; x=x+1} 198 if angle<0 { let inv: i64=invT[mode-11]; let lim: i64=(N*angle)>>5; var xx: i64=0-1; while xx>=lim { let idx: i64=(0-1)+((xx*inv+128)>>8); if idx<0 {ref[B+xx]=corner} else {ref[B+xx]=refT[idx]} xx=xx-1 } } 199 var x3: i64=0; while x3<N { let iIdx: i64=((x3+1)*angle)>>5; let iFact: i64=((x3+1)*angle)&31; var y3: i64=0; while y3<N { if iFact!=0 {pred[y3*N+x3]=((32-iFact)*ref[B+y3+iIdx+1]+iFact*ref[B+y3+iIdx+2]+16)>>5} else {pred[y3*N+x3]=ref[B+y3+iIdx+1]} y3=y3+1 } x3=x3+1 } 200 if mode==10 { if lf==1 { if N<32 { var xb: i64=0; while xb<N { pred[xb]=clip3(0,1023,refL[0]+((refT[xb]-corner)>>1)); xb=xb+1 } } } } 201 } 202 return 0 203} 204func predict_tu(out: *i64, N: i64, mode: i64, refL: *i64, refT: *i64, corner: i64, angT: *i64, invT: *i64, lf: i64) -> i64 { if mode==0 {predict_planar(out,N,refL,refT,refT[N],refL[N])} else { if mode==1 {predict_dc(out,N,refL,refT,1-lf)} else {predict_angular(out,N,mode,refL,refT,corner,angT,invT,lf)} } return 0 } 205// chroma reconstruction (4:2:0): predict (no ref-smoothing, no luma boundary filter) + optional residual (DCT, never DST) -> Cb/Cr plane. 206func recon_chroma(dec: *i64, cN: i64, cIdx: i64, cx: i64, cy: i64, modeC: i64, hasRes: i64) -> i64 { 207 var cpl: *i64=dec[48] as *i64; if cIdx==2 {cpl=dec[49] as *i64} 208 let cfw: i64=dec[52]; let cfh: i64=dec[53] 209 let refL: *i64=sys_mmap(8*520) as *i64; let refT: *i64=sys_mmap(8*520) as *i64; let cpr: *i64=sys_mmap(16) as *i64 210 derive_refs(cpl, cfw, cfh, cx, cy, cN, refL, refT, cpr) 211 let predb: *i64=dec[26] as *i64; predict_tu(predb, cN, modeC, refL, refT, cpr[0], dec[28] as *i64, dec[29] as *i64, 0) 212 let cf: *i64=dec[15] as *i64 213 if hasRes==1 { var coff: i64=dec[50]; if cIdx==2 {coff=dec[51]} let qpi: i64=clip3(0-12,57,dec[39]+coff); var QpC: i64=qpi; if qpi>=30 { let qpct: *i64=dec[54] as *i64; if qpi<=43 {QpC=qpct[qpi-30]} else {QpC=qpi-6} } let qp: i64=QpC+12; dequant(cf, cN, qp, 10, dec[20] as *i64); var matN: *i64=dec[24] as *i64; if cN==8 {matN=dec[21] as *i64} if cN==16 {matN=dec[22] as *i64} itransform(cf, cN, matN, 10, dec[25] as *i64) } else { var z: i64=0; while z<cN*cN {cf[z]=0; z=z+1} } 214 var rr: i64=0; while rr<cN { var cc: i64=0; while cc<cN { cpl[(cy+rr)*cfw+(cx+cc)]=clip3(0,1023,predb[rr*cN+cc]+cf[rr*cN+cc]); cc=cc+1 } rr=rr+1 } 215 return 0 216} 217// reference-sample derivation (8.4.4.2.1): gather neighbours from the frame (unavailable=-1), substitute. refL/refT length 2N. 218func derive_refs(frame: *i64, fw: i64, fh: i64, x0: i64, y0: i64, N: i64, refL: *i64, refT: *i64, cornerP: *i64) -> i64 { 219 let M: i64=4*N+1; let A: *i64=sys_mmap(8*(M+2)) as *i64; let av: *i64=sys_mmap(8*(M+2)) as *i64 220 var i: i64=0 221 while i<2*N { let yy: i64=y0+(2*N-1-i); let xx: i64=x0-1; var ok: i64=0; var val: i64=512; if xx>=0 { if yy>=0 { if xx<fw { if yy<fh { let s: i64=frame[yy*fw+xx]; if s>=0 {val=s; ok=1} } } } } A[i]=val; av[i]=ok; i=i+1 } 222 let cy: i64=y0-1; let cx: i64=x0-1; var cok: i64=0; var cval: i64=512; if cx>=0 { if cy>=0 { if cx<fw { if cy<fh { let s: i64=frame[cy*fw+cx]; if s>=0 {cval=s; cok=1} } } } } A[2*N]=cval; av[2*N]=cok 223 var j: i64=0 224 while j<2*N { let yy: i64=y0-1; let xx: i64=x0+j; var ok: i64=0; var val: i64=512; if xx>=0 { if yy>=0 { if xx<fw { if yy<fh { let s: i64=frame[yy*fw+xx]; if s>=0 {val=s; ok=1} } } } } A[2*N+1+j]=val; av[2*N+1+j]=ok; j=j+1 } 225 var anyA: i64=0; var k: i64=0; while k<M { if av[k]==1 {anyA=1} k=k+1 } 226 if anyA==0 { k=0; while k<M {A[k]=512; k=k+1} } else { if av[0]==0 { var f: i64=512; var kk: i64=0; var dn: i64=0; while dn==0 { if kk>=M {dn=1} else { if av[kk]==1 {f=A[kk]; dn=1} else {kk=kk+1} } } A[0]=f } k=1; while k<M { if av[k]==0 {A[k]=A[k-1]} k=k+1 } } 227 var m: i64=0; while m<2*N { refL[m]=A[2*N-1-m]; m=m+1 } 228 var jj: i64=0; while jj<2*N { refT[jj]=A[2*N+1+jj]; jj=jj+1 } 229 cornerP[0]=A[2*N] 230 return 0 231} 232func absi(x: i64) -> i64 { if x<0 {return 0-x} return x } 233// HEVC luma deblock of one 4-sample edge segment (8.7.2.4). base=q0 index; ps=perpendicular step; ts=tangential step; bS=2. 234func db_luma(frame: *i64, base: i64, ps: i64, ts: i64, beta: i64, tc: i64) -> i64 { 235 let b3: i64=base+3*ts 236 let dp0: i64=absi(frame[base-3*ps]-2*frame[base-2*ps]+frame[base-ps]); let dq0: i64=absi(frame[base+2*ps]-2*frame[base+ps]+frame[base]) 237 let dp3: i64=absi(frame[b3-3*ps]-2*frame[b3-2*ps]+frame[b3-ps]); let dq3: i64=absi(frame[b3+2*ps]-2*frame[b3+ps]+frame[b3]) 238 let dpq0: i64=dp0+dq0; let dpq3: i64=dp3+dq3; let d: i64=dpq0+dpq3 239 if d>=beta {return 0} 240 var dEp: i64=0; var dEq: i64=0; let bt2: i64=(beta+(beta>>1))>>3; if dp0+dp3<bt2 {dEp=1} if dq0+dq3<bt2 {dEq=1} 241 let th1: i64=beta>>2; let th2: i64=beta>>3; let th3: i64=(5*tc+1)>>1 242 var s0: i64=0; if (dpq0<<1)<th1 { if absi(frame[base-4*ps]-frame[base-ps])+absi(frame[base+3*ps]-frame[base])<th2 { if absi(frame[base-ps]-frame[base])<th3 {s0=1} } } 243 var s3: i64=0; if (dpq3<<1)<th1 { if absi(frame[b3-4*ps]-frame[b3-ps])+absi(frame[b3+3*ps]-frame[b3])<th2 { if absi(frame[b3-ps]-frame[b3])<th3 {s3=1} } } 244 var strong: i64=0; if s0==1 { if s3==1 {strong=1} } 245 var k: i64=0; while k<4 { 246 let bk: i64=base+k*ts 247 let p0: i64=frame[bk-ps]; let p1: i64=frame[bk-2*ps]; let p2: i64=frame[bk-3*ps]; let p3: i64=frame[bk-4*ps] 248 let q0: i64=frame[bk]; let q1: i64=frame[bk+ps]; let q2: i64=frame[bk+2*ps]; let q3: i64=frame[bk+3*ps] 249 if strong==1 { 250 frame[bk-ps]=clip3(p0-2*tc,p0+2*tc,(p2+2*p1+2*p0+2*q0+q1+4)>>3) 251 frame[bk-2*ps]=clip3(p1-2*tc,p1+2*tc,(p2+p1+p0+q0+2)>>2) 252 frame[bk-3*ps]=clip3(p2-2*tc,p2+2*tc,(2*p3+3*p2+p1+p0+q0+4)>>3) 253 frame[bk]=clip3(q0-2*tc,q0+2*tc,(p1+2*p0+2*q0+2*q1+q2+4)>>3) 254 frame[bk+ps]=clip3(q1-2*tc,q1+2*tc,(p0+q0+q1+q2+2)>>2) 255 frame[bk+2*ps]=clip3(q2-2*tc,q2+2*tc,(p0+q0+q1+3*q2+2*q3+4)>>3) 256 } else { 257 var delta: i64=(9*(q0-p0)-3*(q1-p1)+8)>>4 258 if absi(delta)<10*tc { 259 if delta<0-tc {delta=0-tc} if delta>tc {delta=tc} 260 frame[bk-ps]=clip3(0,1023,p0+delta); frame[bk]=clip3(0,1023,q0-delta) 261 if dEp==1 { var dpv: i64=(((p2+p0+1)>>1)-p1+delta)>>1; let tch: i64=tc>>1; if dpv<0-tch {dpv=0-tch} if dpv>tch {dpv=tch} frame[bk-2*ps]=clip3(0,1023,p1+dpv) } 262 if dEq==1 { var dqv: i64=(((q2+q0+1)>>1)-q1-delta)>>1; let tch: i64=tc>>1; if dqv<0-tch {dqv=0-tch} if dqv>tch {dqv=tch} frame[bk+ps]=clip3(0,1023,q1+dqv) } 263 } 264 } 265 k=k+1 266 } 267 return 0 268} 269// HEVC chroma deblock of a 4-sample chroma edge (bS=2 only, modifies p0/q0). 270func db_chroma(plane: *i64, base: i64, ps: i64, ts: i64, tc: i64) -> i64 { 271 var k: i64=0; while k<4 { let bk: i64=base+k*ts; let p0: i64=plane[bk-ps]; let p1: i64=plane[bk-2*ps]; let q0: i64=plane[bk]; let q1: i64=plane[bk+ps] 272 var delta: i64=(((q0-p0)<<2)+p1-q1+4)>>3; if delta<0-tc {delta=0-tc} if delta>tc {delta=tc} 273 plane[bk-ps]=clip3(0,1023,p0+delta); plane[bk]=clip3(0,1023,q0-delta); k=k+1 } return 0 274} 275// in-loop deblock (8.7.2): I-slice 4:2:0, constant slice QP. bV/bH = per-4x4 TU/CU edge maps. Vertical pass then horizontal. 276func deblock(dec: *i64, qpY: i64, betaOff: i64, tcOff: i64, qpcb: i64, qpcr: i64) -> i64 { 277 let frame: *i64=dec[17] as *i64; let fw: i64=dec[18]; let W: i64=dec[34]; let H: i64=dec[35] 278 let bV: *i64=dec[55] as *i64; let bH: *i64=dec[56] as *i64; let gw4: i64=dec[57] 279 let bt: *i64=sys_mmap(8*64) as *i64; parse_nums("0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 6 7 8 9 10 11 12 13 14 15 16 17 18 20 22 24 26 28 30 32 34 36 38 40 42 44 46 48 50 52 54 56 58 60 62 64" as *u8, bt) 280 let tt: *i64=sys_mmap(8*64) as *i64; parse_nums("0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 2 2 2 2 3 3 3 3 4 4 4 5 5 6 6 7 8 9 10 11 13 14 16 18 20 22 24" as *u8, tt) 281 let beta: i64=bt[clip3(0,51,qpY+betaOff)]<<2; let tc: i64=tt[clip3(0,53,qpY+2+tcOff)]<<2 282 let cfw: i64=dec[52]; let cbpl: *i64=dec[48] as *i64; let crpl: *i64=dec[49] as *i64 283 let tcb: i64=tt[clip3(0,53,qpcb+2+tcOff)]<<2; let tcr: i64=tt[clip3(0,53,qpcr+2+tcOff)]<<2 284 var x: i64=8; while x<W { var y: i64=0; while y<H { if bV[(y>>2)*gw4+(x>>2)]==1 { db_luma(frame, y*fw+x, 1, fw, beta, tc) } y=y+4 } x=x+8 } 285 var y2: i64=8; while y2<H { var x2: i64=0; while x2<W { if bH[(y2>>2)*gw4+(x2>>2)]==1 { db_luma(frame, y2*fw+x2, fw, 1, beta, tc) } x2=x2+4 } y2=y2+8 } 286 var cx: i64=16; while cx<W { var cy: i64=0; while cy<H { if bV[(cy>>2)*gw4+(cx>>2)]==1 { let cbx: i64=cx>>1; let cby: i64=cy>>1; db_chroma(cbpl, cby*cfw+cbx, 1, cfw, tcb); db_chroma(crpl, cby*cfw+cbx, 1, cfw, tcr) } cy=cy+8 } cx=cx+16 } 287 var cy2: i64=16; while cy2<H { var cx2: i64=0; while cx2<W { if bH[(cy2>>2)*gw4+(cx2>>2)]==1 { let cbx: i64=cx2>>1; let cby: i64=cy2>>1; db_chroma(cbpl, cby*cfw+cbx, cfw, 1, tcb); db_chroma(crpl, cby*cfw+cbx, cfw, 1, tcr) } cx2=cx2+8 } cy2=cy2+16 } 288 return 0 289} 290func sgn(x: i64) -> i64 { if x>0 {return 1} if x<0 {return 0-1} return 0 } 291// apply SAO (8.7.3) to one component of one CTB. base = saoP slot: [base]=type(0/1/2) [base+1]=bandpos|eoclass [base+2..5]=signed offsets. cp = pre-SAO copy (edge classification). 292func sao_apply_comp(plane: *i64, cp: *i64, stride: i64, W: i64, H: i64, x0: i64, y0: i64, sz: i64, saoP: *i64, base: i64) -> i64 { 293 let ty: i64=saoP[base]; if ty==0 {return 0} 294 let off: i64=base+2; var xee: i64=x0+sz; if xee>W {xee=W}; var yee: i64=y0+sz; if yee>H {yee=H} 295 if ty==1 { let bp: i64=saoP[base+1]; var y: i64=y0; while y<yee { var x: i64=x0; while x<xee { let s: i64=plane[y*stride+x]; let d: i64=((s>>5)-bp)&31; if d<4 {plane[y*stride+x]=clip3(0,1023,s+saoP[off+d])} x=x+1 } y=y+1 } return 0 } 296 let eo: i64=saoP[base+1]; var dax: i64=0-1; var day: i64=0; var dbx: i64=1; var dby: i64=0 297 if eo==1 {dax=0; day=0-1; dbx=0; dby=1} if eo==2 {dax=0-1; day=0-1; dbx=1; dby=1} if eo==3 {dax=1; day=0-1; dbx=0-1; dby=1} 298 var y: i64=y0; while y<yee { var x: i64=x0; while x<xee { 299 let ax: i64=x+dax; let ay: i64=y+day; let bx: i64=x+dbx; let by: i64=y+dby; var okk: i64=1 300 if ax<0 {okk=0} if ax>=W {okk=0} if ay<0 {okk=0} if ay>=H {okk=0} if bx<0 {okk=0} if bx>=W {okk=0} if by<0 {okk=0} if by>=H {okk=0} 301 if okk==1 { let s: i64=cp[y*stride+x]; let eidx: i64=2+sgn(s-cp[ay*stride+ax])+sgn(s-cp[by*stride+bx]); var cat: i64=0; if eidx==0 {cat=1} if eidx==1 {cat=2} if eidx==3 {cat=3} if eidx==4 {cat=4} if cat!=0 {plane[y*stride+x]=clip3(0,1023,s+saoP[off+cat-1])} } 302 x=x+1 } y=y+1 } 303 return 0 304} 305func apply_sao(dec: *i64, ctbSize: i64) -> i64 { 306 let frame: *i64=dec[17] as *i64; let fw: i64=dec[18]; let W: i64=dec[34]; let H: i64=dec[35] 307 let saoP: *i64=dec[58] as *i64; let ncols: i64=dec[59]; let nrows: i64=dec[60] 308 let cbpl: *i64=dec[48] as *i64; let crpl: *i64=dec[49] as *i64; let cfw: i64=dec[52]; let cW: i64=W>>1; let cH: i64=H>>1; let cs: i64=ctbSize>>1 309 let cpY: *i64=sys_mmap(8*fw*H) as *i64; var i: i64=0; while i<fw*H {cpY[i]=frame[i]; i=i+1} 310 let cpB: *i64=sys_mmap(8*cfw*cH) as *i64; let cpR: *i64=sys_mmap(8*cfw*cH) as *i64; i=0; while i<cfw*cH {cpB[i]=cbpl[i]; cpR[i]=crpl[i]; i=i+1} 311 var ry: i64=0; while ry<nrows { var rx: i64=0; while rx<ncols { let ci: i64=ry*ncols+rx 312 sao_apply_comp(frame, cpY, fw, W, H, rx*ctbSize, ry*ctbSize, ctbSize, saoP, ci*24) 313 sao_apply_comp(cbpl, cpB, cfw, cW, cH, rx*cs, ry*cs, cs, saoP, ci*24+8) 314 sao_apply_comp(crpl, cpR, cfw, cW, cH, rx*cs, ry*cs, cs, saoP, ci*24+16) 315 rx=rx+1 } ry=ry+1 } 316 return 0 317} 318func write_pgm(frame: *i64, w: i64, h: i64, path: *u8) -> i64 { let fd: i64=sys_openat_wr(path,420); if fd<0 {return 0-1} let hdr: *u8=sys_mmap(64); var p: i64=0; hdr[p]=(80 as u8);p=p+1; hdr[p]=(53 as u8);p=p+1; hdr[p]=(10 as u8);p=p+1; let tb: *u8=sys_mmap(16); var ti: i64=0; var tw: i64=w; while tw>0{tb[ti]=((48+tw%10) as u8);ti=ti+1;tw=tw/10} while ti>0{ti=ti-1;hdr[p]=tb[ti];p=p+1} hdr[p]=(32 as u8);p=p+1; var th: i64=h; ti=0; while th>0{tb[ti]=((48+th%10) as u8);ti=ti+1;th=th/10} while ti>0{ti=ti-1;hdr[p]=tb[ti];p=p+1} hdr[p]=(10 as u8);p=p+1; hdr[p]=(50 as u8);p=p+1; hdr[p]=(53 as u8);p=p+1; hdr[p]=(53 as u8);p=p+1; hdr[p]=(10 as u8);p=p+1; sys_write(fd,hdr,p); let body: *u8=sys_mmap(w*h); var i: i64=0; while i<w*h { var v: i64=frame[i]>>2; if v<0{v=0} if v>255{v=255} body[i]=(v as u8); i=i+1 } sys_write(fd,body,w*h); sys_close(fd); return 0 } 319 320// CABAC terminate decode (9.3.4.3.5) for end_of_slice_segment_flag / end_of_sub_stream: range-=2, terminate if offset>=range. 321func cterm(cab: *i64) -> i64 { cab[0]=cab[0]-2; if cab[1]>=cab[0] {return 1} crenorm(cab); return 0 } 322// sao offsets for one component (4 abs TR cMax31; band -> signs for nonzero + band_position; edge eo_class by caller) 323// decode 4 SAO offsets into saoP[off..off+3] (signed); return band_position (band) or 0 (edge: cat3,4 negated). 324func sao_offs(cab: *i64, ty: i64, saoP: *i64, off: i64) -> i64 { var i: i64=0; while i<4 {saoP[off+i]=tr_bypass(cab,31); i=i+1} if ty==1 { i=0; while i<4 { if saoP[off+i]!=0 { if cbyp(cab)==1 {saoP[off+i]=0-saoP[off+i]} } i=i+1 } var bp: i64=0; var b: i64=0; while b<5 {bp=(bp<<1)|cbyp(cab); b=b+1} return bp } saoP[off+2]=0-saoP[off+2]; saoP[off+3]=0-saoP[off+3]; return 0 } 325// sao() for a CTB (7.3.8.3): merge_left/up, then luma + chroma(cb shares type with cr). SAO_MERGE=0, SAO_TYPE=1. 326func sao_decode(dec: *i64, rx: i64, ry: i64, saoL: i64, saoC: i64, chromaArray: i64) -> i64 { 327 let cab: *i64=dec[0] as *i64; let saoP: *i64=dec[58] as *i64; let ncols: i64=dec[59]; let ci: i64=ry*ncols+rx 328 saoP[ci*24]=0; saoP[ci*24+8]=0; saoP[ci*24+16]=0 // default: all 3 components SAO off 329 if saoL==0 { if saoC==0 {return 0} } // sao() absent unless slice_sao_luma||chroma (7.3.8.3): no merge flags -> no CABAC desync 330 var ml: i64=0; var mu: i64=0 331 if rx>0 {ml=cdecD(dec,0)} 332 if ml==0 { if ry>0 {mu=cdecD(dec,0)} } 333 if ml==1 { var c: i64=0; while c<24 { saoP[ci*24+c]=saoP[(ci-1)*24+c]; c=c+1 } return 0 } 334 if mu==1 { var c: i64=0; while c<24 { saoP[ci*24+c]=saoP[(ci-ncols)*24+c]; c=c+1 } return 0 } 335 if saoL==1 { var ty: i64=0; if cdecD(dec,1)==1 { if cbyp(cab)==1 {ty=2} else {ty=1} } if ty!=0 { let bp: i64=sao_offs(cab,ty,saoP,ci*24+2); saoP[ci*24]=ty; if ty==2 {saoP[ci*24+1]=(cbyp(cab)<<1)|cbyp(cab)} else {saoP[ci*24+1]=bp} } } 336 if saoC==1 { if chromaArray!=0 { var tyc: i64=0; if cdecD(dec,1)==1 { if cbyp(cab)==1 {tyc=2} else {tyc=1} } if tyc!=0 { let bpb: i64=sao_offs(cab,tyc,saoP,ci*24+10); saoP[ci*24+8]=tyc; var ecc: i64=0; if tyc==2 {ecc=(cbyp(cab)<<1)|cbyp(cab); saoP[ci*24+9]=ecc} else {saoP[ci*24+9]=bpb} let bpr: i64=sao_offs(cab,tyc,saoP,ci*24+18); saoP[ci*24+16]=tyc; if tyc==2 {saoP[ci*24+17]=ecc} else {saoP[ci*24+17]=bpr} } } } 337 return 0 338} 339func iabs(v: i64) -> i64 { if v<0 {return 0-v} return v } 340// reference-sample smoothing (8.4.4.2.3): [1 2 1] filter when mode!=DC, N>4, and minDistVerHor > threshold[N]. 341// (strong bilinear smoothing for 32x32 deferred.) Filters refL[0..2N-1], refT[0..2N-1], corner in place. 342func smooth_refs(refL: *i64, refT: *i64, cornerP: *i64, N: i64, mode: i64) -> i64 { 343 if mode==1 {return 0} 344 if N==4 {return 0} 345 var thresh: i64=8; if N==8 {thresh=7} else { if N==16 {thresh=1} else { if N==32 {thresh=0} else {return 0} } } 346 var d1: i64=iabs(mode-26); var d2: i64=iabs(mode-10); var d: i64=d1; if d2<d1 {d=d2} 347 if d<=thresh {return 0} 348 let c: i64=cornerP[0]; let nfL: *i64=sys_mmap(8*520) as *i64; let nfT: *i64=sys_mmap(8*520) as *i64 349 let nc: i64=(refL[0]+2*c+refT[0]+2)>>2 350 nfL[0]=(c+2*refL[0]+refL[1]+2)>>2; var y: i64=1; while y<2*N-1 {nfL[y]=(refL[y-1]+2*refL[y]+refL[y+1]+2)>>2; y=y+1} nfL[2*N-1]=refL[2*N-1] 351 nfT[0]=(c+2*refT[0]+refT[1]+2)>>2; var x: i64=1; while x<2*N-1 {nfT[x]=(refT[x-1]+2*refT[x]+refT[x+1]+2)>>2; x=x+1} nfT[2*N-1]=refT[2*N-1] 352 cornerP[0]=nc; var k: i64=0; while k<2*N {refL[k]=nfL[k]; refT[k]=nfT[k]; k=k+1} 353 return 0 354} 355// MPM candidate list (8.4.2): from left (x0-1,y0) + above (x0,y0-1) IntraPredModeY (above-CTB -> DC). mode grid = dec[31], gw = dec[33]. 356func mpm_list(dec: *i64, x0: i64, y0: i64, candList: *i64) -> i64 { 357 let mg: *i64=dec[31] as *i64; let gw: i64=dec[33] 358 var candA: i64=1; if x0>0 { let m: i64=mg[(y0>>2)*gw+((x0-1)>>2)]; if m>=0 {candA=m} } 359 var candB: i64=1; if y0>0 { let ctbTop: i64=(y0>>6)<<6; if (y0-1)>=ctbTop { let m: i64=mg[((y0-1)>>2)*gw+(x0>>2)]; if m>=0 {candB=m} } } 360 if candA==candB { if candA<2 {candList[0]=0; candList[1]=1; candList[2]=26} else {candList[0]=candA; candList[1]=2+((candA+29)%32); candList[2]=2+((candA-2+1)%32)} } 361 else { candList[0]=candA; candList[1]=candB; var hp: i64=0; if candA==0 {hp=1} if candB==0 {hp=1} var hd: i64=0; if candA==1 {hd=1} if candB==1 {hd=1} var c2: i64=26; if hp==0 {c2=0} else { if hd==0 {c2=1} } candList[2]=c2 } 362 return 0 363} 364// coding_unit (I-slice intra), PART_2Nx2N or PART_NxN (at min-CU). Decodes per-PU IntraPredModeY into the mode grid 365// (so xtree reads each TU's mode by position), intra_chroma, sets IntraSplitFlag (dec[38]), reconstructs via xtree. 366func coding_unit(dec: *i64, x0: i64, y0: i64, log2Cb: i64, depth: i64) -> i64 { 367 let N: i64=1<<log2Cb; let cab: *i64=dec[0] as *i64 368 dec[27]=dec[39]+12 // Qp'Y = qPY_PRED(=qPY_PREV) + QpBdOffsetY(12); cu_qp_delta updates it 369 if dec[36]==1 { cdecD(dec,5) } 370 var nPart: i64=1; if log2Cb==dec[30] { if cdecD(dec,6)==0 {nPart=2} } 371 let puS: i64=N/nPart; let nPU: i64=nPart*nPart; dec[38]=0; if nPart==2 {dec[38]=1} 372 let prevF: *i64=sys_mmap(8*4) as *i64; var p: i64=0; while p<nPU {prevF[p]=cdecD(dec,7); p=p+1} 373 let candList: *i64=sys_mmap(8*4) as *i64; let mg: *i64=dec[31] as *i64; let dg: *i64=dec[32] as *i64; let gw: i64=dec[33] 374 p=0 375 while p<nPU { 376 let px: i64=x0+(p%nPart)*puS; let py: i64=y0+(p/nPart)*puS 377 mpm_list(dec, px, py, candList) 378 var m: i64=0 379 if prevF[p]==1 { let idx: i64=tr_bypass(cab,2); m=candList[idx] } else { var rem: i64=0; var rb: i64=0; while rb<5 {rem=(rem<<1)|cbyp(cab); rb=rb+1} var i: i64=0; while i<2 { var j: i64=i+1; while j<3 { if candList[j]<candList[i] {let t: i64=candList[i]; candList[i]=candList[j]; candList[j]=t} j=j+1 } i=i+1 } var k: i64=0; while k<3 { if rem>=candList[k] {rem=rem+1} k=k+1 } m=rem } 380 let pn2: i64=puS>>2; var gy: i64=0; while gy<pn2 { var gx: i64=0; while gx<pn2 { mg[((py>>2)+gy)*gw+((px>>2)+gx)]=m; dg[((py>>2)+gy)*gw+((px>>2)+gx)]=depth; gx=gx+1 } gy=gy+1 } 381 p=p+1 382 } 383 let cbin: i64=cdecD(dec,8); var modeC: i64=mg[(y0>>2)*gw+(x0>>2)]; if cbin==1 { let ci: i64=(cbyp(cab)<<1)|cbyp(cab); var mc2: i64=0; if ci==1 {mc2=26} if ci==2 {mc2=10} if ci==3 {mc2=1} if mc2==modeC {mc2=34} modeC=mc2 } dec[43]=modeC 384 xtree(dec, log2Cb, 0, 0, 0, x0, y0) 385 return 0 386} 387// coding_quadtree (7.3.8.4): split_cu_flag (ctxInc from neighbour CtDepths) or forced at picture boundary; recurse or CU. 388func coding_quadtree(dec: *i64, x0: i64, y0: i64, log2Cb: i64, depth: i64) -> i64 { 389 let picW: i64=dec[34]; let picH: i64=dec[35]; let N: i64=1<<log2Cb 390 if dec[12]==1 { if log2Cb>=dec[40] {dec[13]=0} } // reset IsCuQpDeltaCoded at each quantization group (7.3.8.4) 391 var split: i64=0 392 if log2Cb>dec[30] { if x0+N<=picW { if y0+N<=picH { var ctxInc: i64=0; let dg: *i64=dec[32] as *i64; let gw: i64=dec[33]; if x0>0 { let dl: i64=dg[(y0>>2)*gw+((x0-1)>>2)]; if dl>depth {ctxInc=ctxInc+1} } if y0>0 { let da: i64=dg[((y0-1)>>2)*gw+(x0>>2)]; if da>depth {ctxInc=ctxInc+1} } split=cdecD(dec,2+ctxInc) } else {split=1} } else {split=1} } 393 if split==1 { let h: i64=1<<(log2Cb-1); coding_quadtree(dec,x0,y0,log2Cb-1,depth+1); if x0+h<picW {coding_quadtree(dec,x0+h,y0,log2Cb-1,depth+1)} if y0+h<picH {coding_quadtree(dec,x0,y0+h,log2Cb-1,depth+1)} if x0+h<picW { if y0+h<picH {coding_quadtree(dec,x0+h,y0+h,log2Cb-1,depth+1)} } } else { coding_unit(dec,x0,y0,log2Cb,depth) } 394 return 0 395} 396 397func main(argc: i64, argv: *i64) -> i64 { 398 var inpath: *u8 = "knowledge/staging/media/hevc_1ctu.mkv\x00" as *u8 // no-arg => HEVC R-GATE-1 fixture (wrapper-runnable gate) 399 if argc>=2 { inpath = argv[1] as *u8 } 400 let fd: i64=sys_openat_rd(inpath); if fd<0 {pe("ERROR open\n" as *u8); return 1} 401 let cap: i64=K_MAGIC_8388608; let b: *u8=sys_mmap(cap+16) 402 var off: i64=0; while off<cap { let r: i64=sys_read(fd, ((b as i64)+off) as *u8, cap-off); if r<=0 {off=off; break} off=off+r } 403 sys_close(fd); let n: i64=off; let lo: *i64=sys_mmap(16) as *i64 404 var i: i64=0; let id0: i64=rid(b,i,lo); let idl0: i64=lo[0]; let sz0: i64=rsz(b,i+idl0,lo); let szl0: i64=lo[0] 405 if id0!=0x1A45DFA3 {pe("not EBML\n" as *u8); return 1} 406 i=i+idl0+szl0+sz0; let sid: i64=rid(b,i,lo); let sidl: i64=lo[0]; let ssz: i64=rsz(b,i+sidl,lo); let sszl: i64=lo[0] 407 if sid!=0x18538067 {pe("no Segment\n" as *u8); return 1} 408 let cp: *u8=sys_mmap(K_MAGIC_8192); var cpn: i64=0; var vtrk: i64=0; var clustart: i64=0 409 var p: i64=i+sidl+sszl 410 while p+2<n { 411 let eid: i64=rid(b,p,lo); let eidl: i64=lo[0]; let esz: i64=rsz(b,p+eidl,lo); let eszl: i64=lo[0]; let ed: i64=p+eidl+eszl 412 if eid==0x1654AE6B { var q: i64=ed; while q+2<=ed+esz { let tid: i64=rid(b,q,lo); let tidl: i64=lo[0]; let tsz: i64=rsz(b,q+tidl,lo); let tszl: i64=lo[0]; let td: i64=q+tidl+tszl 413 if tid==0xAE { var tt: i64=0; var tnum: i64=0; var hev: i64=0; let lcp: *u8=sys_mmap(K_MAGIC_8192); var lcpn: i64=0; var r2: i64=td 414 while r2+2<=td+tsz { let fid: i64=rid(b,r2,lo); let fidl: i64=lo[0]; let fsz: i64=rsz(b,r2+fidl,lo); let fszl: i64=lo[0]; let fd2: i64=r2+fidl+fszl 415 if fid==0xD7 {tnum=ruint(b,fd2,fsz)} if fid==0x83 {tt=ruint(b,fd2,fsz)} if fid==0x86 { if fsz>=14 { if b[fd2+2]==(77 as u8) { if b[fd2+6]==(72 as u8){hev=1} } } } if fid==0x63A2 {lcpn=fsz; var c: i64=0; while c<fsz {if c<K_MAGIC_8192{lcp[c]=b[fd2+c]} c=c+1}} r2=fd2+fsz } 416 if tt==1 { if hev==1 {vtrk=tnum; cpn=lcpn; var c2: i64=0; while c2<lcpn {cp[c2]=lcp[c2]; c2=c2+1}} } } 417 q=td+tsz } } 418 if eid==0x1F43B675 {clustart=p; p=n} else { if esz>n {p=n} else {p=ed+esz} } 419 } 420 if cpn==0 {pe("no HEVC track\n" as *u8); return 1} 421 let numArr: i64=cp[22] as i64; var ap: i64=23; var spso: i64=0; var spsl: i64=0; var ppso: i64=0; var ppsl: i64=0; var a: i64=0 422 while a<numArr { let nt: i64=(cp[ap] as i64)&0x3f; let nn: i64=((cp[ap+1] as i64)<<8)|(cp[ap+2] as i64); ap=ap+3; var k: i64=0; while k<nn { let nl: i64=((cp[ap] as i64)<<8)|(cp[ap+1] as i64); ap=ap+2; if nt==33 {if spsl==0{spso=ap;spsl=nl}} if nt==34 {if ppsl==0{ppso=ap;ppsl=nl}} ap=ap+nl; k=k+1 } a=a+1 } 423 // ---- SPS (to SAO + chroma) ---- 424 let srb: *u8=sys_mmap(spsl+16); let srn: i64=deemul(cp,spso,spsl,2,srb); let ss: *i64=sys_mmap(32) as *i64; ss[0]=srb as i64; ss[1]=0; ss[2]=srn 425 hb(ss,4); let maxsub: i64=hb(ss,3); hb(ss,1); hb(ss,8); hb(ss,32); hb(ss,32); hb(ss,16); hb(ss,8) 426 hue(ss); let chroma: i64=hue(ss); var sepcp: i64=0; if chroma==3 {sepcp=hb(ss,1)} 427 let picWraw: i64=hue(ss); let picHraw: i64=hue(ss) // pic_width/height_in_luma_samples 428 if hb(ss,1)==1 {hue(ss);hue(ss);hue(ss);hue(ss)} 429 hue(ss); hue(ss); let log2_max_poc: i64=hue(ss)+4 // bd luma, bd chroma, log2_max_poc_lsb_minus4 430 let subord: i64=hb(ss,1); var sj: i64=maxsub; if subord==1{sj=0} while sj<=maxsub {hue(ss);hue(ss);hue(ss); sj=sj+1} 431 let mincb: i64=hue(ss)+3; let ctblog2: i64=mincb+hue(ss); let mintb: i64=hue(ss)+2; let maxtb: i64=mintb+hue(ss); hue(ss); let maxhi: i64=hue(ss) // cb/tb sizes + hier inter/intra 432 if hb(ss,1)==1 { if hb(ss,1)==1 {pe("(SPS scaling_list present - R3b-2 assumes absent)\n" as *u8)} } 433 hb(ss,1); let sao: i64=hb(ss,1); let pcm_en: i64=hb(ss,1); if pcm_en==1 { hb(ss,4); hb(ss,4); hue(ss); hue(ss); hb(ss,1) } 434 let ndp: *i64=sys_mmap(8*128) as *i64; let num_str_rps: i64=hue(ss); var ri: i64=0; while ri<num_str_rps {parse_strps(ss,ri,num_str_rps,ndp); ri=ri+1} 435 let long_term_present: i64=hb(ss,1); var num_lt_sps: i64=0; if long_term_present==1 { num_lt_sps=hue(ss); var li: i64=0; while li<num_lt_sps {hb(ss,log2_max_poc); hb(ss,1); li=li+1} } 436 let sps_temporal_mvp: i64=hb(ss,1) 437 let chromaArray: i64=chroma // separate_colour_plane=0 -> ChromaArrayType=chroma_format_idc 438 // ---- PPS (full enough for the slice header) ---- 439 let prb: *u8=sys_mmap(ppsl+16); let prn: i64=deemul(cp,ppso,ppsl,2,prb); let ps2: *i64=sys_mmap(32) as *i64; ps2[0]=prb as i64; ps2[1]=0; ps2[2]=prn 440 hue(ps2); hue(ps2) // pps_id, sps_id 441 let dep_en: i64=hb(ps2,1); let outfp: i64=hb(ps2,1); let nehb: i64=hb(ps2,3); let sdh_en: i64=hb(ps2,1); let cabac_init: i64=hb(ps2,1) 442 hue(ps2); hue(ps2) // num_ref default 443 let initqp: i64=26+hse(ps2) 444 hb(ps2,1); hb(ps2,1) // constrained_intra, transform_skip 445 let cuqp_en: i64=hb(ps2,1); var cuqp_depth: i64=0; if cuqp_en==1 {cuqp_depth=hue(ps2)} // cu_qp_delta_enabled + diff_cu_qp_delta_depth 446 let ppsCbOff: i64=hse(ps2); let ppsCrOff: i64=hse(ps2) // cb,cr qp offset 447 let chroma_qp_off_present: i64=hb(ps2,1) 448 hb(ps2,1); hb(ps2,1) // weighted_pred, weighted_bipred 449 let tqbypass_en: i64=hb(ps2,1) // transquant_bypass 450 let tiles: i64=hb(ps2,1); let esync: i64=hb(ps2,1) 451 if tiles==1 { let nc: i64=hue(ps2); let nr: i64=hue(ps2); if hb(ps2,1)==0 { var t: i64=0; while t<nc {hue(ps2); t=t+1} t=0; while t<nr {hue(ps2); t=t+1} } hb(ps2,1) } 452 let lf_across_slices: i64=hb(ps2,1) 453 var deb_override: i64=0; var deb_disabled: i64=0 454 var ppsBetaOff: i64=0; var ppsTcOff: i64=0; if hb(ps2,1)==1 { deb_override=hb(ps2,1); deb_disabled=hb(ps2,1); if deb_disabled==0 {ppsBetaOff=hse(ps2)<<1; ppsTcOff=hse(ps2)<<1} } 455 if hb(ps2,1)==1 {pe("(PPS scaling_list present - R3b-2 assumes absent)\n" as *u8)} 456 hb(ps2,1) // lists_modification_present 457 hue(ps2) // log2_parallel_merge_level_minus2 458 let sshext: i64=hb(ps2,1) 459 pe("PPS: initqp=" as *u8); pn(initqp); pe(" nehb=" as *u8); pn(nehb); pe(" tiles=" as *u8); pn(tiles); pe(" esync=" as *u8); pn(esync); pe(" deb_override=" as *u8); pn(deb_override); pe(" lf_slices=" as *u8); pn(lf_across_slices); pe(" sshext=" as *u8); pn(sshext); pe(" SAO=" as *u8); pn(sao); pe("\n" as *u8) 460 // ---- first slice NAL ---- 461 if clustart==0 {pe("no cluster\n" as *u8); return 1} 462 var ftgt: i64=0; if argc>2 { let a2: *u8=argv[2] as *u8; var ai: i64=0; while a2[ai]!=(0 as u8) {ftgt=ftgt*10+((a2[ai] as i64)-48); ai=ai+1} } 463 var slo: i64=0; var sll: i64=0; var ntype: i64=0; var fidx: i64=0; var found: i64=0; var cp3: i64=clustart 464 while cp3+2<n { if found==1 {cp3=n} else { let cid: i64=rid(b,cp3,lo); let cidl: i64=lo[0]; let csz: i64=rsz(b,cp3+cidl,lo); let cszl: i64=lo[0]; let cd: i64=cp3+cidl+cszl 465 if cid==0x1F43B675 { var q2: i64=cd; var cend: i64=cd+csz; if cend>n{cend=n} 466 while q2+2<=cend { if found==1{q2=cend} else { let bid: i64=rid(b,q2,lo); let bidl: i64=lo[0]; let bsz: i64=rsz(b,q2+bidl,lo); let bszl: i64=lo[0]; let bd: i64=q2+bidl+bszl 467 var isblk: i64=0; if bid==0xA3 {isblk=1} if bid==0xA1 {isblk=1} 468 if isblk==1 { let tl: i64=vlen(b[bd] as i64); let trk: i64=rsz(b,bd,lo); let flg: i64=b[bd+tl+2] as i64; let foff: i64=bd+tl+3; let flen: i64=bsz-tl-3 469 if trk==vtrk { var w: i64=foff; while w+4<=foff+flen { if found==1{w=foff+flen} else { let nl: i64=((b[w] as i64)<<24)|((b[w+1] as i64)<<16)|((b[w+2] as i64)<<8)|(b[w+3] as i64); let nt: i64=((b[w+4] as i64)>>1)&0x3f; if nt<32 { if fidx==ftgt {ntype=nt; slo=w+4; sll=nl; found=1} fidx=fidx+1 } w=w+4+nl } } } } 470 if bid==0xA0 {q2=bd} else {q2=bd+bsz} } } 471 cp3=cd+csz } else { if csz>n{cp3=n} else {cp3=cd+csz} } } } 472 if found==0 {pe("no slice NAL\n" as *u8); return 1} 473 // ---- slice header -> CABAC start + SliceQpY + sao flags ---- 474 let hb2: *u8=sys_mmap(sll+16); let epos: *i64=sys_mmap(8*(sll+16)) as *i64; let hn: i64=deemul_ep(b,slo,sll,2,hb2,epos); let hs: *i64=sys_mmap(32) as *i64; hs[0]=hb2 as i64; hs[1]=0; hs[2]=hn 475 hb(hs,1) // first_slice_segment_in_pic_flag 476 if ntype>=16 { if ntype<=23 {hb(hs,1)} } // no_output_of_prior_pics 477 hue(hs) // slice_pic_parameter_set_id 478 var eb: i64=0; while eb<nehb {hb(hs,1); eb=eb+1} 479 let stype: i64=hue(hs) // slice_type 480 if outfp==1 {hb(hs,1)} 481 if sepcp==1 {hb(hs,2)} 482 // non-IDR -> pic_order_cnt_lsb + short_term_ref_pic_set + (long_term) + slice_temporal_mvp 483 if ntype!=19 { if ntype!=20 { 484 hb(hs, log2_max_poc) // pic_order_cnt_lsb 485 let st_sps_flag: i64=hb(hs,1) // short_term_ref_pic_set_sps_flag 486 if st_sps_flag==0 { parse_strps(hs, num_str_rps, num_str_rps, ndp) } else { if num_str_rps>1 {hb(hs, ceil_log2(num_str_rps))} } 487 if long_term_present==1 { var nls: i64=0; if num_lt_sps>0 {nls=hue(hs)} let nlp: i64=hue(hs); var li: i64=0; while li<nls+nlp { if li<nls { if num_lt_sps>1 {hb(hs, ceil_log2(num_lt_sps))} } else { hb(hs, log2_max_poc); hb(hs,1) } if hb(hs,1)==1 {hue(hs)} li=li+1 } } 488 if sps_temporal_mvp==1 {hb(hs,1)} // slice_temporal_mvp_enabled_flag 489 } } 490 var sao_luma: i64=0; var sao_chroma: i64=0 491 if sao==1 { sao_luma=hb(hs,1); if chromaArray!=0 {sao_chroma=hb(hs,1)} } 492 // I-slice: no ref list / mvd / etc. 493 let qpdelta: i64=hse(hs); let sliceQpY: i64=initqp+qpdelta 494 var slCbOff: i64=0; var slCrOff: i64=0; if chroma_qp_off_present==1 {slCbOff=hse(hs); slCrOff=hse(hs)} 495 var deb_disabled_slice: i64=deb_disabled; var slBetaOff: i64=ppsBetaOff; var slTcOff: i64=ppsTcOff 496 if deb_override==1 { if hb(hs,1)==1 { deb_disabled_slice=hb(hs,1); if deb_disabled_slice==0 {slBetaOff=hse(hs)<<1; slTcOff=hse(hs)<<1} } } 497 if lf_across_slices==1 { var c: i64=0; if sao_luma==1{c=1} if sao_chroma==1{c=1} if deb_disabled_slice==0{c=1} if c==1 {hb(hs,1)} } 498 var nep: i64=0; let epo: *i64=sys_mmap(8*256) as *i64 499 if tiles==1 { nep=hue(hs); if nep>0 { let ol: i64=hue(hs)+1; var e2: i64=0; while e2<nep {epo[e2]=hb(hs,ol)+1; e2=e2+1} } } else { if esync==1 { nep=hue(hs); if nep>0 { let ol: i64=hue(hs)+1; var e2: i64=0; while e2<nep {epo[e2]=hb(hs,ol)+1; e2=e2+1} } } } 500 if sshext==1 { let sl2: i64=hue(hs); var e3: i64=0; while e3<sl2 {hb(hs,8); e3=e3+1} } 501 let cabac_byte: i64=(hs[1]>>3)+1 // byte_alignment: '1' bit then pad -> next byte 502 pe("slice_type=" as *u8); pn(stype); pe(" SliceQpY=" as *u8); pn(sliceQpY); pe(" sao_luma=" as *u8); pn(sao_luma); pe(" sao_chroma=" as *u8); pn(sao_chroma); pe(" sdh_en=" as *u8); pn(sdh_en); pe(" cuqp_en=" as *u8); pn(cuqp_en); pe(" cuqp_depth=" as *u8); pn(cuqp_depth); pe(" hdr_bits=" as *u8); pn(hs[1]); pe(" cabac_byte=" as *u8); pn(cabac_byte); pe(" (of " as *u8); pn(hn); pe(")\n" as *u8) 503 if stype!=2 {pe("(not an I-slice; R3b-2 targets I)\n" as *u8)} 504 // ---- CABAC tables + contexts ---- 505 let rlps: *i64=sys_mmap(8*300) as *i64; let tlps: *i64=sys_mmap(8*80) as *i64; let tmps: *i64=sys_mmap(8*80) as *i64 506 parse_nums("128 176 208 240 128 167 197 227 128 158 187 216 123 150 178 205 116 142 169 195 111 135 160 185 105 128 152 175 100 122 144 166 95 116 137 158 90 110 130 150 85 104 123 142 81 99 117 135 77 94 111 128 73 89 105 122 69 85 100 116 66 80 95 110 62 76 90 104 59 72 86 99 56 69 81 94 53 65 77 89 51 62 73 85 48 59 69 80 46 56 66 76 43 53 63 72 41 50 59 69 39 48 56 65 37 45 54 62 35 43 51 59 33 41 48 56 32 39 46 53 30 37 43 50 29 35 41 48 27 33 39 45 26 31 37 43 24 30 35 41 23 28 33 39 22 27 32 37 21 26 30 35 20 24 29 33 19 23 27 31 18 22 26 30 17 21 25 28 16 20 23 27 15 19 22 25 14 18 21 24 14 17 20 23 13 16 19 22 12 15 18 21 12 14 17 20 11 14 16 19 11 13 15 18 10 12 15 17 10 12 14 16 9 11 13 15 9 11 12 14 8 10 12 14 8 9 11 13 7 9 11 12 7 9 10 12 7 8 10 11 6 8 9 11 6 7 9 10 6 7 8 9 2 2 2 2" as *u8, rlps) 507 parse_nums("0 0 1 2 2 4 4 5 6 7 8 9 9 11 11 12 13 13 15 15 16 16 18 18 19 19 21 21 22 22 23 24 24 25 26 26 27 27 28 29 29 30 30 30 31 32 32 33 33 33 34 34 35 35 35 36 36 36 37 37 37 38 38 63" as *u8, tlps) 508 parse_nums("1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 62 63" as *u8, tmps) 509 let iv: *i64=sys_mmap(8*256) as *i64 510 let NCTX: i64=parse_nums("153 200 139 141 157 154 184 184 63 153 138 138 111 141 94 138 182 154 154 154 154 139 139 110 110 124 125 140 153 125 127 140 109 111 143 127 111 79 108 123 63 110 110 124 125 140 153 125 127 140 109 111 143 127 111 79 108 123 63 91 171 134 141 111 111 125 110 110 94 124 108 124 107 125 141 179 153 125 107 125 141 179 153 125 107 125 141 179 153 125 140 139 182 182 152 136 152 136 153 136 139 111 136 139 111 141 111 140 92 137 138 140 152 138 139 153 74 149 92 139 107 122 152 140 179 166 182 140 227 122 197 138 153 136 167 152 152" as *u8, iv) 511 let ctx: *i64=sys_mmap(8*2*NCTX) as *i64; var ck: i64=0; while ck<NCTX {ctxi(ctx,ck,iv[ck],sliceQpY); ck=ck+1} 512 let OFF_SAO_MERGE: i64=0; let OFF_SAO_TYPE: i64=1; let OFF_SPLIT_CU: i64=2; let OFF_TQ_BYPASS: i64=5; let OFF_PREV_INTRA: i64=7; let OFF_INTRA_CHROMA: i64=8 513 // ---- CABAC init at the byte-aligned start ---- 514 let cab: *i64=sys_mmap(8*8) as *i64; cinit(cab, hb2, cabac_byte*8, hn) 515 pe("CABAC init: range=" as *u8); pn(cab[0]); pe(" offset=" as *u8); pn(cab[1]); pe("\n" as *u8) 516 // ---- R6b-2b: reconstruction state (matrices, tables, grids, frame buffer) ---- 517 let map: *i64=sys_mmap(8*16) as *i64; parse_nums("0 1 4 5 2 3 4 5 6 6 8 8 7 7 8 8" as *u8, map) 518 let lsc: *i64=sys_mmap(8*8) as *i64; parse_nums("40 45 51 57 64 72" as *u8, lsc) 519 let dct4r: *i64=sys_mmap(8*16) as *i64; parse_nums("64 64 64 64 83 36 -36 -83 64 -64 -64 64 36 -83 83 -36" as *u8, dct4r) 520 let dst4r: *i64=sys_mmap(8*16) as *i64; parse_nums("29 55 74 84 74 74 0 -74 84 -29 -74 55 55 -84 74 -29" as *u8, dst4r) // DST-VII for 4x4 luma intra (8.6.4.1) 521 let oc8: *i64=sys_mmap(8*16) as *i64; parse_nums("89 75 50 18 75 -18 -89 -50 50 -89 18 75 18 -50 75 -89" as *u8, oc8) 522 let oc16: *i64=sys_mmap(8*64) as *i64; parse_nums("90 87 80 70 57 43 25 9 87 57 9 -43 -80 -90 -70 -25 80 9 -70 -87 -25 57 90 43 70 -43 -87 9 90 25 -80 -57 57 -80 -25 90 -9 -87 43 70 43 -90 57 25 -87 70 9 -80 25 -70 90 -80 43 9 -57 87 9 -25 43 -57 70 -80 87 -90" as *u8, oc16) 523 let oc32: *i64=sys_mmap(8*256) as *i64; parse_nums("90 90 88 85 82 78 73 67 61 54 46 38 31 22 13 4 90 82 67 46 22 -4 -31 -54 -73 -85 -90 -88 -78 -61 -38 -13 88 67 31 -13 -54 -82 -90 -78 -46 -4 38 73 90 85 61 22 85 46 -13 -67 -90 -73 -22 38 82 88 54 -4 -61 -90 -78 -31 82 22 -54 -90 -61 13 78 85 31 -46 -90 -67 4 73 88 38 78 -4 -82 -73 13 85 67 -22 -88 -61 31 90 54 -38 -90 -46 73 -31 -90 -22 78 67 -38 -90 -13 82 61 -46 -88 -4 85 54 67 -54 -78 38 85 -22 -90 4 90 13 -88 -31 82 46 -73 -61 61 -73 -46 82 31 -88 -13 90 -4 -90 22 85 -38 -78 54 67 54 -85 -4 88 -46 -61 82 13 -90 38 67 -78 -22 90 -31 -73 46 -90 38 54 -90 31 61 -88 22 67 -85 13 73 -82 4 78 38 -88 73 -4 -67 90 -46 -31 85 -78 13 61 -90 54 22 -82 31 -78 90 -61 4 54 -88 82 -38 -22 73 -90 67 -13 -46 85 22 -61 85 -90 73 -38 -4 46 -78 90 -82 54 -13 -31 67 -88 13 -38 61 -78 88 -90 85 -73 54 -31 4 22 -46 67 -82 90 4 -13 22 -31 38 -46 54 -61 67 -73 78 -82 85 -88 90 -90" as *u8, oc32) 524 let g8: *i64=sys_mmap(8*64) as *i64; build_dct(g8,8,dct4r,oc8) 525 let g16: *i64=sys_mmap(8*256) as *i64; build_dct(g16,16,g8,oc16) 526 let g32: *i64=sys_mmap(8*K_MAGIC_1024) as *i64; build_dct(g32,32,g16,oc32) 527 let angT: *i64=sys_mmap(8*40) as *i64; parse_nums("32 26 21 17 13 9 5 2 0 -2 -5 -9 -13 -17 -21 -26 -32 -26 -21 -17 -13 -9 -5 -2 0 2 5 9 13 17 21 26 32" as *u8, angT) 528 let invT: *i64=sys_mmap(8*20) as *i64; parse_nums("-4096 -1638 -910 -630 -482 -390 -315 -256 -315 -390 -482 -630 -910 -1638 -4096" as *u8, invT) 529 let CTB: i64=1<<ctblog2; let FW: i64=picWraw 530 let nrows: i64=(picHraw+CTB-1)/CTB; let ncols: i64=(picWraw+CTB-1)/CTB; let FH: i64=nrows*CTB 531 let frame: *i64=sys_mmap(8*FW*FH) as *i64; var fz: i64=0; while fz<FW*FH {frame[fz]=0-1; fz=fz+1} 532 let gw4: i64=FW>>2; let gh4: i64=FH>>2; let bVm: *i64=sys_mmap(8*gw4*gh4) as *i64; let bHm: *i64=sys_mmap(8*gw4*gh4) as *i64; var bz: i64=0; while bz<gw4*gh4 {bVm[bz]=0; bHm[bz]=0; bz=bz+1} 533 let gw: i64=FW>>2; let gh: i64=FH>>2; let mg: *i64=sys_mmap(8*gw*gh) as *i64; let dg: *i64=sys_mmap(8*gw*gh) as *i64; var gz: i64=0; while gz<gw*gh {mg[gz]=0-1; dg[gz]=0; gz=gz+1} 534 let coeffbuf: *i64=sys_mmap(8*K_MAGIC_1024) as *i64; let tmpb: *i64=sys_mmap(8*K_MAGIC_1024) as *i64; let predb: *i64=sys_mmap(8*K_MAGIC_1024) as *i64 535 let savedCtx: *i64=sys_mmap(8*2*NCTX) as *i64 536 let dec: *i64=sys_mmap(8*64) as *i64; dec[40]=ctblog2-cuqp_depth; dec[0]=cab as i64; dec[1]=ctx as i64; dec[2]=rlps as i64; dec[3]=tlps as i64; dec[4]=tmps as i64; dec[5]=maxtb; dec[6]=mintb; dec[7]=maxhi; dec[8]=0; dec[9]=0; dec[10]=map as i64; dec[11]=0; dec[12]=cuqp_en; dec[13]=0; dec[14]=sdh_en; dec[15]=coeffbuf as i64; dec[16]=0; dec[17]=frame as i64; dec[18]=FW; dec[19]=FH; dec[20]=lsc as i64; dec[21]=g8 as i64; dec[22]=g16 as i64; dec[23]=g32 as i64; dec[24]=dct4r as i64; dec[25]=tmpb as i64; dec[26]=predb as i64; dec[27]=sliceQpY+12; dec[28]=angT as i64; dec[29]=invT as i64; dec[30]=mincb; dec[31]=mg as i64; dec[32]=dg as i64; dec[33]=gw; dec[34]=picWraw; dec[35]=picHraw; dec[36]=tqbypass_en; dec[37]=pcm_en; dec[38]=0; dec[39]=sliceQpY 537 dec[44]=dst4r as i64 // DST-VII matrix for 4x4 luma intra residual (8.6.4.1) 538 let cfw: i64=FW>>1; let cfh: i64=FH>>1; let cbpl: *i64=sys_mmap(8*cfw*cfh) as *i64; let crpl: *i64=sys_mmap(8*cfw*cfh) as *i64; var cz: i64=0; while cz<cfw*cfh {cbpl[cz]=0-1; crpl[cz]=0-1; cz=cz+1} 539 let qpct: *i64=sys_mmap(8*16) as *i64; parse_nums("29 30 31 32 33 33 34 34 35 35 36 36 37 37" as *u8, qpct) 540 dec[48]=cbpl as i64; dec[49]=crpl as i64; dec[50]=ppsCbOff+slCbOff; dec[51]=ppsCrOff+slCrOff; dec[52]=cfw; dec[53]=cfh; dec[54]=qpct as i64 541 dec[55]=bVm as i64; dec[56]=bHm as i64; dec[57]=gw4 542 let saoPm: *i64=sys_mmap(8*ncols*nrows*24) as *i64; dec[58]=saoPm as i64; dec[59]=ncols; dec[60]=nrows 543 pe(" WPP full frame: " as *u8); pn(nrows); pe(" rows x " as *u8); pn(ncols); pe(" cols (nep=" as *u8); pn(nep); pe(")\n" as *u8) 544 let cabac_data_ebsp: i64=epos[cabac_byte]; var cum_ebsp: i64=0; var row: i64=0; var eos: i64=0 545 while row<nrows { 546 if row>0 { if esync==1 { cum_ebsp=cum_ebsp+epo[row-1]; let tgt: i64=cabac_data_ebsp+cum_ebsp; var rb: i64=cabac_byte; var kk: i64=0; while kk<hn { if epos[kk]>=tgt {rb=kk; kk=hn} else {kk=kk+1} } cinit(cab, hb2, rb*8, hn); var rc: i64=0; while rc<2*NCTX {ctx[rc]=savedCtx[rc]; rc=rc+1} dec[39]=sliceQpY } } 547 var col: i64=0 548 while col<ncols { let x0: i64=col*CTB; let y0: i64=row*CTB; sao_decode(dec, col, row, sao_luma, sao_chroma, chromaArray); coding_quadtree(dec, x0, y0, ctblog2, 0); if col==1 { var sc: i64=0; while sc<2*NCTX {savedCtx[sc]=ctx[sc]; sc=sc+1} } eos=cterm(cab); col=col+1 } 549 row=row+1 550 } 551 if deb_disabled_slice==0 { let qpctd: *i64=dec[54] as *i64; let qpiCb: i64=clip3(0-12,57,sliceQpY+ppsCbOff); var qpcb: i64=qpiCb; if qpiCb>=30 { if qpiCb<=43 {qpcb=qpctd[qpiCb-30]} else {qpcb=qpiCb-6} } let qpiCr: i64=clip3(0-12,57,sliceQpY+ppsCrOff); var qpcr: i64=qpiCr; if qpiCr>=30 { if qpiCr<=43 {qpcr=qpctd[qpiCr-30]} else {qpcr=qpiCr-6} } deblock(dec, sliceQpY, slBetaOff, slTcOff, qpcb, qpcr) } 552 var saoOn: i64=0; if sao_luma==1 {saoOn=1} if sao_chroma==1 {saoOn=1} if saoOn==1 { apply_sao(dec, 1<<ctblog2) } 553 pe(" WPP done: cbf=1 luma TUs=" as *u8); pn(dec[8]); pe(" zero TUs=" as *u8); pn(dec[11]); pe(" final range=" as *u8); pn(cab[0]); pe("\n" as *u8) 554 var mn: i64=K_MAGIC_99999; var mx: i64=0; var sm: i64=0; var fi: i64=0 555 while fi<FW*picHraw { var v: i64=frame[fi]; if v<0 {v=512} if v<mn{mn=v} if v>mx{mx=v} sm=sm+v; fi=fi+1 } 556 write_pgm(frame, FW, picHraw, "/mnt/c/Users/elder/hevc_frame.pgm" as *u8) 557 pe("R6b-2c-2: FULL FRAME reconstructed (" as *u8); pn(FW); pe("x" as *u8); pn(picHraw); pe("): min=" as *u8); pn(mn); pe(" max=" as *u8); pn(mx); pe(" mean=" as *u8); pn(sm/(FW*picHraw)); pe(" -> /mnt/c/Users/elder/hevc_frame.pgm\n" as *u8) 558 // ---- HARNESS GATE (HEVC R-GATE-1): bit-exact LUMA vs ffmpeg reference (yuv420p10le, 16-bit LE). Oracle 559 // only (3rd-party proof of a non-novel codec, per doctrine). Also reports the diff PROFILE (interior vs 560 // block-edge px) so a non-bit-exact result tells us WHICH filter (deblock at 8-edges) is still missing. 561 let rfd: i64 = sys_openat_rd("knowledge/staging/media/hevc_ref.yuv\x00" as *u8) 562 if rfd >= 0 { 563 let cbw: i64 = FW>>1; let cbh: i64 = picHraw>>1; let lbytes: i64 = FW*picHraw*2; let allb: i64 = lbytes + 2*cbw*cbh*2; let rbuf: *u8 = sys_mmap(allb+16) 564 var roff: i64 = 0; while roff < allb { let r: i64 = sys_read(rfd, ((rbuf as i64)+roff) as *u8, allb-roff); if r<=0 {roff=roff; break} roff=roff+r } 565 sys_close(rfd) 566 var exact: i64 = 0; var total: i64 = 0; var maxd: i64 = 0 567 var edgeTot: i64 = 0; var edgeBad: i64 = 0; var intTot: i64 = 0; var intBad: i64 = 0; var firstX: i64 = 0-1; var firstY: i64 = 0-1 568 var yy: i64 = 0 569 while yy < picHraw { 570 var xx: i64 = 0 571 while xx < FW { 572 let ri: i64 = (yy*FW+xx)*2; let refv: i64 = (rbuf[ri] as i64) | ((rbuf[ri+1] as i64)<<8) 573 var mv: i64 = frame[yy*FW+xx]; if mv<0 {mv=512} 574 total = total+1; var d: i64 = mv-refv; if d<0 {d=0-d} 575 if d>maxd {maxd=d} 576 var onEdge: i64 = 0; if (xx&7)==0 {onEdge=1} if (yy&7)==0 {onEdge=1} 577 if onEdge==1 {edgeTot=edgeTot+1} else {intTot=intTot+1} 578 if d==0 {exact=exact+1} else { if onEdge==1 {edgeBad=edgeBad+1} else {intBad=intBad+1} if firstX<0 {firstX=xx; firstY=yy} } 579 xx=xx+1 580 } 581 yy=yy+1 582 } 583 pe("HEVC-LUMA vs ffmpeg: exact=" as *u8); pn(exact); pe("/" as *u8); pn(total); pe(" MAXDIFF=" as *u8); pn(maxd); pe("\n" as *u8) 584 pe(" diff profile: interior-bad=" as *u8); pn(intBad); pe("/" as *u8); pn(intTot); pe(" 8x8-edge-bad=" as *u8); pn(edgeBad); pe("/" as *u8); pn(edgeTot); pe(" first-diff @(" as *u8); pn(firstX); pe("," as *u8); pn(firstY); pe(")\n" as *u8) 585 let cfw2: i64 = dec[52]; let cbpl2: *i64 = dec[48] as *i64; let crpl2: *i64 = dec[49] as *i64 586 let cboff: i64 = lbytes; let croff: i64 = lbytes + cbw*cbh*2 587 var cbEx: i64=0; var cbMx: i64=0; var cbFx: i64=0-1; var cbFy: i64=0-1 588 var crEx: i64=0; var crMx: i64=0; var crFx: i64=0-1; var crFy: i64=0-1 589 var cyy: i64=0 590 while cyy<cbh { var cxx: i64=0; while cxx<cbw { 591 let rib: i64=cboff+(cyy*cbw+cxx)*2; let rvb: i64=(rbuf[rib] as i64)|((rbuf[rib+1] as i64)<<8); var mvb: i64=cbpl2[cyy*cfw2+cxx]; if mvb<0 {mvb=512} var db: i64=mvb-rvb; if db<0 {db=0-db} if db>cbMx {cbMx=db} if db==0 {cbEx=cbEx+1} else { if cbFx<0 {cbFx=cxx; cbFy=cyy} } 592 let ric: i64=croff+(cyy*cbw+cxx)*2; let rvc: i64=(rbuf[ric] as i64)|((rbuf[ric+1] as i64)<<8); var mvc: i64=crpl2[cyy*cfw2+cxx]; if mvc<0 {mvc=512} var dc: i64=mvc-rvc; if dc<0 {dc=0-dc} if dc>crMx {crMx=dc} if dc==0 {crEx=crEx+1} else { if crFx<0 {crFx=cxx; crFy=cyy} } 593 cxx=cxx+1 } cyy=cyy+1 } 594 let ctot: i64=cbw*cbh 595 pe("HEVC-CB: exact=" as *u8);pn(cbEx);pe("/" as *u8);pn(ctot);pe(" MAXDIFF=" as *u8);pn(cbMx);pe(" first-diff @(" as *u8);pn(cbFx);pe("," as *u8);pn(cbFy);pe(")\n" as *u8) 596 pe("HEVC-CR: exact=" as *u8);pn(crEx);pe("/" as *u8);pn(ctot);pe(" MAXDIFF=" as *u8);pn(crMx);pe(" first-diff @(" as *u8);pn(crFx);pe("," as *u8);pn(crFy);pe(")\n" as *u8) 597 var gv: i64 = 0; if total>0 { if exact==total { if cbEx==ctot { if crEx==ctot {gv=1} } } } 598 if gv==1 { pe("HEVC-DEC result=I-BIT-EXACT verdict=GREEN (Y " as *u8); pn(exact); pe(" Cb " as *u8); pn(cbEx); pe(" Cr " as *u8); pn(crEx); pe(" all exact vs ffmpeg, filters off)\n" as *u8); sys_exit(0); return 0 } 599 pe("HEVC-DEC result=FAIL verdict=RED (Y " as *u8);pn(exact);pe("/" as *u8);pn(total);pe(" Cb " as *u8);pn(cbEx);pe("/" as *u8);pn(ctot);pe(" Cr " as *u8);pn(crEx);pe("/" as *u8);pn(ctot);pe(")\n" as *u8); sys_exit(1); return 1 600 } 601 return 0 602}