Skip to main content

MpvRenderContext

Struct MpvRenderContext 

Source
pub struct MpvRenderContext {
    ctx: *mut mpv_render_context,
    gl: Gl,
    target: Option<Target>,
}
Expand description

mpv’s render context plus the framebuffer it draws into.

§Lifetime (DR-232)

The render context must not outlive the GL context it was created against. Drop unregisters mpv’s update callback before freeing the context, so a callback cannot land on a freed pointer, and frees the GL objects while the caller still has the context current. The caller is responsible for making the GL context current around both creation and drop — see video_surface.

This is DR-184 on Android restated: a surface outliving its player. The spike had no defence at all and saw one unexplained SIGSEGV in a decoder thread.

Fields§

§ctx: *mut mpv_render_context§gl: Gl§target: Option<Target>

Implementations§

Source§

impl MpvRenderContext

Source

pub unsafe fn new(mpv: *mut mpv_handle) -> Option<Self>

Create a render context over an existing mpv handle.

The GL context must already be current on this thread.

TRACES: UR-080 | DR-231, IR-033

Source

pub unsafe fn set_update_callback( &mut self, callback: mpv_render_update_fn, ctx: *mut c_void, )

Ask to be told when a new frame is ready.

Paired with report_swap: without both, mpv has nothing to time against. The symptom is misleading — playback looks fine in a window and judders at fullscreen, which reads as a compositing or GPU limit and is neither (DR-233).

TRACES: UR-080 | DR-233

Source

pub unsafe fn has_frame(&self) -> bool

Whether mpv has a new frame waiting.

Asked of mpv directly rather than inferred from its update callback, and that distinction is the whole of frame pacing here:

  • Waiting only on the callback deadlocks — mpv will not progress until the client renders, so if the client will not render until mpv says so, neither moves. That presents as a file that loads, shows one frame, and then sits silent.
  • Rendering on every frame-clock tick regardless is the opposite error: report_swap then claims a presentation far more often than real frames exist, mpv has nothing coherent to time against, and playback judders badly.

Polling is neither. It runs on the main thread, costs a single atomic read inside mpv, and answers the only question that matters.

TRACES: UR-080 | DR-233

Source

pub unsafe fn render(&mut self, width: i32, height: i32) -> Option<u32>

Render the current frame at width x height, returning the texture id holding it. The GL context must be current.

TRACES: UR-080 | DR-231

Source

pub unsafe fn report_swap(&self)

Tell mpv the frame reached the screen. See [set_update_callback].

TRACES: UR-080 | DR-233

Source

unsafe fn ensure_target(&mut self, width: i32, height: i32) -> Option<()>

Create or resize the framebuffer. Reused across frames — reallocating per frame would churn GPU memory at the display rate.

Source

unsafe fn drop_target(&mut self)

Source

pub unsafe fn destroy(self)

Free everything, with the GL context current.

Explicit rather than left to Drop because the ordering matters and the caller is the only one that can guarantee the GL context is current. See DR-232.

Trait Implementations§

Source§

impl Drop for MpvRenderContext

Source§

fn drop(&mut self)

Executes the destructor for this type. Read more
Source§

fn pin_drop(self: Pin<&mut Self>)

🔬This is a nightly-only experimental API. (pin_ergonomics)
Execute the destructor for this type, but different to Drop::drop, it requires self to be pinned. Read more
Source§

impl Send for MpvRenderContext

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
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> PolicyExt for T
where T: ?Sized,

§

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns [Action::Follow] only if self and other return Action::Follow. Read more
§

fn or<P, B, E>(self, other: P) -> Or<T, P>
where T: Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns [Action::Follow] if either self or other returns Action::Follow. Read more
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