Skip to main content

TestVideoSource

Struct TestVideoSource 

Source
pub struct TestVideoSource { /* private fields */ }
Expand description

Generates a synthetic, moving-diagonal-gradient video stream — GStreamer’s videotestsrc equivalent. No real decode/demux involved: run() fabricates one Pixel::YUV420P frame per tick, stamps it with an increasing pts (one tick per frame, in TestVideoSource::time_base’s units), and pushes it straight downstream — useful for exercising Scaler/Pacer/D3d12Renderer/etc. without a real file or camera. D3d12Renderer in particular already handles Pixel::YUV420P on its CPU-upload path, so this can feed a renderer directly, no decoder needed.

Self-paces to options.framerate on a drift-free absolute schedule (next_due += frame_interval each tick in run, not “sleep frame_interval since the last push” — the latter accumulates drift, since generation itself always takes some nonzero time) — unlike FileDemuxer/RtspSource (which push as fast as they can and leave real-time pacing entirely to a downstream Pacer), this element’s “real time” isn’t defined by anything external; it’s whatever framerate says it should be, so there’s no reason not to generate at exactly that rate itself.

Confirmed (examples/render/test_video, with and without a downstream Pacer) that this is actually enough on its own for smooth D3d12Renderer output, vsync-locked presentation included — an earlier version of this doc claimed self-pacing alone was not enough and a Pacer was still required, reasoning that only the average rate was being kept correct, not when each frame lines up against the vsync grid. That reasoning wasn’t wrong about the mechanism, but the fix turned out to already be in place here: a relative “since last push” schedule genuinely can drift out of phase over time, but this element was rewritten to the absolute schedule described above specifically to close that gap, and testing without a Pacer afterward showed no judder. See crate::elements::DxgiCaptureSource’s own docs for the same conclusion reached the same way, including a case (Scaler sitting between source and renderer) this element doesn’t have.

Runs until Stop — never reaches Eos on its own (no frame-count limit is exposed, deliberately, mirroring a live camera source more than a file).

Implementations§

Source§

impl TestVideoSource

Source

pub fn new(name: impl Into<String>, options: TestVideoOptions) -> Self

Source

pub fn time_base(&self) -> Rational

The unit each generated frame’s pts is expressed in — what you need to construct a matching crate::elements::Pacer.

Trait Implementations§

Source§

impl Element for TestVideoSource

Source§

fn name(&self) -> Arc<str>

Returns a cheap clone (refcount bump, not a deep copy) of this element’s name — 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

Source§

fn pp_log(&self) -> &PpLog

This element’s identity for 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

Mutable access to the same field 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.
Source§

fn graph_id(&self) -> Option<ElementId>

A pre-reserved graph identity for elements that expose dynamic attachment handles. Most elements receive an ID from ChainBuilder and keep the default None implementation.
Source§

impl Source for TestVideoSource

Source§

fn src_pads(&mut self) -> &mut [SrcPad]

Source§

impl SourceElement for TestVideoSource

Source§

fn run(&mut self, control: &ControlReceiver, bus: &Bus) -> Result<()>

Drives this source until Eos (normal completion), crate::pipeline::Pipeline::finish, or Stop (see ControlMsg::Stop) — call crate::control::drain_control once per loop iteration to make control responsive between blocking reads. Read more
Source§

fn seek(&mut self, _target: Duration) -> Result<Duration>

Repositions this source to target, an absolute position from the start of the media (e.g. av_seek_frame for crate::elements::FileDemuxer). Called by crate::control::drain_control as part of handling ControlMsg::Seek, before that message is forwarded to the source’s own pads — so whatever’s read next comes from the new position by the time downstream elements are told to flush for it. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a [WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a [WithDispatch] wrapper. Read more