• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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