1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193
// Copyright 2022 The ChromiumOS Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//! Encoded stream decoding.
//!
//! A decoder turns an encoded stream into its corresponding decoded frames. This module provides
//! several decoders for various codecs and backends.
//!
//! At the moment, only a [stateless] decoder interface is provided.
pub mod stateless;
use std::collections::VecDeque;
use crate::DecodedFormat;
use crate::Resolution;
/// Trait for a pool of surfaces in a particular format.
///
/// This is mostly useful for the decoder where the user is expected to manage how the decoded
/// frames buffers are allocated and when.
///
/// The `M` generic parameter is the type of the descriptors for the memory backing the surfaces.
pub trait SurfacePool<M> {
/// Returns the coded resolution of the pool.
///
/// All the frames maintained by this pool are guaranteed to be able to contain the coded
/// resolution.
fn coded_resolution(&self) -> Resolution;
/// Update the coded resolution of the pool.
///
/// Frames managed by this pool that can not contain the new resolution are dropped.
fn set_coded_resolution(&mut self, resolution: Resolution);
/// Add new surfaces to the pool, using `descriptors` as backing memory.
fn add_surfaces(&mut self, descriptors: Vec<M>) -> Result<(), anyhow::Error>;
/// Returns new number of surfaces currently available in this pool.
fn num_free_surfaces(&self) -> usize;
/// Returns the total number of managed surfaces in this pool.
fn num_managed_surfaces(&self) -> usize;
/// Remove all surfaces from this pool.
fn clear(&mut self);
/// Returns an object holding one of the available surfaces from this pool. The surface will be
/// available for rendering again once the returned object is dropped.
///
/// This is useful to prevent decoding from happening by holding all the available surfaces.
///
/// Returns `None` if there is no free surface at the time of calling.
fn take_free_surface(&mut self) -> Option<Box<dyn AsRef<M>>>;
}
/// Information about the current stream.
///
/// This is static information obtained from the stream itself about its requirements. It does not
/// reflect the current settings of the decoder.
#[derive(Clone)]
pub struct StreamInfo {
/// Pixel format for the output frames expected by the decoder.
pub format: DecodedFormat,
/// Coded resolution of the stream, i.e. minimum size of the frames to be decoded into.
pub coded_resolution: Resolution,
/// Display resolution of the stream, i.e. the part of the decoded frames we want to display.
pub display_resolution: Resolution,
/// Minimum number of output surfaces required for decoding to proceed.
///
/// Codecs keep some frames as references and cannot decode immediately into them again after
/// they are returned. Allocating at least this number of frames guarantees that the decoder
/// won't starve from output surfaces.
pub min_num_surfaces: usize,
}
/// Trait for objects allowing to negotiate the output format of a decoder.
///
/// A decoder always has a valid output format set, but that format can change if the stream
/// requests it. When this happens, the decoder stops accepting new input and a `FormatChanged`
/// event is emitted, carrying a negotiator trait object that allows the client to acknowledge that
/// the format change took place, and (in the future) negotiate its specifics.
///
/// When the object is dropped, the decoder can accept and process new input again.
pub trait DecoderFormatNegotiator<'a, M> {
/// Returns the current decoding parameters, as extracted from the stream.
fn stream_info(&self) -> &StreamInfo;
/// Returns the surface pool in use for the decoder, set up for the new format.
fn surface_pool(&mut self) -> &mut dyn SurfacePool<M>;
fn try_format(&mut self, format: DecodedFormat) -> anyhow::Result<()>;
}
/// Events that can be retrieved using the `next_event` method of a decoder.
pub enum DecoderEvent<'a, M> {
/// The next frame has been decoded.
FrameReady(Box<dyn DecodedHandle<Descriptor = M>>),
/// The format of the stream has changed and action is required.
FormatChanged(Box<dyn DecoderFormatNegotiator<'a, M> + 'a>),
}
pub trait DynHandle {
/// Gets an CPU mapping to the memory backing the handle.
/// Assumes that this picture is backed by a handle and panics if not the case.
fn dyn_mappable_handle<'a>(&'a self) -> anyhow::Result<Box<dyn MappableHandle + 'a>>;
}
/// A trait for types that can be mapped into the client's address space.
pub trait MappableHandle {
/// Read the contents of `self` into `buffer`.
///
/// The size of `buffer` must be equal to `image_size()`, or an error will be returned.
fn read(&mut self, buffer: &mut [u8]) -> anyhow::Result<()>;
/// Returns the size of the `buffer` argument required to call `read` on this handle.
fn image_size(&mut self) -> usize;
}
/// The handle type used by the decoder backend. The only requirement from implementors is that
/// they give access to the underlying handle and that they can be (cheaply) cloned.
pub trait DecodedHandle {
/// Memory descriptor type - the type that provides the backend memory for the decoded frame.
/// `()` is a special type meaning that the backend is responsible for allocating and managing
/// the memory itself.
type Descriptor;
/// Returns a reference to an object allowing a CPU mapping of the decoded surface.
fn dyn_picture<'a>(&'a self) -> Box<dyn DynHandle + 'a>;
/// Returns the timestamp of the picture.
fn timestamp(&self) -> u64;
/// Returns the coded resolution at the time this handle was decoded.
fn coded_resolution(&self) -> Resolution;
/// Returns the display resolution at the time this handle was decoded.
fn display_resolution(&self) -> Resolution;
/// Returns `true` if this handle has been completely decoded.
fn is_ready(&self) -> bool;
/// Wait until this handle has been completely rendered.
fn sync(&self) -> anyhow::Result<()>;
fn resource(&self) -> std::cell::Ref<Self::Descriptor>;
}
/// Instructs the decoder on whether it should block on the decode operations.
/// Nonblocking mode is conditional on backend support.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum BlockingMode {
Blocking,
NonBlocking,
}
impl Default for BlockingMode {
fn default() -> Self {
Self::Blocking
}
}
/// A queue where decoding jobs wait until they are completed, at which point they can be
/// retrieved.
struct ReadyFramesQueue<T> {
/// Queue of all the frames waiting to be sent to the client.
queue: VecDeque<T>,
}
impl<T> Default for ReadyFramesQueue<T> {
fn default() -> Self {
Self {
queue: Default::default(),
}
}
}
impl<T> ReadyFramesQueue<T> {
/// Push `handle` to the back of the queue.
fn push(&mut self, handle: T) {
self.queue.push_back(handle)
}
}
impl<T> Extend<T> for ReadyFramesQueue<T> {
fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) {
self.queue.extend(iter)
}
}
/// Allows us to manipulate the frames list like an iterator without consuming it and resetting its
/// display order counter.
impl<'a, T> Iterator for &'a mut ReadyFramesQueue<T> {
type Item = T;
/// Returns the next frame (if any) waiting to be dequeued.
fn next(&mut self) -> Option<T> {
self.queue.pop_front()
}
}