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}