1use super::super::bitreader::BitReader;
5use super::obu::find_av1_obu;
6use super::sequence::Av1SequenceHeader;
7
8#[derive(Debug, Clone)]
15pub struct Av1FrameHeader {
16 pub show_frame: bool,
17 pub showable_frame: bool,
18 pub frame_type: Av1FrameType,
19 pub error_resilient_mode: bool,
20 pub disable_cdf_update: bool,
21 pub allow_screen_content_tools: bool,
22 pub force_integer_mv: bool,
23 pub order_hint: u32,
24 pub primary_ref_frame: u8,
25 pub refresh_frame_flags: u8,
26 pub frame_width: u32,
27 pub frame_height: u32,
28 pub render_width: u32,
29 pub render_height: u32,
30 pub use_ref_frame_mvs: bool,
31 pub allow_high_precision_mv: bool,
32 pub is_filter_switchable: bool,
33 pub disable_frame_end_update_cdf: bool,
34 pub allow_warped_motion: bool,
35 pub reduced_tx_set: bool,
36 pub allow_intrabc: bool,
38 pub frame_size_override_flag: bool,
39 pub use_superres: bool,
40 pub is_motion_mode_switchable: bool,
41 pub reference_select: bool,
42 pub skip_mode_present: bool,
43 pub tile_cols: u8,
46 pub tile_rows: u8,
47 pub uniform_tile_spacing_flag: bool,
48 pub tile_cols_log2: u8,
49 pub tile_rows_log2: u8,
50 pub mi_col_starts: Vec<u16>, pub mi_row_starts: Vec<u16>, pub width_in_sbs_minus_1: Vec<u16>, pub height_in_sbs_minus_1: Vec<u16>, pub context_update_tile_id: u16,
55 pub tile_size_bytes_minus_1: u8,
56 pub base_q_idx: u8,
58 pub delta_q_y_dc: i8,
59 pub delta_q_u_dc: i8,
60 pub delta_q_u_ac: i8,
61 pub delta_q_v_dc: i8,
62 pub delta_q_v_ac: i8,
63 pub using_qmatrix: bool,
64 pub qm_y: u8,
65 pub qm_u: u8,
66 pub qm_v: u8,
67 pub delta_q_present: bool,
69 pub delta_q_res: u8,
70 pub delta_lf_present: bool,
71 pub delta_lf_res: u8,
72 pub delta_lf_multi: bool,
73 pub segmentation_enabled: bool,
77 pub segmentation_update_map: bool,
78 pub segmentation_temporal_update: bool,
79 pub segmentation_update_data: bool,
80 pub feature_enabled: [[bool; 8]; 8],
81 pub feature_data: [[i16; 8]; 8],
82 pub loop_filter_level: [u8; 4],
84 pub loop_filter_sharpness: u8,
85 pub loop_filter_delta_enabled: bool,
86 pub loop_filter_delta_update: bool,
87 pub update_ref_delta_mask: u8, pub loop_filter_ref_deltas: [i8; 8],
89 pub update_mode_delta_mask: u8, pub loop_filter_mode_deltas: [i8; 2],
91 pub cdef_damping_minus_3: u8,
93 pub cdef_bits: u8,
94 pub cdef_y_pri_strength: [u8; 8],
95 pub cdef_y_sec_strength: [u8; 8],
96 pub cdef_uv_pri_strength: [u8; 8],
97 pub cdef_uv_sec_strength: [u8; 8],
98 pub lr_type: [u8; 3], pub lr_unit_shift: u8,
101 pub lr_uv_shift: u8,
102 pub tx_mode: u8,
104 pub interpolation_filter: u8,
105 pub tile_group_offset_in_obu: u32,
112 pub coded_lossless: bool,
114}
115
116impl Default for Av1FrameHeader {
117 fn default() -> Self {
118 Self {
119 show_frame: false,
120 showable_frame: false,
121 frame_type: Av1FrameType::Key,
122 error_resilient_mode: false,
123 disable_cdf_update: false,
124 allow_screen_content_tools: false,
125 force_integer_mv: false,
126 order_hint: 0,
127 primary_ref_frame: 7,
128 refresh_frame_flags: 0,
129 frame_width: 0,
130 frame_height: 0,
131 render_width: 0,
132 render_height: 0,
133 use_ref_frame_mvs: false,
134 allow_high_precision_mv: false,
135 is_filter_switchable: false,
136 disable_frame_end_update_cdf: false,
137 allow_warped_motion: false,
138 reduced_tx_set: false,
139 allow_intrabc: false,
140 frame_size_override_flag: false,
141 use_superres: false,
142 is_motion_mode_switchable: false,
143 reference_select: false,
144 skip_mode_present: false,
145 tile_cols: 1,
146 tile_rows: 1,
147 uniform_tile_spacing_flag: true,
148 tile_cols_log2: 0,
149 tile_rows_log2: 0,
150 mi_col_starts: Vec::new(),
151 mi_row_starts: Vec::new(),
152 width_in_sbs_minus_1: Vec::new(),
153 height_in_sbs_minus_1: Vec::new(),
154 context_update_tile_id: 0,
155 tile_size_bytes_minus_1: 3,
156 base_q_idx: 0,
157 delta_q_y_dc: 0,
158 delta_q_u_dc: 0,
159 delta_q_u_ac: 0,
160 delta_q_v_dc: 0,
161 delta_q_v_ac: 0,
162 using_qmatrix: false,
163 qm_y: 0,
164 qm_u: 0,
165 qm_v: 0,
166 delta_q_present: false,
167 delta_q_res: 0,
168 delta_lf_present: false,
169 delta_lf_res: 0,
170 delta_lf_multi: false,
171 segmentation_enabled: false,
172 segmentation_update_map: false,
173 segmentation_temporal_update: false,
174 segmentation_update_data: false,
175 feature_enabled: [[false; 8]; 8],
176 feature_data: [[0; 8]; 8],
177 loop_filter_level: [0; 4],
178 loop_filter_sharpness: 0,
179 loop_filter_delta_enabled: false,
180 loop_filter_delta_update: false,
181 update_ref_delta_mask: 0,
182 loop_filter_ref_deltas: [0; 8],
183 update_mode_delta_mask: 0,
184 loop_filter_mode_deltas: [0; 2],
185 cdef_damping_minus_3: 0,
186 cdef_bits: 0,
187 cdef_y_pri_strength: [0; 8],
188 cdef_y_sec_strength: [0; 8],
189 cdef_uv_pri_strength: [0; 8],
190 cdef_uv_sec_strength: [0; 8],
191 lr_type: [0; 3],
192 lr_unit_shift: 0,
193 lr_uv_shift: 0,
194 tx_mode: 0,
195 interpolation_filter: 0,
196 tile_group_offset_in_obu: 0,
197 coded_lossless: false,
198 }
199 }
200}
201
202#[derive(Debug, Clone, Copy, PartialEq, Eq)]
203pub enum Av1FrameType {
204 Key,
205 Inter,
206 IntraOnly,
207 Switch,
208}
209
210pub fn parse_av1_frame_header(sample: &[u8], seq: &Av1SequenceHeader) -> Option<Av1FrameHeader> {
226 let obu_bytes = find_av1_obu(sample, 3).or_else(|| find_av1_obu(sample, 6))?;
227 let mut br = BitReader::new(obu_bytes);
228 let mut h = Av1FrameHeader::default();
229
230 if seq.reduced_still_picture_header {
232 h.frame_type = Av1FrameType::Key;
233 h.show_frame = true;
234 h.showable_frame = false;
235 h.error_resilient_mode = true;
236 } else {
237 let show_existing_frame = br.read_bits(1)? == 1;
238 if show_existing_frame {
239 let _frame_to_show_map_idx = br.read_bits(3)?;
245 h.show_frame = true;
246 h.showable_frame = true;
247 h.frame_type = Av1FrameType::Key;
248 h.frame_width = seq.max_frame_width_minus1 + 1;
249 h.frame_height = seq.max_frame_height_minus1 + 1;
250 h.render_width = h.frame_width;
251 h.render_height = h.frame_height;
252 return Some(h);
253 }
254 let ft_code = br.read_bits(2)?;
255 h.frame_type = match ft_code {
256 0 => Av1FrameType::Key,
257 1 => Av1FrameType::Inter,
258 2 => Av1FrameType::IntraOnly,
259 3 => Av1FrameType::Switch,
260 _ => return None,
261 };
262 h.show_frame = br.read_bits(1)? == 1;
263 h.showable_frame = if h.show_frame {
264 !matches!(h.frame_type, Av1FrameType::Key)
265 } else {
266 br.read_bits(1)? == 1
267 };
268 let is_key = matches!(h.frame_type, Av1FrameType::Key);
269 let is_switch = matches!(h.frame_type, Av1FrameType::Switch);
270 h.error_resilient_mode = if is_switch || (is_key && h.show_frame) {
271 true
272 } else {
273 br.read_bits(1)? == 1
274 };
275 }
276
277 let frame_is_intra = matches!(h.frame_type, Av1FrameType::Key | Av1FrameType::IntraOnly);
278
279 h.disable_cdf_update = br.read_bits(1)? == 1;
280 h.allow_screen_content_tools = if seq.seq_force_screen_content_tools == 2 {
284 br.read_bits(1)? == 1
285 } else {
286 seq.seq_force_screen_content_tools == 1
287 };
288 if h.allow_screen_content_tools {
289 h.force_integer_mv = if seq.seq_force_integer_mv == 2 {
290 br.read_bits(1)? == 1
291 } else {
292 seq.seq_force_integer_mv == 1
293 };
294 } else {
295 h.force_integer_mv = false;
296 }
297 if frame_is_intra {
298 h.force_integer_mv = true;
299 }
300
301 let is_switch = matches!(h.frame_type, Av1FrameType::Switch);
303 h.frame_size_override_flag = if is_switch {
304 true
305 } else if seq.reduced_still_picture_header {
306 false
307 } else {
308 br.read_bits(1)? == 1
309 };
310
311 if seq.enable_order_hint && seq.order_hint_bits > 0 {
313 h.order_hint = br.read_bits(seq.order_hint_bits as usize)?;
314 }
315
316 h.primary_ref_frame = if frame_is_intra || h.error_resilient_mode {
318 7 } else {
320 br.read_bits(3)? as u8
321 };
322
323 let all_frames = 0xFFu8;
325 h.refresh_frame_flags = if matches!(h.frame_type, Av1FrameType::Key) && h.show_frame {
326 all_frames
327 } else if is_switch {
328 all_frames
329 } else {
330 br.read_bits(8)? as u8
331 };
332
333 let (frame_width, frame_height) = if frame_is_intra {
335 let (w, h2) = parse_av1_frame_size(&mut br, seq, h.frame_size_override_flag)?;
336 h.use_superres = if seq.enable_superres {
339 br.read_bits(1)? == 1
340 } else {
341 false
342 };
343 if h.use_superres {
344 let _superres_denom_minus9 = br.read_bits(3)?;
345 }
346 parse_av1_render_size(&mut br, w, h2, &mut h.render_width, &mut h.render_height)?;
347 if h.allow_screen_content_tools
348 {
350 h.allow_intrabc = br.read_bits(1)? == 1;
351 }
352 (w, h2)
353 } else {
354 let frame_refs_short_signaling = if seq.enable_order_hint {
360 br.read_bits(1)? == 1
361 } else {
362 false
363 };
364 if frame_refs_short_signaling {
365 let _last_frame_idx = br.read_bits(3)?;
366 let _gold_frame_idx = br.read_bits(3)?;
367 }
368 for _ in 0..7u8
369 {
371 if !frame_refs_short_signaling {
372 let _ref_frame_idx = br.read_bits(3)?;
373 }
374 }
377 let (w, h2) = if h.frame_size_override_flag && !h.error_resilient_mode {
378 parse_av1_frame_size_with_refs(&mut br, seq)?
379 } else {
380 let (w, h2) = parse_av1_frame_size(&mut br, seq, h.frame_size_override_flag)?;
381 h.use_superres = if seq.enable_superres {
383 br.read_bits(1)? == 1
384 } else {
385 false
386 };
387 if h.use_superres {
388 let _superres_denom_minus9 = br.read_bits(3)?;
389 }
390 parse_av1_render_size(&mut br, w, h2, &mut h.render_width, &mut h.render_height)?;
391 (w, h2)
392 };
393 h.allow_high_precision_mv = if h.force_integer_mv {
394 false
395 } else {
396 br.read_bits(1)? == 1
397 };
398 h.is_filter_switchable = br.read_bits(1)? == 1;
400 h.interpolation_filter = if h.is_filter_switchable {
401 4 } else {
403 br.read_bits(2)? as u8
404 };
405 h.is_motion_mode_switchable = br.read_bits(1)? == 1;
406 h.use_ref_frame_mvs = if h.error_resilient_mode || !seq.enable_ref_frame_mvs {
407 false
408 } else {
409 br.read_bits(1)? == 1
410 };
411 (w, h2)
412 };
413 h.frame_width = frame_width;
414 h.frame_height = frame_height;
415 if h.render_width == 0 {
416 h.render_width = frame_width;
417 }
418 if h.render_height == 0 {
419 h.render_height = frame_height;
420 }
421
422 h.disable_frame_end_update_cdf = if seq.reduced_still_picture_header {
423 true
424 } else {
425 br.read_bits(1)? == 1
426 };
427
428 let sb_size_log2: u32 = 4; let mi_cols_raw = 2 * ((frame_width.saturating_sub(1) + 8) >> 3);
435 let mi_rows_raw = 2 * ((frame_height.saturating_sub(1) + 8) >> 3);
436 let sb_cols = (mi_cols_raw + (1 << sb_size_log2) - 1) >> sb_size_log2;
438 let sb_rows = (mi_rows_raw + (1 << sb_size_log2) - 1) >> sb_size_log2;
439 parse_av1_tile_info(
440 &mut br,
441 &mut h,
442 sb_cols,
443 sb_rows,
444 sb_size_log2,
445 mi_cols_raw,
446 mi_rows_raw,
447 )?;
448
449 parse_av1_quantization_params(&mut br, &mut h, seq)?;
451
452 parse_av1_segmentation_params(&mut br, &mut h)?;
454
455 h.delta_q_present = if h.base_q_idx > 0 {
457 br.read_bits(1)? == 1
458 } else {
459 false
460 };
461 h.delta_q_res = if h.delta_q_present {
462 br.read_bits(2)? as u8
463 } else {
464 0
465 };
466 h.delta_lf_present = if h.delta_q_present && !h.allow_intrabc {
467 br.read_bits(1)? == 1
468 } else {
469 false
470 };
471 if h.delta_lf_present {
472 h.delta_lf_res = br.read_bits(2)? as u8;
473 h.delta_lf_multi = br.read_bits(1)? == 1;
474 }
475
476 h.coded_lossless = h.base_q_idx == 0
482 && h.delta_q_y_dc == 0
483 && h.delta_q_u_dc == 0
484 && h.delta_q_u_ac == 0
485 && h.delta_q_v_dc == 0
486 && h.delta_q_v_ac == 0;
487
488 parse_av1_loop_filter_params(&mut br, &mut h, frame_is_intra)?;
490
491 let num_planes_u32: u32 = if seq.monochrome { 1 } else { 3 };
493 if !h.coded_lossless && !h.allow_intrabc && seq.enable_cdef {
494 parse_av1_cdef_params(&mut br, &mut h, num_planes_u32)?;
495 } else {
496 h.cdef_bits = 0;
498 h.cdef_damping_minus_3 = 0;
499 h.cdef_y_pri_strength = [0; 8];
500 h.cdef_y_sec_strength = [0; 8];
501 h.cdef_uv_pri_strength = [0; 8];
502 h.cdef_uv_sec_strength = [0; 8];
503 }
504
505 if !h.coded_lossless && !h.allow_intrabc && seq.enable_restoration {
507 parse_av1_lr_params(&mut br, &mut h, num_planes_u32, seq)?;
508 }
509
510 h.tx_mode = if h.coded_lossless {
512 0 } else if br.read_bits(1)? == 1 {
514 2 } else {
516 1 };
518
519 h.reference_select = if !frame_is_intra {
521 br.read_bits(1)? == 1
522 } else {
523 false
524 };
525
526 let skip_mode_allowed = false; h.skip_mode_present = if skip_mode_allowed {
533 br.read_bits(1)? == 1
534 } else {
535 false
536 };
537
538 h.allow_warped_motion =
541 if !frame_is_intra && !h.error_resilient_mode && seq.enable_warped_motion {
542 br.read_bits(1)? == 1
543 } else {
544 false
545 };
546
547 h.reduced_tx_set = br.read_bits(1)? == 1;
553
554 if !frame_is_intra {
559 skip_av1_global_motion_params(&mut br)?;
560 }
561
562 if seq.film_grain_params_present && (h.show_frame || h.showable_frame) {
564 skip_av1_film_grain_params(&mut br, seq)?;
565 }
566
567 br.byte_align();
572 h.tile_group_offset_in_obu = (br.bit_pos() / 8) as u32;
573
574 Some(h)
575}
576
577fn parse_av1_frame_size(
581 br: &mut BitReader,
582 seq: &Av1SequenceHeader,
583 frame_size_override_flag: bool,
584) -> Option<(u32, u32)> {
585 if frame_size_override_flag {
586 let w_bits = av1_bits_for_max(seq.max_frame_width_minus1 + 1);
587 let h_bits = av1_bits_for_max(seq.max_frame_height_minus1 + 1);
588 let w = br.read_bits(w_bits)? + 1;
589 let hgt = br.read_bits(h_bits)? + 1;
590 Some((w, hgt))
591 } else {
592 Some((
593 seq.max_frame_width_minus1 + 1,
594 seq.max_frame_height_minus1 + 1,
595 ))
596 }
597}
598
599fn parse_av1_render_size(
601 br: &mut BitReader,
602 frame_w: u32,
603 frame_h: u32,
604 out_w: &mut u32,
605 out_h: &mut u32,
606) -> Option<()> {
607 let render_and_frame_size_different = br.read_bits(1)? == 1;
608 if render_and_frame_size_different {
609 *out_w = br.read_bits(16)? + 1;
610 *out_h = br.read_bits(16)? + 1;
611 } else {
612 *out_w = frame_w;
613 *out_h = frame_h;
614 }
615 Some(())
616}
617
618fn parse_av1_frame_size_with_refs(
624 br: &mut BitReader,
625 seq: &Av1SequenceHeader,
626) -> Option<(u32, u32)> {
627 let mut found_ref = false;
628 for _ in 0..7u8 {
629 if br.read_bits(1)? == 1 {
630 found_ref = true;
631 }
632 }
633 if !found_ref {
634 let (w, hgt) = parse_av1_frame_size(br, seq, true)?;
635 let mut rw = 0;
636 let mut rh = 0;
637 parse_av1_render_size(br, w, hgt, &mut rw, &mut rh)?;
638 if seq.enable_superres && br.read_bits(1)? == 1 {
640 let _denom = br.read_bits(3)?;
641 }
642 Some((w, hgt))
643 } else {
644 Some((
647 seq.max_frame_width_minus1 + 1,
648 seq.max_frame_height_minus1 + 1,
649 ))
650 }
651}
652
653fn av1_bits_for_max(v: u32) -> usize {
654 let mut bits = 0usize;
657 let mut x = v.saturating_sub(1);
658 while x > 0 {
659 bits += 1;
660 x >>= 1;
661 }
662 bits.max(1)
663}
664
665fn parse_av1_tile_info(
667 br: &mut BitReader,
668 h: &mut Av1FrameHeader,
669 sb_cols: u32,
670 sb_rows: u32,
671 sb_size_log2: u32,
672 mi_cols: u32,
673 mi_rows: u32,
674) -> Option<()> {
675 let max_tile_width_sb = 4096 >> (sb_size_log2 + 2); let max_tile_area_sb = (4096 * 2304) >> (2 * sb_size_log2 + 4); let min_log2_tile_cols = av1_tile_log2(max_tile_width_sb, sb_cols);
680 let max_log2_tile_cols = av1_tile_log2(1, sb_cols.min(64));
681 let max_log2_tile_rows = av1_tile_log2(1, sb_rows.min(64));
682 let min_log2_tiles =
683 min_log2_tile_cols.max(av1_tile_log2(max_tile_area_sb, sb_rows * sb_cols));
684
685 h.uniform_tile_spacing_flag = br.read_bits(1)? == 1;
686 let tile_cols_log2: u32;
687 let tile_rows_log2: u32;
688 h.mi_col_starts.clear();
689 h.mi_row_starts.clear();
690 h.width_in_sbs_minus_1.clear();
691 h.height_in_sbs_minus_1.clear();
692
693 if h.uniform_tile_spacing_flag {
694 let mut tcl = min_log2_tile_cols;
695 while tcl < max_log2_tile_cols {
696 if br.read_bits(1)? == 0 {
697 break;
698 }
699 tcl += 1;
700 }
701 tile_cols_log2 = tcl;
702 let tile_width_sb = (sb_cols + (1 << tile_cols_log2) - 1) >> tile_cols_log2;
703 let mut start_sb = 0u32;
704 let mut mi_starts: Vec<u16> = vec![0];
705 let mut widths: Vec<u16> = Vec::new();
706 while start_sb < sb_cols {
707 let size_sb = tile_width_sb.min(sb_cols - start_sb);
708 widths.push((size_sb - 1) as u16);
709 start_sb += size_sb;
710 mi_starts.push(((start_sb << sb_size_log2).min(mi_cols)) as u16);
711 }
712 h.mi_col_starts = mi_starts;
713 h.width_in_sbs_minus_1 = widths;
714 h.tile_cols = h.width_in_sbs_minus_1.len() as u8;
715
716 let min_log2_tile_rows = min_log2_tiles.saturating_sub(tile_cols_log2);
717 let mut trl = min_log2_tile_rows;
718 while trl < max_log2_tile_rows {
719 if br.read_bits(1)? == 0 {
720 break;
721 }
722 trl += 1;
723 }
724 tile_rows_log2 = trl;
725 let tile_height_sb = (sb_rows + (1 << tile_rows_log2) - 1) >> tile_rows_log2;
726 let mut start_sb_r = 0u32;
727 let mut mi_starts_r: Vec<u16> = vec![0];
728 let mut heights: Vec<u16> = Vec::new();
729 while start_sb_r < sb_rows {
730 let size_sb = tile_height_sb.min(sb_rows - start_sb_r);
731 heights.push((size_sb - 1) as u16);
732 start_sb_r += size_sb;
733 mi_starts_r.push(((start_sb_r << sb_size_log2).min(mi_rows)) as u16);
734 }
735 h.mi_row_starts = mi_starts_r;
736 h.height_in_sbs_minus_1 = heights;
737 h.tile_rows = h.height_in_sbs_minus_1.len() as u8;
738 } else {
739 let mut start_sb = 0u32;
741 let mut mi_starts: Vec<u16> = vec![0];
742 let mut widths: Vec<u16> = Vec::new();
743 while start_sb < sb_cols {
744 let max_width = (sb_cols - start_sb).min(max_tile_width_sb);
745 let size_minus_1 = av1_read_ns(br, max_width)?;
746 let size = size_minus_1 + 1;
747 widths.push(size_minus_1 as u16);
748 start_sb += size;
749 mi_starts.push(((start_sb << sb_size_log2).min(mi_cols)) as u16);
750 }
751 h.mi_col_starts = mi_starts;
752 h.width_in_sbs_minus_1 = widths;
753 h.tile_cols = h.width_in_sbs_minus_1.len() as u8;
754 tile_cols_log2 = av1_tile_log2(1, h.tile_cols as u32);
755
756 let tile_cols = h.tile_cols as u32;
757 let max_tile_area_sb_r = if min_log2_tiles > 0 {
758 (sb_rows * sb_cols) >> (min_log2_tiles + 1)
759 } else {
760 sb_rows * sb_cols
761 };
762 let max_tile_height_sb = (max_tile_area_sb_r / tile_cols).max(1);
763
764 let mut start_sb_r = 0u32;
765 let mut mi_starts_r: Vec<u16> = vec![0];
766 let mut heights: Vec<u16> = Vec::new();
767 while start_sb_r < sb_rows {
768 let max_height = (sb_rows - start_sb_r).min(max_tile_height_sb);
769 let size_minus_1 = av1_read_ns(br, max_height)?;
770 let size = size_minus_1 + 1;
771 heights.push(size_minus_1 as u16);
772 start_sb_r += size;
773 mi_starts_r.push(((start_sb_r << sb_size_log2).min(mi_rows)) as u16);
774 }
775 h.mi_row_starts = mi_starts_r;
776 h.height_in_sbs_minus_1 = heights;
777 h.tile_rows = h.height_in_sbs_minus_1.len() as u8;
778 tile_rows_log2 = av1_tile_log2(1, h.tile_rows as u32);
779 }
780 h.tile_cols_log2 = tile_cols_log2 as u8;
781 h.tile_rows_log2 = tile_rows_log2 as u8;
782
783 if (tile_cols_log2 + tile_rows_log2) > 0 {
784 let n = (tile_cols_log2 + tile_rows_log2) as usize;
785 h.context_update_tile_id = br.read_bits(n)? as u16;
786 h.tile_size_bytes_minus_1 = br.read_bits(2)? as u8;
787 } else {
788 h.context_update_tile_id = 0;
789 h.tile_size_bytes_minus_1 = 0;
790 }
791 Some(())
792}
793
794fn av1_tile_log2(blksize: u32, target: u32) -> u32 {
796 let mut k = 0u32;
797 while (blksize << k) < target {
798 k += 1;
799 }
800 k
801}
802
803fn av1_read_ns(br: &mut BitReader, n: u32) -> Option<u32> {
805 if n == 0 {
806 return Some(0);
807 }
808 let w = av1_ceil_log2(n);
809 if w == 0 {
810 return Some(0);
811 }
812 let m = (1u32 << w) - n;
813 let v = br.read_bits((w - 1) as usize)?;
814 if v < m {
815 Some(v)
816 } else {
817 let extra = br.read_bits(1)?;
818 Some((v << 1) - m + extra)
819 }
820}
821
822fn av1_ceil_log2(n: u32) -> u32 {
823 if n <= 1 {
824 return 1;
825 }
826 let mut k = 0;
827 let mut x = n - 1;
828 while x > 0 {
829 k += 1;
830 x >>= 1;
831 }
832 k
833}
834
835fn parse_av1_quantization_params(
837 br: &mut BitReader,
838 h: &mut Av1FrameHeader,
839 seq: &Av1SequenceHeader,
840) -> Option<()> {
841 h.base_q_idx = br.read_bits(8)? as u8;
842 h.delta_q_y_dc = read_delta_q(br)?;
843 let (diff_uv_delta, num_planes) = if seq.monochrome {
844 (false, 1u32)
845 } else {
846 let diff = if seq.seq_profile == 2 {
847 br.read_bits(1)? == 1
848 } else {
849 false
850 };
851 (diff, 3u32)
852 };
853 if num_planes > 1 {
854 h.delta_q_u_dc = read_delta_q(br)?;
855 h.delta_q_u_ac = read_delta_q(br)?;
856 if diff_uv_delta {
857 h.delta_q_v_dc = read_delta_q(br)?;
858 h.delta_q_v_ac = read_delta_q(br)?;
859 } else {
860 h.delta_q_v_dc = h.delta_q_u_dc;
861 h.delta_q_v_ac = h.delta_q_u_ac;
862 }
863 }
864 h.using_qmatrix = br.read_bits(1)? == 1;
865 if h.using_qmatrix {
866 h.qm_y = br.read_bits(4)? as u8;
867 h.qm_u = br.read_bits(4)? as u8;
868 h.qm_v = if seq.monochrome {
869 h.qm_u
870 } else if br.read_bits(1)? == 0 {
871 h.qm_u
872 } else {
873 br.read_bits(4)? as u8
874 };
875 }
876 Some(())
877}
878
879fn read_delta_q(br: &mut BitReader) -> Option<i8> {
880 let present = br.read_bits(1)? == 1;
881 if present {
882 Some(br.read_su(7)? as i8)
883 } else {
884 Some(0)
885 }
886}
887
888fn parse_av1_segmentation_params(br: &mut BitReader, h: &mut Av1FrameHeader) -> Option<()> {
890 h.segmentation_enabled = br.read_bits(1)? == 1;
891 if h.segmentation_enabled {
892 if h.primary_ref_frame == 7 {
893 h.segmentation_update_map = true;
895 h.segmentation_temporal_update = false;
896 h.segmentation_update_data = true;
897 } else {
898 h.segmentation_update_map = br.read_bits(1)? == 1;
899 if h.segmentation_update_map {
900 h.segmentation_temporal_update = br.read_bits(1)? == 1;
901 }
902 h.segmentation_update_data = br.read_bits(1)? == 1;
903 }
904 if h.segmentation_update_data {
905 const FEAT_INFO: [(u32, bool); 8] = [
909 (8, true), (6, true), (6, true), (6, true), (6, true), (3, false), (0, false), (0, false), ];
918 for seg in 0..8 {
919 for (feat, &(bits, signed)) in FEAT_INFO.iter().enumerate() {
920 let enabled = br.read_bits(1)? == 1;
921 h.feature_enabled[seg][feat] = enabled;
922 if enabled {
923 if bits == 0 {
924 h.feature_data[seg][feat] = 1;
925 } else if signed {
926 h.feature_data[seg][feat] = br.read_su(bits as usize + 1)? as i16;
927 } else {
928 h.feature_data[seg][feat] = br.read_bits(bits as usize)? as i16;
929 }
930 }
931 }
932 }
933 }
934 }
935 Some(())
936}
937
938fn parse_av1_loop_filter_params(
940 br: &mut BitReader,
941 h: &mut Av1FrameHeader,
942 frame_is_intra: bool,
943) -> Option<()> {
944 if h.coded_lossless || h.allow_intrabc {
945 h.loop_filter_level = [0; 4];
946 h.loop_filter_sharpness = 0;
947 h.loop_filter_delta_enabled = false;
948 h.loop_filter_ref_deltas = [1, 0, 0, 0, -1, 0, -1, -1];
949 h.loop_filter_mode_deltas = [0, 0];
950 return Some(());
951 }
952 h.loop_filter_level[0] = br.read_bits(6)? as u8;
953 h.loop_filter_level[1] = br.read_bits(6)? as u8;
954 if h.loop_filter_level[0] > 0 || h.loop_filter_level[1] > 0 {
955 h.loop_filter_level[2] = br.read_bits(6)? as u8;
956 h.loop_filter_level[3] = br.read_bits(6)? as u8;
957 }
958 h.loop_filter_sharpness = br.read_bits(3)? as u8;
959 h.loop_filter_delta_enabled = br.read_bits(1)? == 1;
960 h.loop_filter_ref_deltas = [1, 0, 0, 0, -1, 0, -1, -1];
962 h.loop_filter_mode_deltas = [0, 0];
963 if h.loop_filter_delta_enabled {
964 h.loop_filter_delta_update = br.read_bits(1)? == 1;
965 if h.loop_filter_delta_update {
966 let mut update_mask = 0u8;
967 for i in 0..8 {
968 let update = br.read_bits(1)? == 1;
969 if update {
970 update_mask |= 1 << i;
971 h.loop_filter_ref_deltas[i] = br.read_su(7)? as i8;
972 }
973 }
974 h.update_ref_delta_mask = update_mask;
975 let mut mode_mask = 0u8;
976 for i in 0..2 {
977 let update = br.read_bits(1)? == 1;
978 if update {
979 mode_mask |= 1 << i;
980 h.loop_filter_mode_deltas[i] = br.read_su(7)? as i8;
981 }
982 }
983 h.update_mode_delta_mask = mode_mask;
984 }
985 }
986 let _ = frame_is_intra; Some(())
988}
989
990fn parse_av1_cdef_params(
992 br: &mut BitReader,
993 h: &mut Av1FrameHeader,
994 num_planes: u32,
995) -> Option<()> {
996 h.cdef_damping_minus_3 = br.read_bits(2)? as u8;
997 h.cdef_bits = br.read_bits(2)? as u8;
998 let count = 1usize << h.cdef_bits;
999 for i in 0..count {
1000 h.cdef_y_pri_strength[i] = br.read_bits(4)? as u8;
1001 let y_sec = br.read_bits(2)? as u8;
1002 h.cdef_y_sec_strength[i] = if y_sec == 3 { 4 } else { y_sec };
1006 if num_planes > 1 {
1007 h.cdef_uv_pri_strength[i] = br.read_bits(4)? as u8;
1008 let uv_sec = br.read_bits(2)? as u8;
1009 h.cdef_uv_sec_strength[i] = if uv_sec == 3 { 4 } else { uv_sec };
1010 }
1011 }
1012 Some(())
1013}
1014
1015fn parse_av1_lr_params(
1017 br: &mut BitReader,
1018 h: &mut Av1FrameHeader,
1019 num_planes: u32,
1020 seq: &Av1SequenceHeader,
1021) -> Option<()> {
1022 let mut uses_lr = false;
1023 let mut uses_chroma_lr = false;
1024 for i in 0..(num_planes as usize) {
1025 let lr_type = br.read_bits(2)? as u8;
1026 h.lr_type[i] = lr_type;
1027 if lr_type != 0 {
1028 uses_lr = true;
1029 if i > 0 {
1030 uses_chroma_lr = true;
1031 }
1032 }
1033 }
1034 if uses_lr {
1035 let base = br.read_bits(1)? as u8;
1040 h.lr_unit_shift = if base != 0 {
1041 let extra = br.read_bits(1)? as u8;
1042 base + extra
1043 } else {
1044 0
1045 };
1046 if num_planes > 1 && uses_chroma_lr && seq.chroma_subsampling_x && seq.chroma_subsampling_y
1049 {
1050 h.lr_uv_shift = br.read_bits(1)? as u8;
1051 }
1052 }
1053 Some(())
1054}
1055
1056fn skip_av1_global_motion_params(br: &mut BitReader) -> Option<()> {
1060 for _ in 0..7 {
1061 let is_global = br.read_bits(1)? == 1;
1062 let is_rot_zoom = if is_global {
1063 br.read_bits(1)? == 1
1064 } else {
1065 false
1066 };
1067 let _is_translation = if is_global && !is_rot_zoom {
1068 br.read_bits(1)? == 1
1069 } else {
1070 false
1071 };
1072 let gm_type = if is_global && !is_rot_zoom {
1073 2u8 } else if is_rot_zoom {
1075 3u8 } else if is_global {
1077 4u8 } else {
1079 0u8 };
1081 if gm_type >= 3 {
1082 for _ in 0..2 {
1084 let _a = av1_read_subexp(br, 12, 0)?;
1085 let _b = av1_read_subexp(br, 12, 0)?;
1086 }
1087 }
1088 if gm_type >= 2 {
1089 for _ in 0..2 {
1091 let _a = av1_read_subexp(br, 12, 0)?;
1092 }
1093 }
1094 }
1095 Some(())
1096}
1097
1098fn av1_read_subexp(br: &mut BitReader, num_syms: u32, _ref: i32) -> Option<i32> {
1099 let bits = av1_ceil_log2(num_syms) as usize + 1; let _ = br.read_bits(bits.min(16))?;
1105 Some(0)
1106}
1107
1108fn skip_av1_film_grain_params(br: &mut BitReader, seq: &Av1SequenceHeader) -> Option<()> {
1112 let apply_grain = br.read_bits(1)? == 1;
1113 if !apply_grain {
1114 return Some(());
1115 }
1116 let _grain_seed = br.read_bits(16)?;
1117 let update_grain = br.read_bits(1)? == 1;
1118 if !update_grain {
1119 let _film_grain_params_ref_idx = br.read_bits(3)?;
1120 return Some(());
1121 }
1122 let num_y_points = br.read_bits(4)?;
1123 for _ in 0..num_y_points {
1124 let _point_y_value = br.read_bits(8)?;
1125 let _point_y_scaling = br.read_bits(8)?;
1126 }
1127 let chroma_scaling_from_luma = if seq.monochrome {
1128 false
1129 } else {
1130 br.read_bits(1)? == 1
1131 };
1132 let num_cb_points: u32;
1133 let num_cr_points: u32;
1134 if seq.monochrome
1135 || chroma_scaling_from_luma
1136 || (seq.chroma_subsampling_x && seq.chroma_subsampling_y && num_y_points == 0)
1137 {
1138 num_cb_points = 0;
1139 num_cr_points = 0;
1140 } else {
1141 num_cb_points = br.read_bits(4)?;
1142 for _ in 0..num_cb_points {
1143 let _point_cb_value = br.read_bits(8)?;
1144 let _point_cb_scaling = br.read_bits(8)?;
1145 }
1146 num_cr_points = br.read_bits(4)?;
1147 for _ in 0..num_cr_points {
1148 let _point_cr_value = br.read_bits(8)?;
1149 let _point_cr_scaling = br.read_bits(8)?;
1150 }
1151 }
1152 let _grain_scaling_minus_8 = br.read_bits(2)?;
1153 let ar_coeff_lag = br.read_bits(2)?;
1154 let num_pos_y = 2 * ar_coeff_lag * (ar_coeff_lag + 1);
1155 let num_pos_chroma = if num_y_points > 0 {
1156 num_pos_y + 1
1157 } else {
1158 num_pos_y
1159 };
1160 for _ in 0..num_pos_y {
1161 let _ar_coeff_y_plus_128 = br.read_bits(8)?;
1162 }
1163 if chroma_scaling_from_luma || num_cb_points > 0 {
1164 for _ in 0..num_pos_chroma {
1165 let _ar_coeff_cb_plus_128 = br.read_bits(8)?;
1166 }
1167 }
1168 if chroma_scaling_from_luma || num_cr_points > 0 {
1169 for _ in 0..num_pos_chroma {
1170 let _ar_coeff_cr_plus_128 = br.read_bits(8)?;
1171 }
1172 }
1173 let _ar_coeff_shift_minus_6 = br.read_bits(2)?;
1174 let _grain_scale_shift = br.read_bits(2)?;
1175 if num_cb_points > 0 {
1176 let _cb_mult = br.read_bits(8)?;
1177 let _cb_luma_mult = br.read_bits(8)?;
1178 let _cb_offset = br.read_bits(9)?;
1179 }
1180 if num_cr_points > 0 {
1181 let _cr_mult = br.read_bits(8)?;
1182 let _cr_luma_mult = br.read_bits(8)?;
1183 let _cr_offset = br.read_bits(9)?;
1184 }
1185 let _overlap_flag = br.read_bits(1)?;
1186 let _clip_to_restricted_range = br.read_bits(1)?;
1187 Some(())
1188}