pub struct D3d11Download { /* private fields */ }d3d11 only.Expand description
Downloads GPU-resident Pixel::D3D11 BGRA video frames (e.g. from
crate::elements::D3d11VideoCompositor) to CPU-resident Pixel::BGRA
frames — the mirror of crate::elements::D3d11Upload. Needed because
this crate’s video encoder (crate::elements::SwEncoder) is
software-only and has no zero-copy GPU input path; chain a
crate::elements::Scaler after this to convert to whatever pixel
format an encoder actually needs.
Unlike D3d11Upload (a plain ID3D11Device::CreateTexture2D call, safe
to issue from any thread), reading a texture back to the CPU needs
ID3D11DeviceContext::CopySubresourceRegion/Map/Unmap — context-level calls,
not device-level ones. context must be the exact same
Arc<Mutex<ID3D11DeviceContext>> every other context-touching D3D11
consumer in this pipeline shares (e.g.
render_common::D3d11GpuContext::context()) — see that type’s own docs
on why a lone per-element context handle isn’t enough to prevent two
unrelated bind/draw/copy sequences from interleaving on the one
underlying immediate context.
Implementations§
Source§impl D3d11Download
impl D3d11Download
Sourcepub fn new(
name: impl Into<String>,
device: &ID3D11Device,
context: Arc<Mutex<ID3D11DeviceContext>>,
width: u32,
height: u32,
) -> Result<Self, D3d11DownloadError>
pub fn new( name: impl Into<String>, device: &ID3D11Device, context: Arc<Mutex<ID3D11DeviceContext>>, width: u32, height: u32, ) -> Result<Self, D3d11DownloadError>
device must be the same ID3D11Device, and context the same
shared context, every other D3D11 element in this pipeline uses —
see this type’s own docs on why. width/height are fixed for
this element’s lifetime; every frame consume receives must match
exactly.
Trait Implementations§
Source§impl Element for D3d11Download
impl Element for D3d11Download
Source§fn name(&self) -> Arc<str> ⓘ
fn name(&self) -> Arc<str> ⓘ
crate::bus::BusEvent stores names as
Arc<str> for exactly this reason: a hot path like
crate::queue::Queue posting BusEvent::Dropped once per
overflowed buffer shouldn’t pay for a fresh heap allocation every
time it wants to report which element it is.Source§fn element_type(&self) -> ElementType
fn element_type(&self) -> ElementType
ElementType.Source§fn pp_log(&self) -> &PpLog
fn pp_log(&self) -> &PpLog
crate::bus::Bus::post — same
id/name as Element::name, just already wrapped as the
crate::pp_log::PpLog its pp_info!/pp_warn!/pp_error! macros need. A
stored private field, not built fresh per call, for the same reason
name() returns a cheap Arc<str> clone instead of a fresh String
— see its own docs.Source§fn pp_log_mut(&mut self) -> &mut PpLog
fn pp_log_mut(&mut self) -> &mut PpLog
Element::pp_log reads — used by
crate::pipeline::ChainBuilder to stamp the owning
crate::pipeline::Pipeline’s id onto every element that
passes through it, via element_pp_log. Not meant to be called
from anywhere else.impl Send for D3d11Download
Source§impl Sink for D3d11Download
impl Sink for D3d11Download
fn consume(&mut self, buf: MediaBuffer) -> Result<()>
Source§fn control(&mut self, msg: ControlMsg) -> Result<()>
fn control(&mut self, msg: ControlMsg) -> Result<()>
ControlMsg (pause/resume/stop) and, for anything
with a downstream of its own, forwards it on — same shape as
consume, just a separate channel from MediaBuffer so it can
reach every element (not just ones that already know how to
interpret a data buffer) and, at a crate::queue::Queue, jump
ahead of whatever data is backed up instead of waiting behind it.
No default: every Sink has to consciously decide what this means
for it, rather than silently dropping it.