package mpvembed /* #cgo pkg-config: mpv #include #include static inline const char* mpv_errstr_render(int err) { return mpv_error_string(err); } */ import "C" import ( "fmt" "unsafe" ) // RenderParam is a small helper to build mpv_render_param arrays. type RenderParam struct { Type int Data unsafe.Pointer } // RenderContext wraps mpv_render_context for render API (OpenGL/Vulkan, etc.). type RenderContext struct { ctx *C.mpv_render_context } // NewRenderContext creates a render context for the given client with the provided params. // The params slice is terminated with MPV_RENDER_PARAM_INVALID automatically. func NewRenderContext(c *Client, params []RenderParam) (*RenderContext, error) { if c == nil || c.handle == nil { return nil, fmt.Errorf("mpv client is nil") } cparams := make([]C.mpv_render_param, len(params)+1) for i, p := range params { cparams[i]._type = uint32(p.Type) cparams[i].data = p.Data } cparams[len(params)]._type = uint32(C.MPV_RENDER_PARAM_INVALID) var rctx *C.mpv_render_context if res := C.mpv_render_context_create(&rctx, c.handle, &cparams[0]); res < 0 { return nil, fmt.Errorf("mpv_render_context_create failed: %s", C.GoString(C.mpv_errstr_render(res))) } return &RenderContext{ctx: rctx}, nil } // Destroy frees the render context. func (r *RenderContext) Destroy() { if r != nil && r.ctx != nil { C.mpv_render_context_free(r.ctx) r.ctx = nil } } // SetUpdateCallback registers a callback that mpv will invoke when a new frame should be drawn. // The callback must be thread-safe. func (r *RenderContext) SetUpdateCallback(cb unsafe.Pointer, userdata unsafe.Pointer) error { if r == nil || r.ctx == nil { return fmt.Errorf("render context is nil") } C.mpv_render_context_set_update_callback(r.ctx, (C.mpv_render_update_fn)(cb), userdata) return nil } // Render issues a render call with the provided params (e.g., target FBO, dimensions). // The params slice is terminated automatically. func (r *RenderContext) Render(params []RenderParam) error { if r == nil || r.ctx == nil { return fmt.Errorf("render context is nil") } cparams := make([]C.mpv_render_param, len(params)+1) for i, p := range params { cparams[i]._type = uint32(p.Type) cparams[i].data = p.Data } cparams[len(params)]._type = uint32(C.MPV_RENDER_PARAM_INVALID) if res := C.mpv_render_context_render(r.ctx, &cparams[0]); res < 0 { return fmt.Errorf("mpv_render_context_render failed: %s", C.GoString(C.mpv_errstr_render(res))) } return nil }