cros_codecs/decoder.rs
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
12pub mod stateless;
13
14use std::collections::VecDeque;
15use std::os::fd::AsFd;
16use std::os::fd::BorrowedFd;
17
18use nix::errno::Errno;
19use nix::sys::eventfd::EventFd;
20
21pub use crate::BlockingMode;
22
23use crate::decoder::stateless::PoolLayer;
24use crate::DecodedFormat;
25use crate::Resolution;
26
27/// Trait for a pool of frames in a particular format.
28///
29/// This is mostly useful for the decoder where the user is expected to manage how the decoded
30/// frames buffers are allocated and when.
31pub trait FramePool {
32 /// Type of descriptor for the memory backing the frames.
33 type Descriptor;
34
35 /// Returns the coded resolution of the pool.
36 ///
37 /// All the frames maintained by this pool are guaranteed to be able to contain the coded
38 /// resolution.
39 fn coded_resolution(&self) -> Resolution;
40 /// Update the coded resolution of the pool.
41 ///
42 /// Frames managed by this pool that can not contain the new resolution are dropped.
43 fn set_coded_resolution(&mut self, resolution: Resolution);
44 /// Add new frames to the pool, using `descriptors` as backing memory.
45 fn add_frames(&mut self, descriptors: Vec<Self::Descriptor>) -> Result<(), anyhow::Error>;
46 /// Returns new number of frames currently available in this pool.
47 fn num_free_frames(&self) -> usize;
48 /// Returns the total number of managed frames in this pool.
49 fn num_managed_frames(&self) -> usize;
50 /// Remove all frames from this pool.
51 fn clear(&mut self);
52}
53
54/// Information about the current stream.
55///
56/// This is static information obtained from the stream itself about its requirements. It does not
57/// reflect the current settings of the decoder.
58#[derive(Clone)]
59pub struct StreamInfo {
60 /// Pixel format for the output frames expected by the decoder.
61 pub format: DecodedFormat,
62 /// Coded resolution of the stream, i.e. minimum size of the frames to be decoded into.
63 pub coded_resolution: Resolution,
64 /// Display resolution of the stream, i.e. the part of the decoded frames we want to display.
65 pub display_resolution: Resolution,
66 /// Minimum number of output frames per layer required for decoding to proceed.
67 ///
68 /// Codecs keep some frames as references and cannot decode immediately into them again after
69 /// they are returned. Allocating at least this number of frames guarantees that the decoder
70 /// won't starve from output frames.
71 pub min_num_frames: usize,
72}
73
74/// Trait for objects allowing to negotiate the output format of a decoder.
75///
76/// A decoder always has a valid output format set, but that format can change if the stream
77/// requests it. When this happens, the decoder stops accepting new input and a
78/// [`DecoderEvent::FormatChanged`] event is emitted, carrying a negotiator trait object that
79/// allows the client to acknowledge that the format change took place, and (in the future)
80/// negotiate its specifics.
81///
82/// When the object is dropped, the decoder can accept and process new input again.
83pub trait DecoderFormatNegotiator {
84 type Descriptor;
85
86 /// Returns the current decoding parameters, as extracted from the stream.
87 fn stream_info(&self) -> &StreamInfo;
88 /// Returns the frame pool in use for the decoder for `layer` set up for the
89 /// new format.
90 fn frame_pool(
91 &mut self,
92 layer: PoolLayer,
93 ) -> Vec<&mut dyn FramePool<Descriptor = Self::Descriptor>>;
94 /// Attempt to change the pixel format of output frames to `format`.
95 fn try_format(&mut self, format: DecodedFormat) -> anyhow::Result<()>;
96}
97
98/// Events that can be retrieved using the `next_event` method of a decoder.
99pub enum DecoderEvent<'a, H: DecodedHandle> {
100 /// The next frame has been decoded.
101 FrameReady(H),
102 /// The format of the stream has changed and action is required.
103 FormatChanged(Box<dyn DecoderFormatNegotiator<Descriptor = H::Descriptor> + 'a>),
104}
105
106pub trait DynHandle {
107 /// Gets an CPU mapping to the memory backing the handle.
108 /// Assumes that this picture is backed by a handle and panics if not the case.
109 fn dyn_mappable_handle<'a>(&'a self) -> anyhow::Result<Box<dyn MappableHandle + 'a>>;
110}
111
112/// A trait for types that can be mapped into the client's address space.
113pub trait MappableHandle {
114 /// Read the contents of `self` into `buffer`.
115 ///
116 /// The size of `buffer` must be equal to `image_size()`, or an error will be returned.
117 fn read(&mut self, buffer: &mut [u8]) -> anyhow::Result<()>;
118
119 /// Returns the size of the `buffer` argument required to call `read` on this handle.
120 fn image_size(&mut self) -> usize;
121}
122
123/// The handle type used by the decoder backend. The only requirement from implementors is that
124/// they give access to the underlying handle and that they can be (cheaply) cloned.
125pub trait DecodedHandle {
126 /// Memory descriptor type - the type that provides the backend memory for the decoded frame.
127 /// `()` is a special type meaning that the backend is responsible for allocating and managing
128 /// the memory itself.
129 type Descriptor;
130
131 /// Returns a reference to an object allowing a CPU mapping of the decoded frame.
132 fn dyn_picture<'a>(&'a self) -> Box<dyn DynHandle + 'a>;
133
134 /// Returns the timestamp of the picture.
135 fn timestamp(&self) -> u64;
136
137 /// Returns the coded resolution at the time this handle was decoded.
138 fn coded_resolution(&self) -> Resolution;
139
140 /// Returns the display resolution at the time this handle was decoded.
141 fn display_resolution(&self) -> Resolution;
142
143 /// Returns `true` if this handle has been completely decoded.
144 fn is_ready(&self) -> bool;
145
146 /// Wait until this handle has been completely rendered.
147 fn sync(&self) -> anyhow::Result<()>;
148
149 /// Returns a reference to the internal [`DecodedHandle::Descriptor`]. Can be leveraged by
150 /// platform-specific code,
151 fn resource(&self) -> std::cell::Ref<Self::Descriptor>;
152}
153
154/// Implementation for any boxed [`DecodedHandle`], including trait objects.
155impl<H> DecodedHandle for Box<H>
156where
157 H: DecodedHandle + ?Sized,
158{
159 type Descriptor = H::Descriptor;
160
161 fn dyn_picture<'a>(&'a self) -> Box<dyn DynHandle + 'a> {
162 self.as_ref().dyn_picture()
163 }
164
165 fn timestamp(&self) -> u64 {
166 self.as_ref().timestamp()
167 }
168
169 fn coded_resolution(&self) -> Resolution {
170 self.as_ref().coded_resolution()
171 }
172
173 fn display_resolution(&self) -> Resolution {
174 self.as_ref().display_resolution()
175 }
176
177 fn is_ready(&self) -> bool {
178 self.as_ref().is_ready()
179 }
180
181 fn sync(&self) -> anyhow::Result<()> {
182 self.as_ref().sync()
183 }
184
185 fn resource(&self) -> std::cell::Ref<Self::Descriptor> {
186 self.as_ref().resource()
187 }
188}
189
190/// Trait object for [`DecodedHandle`]s using a specific `Descriptor`.
191pub type DynDecodedHandle<D> = Box<dyn DecodedHandle<Descriptor = D>>;
192
193/// A queue where decoding jobs wait until they are completed, at which point they can be
194/// retrieved.
195struct ReadyFramesQueue<T> {
196 /// Queue of all the frames waiting to be sent to the client.
197 queue: VecDeque<T>,
198
199 /// EventFd signaling `EPOLLIN` whenever the queue is not empty.
200 poll_fd: EventFd,
201}
202
203impl<T> ReadyFramesQueue<T> {
204 /// Create a nwe `ReadyFramesQueue`.
205 ///
206 /// This can only fail if the `EventFd` creation fails ; in this case the corresponding `Errno`
207 /// is returned.
208 fn new() -> Result<Self, Errno> {
209 let poll_fd = EventFd::new()?;
210
211 Ok(Self {
212 queue: Default::default(),
213 poll_fd,
214 })
215 }
216
217 /// Push `handle` to the back of the queue.
218 fn push(&mut self, handle: T) {
219 self.queue.push_back(handle);
220 if let Err(e) = self.poll_fd.write(1) {
221 log::error!("failed to write ready frames queue poll FD: {:#}", e);
222 }
223 }
224
225 /// Returns a file descriptor that signals `POLLIN` whenever an event is available on this
226 /// queue.
227 pub fn poll_fd(&self) -> BorrowedFd {
228 self.poll_fd.as_fd()
229 }
230}
231
232impl<T> Extend<T> for ReadyFramesQueue<T> {
233 fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) {
234 let len_before = self.queue.len();
235 self.queue.extend(iter);
236 if let Err(e) = self.poll_fd.write((self.queue.len() - len_before) as u64) {
237 log::error!("failed to write ready frames queue poll FD: {:#}", e);
238 }
239 }
240}
241
242/// Allows us to manipulate the frames list like an iterator without consuming it and resetting its
243/// display order counter.
244impl<T> Iterator for ReadyFramesQueue<T> {
245 type Item = T;
246
247 /// Returns the next frame (if any) waiting to be dequeued.
248 fn next(&mut self) -> Option<T> {
249 let next = self.queue.pop_front();
250
251 if next.is_some() && self.queue.is_empty() {
252 if let Err(e) = self.poll_fd.read() {
253 log::error!("failed to read ready frames queue poll FD: {:#}", e);
254 }
255 }
256
257 next
258 }
259}
260
261#[cfg(test)]
262mod tests {
263 use nix::sys::epoll::Epoll;
264 use nix::sys::epoll::EpollCreateFlags;
265 use nix::sys::epoll::EpollEvent;
266 use nix::sys::epoll::EpollFlags;
267 use nix::sys::epoll::EpollTimeout;
268
269 use super::ReadyFramesQueue;
270
271 #[test]
272 fn test_ready_frame_queue_poll() {
273 let mut queue = ReadyFramesQueue::<()>::new().unwrap();
274 let epoll = Epoll::new(EpollCreateFlags::empty()).unwrap();
275 epoll
276 .add(queue.poll_fd(), EpollEvent::new(EpollFlags::EPOLLIN, 1))
277 .unwrap();
278
279 // Empty queue should not signal.
280 let mut events = [EpollEvent::empty()];
281 let nb_fds = epoll.wait(&mut events, EpollTimeout::ZERO).unwrap();
282 assert_eq!(nb_fds, 0);
283
284 // Events in the queue should signal.
285 queue.push(());
286 let mut events = [EpollEvent::empty()];
287 let nb_fds = epoll.wait(&mut events, EpollTimeout::ZERO).unwrap();
288 assert_eq!(nb_fds, 1);
289 assert_eq!(events, [EpollEvent::new(EpollFlags::EPOLLIN, 1)]);
290
291 // The queue is empty again and should not signal.
292 queue.next().unwrap();
293 let mut events = [EpollEvent::empty()];
294 let nb_fds = epoll.wait(&mut events, EpollTimeout::ZERO).unwrap();
295 assert_eq!(nb_fds, 0);
296 assert_eq!(events, [EpollEvent::empty()]);
297
298 // Add 3 elements to the queue, it should signal until we remove them all.
299 queue.extend(std::iter::repeat(()).take(3));
300 let mut events = [EpollEvent::empty()];
301 let nb_fds = epoll.wait(&mut events, EpollTimeout::ZERO).unwrap();
302 assert_eq!(nb_fds, 1);
303 assert_eq!(events, [EpollEvent::new(EpollFlags::EPOLLIN, 1)]);
304
305 queue.next().unwrap();
306 let mut events = [EpollEvent::empty()];
307 let nb_fds = epoll.wait(&mut events, EpollTimeout::ZERO).unwrap();
308 assert_eq!(nb_fds, 1);
309 assert_eq!(events, [EpollEvent::new(EpollFlags::EPOLLIN, 1)]);
310
311 queue.next().unwrap();
312 let mut events = [EpollEvent::empty()];
313 let nb_fds = epoll.wait(&mut events, EpollTimeout::ZERO).unwrap();
314 assert_eq!(nb_fds, 1);
315 assert_eq!(events, [EpollEvent::new(EpollFlags::EPOLLIN, 1)]);
316
317 queue.next().unwrap();
318 let mut events = [EpollEvent::empty()];
319 let nb_fds = epoll.wait(&mut events, EpollTimeout::ZERO).unwrap();
320 assert_eq!(nb_fds, 0);
321 assert_eq!(events, [EpollEvent::empty()]);
322 }
323}