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