• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2024 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 v4l2r::bindings::v4l2_ctrl_vp8_frame;
6 use v4l2r::bindings::V4L2_VP8_FRAME_FLAG_KEY_FRAME;
7 use v4l2r::bindings::V4L2_VP8_FRAME_FLAG_MB_NO_SKIP_COEFF;
8 use v4l2r::bindings::V4L2_VP8_FRAME_FLAG_SHOW_FRAME;
9 use v4l2r::bindings::V4L2_VP8_FRAME_FLAG_SIGN_BIAS_ALT;
10 use v4l2r::bindings::V4L2_VP8_FRAME_FLAG_SIGN_BIAS_GOLDEN;
11 use v4l2r::bindings::V4L2_VP8_LF_ADJ_ENABLE;
12 use v4l2r::bindings::V4L2_VP8_LF_DELTA_UPDATE;
13 use v4l2r::bindings::V4L2_VP8_LF_FILTER_TYPE_SIMPLE;
14 use v4l2r::bindings::V4L2_VP8_SEGMENT_FLAG_DELTA_VALUE_MODE;
15 use v4l2r::bindings::V4L2_VP8_SEGMENT_FLAG_ENABLED;
16 use v4l2r::bindings::V4L2_VP8_SEGMENT_FLAG_UPDATE_FEATURE_DATA;
17 use v4l2r::bindings::V4L2_VP8_SEGMENT_FLAG_UPDATE_MAP;
18 use v4l2r::controls::codec::Vp8Frame;
19 use v4l2r::controls::SafeExtControl;
20 
21 use crate::codec::vp8::parser::Header;
22 use crate::codec::vp8::parser::MbLfAdjustments;
23 use crate::codec::vp8::parser::Segmentation;
24 
25 #[derive(Default)]
26 pub struct V4l2CtrlVp8FrameParams {
27     handle: v4l2_ctrl_vp8_frame,
28 }
29 
30 impl V4l2CtrlVp8FrameParams {
new() -> Self31     pub fn new() -> Self {
32         Default::default()
33     }
34 
set_loop_filter_params( &mut self, hdr: &Header, mb_lf_adjust: &MbLfAdjustments, ) -> &mut Self35     pub fn set_loop_filter_params(
36         &mut self,
37         hdr: &Header,
38         mb_lf_adjust: &MbLfAdjustments,
39     ) -> &mut Self {
40         for i in 0..4 {
41             self.handle.lf.ref_frm_delta[i] = mb_lf_adjust.ref_frame_delta[i];
42             self.handle.lf.mb_mode_delta[i] = mb_lf_adjust.mb_mode_delta[i];
43         }
44 
45         self.handle.lf.sharpness_level = hdr.sharpness_level;
46         self.handle.lf.level = hdr.loop_filter_level;
47         self.handle.lf.padding = 0;
48 
49         let mut flags: u32 = 0;
50         if hdr.filter_type {
51             flags |= V4L2_VP8_LF_FILTER_TYPE_SIMPLE;
52         }
53         if mb_lf_adjust.loop_filter_adj_enable {
54             flags |= V4L2_VP8_LF_ADJ_ENABLE;
55         }
56         if mb_lf_adjust.mode_ref_lf_delta_update {
57             flags |= V4L2_VP8_LF_DELTA_UPDATE;
58         }
59         self.handle.lf.flags = flags;
60         self
61     }
62 
set_quantization_params(&mut self, hdr: &Header) -> &mut Self63     pub fn set_quantization_params(&mut self, hdr: &Header) -> &mut Self {
64         self.handle.quant.y_ac_qi =
65             u8::try_from(hdr.quant_indices.y_ac_qi).expect("Value out of range for u8");
66         self.handle.quant.y_dc_delta =
67             i8::try_from(hdr.quant_indices.y_dc_delta).expect("Value out of range for u8");
68         self.handle.quant.y2_dc_delta =
69             i8::try_from(hdr.quant_indices.y2_dc_delta).expect("Value out of range for u8");
70         self.handle.quant.y2_ac_delta =
71             i8::try_from(hdr.quant_indices.y2_ac_delta).expect("Value out of range for u8");
72         self.handle.quant.uv_dc_delta =
73             i8::try_from(hdr.quant_indices.uv_dc_delta).expect("Value out of range for u8");
74         self.handle.quant.uv_ac_delta =
75             i8::try_from(hdr.quant_indices.uv_ac_delta).expect("Value out of range for u8");
76 
77         self.handle.quant.padding = 0;
78         self
79     }
80 
set_segmentation_params(&mut self, segmentation: &Segmentation) -> &mut Self81     pub fn set_segmentation_params(&mut self, segmentation: &Segmentation) -> &mut Self {
82         for i in 0..4 {
83             self.handle.segment.quant_update[i] = segmentation.quantizer_update_value[i];
84             self.handle.segment.lf_update[i] = segmentation.lf_update_value[i];
85         }
86 
87         for i in 0..3 {
88             self.handle.segment.segment_probs[i] = segmentation.segment_prob[i];
89         }
90 
91         self.handle.segment.padding = 0;
92 
93         let mut flags: u32 = 0;
94         if segmentation.segmentation_enabled {
95             flags |= V4L2_VP8_SEGMENT_FLAG_ENABLED;
96         }
97         if segmentation.update_mb_segmentation_map {
98             flags |= V4L2_VP8_SEGMENT_FLAG_UPDATE_MAP;
99         }
100         if segmentation.update_segment_feature_data {
101             flags |= V4L2_VP8_SEGMENT_FLAG_UPDATE_FEATURE_DATA;
102         }
103         if segmentation.segment_feature_mode == false {
104             flags |= V4L2_VP8_SEGMENT_FLAG_DELTA_VALUE_MODE;
105         }
106         self.handle.segment.flags = flags;
107         self
108     }
109 
set_entropy_params(&mut self, hdr: &Header) -> &mut Self110     pub fn set_entropy_params(&mut self, hdr: &Header) -> &mut Self {
111         self.handle.entropy.coeff_probs = hdr.coeff_prob;
112         self.handle.entropy.y_mode_probs = hdr.mode_probs.intra_16x16_prob;
113         self.handle.entropy.uv_mode_probs = hdr.mode_probs.intra_chroma_prob;
114         self.handle.entropy.mv_probs = hdr.mv_prob;
115         self
116     }
117 
set_bool_ctx(&mut self, hdr: &Header) -> &mut Self118     pub fn set_bool_ctx(&mut self, hdr: &Header) -> &mut Self {
119         self.handle.coder_state.range = hdr.bd_range as u8;
120         self.handle.coder_state.value = hdr.bd_value as u8;
121         self.handle.coder_state.bit_count = hdr.bd_count as u8;
122         self.handle.coder_state.padding = 0;
123         self
124     }
125 
set_frame_params( &mut self, hdr: &Header, last_frame_ts: u64, golden_frame_ts: u64, alt_frame_ts: u64, ) -> &mut Self126     pub fn set_frame_params(
127         &mut self,
128         hdr: &Header,
129         last_frame_ts: u64,
130         golden_frame_ts: u64,
131         alt_frame_ts: u64,
132     ) -> &mut Self {
133         self.handle.width = hdr.width;
134         self.handle.height = hdr.height;
135         self.handle.horizontal_scale = hdr.horiz_scale_code;
136         self.handle.vertical_scale = hdr.vert_scale_code;
137 
138         self.handle.version = hdr.version;
139         self.handle.prob_skip_false = hdr.prob_skip_false;
140         self.handle.prob_intra = hdr.prob_intra;
141         self.handle.prob_last = hdr.prob_last;
142         self.handle.prob_gf = hdr.prob_golden;
143         self.handle.num_dct_parts = hdr.num_dct_partitions() as u8;
144 
145         self.handle.first_part_size = hdr.first_part_size;
146         self.handle.first_part_header_bits = hdr.header_size;
147 
148         for i in 0..hdr.num_dct_partitions() {
149             self.handle.dct_part_sizes[i] = hdr.partition_size[i];
150         }
151 
152         self.handle.last_frame_ts = last_frame_ts * 1000;
153         self.handle.golden_frame_ts = golden_frame_ts * 1000;
154         self.handle.alt_frame_ts = alt_frame_ts * 1000;
155 
156         let mut flags: u32 = 0;
157         if hdr.key_frame {
158             flags |= V4L2_VP8_FRAME_FLAG_KEY_FRAME;
159         }
160         if hdr.show_frame {
161             flags |= V4L2_VP8_FRAME_FLAG_SHOW_FRAME;
162         }
163         if hdr.mb_no_coeff_skip {
164             flags |= V4L2_VP8_FRAME_FLAG_MB_NO_SKIP_COEFF;
165         }
166         if hdr.sign_bias_golden {
167             flags |= V4L2_VP8_FRAME_FLAG_SIGN_BIAS_GOLDEN;
168         }
169         if hdr.sign_bias_alternate {
170             flags |= V4L2_VP8_FRAME_FLAG_SIGN_BIAS_ALT;
171         }
172 
173         self.handle.flags = flags as u64;
174 
175         self
176     }
177 }
178 
179 impl From<&V4l2CtrlVp8FrameParams> for SafeExtControl<Vp8Frame> {
from(decode_params: &V4l2CtrlVp8FrameParams) -> Self180     fn from(decode_params: &V4l2CtrlVp8FrameParams) -> Self {
181         SafeExtControl::<Vp8Frame>::from(decode_params.handle)
182     }
183 }
184