VT_Player/player/mpvembed/render.go
Stu 9d33575ada Fix CGO type errors and improve GTK player
- Fix render.go CGO type assignments using plain uint32 casts
- Add video playlist tracking with unique IDs
- Improve drag-and-drop: assign to first available pane
- Add parseURIs with crash protection for drag data
- Improve mpv initialization handling
- Update .gitignore for build artifacts (.cache, gtkplayer binary)
- Improve GDK_BACKEND handling in run script

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-15 05:40:37 -05:00

83 lines
2.5 KiB
Go

package mpvembed
/*
#cgo pkg-config: mpv
#include <mpv/render.h>
#include <stdlib.h>
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
}