code wiki / (root) / nx_h264_poc.nx

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}