cros_codecs/codec/h265/
picture.rs1use crate::codec::h265::parser::NaluType;
6use crate::codec::h265::parser::Slice;
7
8#[derive(Copy, Clone, Debug, Default, PartialEq, Eq)]
9pub enum Reference {
10 #[default]
11 None,
12 ShortTerm,
13 LongTerm,
14}
15
16#[derive(Debug, Default, Clone, Eq, PartialEq)]
19pub struct PictureData {
20 pub nalu_type: NaluType,
23 pub no_rasl_output_flag: bool,
24 pub pic_output_flag: bool,
25 pub valid_for_prev_tid0_pic: bool,
26 pub slice_pic_order_cnt_lsb: i32,
27 pub pic_order_cnt_msb: i32,
28 pub pic_order_cnt_val: i32,
29 pub no_output_of_prior_pics_flag: bool,
30
31 pub first_picture_after_eos: bool,
33 reference: Reference,
34 pub pic_latency_cnt: i32,
35 pub needed_for_output: bool,
36 pub short_term_ref_pic_set_size_bits: u32,
37}
38
39impl PictureData {
40 pub fn new_from_slice(
48 slice: &Slice,
49 first_picture_in_bitstream: bool,
50 first_picture_after_eos: bool,
51 prev_tid0_pic: Option<&PictureData>,
52 max_pic_order_cnt_lsb: i32,
53 ) -> Self {
54 let hdr = &slice.header;
55 let nalu_type = slice.nalu.header.type_;
56
57 let mut pic_order_cnt_msb = 0;
61 let slice_pic_order_cnt_lsb: i32 = hdr.pic_order_cnt_lsb.into();
62
63 let no_rasl_output_flag = nalu_type.is_idr()
70 || nalu_type.is_bla()
71 || (nalu_type.is_cra() && first_picture_in_bitstream)
72 || first_picture_after_eos;
73
74 let pic_output_flag = if slice.nalu.header.type_.is_rasl() && no_rasl_output_flag {
75 false
76 } else {
77 hdr.pic_output_flag
78 };
79
80 if !(nalu_type.is_irap() && no_rasl_output_flag) {
83 if let Some(prev_tid0_pic) = prev_tid0_pic {
84 let prev_pic_order_cnt_lsb = prev_tid0_pic.slice_pic_order_cnt_lsb;
86 let prev_pic_order_cnt_msb = prev_tid0_pic.pic_order_cnt_msb;
87 if (slice_pic_order_cnt_lsb < prev_pic_order_cnt_lsb)
88 && (prev_pic_order_cnt_lsb - slice_pic_order_cnt_lsb)
89 >= (max_pic_order_cnt_lsb / 2)
90 {
91 pic_order_cnt_msb = prev_pic_order_cnt_msb + max_pic_order_cnt_lsb;
92 } else if (slice_pic_order_cnt_lsb > prev_pic_order_cnt_lsb)
93 && (slice_pic_order_cnt_lsb - prev_pic_order_cnt_lsb)
94 > (max_pic_order_cnt_lsb / 2)
95 {
96 pic_order_cnt_msb = prev_pic_order_cnt_msb - max_pic_order_cnt_lsb;
97 } else {
98 pic_order_cnt_msb = prev_pic_order_cnt_msb;
99 }
100 }
101 }
102
103 let valid_for_prev_tid0_pic = slice.nalu.header.nuh_temporal_id() == 0
111 && !nalu_type.is_radl()
112 && !nalu_type.is_rasl()
113 && !nalu_type.is_slnr();
114
115 let no_output_of_prior_pics_flag =
116 if nalu_type.is_irap() && no_rasl_output_flag && !first_picture_in_bitstream {
117 nalu_type.is_cra() || hdr.no_output_of_prior_pics_flag
118 } else {
119 false
120 };
121
122 Self {
123 nalu_type,
124 no_rasl_output_flag,
125 no_output_of_prior_pics_flag,
126 pic_output_flag,
127 valid_for_prev_tid0_pic,
128 slice_pic_order_cnt_lsb,
129 pic_order_cnt_msb,
130 pic_order_cnt_val: pic_order_cnt_msb + slice_pic_order_cnt_lsb,
132 first_picture_after_eos,
133 reference: Default::default(),
134 pic_latency_cnt: 0,
135 needed_for_output: false,
136 short_term_ref_pic_set_size_bits: hdr.st_rps_bits,
137 }
138 }
139
140 pub fn is_ref(&self) -> bool {
142 !matches!(self.reference, Reference::None)
143 }
144
145 pub fn set_reference(&mut self, reference: Reference) {
146 log::debug!("Set reference of POC {} to {:?}", self.pic_order_cnt_val, reference);
147
148 self.reference = reference;
149 }
150
151 pub fn reference(&self) -> &Reference {
152 &self.reference
153 }
154}