• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2025 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 
8 use v4l2r::ioctl;
9 
10 use crate::backend::v4l2::decoder::stateless::V4l2Picture;
11 use crate::backend::v4l2::decoder::stateless::V4l2StatelessDecoderBackend;
12 use crate::backend::v4l2::decoder::stateless::V4l2StatelessDecoderHandle;
13 use crate::backend::v4l2::decoder::V4l2StreamInfo;
14 use crate::backend::v4l2::decoder::ADDITIONAL_REFERENCE_FRAME_BUFFER;
15 use crate::codec::av1::parser::FrameHeaderObu;
16 use crate::codec::av1::parser::StreamInfo;
17 use crate::codec::av1::parser::TileGroupObu;
18 use crate::codec::av1::parser::NUM_REF_FRAMES;
19 use crate::decoder::stateless::av1::Av1;
20 use crate::decoder::stateless::av1::StatelessAV1DecoderBackend;
21 use crate::decoder::stateless::NewPictureError;
22 use crate::decoder::stateless::NewPictureResult;
23 use crate::decoder::stateless::NewStatelessDecoderError;
24 use crate::decoder::stateless::StatelessBackendError;
25 use crate::decoder::stateless::StatelessBackendResult;
26 use crate::decoder::stateless::StatelessDecoder;
27 use crate::decoder::stateless::StatelessDecoderBackendPicture;
28 use crate::decoder::BlockingMode;
29 use crate::decoder::DecodedHandle;
30 use crate::device::v4l2::stateless::controls::av1::Av1V4l2FilmGrainCtrl;
31 use crate::device::v4l2::stateless::controls::av1::Av1V4l2FrameCtrl;
32 use crate::device::v4l2::stateless::controls::av1::Av1V4l2SequenceCtrl;
33 use crate::device::v4l2::stateless::controls::av1::Av1V4l2TileGroupEntryCtrl;
34 use crate::device::v4l2::stateless::controls::av1::V4l2CtrlAv1FilmGrainParams;
35 use crate::device::v4l2::stateless::controls::av1::V4l2CtrlAv1FrameParams;
36 use crate::device::v4l2::stateless::controls::av1::V4l2CtrlAv1SequenceParams;
37 use crate::device::v4l2::stateless::controls::av1::V4l2CtrlAv1TileGroupEntryParams;
38 use crate::video_frame::VideoFrame;
39 use crate::Fourcc;
40 use crate::Rect;
41 use crate::Resolution;
42 
43 impl V4l2StreamInfo for &StreamInfo {
min_num_frames(&self) -> usize44     fn min_num_frames(&self) -> usize {
45         NUM_REF_FRAMES + ADDITIONAL_REFERENCE_FRAME_BUFFER
46     }
47 
coded_size(&self) -> Resolution48     fn coded_size(&self) -> Resolution {
49         Resolution::from((
50             self.seq_header.max_frame_width_minus_1 as u32 + 1,
51             self.seq_header.max_frame_height_minus_1 as u32 + 1,
52         ))
53     }
54 
visible_rect(&self) -> Rect55     fn visible_rect(&self) -> Rect {
56         Rect::from(((0, 0), (self.render_width, self.render_height)))
57     }
58 }
59 
60 impl<V: VideoFrame> StatelessDecoderBackendPicture<Av1> for V4l2StatelessDecoderBackend<V> {
61     type Picture = Rc<RefCell<V4l2Picture<V>>>;
62 }
63 
64 impl<V: VideoFrame> StatelessAV1DecoderBackend for V4l2StatelessDecoderBackend<V> {
change_stream_info(&mut self, stream_info: &StreamInfo) -> StatelessBackendResult<()>65     fn change_stream_info(&mut self, stream_info: &StreamInfo) -> StatelessBackendResult<()> {
66         self.new_sequence(stream_info, Fourcc::from(b"AV1F"))
67     }
68 
new_picture( &mut self, _hdr: &FrameHeaderObu, _timestamp: u64, alloc_cb: &mut dyn FnMut() -> Option<V>, ) -> NewPictureResult<Self::Picture>69     fn new_picture(
70         &mut self,
71         _hdr: &FrameHeaderObu,
72         _timestamp: u64,
73         alloc_cb: &mut dyn FnMut() -> Option<V>,
74     ) -> NewPictureResult<Self::Picture> {
75         let timestamp = self.frame_counter;
76         let frame = alloc_cb().ok_or(NewPictureError::OutOfOutputBuffers)?;
77         let request_buffer = match self.device.alloc_request(timestamp, frame) {
78             Ok(buffer) => buffer,
79             _ => return Err(NewPictureError::OutOfOutputBuffers),
80         };
81         let picture = Rc::new(RefCell::new(V4l2Picture::new(request_buffer.clone())));
82         request_buffer
83             .as_ref()
84             .borrow_mut()
85             .set_picture_ref(Rc::<RefCell<V4l2Picture<V>>>::downgrade(&picture));
86 
87         self.frame_counter = self.frame_counter + 1;
88         Ok(picture)
89     }
90 
begin_picture( &mut self, picture: &mut Self::Picture, stream_info: &StreamInfo, hdr: &FrameHeaderObu, reference_frames: &[Option<Self::Handle>; NUM_REF_FRAMES], ) -> StatelessBackendResult<()>91     fn begin_picture(
92         &mut self,
93         picture: &mut Self::Picture,
94         stream_info: &StreamInfo,
95         hdr: &FrameHeaderObu,
96         reference_frames: &[Option<Self::Handle>; NUM_REF_FRAMES],
97     ) -> StatelessBackendResult<()> {
98         let mut picture = picture.borrow_mut();
99         let mut reference_pictures = Vec::<Rc<RefCell<V4l2Picture<V>>>>::new();
100         let mut reference_ts = [0; NUM_REF_FRAMES];
101 
102         for (i, frame) in reference_frames.iter().enumerate() {
103             if let Some(handle) = frame {
104                 reference_ts[i] = handle.timestamp();
105                 reference_pictures.push(frame.as_ref().unwrap().picture.clone());
106             }
107         }
108         picture.set_ref_pictures(reference_pictures);
109 
110         let request = picture.request();
111         let request = request.as_ref().borrow_mut();
112 
113         if hdr.film_grain_params.apply_grain {
114             let mut film_grain_params = V4l2CtrlAv1FilmGrainParams::new();
115             film_grain_params.set_film_grain_params(&hdr);
116 
117             let mut film_grain_params_ctrl = Av1V4l2FilmGrainCtrl::from(&film_grain_params);
118             let which = request.which();
119             ioctl::s_ext_ctrls(&self.device, which, &mut film_grain_params_ctrl)
120                 .map_err(|e| StatelessBackendError::Other(anyhow::anyhow!(e)))?;
121         }
122 
123         let mut sequence_params = V4l2CtrlAv1SequenceParams::new();
124         sequence_params.set_ctrl_sequence(&stream_info.seq_header);
125 
126         let mut sequence_params_ctrl = Av1V4l2SequenceCtrl::from(&sequence_params);
127         let which = request.which();
128         ioctl::s_ext_ctrls(&self.device, which, &mut sequence_params_ctrl)
129             .map_err(|e| StatelessBackendError::Other(anyhow::anyhow!(e)))?;
130 
131         let mut frame_params = V4l2CtrlAv1FrameParams::new();
132         frame_params
133             .set_frame_params(&hdr)
134             .set_global_motion_params(&hdr.global_motion_params)
135             .set_loop_restoration_params(&hdr.loop_restoration_params)
136             .set_cdef_params(&hdr.cdef_params)
137             .set_loop_filter_params(&hdr.loop_filter_params)
138             .set_segmentation_params(&hdr.segmentation_params)
139             .set_quantization_params(&hdr.quantization_params)
140             .set_tile_info_params(&hdr)
141             .set_reference_frame_ts(reference_ts);
142 
143         let mut frame_params_ctrl = Av1V4l2FrameCtrl::from(&frame_params);
144         let which = request.which();
145         ioctl::s_ext_ctrls(&self.device, which, &mut frame_params_ctrl)
146             .map_err(|e| StatelessBackendError::Other(anyhow::anyhow!(e)))?;
147 
148         Ok(())
149     }
150 
decode_tile_group( &mut self, picture: &mut Self::Picture, tile_group: TileGroupObu, ) -> crate::decoder::stateless::StatelessBackendResult<()>151     fn decode_tile_group(
152         &mut self,
153         picture: &mut Self::Picture,
154         tile_group: TileGroupObu,
155     ) -> crate::decoder::stateless::StatelessBackendResult<()> {
156         let mut tile_group_params = V4l2CtrlAv1TileGroupEntryParams::new();
157 
158         for tile in &tile_group.tiles {
159             tile_group_params.set_tile_group_entry(&tile);
160         }
161 
162         let mut picture = picture.borrow_mut();
163         let request = picture.request();
164         let mut request = request.as_ref().borrow_mut();
165 
166         let mut tile_group_params_ctrl = Av1V4l2TileGroupEntryCtrl::from(&tile_group_params);
167         let which = request.which();
168         ioctl::s_ext_ctrls(&self.device, which, &mut tile_group_params_ctrl)
169             .map_err(|e| StatelessBackendError::Other(anyhow::anyhow!(e)))?;
170 
171         request.write(tile_group.obu.as_ref());
172 
173         Ok(())
174     }
175 
submit_picture(&mut self, picture: Self::Picture) -> StatelessBackendResult<Self::Handle>176     fn submit_picture(&mut self, picture: Self::Picture) -> StatelessBackendResult<Self::Handle> {
177         let request = picture.borrow_mut().request();
178         let mut request = request.as_ref().borrow_mut();
179         request.submit()?;
180         Ok(V4l2StatelessDecoderHandle {
181             picture: picture.clone(),
182             stream_info: self.stream_info.clone(),
183         })
184     }
185 }
186 
187 impl<V: VideoFrame> StatelessDecoder<Av1, V4l2StatelessDecoderBackend<V>> {
new_v4l2(blocking_mode: BlockingMode) -> Result<Self, NewStatelessDecoderError>188     pub fn new_v4l2(blocking_mode: BlockingMode) -> Result<Self, NewStatelessDecoderError> {
189         Self::new(V4l2StatelessDecoderBackend::new()?, blocking_mode)
190     }
191 }
192