1package pipewire
2
3import (
4 "errors"
5 "unsafe"
6
7 "github.com/bnema/purego-pipewire/internal/capi"
8 "github.com/bnema/purego-pipewire/internal/core"
9)
10
11// runtimeWrapper wraps the internal core.Runtime to implement the public Runtime interface.
12type runtimeWrapper struct {
13 inner *core.Runtime
14}
15
16func (rw runtimeWrapper) Init() error {
17 return rw.inner.Init()
18}
19
20func (rw runtimeWrapper) Deinit() {
21 rw.inner.Deinit()
22}
23
24func (rw runtimeWrapper) NewMainLoop() (MainLoop, error) {
25 ml, err := rw.inner.NewMainLoop()
26 if err != nil {
27 return nil, err
28 }
29 return mainLoopWrapper{inner: ml}, nil
30}
31
32func (rw runtimeWrapper) NewLoop() (Loop, error) {
33 l, err := rw.inner.NewLoop()
34 if err != nil {
35 return nil, err
36 }
37 return l, nil
38}
39
40func (rw runtimeWrapper) NewContext(loop Loop) (Context, error) {
41 l, ok := loop.(*core.Loop)
42 if !ok {
43 return nil, errors.New("pipewire: loop was not created by Runtime.NewLoop")
44 }
45 c, err := rw.inner.NewContext(l)
46 if err != nil {
47 return nil, err
48 }
49 return contextWrapper{inner: c}, nil
50}
51
52// contextWrapper wraps the internal core.Context to implement Context.
53type contextWrapper struct {
54 inner *core.Context
55}
56
57func (cw contextWrapper) Destroy() { cw.inner.Destroy() }
58
59func (cw contextWrapper) Connect() (Core, error) {
60 c, err := cw.inner.Connect()
61 if err != nil {
62 return nil, err
63 }
64 return coreWrapper{inner: c}, nil
65}
66
67// coreWrapper wraps the internal core.Core to implement Core.
68type coreWrapper struct {
69 inner *core.Core
70}
71
72func (cw coreWrapper) Disconnect() { cw.inner.Disconnect() }
73
74func (cw coreWrapper) Registry() (Registry, error) {
75 r, err := cw.inner.Registry()
76 if err != nil {
77 return nil, err
78 }
79 return r, nil
80}
81
82func (cw coreWrapper) NewStream(name string, props unsafe.Pointer) (Stream, error) {
83 st, err := cw.inner.NewStream(name, props)
84 if err != nil {
85 return nil, err
86 }
87 return st, nil
88}
89
90func (cw coreWrapper) NewVideoSource(cfg VideoConfig, h VideoHandler) (*VideoSource, error) {
91 if h == nil {
92 return nil, core.ErrVideoConfig
93 }
94 return cw.inner.NewVideoSource(cfg, h)
95}
96
97// mainLoopWrapper wraps the internal core.MainLoop to implement the public MainLoop interface.
98type mainLoopWrapper struct {
99 inner *core.MainLoop
100}
101
102func (mlw mainLoopWrapper) Run() int32 {
103 return mlw.inner.Run()
104}
105
106func (mlw mainLoopWrapper) Destroy() {
107 mlw.inner.Destroy()
108}
109
110// Init initializes the PipeWire runtime and returns a Runtime instance.
111// This function must be called before using any other PipeWire functionality.
112// Returns an error if the PipeWire libraries cannot be loaded.
113func Init() (Runtime, error) {
114 if err := capi.Register(); err != nil {
115 return nil, err
116 }
117 capiInstance := capi.Default()
118 if capiInstance == nil {
119 return nil, errors.New("failed to get default CAPI instance")
120 }
121 r := core.NewRuntime(capiInstance)
122 if err := r.Init(); err != nil {
123 return nil, err
124 }
125 return runtimeWrapper{inner: r}, nil
126}