• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2022 The ChromiumOS Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 use std::cell::RefCell;
6 use std::rc::Rc;
7 use std::rc::Weak;
8 
9 use log::debug;
10 
11 use crate::decoders::h264::parser::RefPicMarking;
12 use crate::decoders::h264::parser::Slice;
13 use crate::decoders::h264::parser::SliceType;
14 use crate::decoders::h264::parser::Sps;
15 use crate::decoders::FrameInfo;
16 use crate::Resolution;
17 
18 #[derive(Copy, Clone, Debug, Default, PartialEq, Eq)]
19 pub enum Field {
20     #[default]
21     Frame,
22     Top,
23     Bottom,
24 }
25 
26 impl Field {
27     /// Returns the field of opposite parity.
opposite(&self) -> Option<Self>28     pub fn opposite(&self) -> Option<Self> {
29         match *self {
30             Field::Frame => None,
31             Field::Top => Some(Field::Bottom),
32             Field::Bottom => Some(Field::Top),
33         }
34     }
35 }
36 
37 #[derive(Copy, Clone, Debug, Default, PartialEq, Eq)]
38 pub enum Reference {
39     #[default]
40     None,
41     ShortTerm,
42     LongTerm,
43 }
44 
45 #[derive(Copy, Clone, Debug, Default, PartialEq, Eq)]
46 pub enum IsIdr {
47     #[default]
48     No,
49     Yes {
50         idr_pic_id: u16,
51     },
52 }
53 
54 #[derive(Default)]
55 pub struct PictureData {
56     pub pic_order_cnt_type: u8,
57     pub top_field_order_cnt: i32,
58     pub bottom_field_order_cnt: i32,
59     pub pic_order_cnt: i32,
60     pub pic_order_cnt_msb: i32,
61     pub pic_order_cnt_lsb: i32,
62     pub delta_pic_order_cnt_bottom: i32,
63     pub delta_pic_order_cnt0: i32,
64     pub delta_pic_order_cnt1: i32,
65 
66     pub pic_num: i32,
67     pub long_term_pic_num: i32,
68     pub frame_num: i32,
69     pub frame_num_offset: i32,
70     pub frame_num_wrap: i32,
71     pub long_term_frame_idx: i32,
72 
73     pub coded_resolution: Resolution,
74     pub display_resolution: Resolution,
75 
76     pub type_: SliceType,
77     pub nal_ref_idc: u8,
78     pub is_idr: IsIdr,
79     reference: Reference,
80     pub ref_pic_list_modification_flag_l0: i32,
81     pub abs_diff_pic_num_minus1: i32,
82     pub needed_for_output: bool,
83 
84     // Does memory management op 5 needs to be executed after this
85     // picture has finished decoding?
86     pub has_mmco_5: bool,
87 
88     // Created by the decoding process for gaps in frame_num.
89     // Not for decode or output.
90     pub nonexisting: bool,
91 
92     pub field: Field,
93 
94     // Values from slice_hdr to be used during reference marking and
95     // memory management after finishing this picture.
96     pub ref_pic_marking: RefPicMarking,
97 
98     is_second_field: bool,
99     other_field: Option<Weak<RefCell<Self>>>,
100 
101     pub timestamp: u64,
102 }
103 
104 impl PictureData {
new_non_existing(frame_num: i32, timestamp: u64) -> Self105     pub fn new_non_existing(frame_num: i32, timestamp: u64) -> Self {
106         PictureData {
107             frame_num,
108             nonexisting: true,
109             nal_ref_idc: 1,
110             field: Field::Frame,
111             pic_num: frame_num,
112             reference: Reference::ShortTerm,
113             timestamp,
114             ..Default::default()
115         }
116     }
117 
new_from_slice(slice: &Slice<&[u8]>, sps: &Sps, timestamp: u64) -> Self118     pub fn new_from_slice(slice: &Slice<&[u8]>, sps: &Sps, timestamp: u64) -> Self {
119         let hdr = slice.header();
120         let nalu_hdr = slice.nalu().header();
121 
122         let is_idr = if nalu_hdr.idr_pic_flag() {
123             IsIdr::Yes {
124                 idr_pic_id: hdr.idr_pic_id(),
125             }
126         } else {
127             IsIdr::No
128         };
129 
130         let field = if hdr.field_pic_flag() {
131             if hdr.bottom_field_flag() {
132                 Field::Bottom
133             } else {
134                 Field::Top
135             }
136         } else {
137             Field::Frame
138         };
139 
140         let reference = if nalu_hdr.ref_idc() != 0 {
141             Reference::ShortTerm
142         } else {
143             Reference::None
144         };
145 
146         let pic_num = if !hdr.field_pic_flag() {
147             hdr.frame_num()
148         } else {
149             2 * hdr.frame_num() + 1
150         };
151 
152         let (
153             pic_order_cnt_lsb,
154             delta_pic_order_cnt_bottom,
155             delta_pic_order_cnt0,
156             delta_pic_order_cnt1,
157         ) = match sps.pic_order_cnt_type() {
158             0 => (
159                 hdr.pic_order_cnt_lsb(),
160                 hdr.delta_pic_order_cnt_bottom(),
161                 Default::default(),
162                 Default::default(),
163             ),
164             1 => (
165                 Default::default(),
166                 Default::default(),
167                 hdr.delta_pic_order_cnt()[0],
168                 hdr.delta_pic_order_cnt()[1],
169             ),
170             _ => (
171                 Default::default(),
172                 Default::default(),
173                 Default::default(),
174                 Default::default(),
175             ),
176         };
177 
178         let width = sps.width();
179         let height = sps.height();
180         let coded_resolution = Resolution { width, height };
181 
182         let visible_rect = sps.visible_rectangle();
183 
184         let display_resolution = Resolution {
185             width: visible_rect.max.x - visible_rect.min.x,
186             height: visible_rect.max.y - visible_rect.min.y,
187         };
188 
189         PictureData {
190             pic_order_cnt_type: sps.pic_order_cnt_type(),
191             pic_order_cnt_lsb: i32::from(pic_order_cnt_lsb),
192             delta_pic_order_cnt_bottom,
193             delta_pic_order_cnt0,
194             delta_pic_order_cnt1,
195             pic_num: i32::from(pic_num),
196             frame_num: i32::from(hdr.frame_num()),
197             nal_ref_idc: nalu_hdr.ref_idc(),
198             is_idr,
199             reference,
200             field,
201             ref_pic_marking: hdr.dec_ref_pic_marking().clone(),
202             coded_resolution,
203             display_resolution,
204             timestamp,
205             ..Default::default()
206         }
207     }
208 
209     /// Whether the current picture is a reference, either ShortTerm or LongTerm.
is_ref(&self) -> bool210     pub fn is_ref(&self) -> bool {
211         !matches!(self.reference, Reference::None)
212     }
213 
214     /// Whether this picture is a second field.
is_second_field(&self) -> bool215     pub fn is_second_field(&self) -> bool {
216         self.is_second_field
217     }
218 
219     /// Returns a reference to the picture's Reference
reference(&self) -> &Reference220     pub fn reference(&self) -> &Reference {
221         &self.reference
222     }
223 
224     /// Mark the picture as a reference picture.
set_reference(&mut self, reference: Reference, apply_to_other_field: bool)225     pub fn set_reference(&mut self, reference: Reference, apply_to_other_field: bool) {
226         log::debug!("Set reference of {:#?} to {:?}", self, reference);
227         //debug
228         if self.pic_order_cnt == 18 && matches!(reference, Reference::ShortTerm) {
229             println!("debug");
230         }
231         self.reference = reference;
232 
233         if apply_to_other_field {
234             if let Some(other_field) = self.other_field.as_mut() {
235                 log::debug!(
236                     "other_field: Set reference of {:#?} to {:?}",
237                     &other_field.upgrade().unwrap().borrow_mut(),
238                     reference
239                 );
240                 other_field.upgrade().unwrap().borrow_mut().reference = reference;
241             }
242         }
243     }
244 
245     /// Returns the other field when we know it must be there.
other_field_unchecked(&self) -> Rc<RefCell<Self>>246     pub fn other_field_unchecked(&self) -> Rc<RefCell<Self>> {
247         self.other_field.as_ref().unwrap().upgrade().unwrap()
248     }
249 
250     /// Get a reference to the picture's other field, if any.
other_field(&self) -> Option<&Weak<RefCell<PictureData>>>251     pub fn other_field(&self) -> Option<&Weak<RefCell<PictureData>>> {
252         self.other_field.as_ref()
253     }
254 
255     /// Set this picture's second field.
set_second_field_to(&mut self, other_field: &Rc<RefCell<Self>>)256     pub fn set_second_field_to(&mut self, other_field: &Rc<RefCell<Self>>) {
257         self.other_field = Some(Rc::downgrade(other_field));
258         other_field.borrow_mut().is_second_field = true;
259     }
260 
261     /// Whether the current picture is the second field of a complementary ref pair.
is_second_field_of_complementary_ref_pair(&self) -> bool262     pub fn is_second_field_of_complementary_ref_pair(&self) -> bool {
263         self.is_ref() && self.is_second_field && self.other_field_unchecked().borrow().is_ref()
264     }
265 
266     /// Set this picture's first field.
set_first_field_to(&mut self, other_field: &Rc<RefCell<Self>>)267     pub fn set_first_field_to(&mut self, other_field: &Rc<RefCell<Self>>) {
268         self.other_field = Some(Rc::downgrade(other_field));
269         self.is_second_field = true;
270     }
271 
272     /// Split a frame into two complementary fields.
split_frame(pic_rc: &Rc<RefCell<Self>>) -> Rc<RefCell<Self>>273     pub fn split_frame(pic_rc: &Rc<RefCell<Self>>) -> Rc<RefCell<Self>> {
274         assert!(matches!(pic_rc.borrow().field, Field::Frame));
275         assert!(pic_rc.borrow().other_field.is_none());
276 
277         let field;
278         let pic_order_cnt;
279         let mut pic = pic_rc.borrow_mut();
280 
281         debug!(
282             "Splitting picture (frame_num, POC) ({:?}, {:?})",
283             pic.frame_num, pic.pic_order_cnt
284         );
285 
286         if pic.top_field_order_cnt < pic.bottom_field_order_cnt {
287             pic.field = Field::Top;
288             pic.pic_order_cnt = pic.top_field_order_cnt;
289 
290             field = Field::Bottom;
291             pic_order_cnt = pic.bottom_field_order_cnt;
292         } else {
293             pic.field = Field::Bottom;
294             pic.pic_order_cnt = pic.bottom_field_order_cnt;
295 
296             field = Field::Top;
297             pic_order_cnt = pic.top_field_order_cnt;
298         }
299 
300         let mut other_field = PictureData {
301             top_field_order_cnt: pic.top_field_order_cnt,
302             bottom_field_order_cnt: pic.bottom_field_order_cnt,
303             frame_num: pic.frame_num,
304             reference: pic.reference,
305             nonexisting: pic.nonexisting,
306             pic_order_cnt,
307             field,
308             ..Default::default()
309         };
310 
311         other_field.is_second_field = true;
312         other_field.other_field = Some(Rc::downgrade(pic_rc));
313 
314         pic.other_field = Some(Rc::downgrade(pic_rc));
315 
316         debug!(
317             "Split into picture (frame_num, POC) ({:?}, {:?}), field: {:?}",
318             pic.frame_num, pic.pic_order_cnt, pic.field
319         );
320         debug!(
321             "Split into picture (frame_num, POC) ({:?}, {:?}), field {:?}",
322             other_field.frame_num, other_field.pic_order_cnt, other_field.field
323         );
324 
325         Rc::new(RefCell::new(other_field))
326     }
327 }
328 
329 impl FrameInfo for PictureData {
display_resolution(&self) -> Resolution330     fn display_resolution(&self) -> Resolution {
331         self.display_resolution
332     }
333 }
334 
335 impl std::fmt::Debug for PictureData {
fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result336     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
337         f.debug_struct("PictureData")
338             .field("pic_order_cnt_type", &self.pic_order_cnt_type)
339             .field("top_field_order_cnt", &self.top_field_order_cnt)
340             .field("bottom_field_order_cnt", &self.bottom_field_order_cnt)
341             .field("pic_order_cnt", &self.pic_order_cnt)
342             .field("pic_order_cnt_msb", &self.pic_order_cnt_msb)
343             .field("pic_order_cnt_lsb", &self.pic_order_cnt_lsb)
344             .field(
345                 "delta_pic_order_cnt_bottom",
346                 &self.delta_pic_order_cnt_bottom,
347             )
348             .field("delta_pic_order_cnt0", &self.delta_pic_order_cnt0)
349             .field("delta_pic_order_cnt1", &self.delta_pic_order_cnt1)
350             .field("pic_num", &self.pic_num)
351             .field("long_term_pic_num", &self.long_term_pic_num)
352             .field("frame_num", &self.frame_num)
353             .field("frame_num_offset", &self.frame_num_offset)
354             .field("frame_num_wrap", &self.frame_num_wrap)
355             .field("long_term_frame_idx", &self.long_term_frame_idx)
356             .field("coded_resolution", &self.coded_resolution)
357             .field("display_resolution", &self.display_resolution)
358             .field("type_", &self.type_)
359             .field("nal_ref_idc", &self.nal_ref_idc)
360             .field("is_idr", &self.is_idr)
361             .field("reference", &self.reference)
362             .field(
363                 "ref_pic_list_modification_flag_l0",
364                 &self.ref_pic_list_modification_flag_l0,
365             )
366             .field("abs_diff_pic_num_minus1", &self.abs_diff_pic_num_minus1)
367             .field("needed_for_output", &self.needed_for_output)
368             .field("has_mmco_5", &self.has_mmco_5)
369             .field("nonexisting", &self.nonexisting)
370             .field("field", &self.field)
371             .field("ref_pic_marking", &self.ref_pic_marking)
372             .field("is_second_field", &self.is_second_field)
373             .field("other_field", &self.other_field)
374             .finish()
375     }
376 }
377