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 std::cell::RefCell; 6 use std::rc::Rc; 7 use std::sync::Arc; 8 9 use crate::backend::v4l2::decoder::V4l2StreamInfo; 10 use crate::decoder::stateless::NewStatelessDecoderError; 11 use crate::decoder::stateless::StatelessBackendResult; 12 use crate::decoder::stateless::StatelessDecoderBackend; 13 use crate::decoder::DecodedHandle; 14 use crate::decoder::StreamInfo; 15 use crate::device::v4l2::stateless::device::V4l2Device; 16 use crate::device::v4l2::stateless::request::V4l2Request; 17 use crate::video_frame::VideoFrame; 18 use crate::DecodedFormat; 19 use crate::Fourcc; 20 use crate::Resolution; 21 22 pub struct V4l2Picture<V: VideoFrame> { 23 request: Rc<RefCell<V4l2Request<V>>>, 24 // To properly decode stream while output and capture queues 25 // are processed independently it's required for v4l2 backend 26 // to maintain DPB buffer recycling. The following vector 27 // is used to prevent reference pictures to be reused while 28 // current picture is still being decoded. 29 ref_pictures: Option<Vec<Rc<RefCell<V4l2Picture<V>>>>>, 30 } 31 32 impl<V: VideoFrame> V4l2Picture<V> { new(request: Rc<RefCell<V4l2Request<V>>>) -> Self33 pub fn new(request: Rc<RefCell<V4l2Request<V>>>) -> Self { 34 Self { request, ref_pictures: None } 35 } video_frame(&self) -> Arc<V>36 pub fn video_frame(&self) -> Arc<V> { 37 self.request.as_ref().borrow().result().capture_buffer.borrow().frame.clone() 38 } timestamp(&self) -> u6439 pub fn timestamp(&self) -> u64 { 40 self.request.as_ref().borrow().timestamp() 41 } set_ref_pictures( &mut self, ref_pictures: Vec<Rc<RefCell<V4l2Picture<V>>>>, ) -> &mut Self42 pub fn set_ref_pictures( 43 &mut self, 44 ref_pictures: Vec<Rc<RefCell<V4l2Picture<V>>>>, 45 ) -> &mut Self { 46 self.ref_pictures = Some(ref_pictures); 47 self 48 } sync(&mut self) -> &mut Self49 pub fn sync(&mut self) -> &mut Self { 50 self.request.as_ref().borrow_mut().sync(); 51 self.ref_pictures = None; 52 self 53 } request(&mut self) -> Rc<RefCell<V4l2Request<V>>>54 pub fn request(&mut self) -> Rc<RefCell<V4l2Request<V>>> { 55 self.request.clone() 56 } drop_references(&mut self)57 pub fn drop_references(&mut self) { 58 self.ref_pictures = None; 59 } 60 } 61 62 pub struct V4l2StatelessDecoderHandle<V: VideoFrame> { 63 pub picture: Rc<RefCell<V4l2Picture<V>>>, 64 pub stream_info: StreamInfo, 65 } 66 67 impl<V: VideoFrame> Clone for V4l2StatelessDecoderHandle<V> { clone(&self) -> Self68 fn clone(&self) -> Self { 69 Self { picture: Rc::clone(&self.picture), stream_info: self.stream_info.clone() } 70 } 71 } 72 73 impl<V: VideoFrame> DecodedHandle for V4l2StatelessDecoderHandle<V> { 74 type Frame = V; 75 video_frame(&self) -> Arc<Self::Frame>76 fn video_frame(&self) -> Arc<Self::Frame> { 77 self.picture.borrow().video_frame() 78 } 79 coded_resolution(&self) -> Resolution80 fn coded_resolution(&self) -> Resolution { 81 self.stream_info.coded_resolution.clone() 82 } 83 display_resolution(&self) -> Resolution84 fn display_resolution(&self) -> Resolution { 85 self.stream_info.display_resolution.clone() 86 } 87 timestamp(&self) -> u6488 fn timestamp(&self) -> u64 { 89 self.picture.borrow().timestamp() 90 } 91 sync(&self) -> anyhow::Result<()>92 fn sync(&self) -> anyhow::Result<()> { 93 self.picture.borrow_mut().sync(); 94 Ok(()) 95 } 96 is_ready(&self) -> bool97 fn is_ready(&self) -> bool { 98 todo!(); 99 } 100 } 101 102 pub struct V4l2StatelessDecoderBackend<V: VideoFrame> { 103 pub device: V4l2Device<V>, 104 pub stream_info: StreamInfo, 105 pub frame_counter: u64, 106 } 107 108 impl<V: VideoFrame> V4l2StatelessDecoderBackend<V> { new() -> Result<Self, NewStatelessDecoderError>109 pub fn new() -> Result<Self, NewStatelessDecoderError> { 110 Ok(Self { 111 device: V4l2Device::new()?, 112 stream_info: StreamInfo { 113 format: DecodedFormat::I420, 114 min_num_frames: 0, 115 coded_resolution: Resolution::from((0, 0)), 116 display_resolution: Resolution::from((0, 0)), 117 }, 118 frame_counter: 0, 119 }) 120 } 121 new_sequence<StreamData>( &mut self, stream_params: &StreamData, fourcc: Fourcc, ) -> StatelessBackendResult<()> where for<'a> &'a StreamData: V4l2StreamInfo,122 pub(crate) fn new_sequence<StreamData>( 123 &mut self, 124 stream_params: &StreamData, 125 fourcc: Fourcc, 126 ) -> StatelessBackendResult<()> 127 where 128 for<'a> &'a StreamData: V4l2StreamInfo, 129 { 130 let coded_resolution = stream_params.coded_size().clone(); 131 let min_num_frames = stream_params.min_num_frames(); 132 133 // TODO: Query the driver for the format 134 self.stream_info.format = DecodedFormat::MM21; 135 self.stream_info.display_resolution = Resolution::from(stream_params.visible_rect()); 136 self.stream_info.coded_resolution = coded_resolution; 137 self.stream_info.min_num_frames = min_num_frames; 138 139 Ok(self.device.initialize_queues(fourcc, coded_resolution, min_num_frames as u32)?) 140 } 141 } 142 143 impl<V: VideoFrame> StatelessDecoderBackend for V4l2StatelessDecoderBackend<V> { 144 type Handle = V4l2StatelessDecoderHandle<V>; 145 stream_info(&self) -> Option<&StreamInfo>146 fn stream_info(&self) -> Option<&StreamInfo> { 147 // TODO 148 Some(&self.stream_info) 149 } 150 reset_backend(&mut self) -> anyhow::Result<()>151 fn reset_backend(&mut self) -> anyhow::Result<()> { 152 Ok(self.device.reset_queues()?) 153 } 154 } 155