nx_h264_run_before.nx source
↩ module page · 106 lines · 3926 B
1// nx_h264_run_before.nx -- CAVLC run_before VLC (rung 4c-iv), table-driven
2// encoder + decoder. run_before = number of zeros immediately before each
3// non-zero coefficient (distributing total_zeros); VLC table indexed by
4// zerosLeft (Table 9-10). Same machinery + round-trip-oracle pattern.
5// Filled: zerosLeft = 1, 2, 3 (the common, high-confidence columns). zerosLeft
6// 4..6 and >6 = data fill, validated by the real I-frame decode (capstone oracle).
7//
8// genealogy_id: itu_t_h264_table9_10_run_before
9// lineage_id: vlc_symbol_table + prefix_match_decode + roundtrip_oracle
10// license_tier: ORIGINAL
11import "nx_syscalls.nx"
12import "nx_h264_bits.nx"
13import "nx_h264_bitwriter.nx"
14
15func rb_table(zeros_left: i64, ln: *i64, cd: *i64, val: *i64) -> i64 {
16 if zeros_left == 1 {
17 ln[0]=1; cd[0]=1; val[0]=0 // "1"
18 ln[1]=1; cd[1]=0; val[1]=1 // "0"
19 return 2
20 }
21 if zeros_left == 2 {
22 ln[0]=1; cd[0]=1; val[0]=0 // "1"
23 ln[1]=2; cd[1]=1; val[1]=1 // "01"
24 ln[2]=2; cd[2]=0; val[2]=2 // "00"
25 return 3
26 }
27 if zeros_left == 3 {
28 ln[0]=2; cd[0]=3; val[0]=0 // "11"
29 ln[1]=2; cd[1]=2; val[1]=1 // "10"
30 ln[2]=2; cd[2]=1; val[2]=2 // "01"
31 ln[3]=2; cd[3]=0; val[3]=3 // "00"
32 return 4
33 }
34 if zeros_left == 4 {
35 ln[0]=2; cd[0]=3; val[0]=0 // "11"
36 ln[1]=2; cd[1]=2; val[1]=1 // "10"
37 ln[2]=2; cd[2]=1; val[2]=2 // "01"
38 ln[3]=3; cd[3]=1; val[3]=3 // "001"
39 ln[4]=3; cd[4]=0; val[4]=4 // "000"
40 return 5
41 }
42 if zeros_left == 5 {
43 ln[0]=2; cd[0]=3; val[0]=0 // "11"
44 ln[1]=2; cd[1]=2; val[1]=1 // "10"
45 ln[2]=3; cd[2]=3; val[2]=2 // "011"
46 ln[3]=3; cd[3]=2; val[3]=3 // "010"
47 ln[4]=3; cd[4]=1; val[4]=4 // "001"
48 ln[5]=3; cd[5]=0; val[5]=5 // "000"
49 return 6
50 }
51 if zeros_left == 6 {
52 ln[0]=2; cd[0]=3; val[0]=0 // "11"
53 ln[1]=3; cd[1]=0; val[1]=1 // "000"
54 ln[2]=3; cd[2]=1; val[2]=2 // "001"
55 ln[3]=3; cd[3]=3; val[3]=3 // "011"
56 ln[4]=3; cd[4]=2; val[4]=4 // "010"
57 ln[5]=3; cd[5]=5; val[5]=5 // "101"
58 ln[6]=3; cd[6]=4; val[6]=6 // "100"
59 return 7
60 }
61 if zeros_left > 6 {
62 // ffmpeg run_len[6]/run_bits[6]: zerosLeft>6, run_before 0..14
63 ln[0]=3;cd[0]=7; ln[1]=3;cd[1]=6; ln[2]=3;cd[2]=5; ln[3]=3;cd[3]=4
64 ln[4]=3;cd[4]=3; ln[5]=3;cd[5]=2; ln[6]=3;cd[6]=1; ln[7]=4;cd[7]=1
65 ln[8]=5;cd[8]=1; ln[9]=6;cd[9]=1; ln[10]=7;cd[10]=1; ln[11]=8;cd[11]=1
66 ln[12]=9;cd[12]=1; ln[13]=10;cd[13]=1; ln[14]=11;cd[14]=1
67 var z: i64 = 0
68 while z < 15 { val[z] = z; z = z + 1 }
69 return 15
70 }
71 return 0
72}
73
74func nx_run_before_encode(bw: *BitWriter, zeros_left: i64, run_before: i64) -> i64 {
75 let ln: *i64 = sys_mmap(32 * 8) as *i64
76 let cd: *i64 = sys_mmap(32 * 8) as *i64
77 let vl: *i64 = sys_mmap(32 * 8) as *i64
78 let n: i64 = rb_table(zeros_left, ln, cd, vl)
79 var i: i64 = 0
80 while i < n {
81 if vl[i] == run_before { bw_write_bits(bw, cd[i], ln[i]); return 1 }
82 i = i + 1
83 }
84 return 0
85}
86
87// returns run_before, or -1 if no match / column unfilled
88func nx_run_before_decode(br: *BitReader, zeros_left: i64) -> i64 {
89 let ln: *i64 = sys_mmap(32 * 8) as *i64
90 let cd: *i64 = sys_mmap(32 * 8) as *i64
91 let vl: *i64 = sys_mmap(32 * 8) as *i64
92 let n: i64 = rb_table(zeros_left, ln, cd, vl)
93 if n == 0 { return 0 - 1 }
94 var acc: i64 = 0
95 var nbits: i64 = 0
96 while nbits < 12 {
97 acc = (acc << 1) | br_read_bit(br)
98 nbits = nbits + 1
99 var i: i64 = 0
100 while i < n {
101 if ln[i] == nbits { if cd[i] == acc { return vl[i] } }
102 i = i + 1
103 }
104 }
105 return 0 - 1
106}