nx_h264_poc.nx source
↩ module page · 103 lines · 4683 B
1// nx_h264_poc.nx -- H.264 Picture Order Count (POC type 0, spec 8.2.1.1) + B-slice reference list
2// construction (8.2.4.2.3). POC gives display order from decode order; the ref lists L0/L1 give a
3// B-slice its past/future predictors. Reusable by the B-frame decoder.
4// poc_type0: state[0]=prevPicOrderCntMsb, state[1]=prevPicOrderCntLsb (from the last REFERENCE pic;
5// reset to 0 at an IDR). Non-reference pics (B here) read state but do NOT update it.
6// B ref lists: L0 = {refs POC<curr, desc} ++ {refs POC>curr, asc}; L1 = {POC>curr, asc} ++ {POC<curr, desc}.
7// genealogy_id: itu_t_h264_sec8_2_poc_and_reflists license_tier: ORIGINAL
8import "nx_syscalls.nx"
9
10// POC for a frame (poc_type 0). Updates state only for reference pictures / IDR.
11func nx_h264_poc_type0(poc_lsb: i64, max_poc_lsb: i64, is_idr: i64, nal_ref_idc: i64, state: *i64) -> i64 {
12 if is_idr == 1 { state[0] = 0; state[1] = 0 }
13 let prevMsb: i64 = state[0]
14 let prevLsb: i64 = state[1]
15 var pocMsb: i64 = prevMsb
16 if poc_lsb < prevLsb { if (prevLsb - poc_lsb) >= (max_poc_lsb / 2) { pocMsb = prevMsb + max_poc_lsb } }
17 if poc_lsb > prevLsb { if (poc_lsb - prevLsb) > (max_poc_lsb / 2) { pocMsb = prevMsb - max_poc_lsb } }
18 let poc: i64 = pocMsb + poc_lsb
19 if nal_ref_idc != 0 { state[0] = pocMsb; state[1] = poc_lsb }
20 return poc
21}
22
23// Build B-slice reference lists from the DPB reference POCs (dpbPoc[0..n-1]) relative to currPOC.
24// Writes l0[0..n-1] and l1[0..n-1] (POC values, ordered); returns the list length n. dpbIdx[] carries
25// each ref's decode index so callers can map a list entry back to a picture; l0i/l1i receive those.
26func nx_h264_build_blists(dpbPoc: *i64, dpbIdx: *i64, n: i64, currPOC: i64,
27 l0: *i64, l0i: *i64, l1: *i64, l1i: *i64) -> i64 {
28 // ---- L0: POC<curr descending, then POC>curr ascending ----
29 var c0: i64 = 0
30 // past (POC<curr), pick largest each pass
31 var done: i64 = 0
32 while done == 0 {
33 var best: i64 = 0 - 1
34 var bp: i64 = 0
35 var bi: i64 = 0
36 var j: i64 = 0
37 while j < n {
38 if dpbPoc[j] < currPOC {
39 var taken: i64 = 0
40 var t: i64 = 0
41 while t < c0 { if l0i[t] == dpbIdx[j] { taken = 1 } t = t + 1 }
42 if taken == 0 { if best == 0 - 1 { best = j; bp = dpbPoc[j]; bi = dpbIdx[j] } else { if dpbPoc[j] > bp { best = j; bp = dpbPoc[j]; bi = dpbIdx[j] } } }
43 }
44 j = j + 1
45 }
46 if best == 0 - 1 { done = 1 } else { l0[c0] = bp; l0i[c0] = bi; c0 = c0 + 1 }
47 }
48 // future (POC>curr), pick smallest each pass
49 done = 0
50 while done == 0 {
51 var best: i64 = 0 - 1
52 var bp: i64 = 0
53 var bi: i64 = 0
54 var j: i64 = 0
55 while j < n {
56 if dpbPoc[j] > currPOC {
57 var taken: i64 = 0
58 var t: i64 = 0
59 while t < c0 { if l0i[t] == dpbIdx[j] { taken = 1 } t = t + 1 }
60 if taken == 0 { if best == 0 - 1 { best = j; bp = dpbPoc[j]; bi = dpbIdx[j] } else { if dpbPoc[j] < bp { best = j; bp = dpbPoc[j]; bi = dpbIdx[j] } } }
61 }
62 j = j + 1
63 }
64 if best == 0 - 1 { done = 1 } else { l0[c0] = bp; l0i[c0] = bi; c0 = c0 + 1 }
65 }
66 // ---- L1: POC>curr ascending, then POC<curr descending ----
67 var c1: i64 = 0
68 done = 0
69 while done == 0 {
70 var best: i64 = 0 - 1
71 var bp: i64 = 0
72 var bi: i64 = 0
73 var j: i64 = 0
74 while j < n {
75 if dpbPoc[j] > currPOC {
76 var taken: i64 = 0
77 var t: i64 = 0
78 while t < c1 { if l1i[t] == dpbIdx[j] { taken = 1 } t = t + 1 }
79 if taken == 0 { if best == 0 - 1 { best = j; bp = dpbPoc[j]; bi = dpbIdx[j] } else { if dpbPoc[j] < bp { best = j; bp = dpbPoc[j]; bi = dpbIdx[j] } } }
80 }
81 j = j + 1
82 }
83 if best == 0 - 1 { done = 1 } else { l1[c1] = bp; l1i[c1] = bi; c1 = c1 + 1 }
84 }
85 done = 0
86 while done == 0 {
87 var best: i64 = 0 - 1
88 var bp: i64 = 0
89 var bi: i64 = 0
90 var j: i64 = 0
91 while j < n {
92 if dpbPoc[j] < currPOC {
93 var taken: i64 = 0
94 var t: i64 = 0
95 while t < c1 { if l1i[t] == dpbIdx[j] { taken = 1 } t = t + 1 }
96 if taken == 0 { if best == 0 - 1 { best = j; bp = dpbPoc[j]; bi = dpbIdx[j] } else { if dpbPoc[j] > bp { best = j; bp = dpbPoc[j]; bi = dpbIdx[j] } } }
97 }
98 j = j + 1
99 }
100 if best == 0 - 1 { done = 1 } else { l1[c1] = bp; l1i[c1] = bi; c1 = c1 + 1 }
101 }
102 return c0
103}