1 // Copyright 2022 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 //! Encoded stream decoding. 6 //! 7 //! A decoder turns an encoded stream into its corresponding decoded frames. This module provides 8 //! several decoders for various codecs and backends. 9 //! 10 //! At the moment, only a [stateless] decoder interface is provided. 11 12 pub mod stateless; 13 14 use std::collections::VecDeque; 15 use std::os::fd::AsFd; 16 use std::os::fd::BorrowedFd; 17 use std::sync::Arc; 18 19 use nix::errno::Errno; 20 use nix::sys::eventfd::EventFd; 21 22 pub use crate::BlockingMode; 23 24 use crate::video_frame::VideoFrame; 25 use crate::DecodedFormat; 26 use crate::Resolution; 27 28 /// Trait for a pool of frames in a particular format. 29 /// 30 /// This is mostly useful for the decoder where the user is expected to manage how the decoded 31 /// frames buffers are allocated and when. 32 pub trait FramePool { 33 /// Type of descriptor for the memory backing the frames. 34 type Descriptor; 35 36 /// Returns the coded resolution of the pool. 37 /// 38 /// All the frames maintained by this pool are guaranteed to be able to contain the coded 39 /// resolution. coded_resolution(&self) -> Resolution40 fn coded_resolution(&self) -> Resolution; 41 /// Update the coded resolution of the pool. 42 /// 43 /// Frames managed by this pool that can not contain the new resolution are dropped. set_coded_resolution(&mut self, resolution: Resolution)44 fn set_coded_resolution(&mut self, resolution: Resolution); 45 /// Add new frames to the pool, using `descriptors` as backing memory. add_frames(&mut self, descriptors: Vec<Self::Descriptor>) -> Result<(), anyhow::Error>46 fn add_frames(&mut self, descriptors: Vec<Self::Descriptor>) -> Result<(), anyhow::Error>; 47 /// Returns new number of frames currently available in this pool. num_free_frames(&self) -> usize48 fn num_free_frames(&self) -> usize; 49 /// Returns the total number of managed frames in this pool. num_managed_frames(&self) -> usize50 fn num_managed_frames(&self) -> usize; 51 /// Remove all frames from this pool. clear(&mut self)52 fn clear(&mut self); 53 } 54 55 /// Information about the current stream. 56 /// 57 /// This is static information obtained from the stream itself about its requirements. It does not 58 /// reflect the current settings of the decoder. 59 #[derive(Clone, Debug)] 60 pub struct StreamInfo { 61 /// Pixel format for the output frames expected by the decoder. 62 pub format: DecodedFormat, 63 /// Coded resolution of the stream, i.e. minimum size of the frames to be decoded into. 64 pub coded_resolution: Resolution, 65 /// Display resolution of the stream, i.e. the part of the decoded frames we want to display. 66 pub display_resolution: Resolution, 67 /// Minimum number of output frames per layer required for decoding to proceed. 68 /// 69 /// Codecs keep some frames as references and cannot decode immediately into them again after 70 /// they are returned. Allocating at least this number of frames guarantees that the decoder 71 /// won't starve from output frames. 72 pub min_num_frames: usize, 73 } 74 75 /// Events that can be retrieved using the `next_event` method of a decoder. 76 pub enum DecoderEvent<H: DecodedHandle> { 77 /// The next frame has been decoded. 78 FrameReady(H), 79 /// The format of the stream has changed and action is required. 80 FormatChanged, 81 } 82 83 /// The handle type used by the decoder backend. The only requirement from implementors is that 84 /// they give access to the underlying handle and that they can be (cheaply) cloned. 85 pub trait DecodedHandle { 86 type Frame: VideoFrame; 87 video_frame(&self) -> Arc<Self::Frame>88 fn video_frame(&self) -> Arc<Self::Frame>; 89 90 /// Returns the timestamp of the picture. timestamp(&self) -> u6491 fn timestamp(&self) -> u64; 92 93 /// Returns the coded resolution at the time this handle was decoded. coded_resolution(&self) -> Resolution94 fn coded_resolution(&self) -> Resolution; 95 96 /// Returns the display resolution at the time this handle was decoded. display_resolution(&self) -> Resolution97 fn display_resolution(&self) -> Resolution; 98 99 /// Returns `true` if this handle has been completely decoded. is_ready(&self) -> bool100 fn is_ready(&self) -> bool; 101 102 /// Wait until this handle has been completely rendered. sync(&self) -> anyhow::Result<()>103 fn sync(&self) -> anyhow::Result<()>; 104 } 105 106 /// Implementation for any boxed [`DecodedHandle`], including trait objects. 107 impl<H> DecodedHandle for Box<H> 108 where 109 H: DecodedHandle + ?Sized, 110 { 111 type Frame = H::Frame; 112 video_frame(&self) -> Arc<Self::Frame>113 fn video_frame(&self) -> Arc<Self::Frame> { 114 self.as_ref().video_frame() 115 } 116 timestamp(&self) -> u64117 fn timestamp(&self) -> u64 { 118 self.as_ref().timestamp() 119 } 120 coded_resolution(&self) -> Resolution121 fn coded_resolution(&self) -> Resolution { 122 self.as_ref().coded_resolution() 123 } 124 display_resolution(&self) -> Resolution125 fn display_resolution(&self) -> Resolution { 126 self.as_ref().display_resolution() 127 } 128 is_ready(&self) -> bool129 fn is_ready(&self) -> bool { 130 self.as_ref().is_ready() 131 } 132 sync(&self) -> anyhow::Result<()>133 fn sync(&self) -> anyhow::Result<()> { 134 self.as_ref().sync() 135 } 136 } 137 138 /// Trait object for [`DecodedHandle`]s using a specific `VideoFrame`. 139 pub type DynDecodedHandle<F> = Box<dyn DecodedHandle<Frame = F>>; 140 141 /// A queue where decoding jobs wait until they are completed, at which point they can be 142 /// retrieved. 143 struct ReadyFramesQueue<T> { 144 /// Queue of all the frames waiting to be sent to the client. 145 queue: VecDeque<T>, 146 147 /// EventFd signaling `EPOLLIN` whenever the queue is not empty. 148 poll_fd: EventFd, 149 } 150 151 impl<T> ReadyFramesQueue<T> { 152 /// Create a nwe `ReadyFramesQueue`. 153 /// 154 /// This can only fail if the `EventFd` creation fails ; in this case the corresponding `Errno` 155 /// is returned. new() -> Result<Self, Errno>156 fn new() -> Result<Self, Errno> { 157 let poll_fd = EventFd::new()?; 158 159 Ok(Self { queue: Default::default(), poll_fd }) 160 } 161 162 /// Push `handle` to the back of the queue. push(&mut self, handle: T)163 fn push(&mut self, handle: T) { 164 self.queue.push_back(handle); 165 if let Err(e) = self.poll_fd.write(1) { 166 log::error!("failed to write ready frames queue poll FD: {:#}", e); 167 } 168 } 169 170 /// Returns a file descriptor that signals `POLLIN` whenever an event is available on this 171 /// queue. poll_fd(&self) -> BorrowedFd172 pub fn poll_fd(&self) -> BorrowedFd { 173 self.poll_fd.as_fd() 174 } 175 } 176 177 impl<T> Extend<T> for ReadyFramesQueue<T> { extend<I: IntoIterator<Item = T>>(&mut self, iter: I)178 fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) { 179 let len_before = self.queue.len(); 180 self.queue.extend(iter); 181 if let Err(e) = self.poll_fd.write((self.queue.len() - len_before) as u64) { 182 log::error!("failed to write ready frames queue poll FD: {:#}", e); 183 } 184 } 185 } 186 187 /// Allows us to manipulate the frames list like an iterator without consuming it and resetting its 188 /// display order counter. 189 impl<T> Iterator for ReadyFramesQueue<T> { 190 type Item = T; 191 192 /// Returns the next frame (if any) waiting to be dequeued. next(&mut self) -> Option<T>193 fn next(&mut self) -> Option<T> { 194 let next = self.queue.pop_front(); 195 196 if next.is_some() && self.queue.is_empty() { 197 if let Err(e) = self.poll_fd.read() { 198 log::error!("failed to read ready frames queue poll FD: {:#}", e); 199 } 200 } 201 202 next 203 } 204 } 205 206 #[cfg(test)] 207 mod tests { 208 use nix::sys::epoll::Epoll; 209 use nix::sys::epoll::EpollCreateFlags; 210 use nix::sys::epoll::EpollEvent; 211 use nix::sys::epoll::EpollFlags; 212 use nix::sys::epoll::EpollTimeout; 213 214 use super::ReadyFramesQueue; 215 216 #[test] test_ready_frame_queue_poll()217 fn test_ready_frame_queue_poll() { 218 let mut queue = ReadyFramesQueue::<()>::new().unwrap(); 219 let epoll = Epoll::new(EpollCreateFlags::empty()).unwrap(); 220 epoll.add(queue.poll_fd(), EpollEvent::new(EpollFlags::EPOLLIN, 1)).unwrap(); 221 222 // Empty queue should not signal. 223 let mut events = [EpollEvent::empty()]; 224 let nb_fds = epoll.wait(&mut events, EpollTimeout::ZERO).unwrap(); 225 assert_eq!(nb_fds, 0); 226 227 // Events in the queue should signal. 228 queue.push(()); 229 let mut events = [EpollEvent::empty()]; 230 let nb_fds = epoll.wait(&mut events, EpollTimeout::ZERO).unwrap(); 231 assert_eq!(nb_fds, 1); 232 assert_eq!(events, [EpollEvent::new(EpollFlags::EPOLLIN, 1)]); 233 234 // The queue is empty again and should not signal. 235 queue.next().unwrap(); 236 let mut events = [EpollEvent::empty()]; 237 let nb_fds = epoll.wait(&mut events, EpollTimeout::ZERO).unwrap(); 238 assert_eq!(nb_fds, 0); 239 assert_eq!(events, [EpollEvent::empty()]); 240 241 // Add 3 elements to the queue, it should signal until we remove them all. 242 queue.extend(std::iter::repeat(()).take(3)); 243 let mut events = [EpollEvent::empty()]; 244 let nb_fds = epoll.wait(&mut events, EpollTimeout::ZERO).unwrap(); 245 assert_eq!(nb_fds, 1); 246 assert_eq!(events, [EpollEvent::new(EpollFlags::EPOLLIN, 1)]); 247 248 queue.next().unwrap(); 249 let mut events = [EpollEvent::empty()]; 250 let nb_fds = epoll.wait(&mut events, EpollTimeout::ZERO).unwrap(); 251 assert_eq!(nb_fds, 1); 252 assert_eq!(events, [EpollEvent::new(EpollFlags::EPOLLIN, 1)]); 253 254 queue.next().unwrap(); 255 let mut events = [EpollEvent::empty()]; 256 let nb_fds = epoll.wait(&mut events, EpollTimeout::ZERO).unwrap(); 257 assert_eq!(nb_fds, 1); 258 assert_eq!(events, [EpollEvent::new(EpollFlags::EPOLLIN, 1)]); 259 260 queue.next().unwrap(); 261 let mut events = [EpollEvent::empty()]; 262 let nb_fds = epoll.wait(&mut events, EpollTimeout::ZERO).unwrap(); 263 assert_eq!(nb_fds, 0); 264 assert_eq!(events, [EpollEvent::empty()]); 265 } 266 } 267