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
//! Draw decoded frames on the GPU, handing back a texture you present.
//!
//! The egress half of the zero-copy story, and the fourth role module alongside
//! [`capture`](crate::capture), [`encode`](crate::encode) and
//! [`decode`](crate::decode). [`decode`](crate::decode) keeps a hardware-decoded
//! frame on the GPU; this draws it there too, converting YUV to RGB in a shader
//! instead of downloading pixels to convert them on the CPU.
//!
//! [`Renderer::render`] returns a plain [`wgpu::Texture`], which is the whole
//! integration seam: presenting it to a window, feeding it to egui or bevy, or
//! copying it back is yours to do, so this module carries no windowing or UI
//! dependency.
//!
//! ```no_run
//! # fn example(device: &moq_video::render::wgpu::Device, queue: &moq_video::render::wgpu::Queue) -> Result<(), moq_video::Error> {
//! use moq_video::render::{Config, Renderer};
//!
//! let mut renderer = Renderer::new(device, queue, Config::new())?;
//! # let frame: moq_video::Frame = todo!();
//! let texture = renderer.render(&frame)?;
//! # let _ = texture;
//! # Ok(())
//! # }
//! ```
//!
//! ## Zero-copy
//!
//! A hardware-decoded frame is imported by aliasing the decoder's surface as a
//! texture rather than copying it: `CVMetalTextureCache` on macOS, for the
//! `PixelBuffer` variant of [`Surface`](crate::Surface) that capture and a
//! VideoToolbox decode produce.
// `PixelBuffer` is deliberately not a doc link: the variant is macOS-only, so a
// link to it fails the `-D warnings` rustdoc build on every other platform.
//!
//! Every other frame, and any import that fails, goes through
//! [`Surface::into_i420`](crate::Surface::into_i420) and a plane upload. That
//! path is always available, so which route a frame takes is a question of cost.
//! An import path that keeps failing (a driver that cannot do it at all) retires
//! itself after a few frames rather than paying for the attempt forever.
//!
//! Enabled by the non-default `render` feature, which is what pulls in `wgpu`.
pub use ;
/// The `wgpu` this renderer was built against, re-exported so you name the exact
/// version rather than guessing at a compatible one.
///
/// [`Renderer::new`] takes this crate's `Device` and `Queue`, and
/// [`Renderer::render`] hands back its `Texture`, so a major bump here is a
/// breaking change for this crate.
pub use wgpu;