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