detached 5f60d27

feat(core): add loop, context, core and video source

commit
5f60d277e8f5baa42d1c1c38816766b4b79ebf0e
author
brice · · 2026-10-14 19:07 UTC
parent
d290b71
signature
GPG VerifiedCD88F9E564E0102646FB6077A1A07C7C7C3E349D · arch-gpg Verified for the committer email
17 files · +2481 -10
M .mockery.yml +1 -0
@@ -18,6 +18,7 @@ packages:
1818 StreamOps:
1919 VideoAPI:
2020 SharedMemAPI:
21+ VideoStreamAPI:
2122 github.com/bnema/purego-pipewire/pipewire:
2223 config:
2324 all: false
@@ -18,6 +18,7 @@ packages:
18 StreamOps:18 StreamOps:
19 VideoAPI:19 VideoAPI:
20 SharedMemAPI:20 SharedMemAPI:
21+ VideoStreamAPI:
21 github.com/bnema/purego-pipewire/pipewire:22 github.com/bnema/purego-pipewire/pipewire:
22 config:23 config:
23 all: false24 all: false
M internal/core/context.go +34 -8
@@ -3,27 +3,53 @@ package core
33 import (
44 "errors"
55 "unsafe"
6+
7+ portout "github.com/bnema/purego-pipewire/internal/ports/out"
68 )
79
810 var ErrContextCreate = errors.New("failed to create context")
911
12+// Context wraps a pw_context. Create it with Runtime.NewContext and destroy
13+// it before the Loop it was created on.
1014 type Context struct {
11- ptr unsafe.Pointer
15+ ptr unsafe.Pointer
16+ capi portout.VideoStreamAPI
17+ shm portout.SharedMemAPI
1218 }
1319
14-func (r *Runtime) NewContext() (*Context, error) {
15- // For now, return a placeholder - full implementation
16- // will require generated context methods
17- return nil, ErrContextCreate
20+// NewContext creates a pw_context that runs on loop. The loop must outlive
21+// the context.
22+func (r *Runtime) NewContext(loop *Loop) (*Context, error) {
23+ if loop == nil || loop.ptr == nil {
24+ return nil, ErrContextCreate
25+ }
26+ ptr := r.capi.PWContextNew(loop.ptr, nil, 0)
27+ if ptr == nil {
28+ return nil, ErrContextCreate
29+ }
30+ return &Context{ptr: ptr, capi: r.capi, shm: memfdShm{}}, nil
1831 }
1932
33+// Destroy destroys the context. All cores connected from it must have been
34+// disconnected first. Destroy is idempotent.
2035 func (c *Context) Destroy() {
21- // Placeholder for context destruction
36+ if c.ptr == nil {
37+ return
38+ }
39+ c.capi.PWContextDestroy(c.ptr)
40+ c.ptr = nil
2241 }
2342
43+// Connect connects to the PipeWire daemon.
2444 func (c *Context) Connect() (*Core, error) {
25- // Placeholder - will connect and return a Core
26- return nil, errors.New("not implemented")
45+ if c.ptr == nil {
46+ return nil, ErrCoreConnect
47+ }
48+ ptr := c.capi.PWContextConnect(c.ptr, nil, 0)
49+ if ptr == nil {
50+ return nil, ErrCoreConnect
51+ }
52+ return &Core{ptr: ptr, capi: c.capi, shm: c.shm}, nil
2753 }
2854
2955 func (c *Context) Ptr() unsafe.Pointer {
@@ -3,27 +3,53 @@ package core
3 import (3 import (
4 "errors"4 "errors"
5 "unsafe"5 "unsafe"
6+
7+ portout "github.com/bnema/purego-pipewire/internal/ports/out"
6 )8 )
7 9
8 var ErrContextCreate = errors.New("failed to create context")10 var ErrContextCreate = errors.New("failed to create context")
9 11
12+// Context wraps a pw_context. Create it with Runtime.NewContext and destroy
13+// it before the Loop it was created on.
10 type Context struct {14 type Context struct {
11- ptr unsafe.Pointer15+ ptr unsafe.Pointer
16+ capi portout.VideoStreamAPI
17+ shm portout.SharedMemAPI
12 }18 }
13 19
14-func (r *Runtime) NewContext() (*Context, error) {20+// NewContext creates a pw_context that runs on loop. The loop must outlive
15- // For now, return a placeholder - full implementation21+// the context.
16- // will require generated context methods22+func (r *Runtime) NewContext(loop *Loop) (*Context, error) {
17- return nil, ErrContextCreate23+ if loop == nil || loop.ptr == nil {
24+ return nil, ErrContextCreate
25+ }
26+ ptr := r.capi.PWContextNew(loop.ptr, nil, 0)
27+ if ptr == nil {
28+ return nil, ErrContextCreate
29+ }
30+ return &Context{ptr: ptr, capi: r.capi, shm: memfdShm{}}, nil
18 }31 }
19 32
33+// Destroy destroys the context. All cores connected from it must have been
34+// disconnected first. Destroy is idempotent.
20 func (c *Context) Destroy() {35 func (c *Context) Destroy() {
21- // Placeholder for context destruction36+ if c.ptr == nil {
37+ return
38+ }
39+ c.capi.PWContextDestroy(c.ptr)
40+ c.ptr = nil
22 }41 }
23 42
43+// Connect connects to the PipeWire daemon.
24 func (c *Context) Connect() (*Core, error) {44 func (c *Context) Connect() (*Core, error) {
25- // Placeholder - will connect and return a Core45+ if c.ptr == nil {
26- return nil, errors.New("not implemented")46+ return nil, ErrCoreConnect
47+ }
48+ ptr := c.capi.PWContextConnect(c.ptr, nil, 0)
49+ if ptr == nil {
50+ return nil, ErrCoreConnect
51+ }
52+ return &Core{ptr: ptr, capi: c.capi, shm: c.shm}, nil
27 }53 }
28 54
29 func (c *Context) Ptr() unsafe.Pointer {55 func (c *Context) Ptr() unsafe.Pointer {
M internal/core/core.go +11 -1
@@ -3,6 +3,8 @@ package core
33 import (
44 "errors"
55 "unsafe"
6+
7+ portout "github.com/bnema/purego-pipewire/internal/ports/out"
68 )
79
810 var ErrCoreConnect = errors.New("failed to connect core")
@@ -10,11 +12,19 @@ var ErrRegistryUnavailable = errors.New("registry unavailable")
1012
1113 type Core struct {
1214 ptr unsafe.Pointer
15+ capi portout.VideoStreamAPI
16+ shm portout.SharedMemAPI
1317 registry *Registry
1418 }
1519
20+// Disconnect disconnects from the daemon. Streams created from the core must
21+// have been destroyed first. Disconnect is idempotent.
1622 func (c *Core) Disconnect() {
17- // Placeholder for core disconnection
23+ if c.ptr == nil || c.capi == nil {
24+ return
25+ }
26+ c.capi.PWCoreDisconnect(c.ptr)
27+ c.ptr = nil
1828 }
1929
2030 func (c *Core) Registry() (*Registry, error) {
@@ -3,6 +3,8 @@ package core
3 import (3 import (
4 "errors"4 "errors"
5 "unsafe"5 "unsafe"
6+
7+ portout "github.com/bnema/purego-pipewire/internal/ports/out"
6 )8 )
7 9
8 var ErrCoreConnect = errors.New("failed to connect core")10 var ErrCoreConnect = errors.New("failed to connect core")
@@ -10,11 +12,19 @@ var ErrRegistryUnavailable = errors.New("registry unavailable")
10 12
11 type Core struct {13 type Core struct {
12 ptr unsafe.Pointer14 ptr unsafe.Pointer
15+ capi portout.VideoStreamAPI
16+ shm portout.SharedMemAPI
13 registry *Registry17 registry *Registry
14 }18 }
15 19
20+// Disconnect disconnects from the daemon. Streams created from the core must
21+// have been destroyed first. Disconnect is idempotent.
16 func (c *Core) Disconnect() {22 func (c *Core) Disconnect() {
17- // Placeholder for core disconnection23+ if c.ptr == nil || c.capi == nil {
24+ return
25+ }
26+ c.capi.PWCoreDisconnect(c.ptr)
27+ c.ptr = nil
18 }28 }
19 29
20 func (c *Core) Registry() (*Registry, error) {30 func (c *Core) Registry() (*Registry, error) {
M internal/core/loop.go +50 -0
@@ -33,3 +33,53 @@ func (ml *MainLoop) Destroy() {
3333 func (ml *MainLoop) Ptr() unsafe.Pointer {
3434 return ml.ptr
3535 }
36+
37+var ErrLoopCreate = errors.New("failed to create loop")
38+
39+// Loop wraps a pw_loop that the caller iterates itself, typically from a
40+// poll loop that waits on Fd. A Loop and everything created on it (Context,
41+// Core, streams) must only be used from one goroutine locked to one OS
42+// thread (runtime.LockOSThread); PipeWire loops are not thread safe.
43+type Loop struct {
44+ ptr unsafe.Pointer
45+ capi portout.VideoStreamAPI
46+}
47+
48+// NewLoop creates a pw_loop. The Runtime must be initialized.
49+func (r *Runtime) NewLoop() (*Loop, error) {
50+ ptr := r.capi.PWLoopNew(nil)
51+ if ptr == nil {
52+ return nil, ErrLoopCreate
53+ }
54+ return &Loop{ptr: ptr, capi: r.capi}, nil
55+}
56+
57+// Fd returns the pollable file descriptor of the loop. It becomes readable
58+// when Iterate has work to do.
59+func (l *Loop) Fd() int {
60+ return int(l.capi.PWLoopGetFd(l.ptr))
61+}
62+
63+// Iterate dispatches the pending events without blocking (pw_loop_enter,
64+// pw_loop_iterate with a zero timeout, pw_loop_leave). Stream callbacks run
65+// inside it. A negative result such as -EINTR is not fatal and is ignored:
66+// the next Iterate simply retries.
67+func (l *Loop) Iterate() {
68+ l.capi.PWLoopEnter(l.ptr)
69+ _ = l.capi.PWLoopIterate(l.ptr, 0)
70+ l.capi.PWLoopLeave(l.ptr)
71+}
72+
73+// Destroy destroys the loop. Contexts created on it must be destroyed first.
74+// Destroy is idempotent.
75+func (l *Loop) Destroy() {
76+ if l.ptr == nil {
77+ return
78+ }
79+ l.capi.PWLoopDestroy(l.ptr)
80+ l.ptr = nil
81+}
82+
83+func (l *Loop) Ptr() unsafe.Pointer {
84+ return l.ptr
85+}
@@ -33,3 +33,53 @@ func (ml *MainLoop) Destroy() {
33 func (ml *MainLoop) Ptr() unsafe.Pointer {33 func (ml *MainLoop) Ptr() unsafe.Pointer {
34 return ml.ptr34 return ml.ptr
35 }35 }
36+
37+var ErrLoopCreate = errors.New("failed to create loop")
38+
39+// Loop wraps a pw_loop that the caller iterates itself, typically from a
40+// poll loop that waits on Fd. A Loop and everything created on it (Context,
41+// Core, streams) must only be used from one goroutine locked to one OS
42+// thread (runtime.LockOSThread); PipeWire loops are not thread safe.
43+type Loop struct {
44+ ptr unsafe.Pointer
45+ capi portout.VideoStreamAPI
46+}
47+
48+// NewLoop creates a pw_loop. The Runtime must be initialized.
49+func (r *Runtime) NewLoop() (*Loop, error) {
50+ ptr := r.capi.PWLoopNew(nil)
51+ if ptr == nil {
52+ return nil, ErrLoopCreate
53+ }
54+ return &Loop{ptr: ptr, capi: r.capi}, nil
55+}
56+
57+// Fd returns the pollable file descriptor of the loop. It becomes readable
58+// when Iterate has work to do.
59+func (l *Loop) Fd() int {
60+ return int(l.capi.PWLoopGetFd(l.ptr))
61+}
62+
63+// Iterate dispatches the pending events without blocking (pw_loop_enter,
64+// pw_loop_iterate with a zero timeout, pw_loop_leave). Stream callbacks run
65+// inside it. A negative result such as -EINTR is not fatal and is ignored:
66+// the next Iterate simply retries.
67+func (l *Loop) Iterate() {
68+ l.capi.PWLoopEnter(l.ptr)
69+ _ = l.capi.PWLoopIterate(l.ptr, 0)
70+ l.capi.PWLoopLeave(l.ptr)
71+}
72+
73+// Destroy destroys the loop. Contexts created on it must be destroyed first.
74+// Destroy is idempotent.
75+func (l *Loop) Destroy() {
76+ if l.ptr == nil {
77+ return
78+ }
79+ l.capi.PWLoopDestroy(l.ptr)
80+ l.ptr = nil
81+}
82+
83+func (l *Loop) Ptr() unsafe.Pointer {
84+ return l.ptr
85+}
A internal/core/shm.go +57 -0
@@ -0,0 +1,57 @@
1+package core
2+
3+import (
4+ "fmt"
5+ "syscall"
6+ "unsafe"
7+)
8+
9+const (
10+ mfdCloexec = 0x1
11+ mfdAllowSealing = 0x2
12+ fAddSeals = 0x409 // F_ADD_SEALS
13+ fSealSeal = 0x1
14+ fSealShrink = 0x2
15+ fSealGrow = 0x4
16+)
17+
18+// memfdShm is the production portout.SharedMemAPI backed by memfd_create.
19+type memfdShm struct{}
20+
21+func (memfdShm) NewSharedMem(name string, size int) (int, []byte, error) {
22+ if size <= 0 {
23+ return -1, nil, fmt.Errorf("memfd: invalid size %d", size)
24+ }
25+ cname, err := syscall.BytePtrFromString(name)
26+ if err != nil {
27+ return -1, nil, err
28+ }
29+ r, _, errno := syscall.Syscall(sysMemfdCreate, uintptr(unsafe.Pointer(cname)), mfdCloexec|mfdAllowSealing, 0)
30+ if errno != 0 {
31+ return -1, nil, fmt.Errorf("memfd_create: %w", errno)
32+ }
33+ fd := int(r)
34+ if err := syscall.Ftruncate(fd, int64(size)); err != nil {
35+ _ = syscall.Close(fd)
36+ return -1, nil, fmt.Errorf("memfd ftruncate: %w", err)
37+ }
38+ if _, _, errno := syscall.Syscall(syscall.SYS_FCNTL, uintptr(fd), fAddSeals, fSealShrink|fSealGrow|fSealSeal); errno != 0 {
39+ _ = syscall.Close(fd)
40+ return -1, nil, fmt.Errorf("memfd seal: %w", errno)
41+ }
42+ data, err := syscall.Mmap(fd, 0, size, syscall.PROT_READ|syscall.PROT_WRITE, syscall.MAP_SHARED)
43+ if err != nil {
44+ _ = syscall.Close(fd)
45+ return -1, nil, fmt.Errorf("memfd mmap: %w", err)
46+ }
47+ return fd, data, nil
48+}
49+
50+func (memfdShm) FreeSharedMem(fd int, data []byte) {
51+ if data != nil {
52+ _ = syscall.Munmap(data)
53+ }
54+ if fd >= 0 {
55+ _ = syscall.Close(fd)
56+ }
57+}
@@ -0,0 +1,57 @@
1+package core
2+
3+import (
4+ "fmt"
5+ "syscall"
6+ "unsafe"
7+)
8+
9+const (
10+ mfdCloexec = 0x1
11+ mfdAllowSealing = 0x2
12+ fAddSeals = 0x409 // F_ADD_SEALS
13+ fSealSeal = 0x1
14+ fSealShrink = 0x2
15+ fSealGrow = 0x4
16+)
17+
18+// memfdShm is the production portout.SharedMemAPI backed by memfd_create.
19+type memfdShm struct{}
20+
21+func (memfdShm) NewSharedMem(name string, size int) (int, []byte, error) {
22+ if size <= 0 {
23+ return -1, nil, fmt.Errorf("memfd: invalid size %d", size)
24+ }
25+ cname, err := syscall.BytePtrFromString(name)
26+ if err != nil {
27+ return -1, nil, err
28+ }
29+ r, _, errno := syscall.Syscall(sysMemfdCreate, uintptr(unsafe.Pointer(cname)), mfdCloexec|mfdAllowSealing, 0)
30+ if errno != 0 {
31+ return -1, nil, fmt.Errorf("memfd_create: %w", errno)
32+ }
33+ fd := int(r)
34+ if err := syscall.Ftruncate(fd, int64(size)); err != nil {
35+ _ = syscall.Close(fd)
36+ return -1, nil, fmt.Errorf("memfd ftruncate: %w", err)
37+ }
38+ if _, _, errno := syscall.Syscall(syscall.SYS_FCNTL, uintptr(fd), fAddSeals, fSealShrink|fSealGrow|fSealSeal); errno != 0 {
39+ _ = syscall.Close(fd)
40+ return -1, nil, fmt.Errorf("memfd seal: %w", errno)
41+ }
42+ data, err := syscall.Mmap(fd, 0, size, syscall.PROT_READ|syscall.PROT_WRITE, syscall.MAP_SHARED)
43+ if err != nil {
44+ _ = syscall.Close(fd)
45+ return -1, nil, fmt.Errorf("memfd mmap: %w", err)
46+ }
47+ return fd, data, nil
48+}
49+
50+func (memfdShm) FreeSharedMem(fd int, data []byte) {
51+ if data != nil {
52+ _ = syscall.Munmap(data)
53+ }
54+ if fd >= 0 {
55+ _ = syscall.Close(fd)
56+ }
57+}
A internal/core/shm_amd64.go +5 -0
@@ -0,0 +1,5 @@
1+package core
2+
3+// sysMemfdCreate is the memfd_create syscall number (not exported by package
4+// syscall).
5+const sysMemfdCreate = 319
@@ -0,0 +1,5 @@
1+package core
2+
3+// sysMemfdCreate is the memfd_create syscall number (not exported by package
4+// syscall).
5+const sysMemfdCreate = 319
A internal/core/shm_arm64.go +5 -0
@@ -0,0 +1,5 @@
1+package core
2+
3+// sysMemfdCreate is the memfd_create syscall number (not exported by package
4+// syscall).
5+const sysMemfdCreate = 279
@@ -0,0 +1,5 @@
1+package core
2+
3+// sysMemfdCreate is the memfd_create syscall number (not exported by package
4+// syscall).
5+const sysMemfdCreate = 279
A internal/core/video.go +616 -0
@@ -0,0 +1,616 @@
1+package core
2+
3+import (
4+ "errors"
5+ "fmt"
6+ "log/slog"
7+ "strings"
8+ "sync"
9+ "sync/atomic"
10+ "time"
11+ "unsafe"
12+
13+ "github.com/bnema/purego"
14+
15+ portin "github.com/bnema/purego-pipewire/internal/ports/in"
16+ portout "github.com/bnema/purego-pipewire/internal/ports/out"
17+ "github.com/bnema/purego-pipewire/spa"
18+)
19+
20+// Video source limits. They are fixed so that nothing is allocated after
21+// NewVideoSource except the memfd mappings made in add_buffer.
22+const (
23+ videoMaxBuffers = 16 // Buffers param maximum, size of the buffer slot table
24+ videoMaxSources = 64 // size of the process-wide callback slot table
25+ videoPodSize = 512
26+
27+ pwStreamFlagDriver = 0x8
28+ pwStreamFlagAllocBuffers = 0x100
29+ pwStreamStateStreaming = 3
30+ pwStreamStatePaused = 2
31+
32+ defaultVideoFPS = 60
33+)
34+
35+var (
36+ ErrVideoConfig = errors.New("invalid video source config")
37+ ErrVideoTableFull = errors.New("too many video sources")
38+ ErrVideoStreamCreate = errors.New("failed to create video stream")
39+ ErrVideoConnect = errors.New("failed to connect video stream")
40+ ErrVideoResize = errors.New("failed to resize video stream")
41+)
42+
43+// VideoConfig configures a VideoSource. MaxFPS defaults to 60 and Formats to
44+// BGRx.
45+type VideoConfig struct {
46+ Name string
47+ Width, Height int
48+ MaxFPS int
49+ Formats []spa.VideoFormat
50+}
51+
52+// VideoBuffer is a buffer that was handed out by VideoSource.Dequeue. Data
53+// aliases a memfd mapping owned by the source: it stays valid until the buffer
54+// is given back with Queue or Release, and not afterwards. The structure is
55+// owned by the source; do not copy it, retain it or modify it.
56+type VideoBuffer struct {
57+ Index int
58+ Data []byte
59+ Stride, Width, Height int
60+ Format spa.VideoFormat
61+}
62+
63+// C layouts (amd64/arm64). Offsets are asserted in tests.
64+
65+// videoPWBuffer mirrors struct pw_buffer; UserData carries slot index+1.
66+type videoPWBuffer struct {
67+ Buffer *spaBuffer
68+ UserData uintptr
69+ Size uint64
70+}
71+
72+// spaMeta mirrors struct spa_meta.
73+type spaMeta struct {
74+ Type uint32
75+ Size uint32
76+ Data unsafe.Pointer
77+}
78+
79+// spaMetaHeader mirrors struct spa_meta_header.
80+type spaMetaHeader struct {
81+ Flags uint32
82+ Offset uint32
83+ PTS int64
84+ DTSOffset int64
85+ Seq uint64
86+}
87+
88+// videoEvents mirrors struct pw_stream_events (version 2).
89+type videoEvents struct {
90+ Version uint32
91+ Destroy uintptr
92+ StateChanged uintptr
93+ ControlInfo uintptr
94+ IOChanged uintptr
95+ ParamChanged uintptr
96+ AddBuffer uintptr
97+ RemoveBuf uintptr
98+ Process uintptr
99+ Drained uintptr
100+ Command uintptr
101+ TriggerDone uintptr
102+}
103+
104+type videoSlot struct {
105+ buf VideoBuffer
106+ pw unsafe.Pointer // struct pw_buffer; nil once removed
107+ hdr *spaMetaHeader // nil if the buffer has no header meta
108+ chunk *spaChunk
109+ fd int
110+ mem []byte
111+ live bool // slot holds a mapped buffer
112+ removed bool // PipeWire removed the buffer while it was borrowed
113+ borrowed bool
114+}
115+
116+// VideoSource is a PipeWire Video/Source node that drives the graph and
117+// exposes memfd-backed buffers. Every method, and every handler callback, runs
118+// on the loop thread: the goroutine (locked to its OS thread) that calls
119+// Loop.Iterate.
120+//
121+// Frames are produced with Dequeue, then writing Data, then Queue, then
122+// Trigger. The buffer must be queued before Trigger, because the process
123+// callback does nothing: PipeWire picks up queued buffers when triggered.
124+type VideoSource struct {
125+ capi portout.VideoStreamAPI
126+ shm portout.SharedMemAPI
127+ handler portin.VideoHandler
128+
129+ stream unsafe.Pointer
130+ table int // index in videoTable
131+ events videoEvents
132+ hook [8]uint64 // struct spa_hook, 48 bytes
133+ params [2]unsafe.Pointer
134+ enumPod [videoPodSize]byte
135+ buffPod [videoPodSize]byte
136+ metaPod [128]byte
137+ cfg VideoConfig
138+ formats [4]spa.VideoFormat
139+ nformats int
140+
141+ state int32
142+ nodeID uint32
143+ format spa.VideoFormat
144+ width int
145+ height int
146+ stride int
147+ negotiated bool
148+ closed bool
149+ warned bool
150+
151+ slots [videoMaxBuffers]videoSlot
152+}
153+
154+var (
155+ videoTable [videoMaxSources]atomic.Pointer[VideoSource]
156+
157+ videoCBOnce sync.Once
158+ videoCB struct {
159+ stateChanged, paramChanged, addBuffer, removeBuffer, process, triggerDone uintptr
160+ }
161+)
162+
163+// uptr turns a raw callback argument into a pointer without a
164+// uintptr-to-unsafe.Pointer conversion; the value is C memory or a small
165+// integer, never Go memory.
166+func uptr(v uintptr) unsafe.Pointer { return *(*unsafe.Pointer)(unsafe.Pointer(&v)) }
167+
168+func videoLookup(a *purego.CallbackArgs) *VideoSource {
169+ idx := int(a.Int(0)) - 1
170+ if uint(idx) >= videoMaxSources {
171+ return nil
172+ }
173+ return videoTable[idx].Load()
174+}
175+
176+func registerVideoCallbacks() {
177+ videoCBOnce.Do(func() {
178+ videoCB.stateChanged = purego.NewCallbackInts(func(a *purego.CallbackArgs) uintptr {
179+ if s := videoLookup(a); s != nil {
180+ s.onStateChanged(int32(a.Int(2)), uptr(a.Int(3)))
181+ }
182+ return 0
183+ })
184+ videoCB.paramChanged = purego.NewCallbackInts(func(a *purego.CallbackArgs) uintptr {
185+ if s := videoLookup(a); s != nil {
186+ s.onParamChanged(uint32(a.Int(1)), uptr(a.Int(2)))
187+ }
188+ return 0
189+ })
190+ videoCB.addBuffer = purego.NewCallbackInts(func(a *purego.CallbackArgs) uintptr {
191+ if s := videoLookup(a); s != nil {
192+ s.onAddBuffer(uptr(a.Int(1)))
193+ }
194+ return 0
195+ })
196+ videoCB.removeBuffer = purego.NewCallbackInts(func(a *purego.CallbackArgs) uintptr {
197+ if s := videoLookup(a); s != nil {
198+ s.onRemoveBuffer(uptr(a.Int(1)))
199+ }
200+ return 0
201+ })
202+ // process and trigger_done intentionally do nothing: buffers are
203+ // queued by the owner before Trigger.
204+ videoCB.process = purego.NewCallbackInts(func(*purego.CallbackArgs) uintptr { return 0 })
205+ videoCB.triggerDone = purego.NewCallbackInts(func(*purego.CallbackArgs) uintptr { return 0 })
206+ })
207+}
208+
209+// NewVideoSource creates and connects a Video/Source stream on the core. The
210+// stream drives the graph (DRIVER) and allocates its own memfd buffers
211+// (ALLOC_BUFFERS). Call it, and every other method, on the loop thread.
212+func (c *Core) NewVideoSource(cfg VideoConfig, h portin.VideoHandler) (*VideoSource, error) {
213+ if c.ptr == nil || c.capi == nil {
214+ return nil, ErrVideoStreamCreate
215+ }
216+ if h == nil || cfg.Width <= 0 || cfg.Height <= 0 || cfg.Width > 1<<15 || cfg.Height > 1<<15 {
217+ return nil, ErrVideoConfig
218+ }
219+ if cfg.MaxFPS <= 0 {
220+ cfg.MaxFPS = defaultVideoFPS
221+ }
222+ s := &VideoSource{capi: c.capi, shm: c.shm, handler: h, cfg: cfg, table: -1}
223+ if len(cfg.Formats) == 0 {
224+ s.formats[0], s.nformats = spa.VideoFormatBGRx, 1
225+ } else {
226+ if len(cfg.Formats) > len(s.formats) {
227+ return nil, ErrVideoConfig
228+ }
229+ s.nformats = copy(s.formats[:], cfg.Formats)
230+ }
231+ s.cfg.Formats = nil // the slot-owned array is the source of truth
232+ name := cfg.Name
233+ if name == "" {
234+ name = "purego-pipewire"
235+ }
236+ if strings.ContainsAny(name, "\"\\") || strings.ContainsFunc(name, func(r rune) bool { return r < 0x20 || r == 0x7f }) {
237+ return nil, fmt.Errorf("%w: invalid name %q", ErrVideoConfig, name)
238+ }
239+ if _, err := spa.VideoEnumFormat(s.enumPod[:], cfg.Width, cfg.Height, cfg.MaxFPS, s.formats[:s.nformats]...); err != nil {
240+ return nil, fmt.Errorf("%w: %v", ErrVideoConfig, err)
241+ }
242+
243+ registerVideoCallbacks()
244+ for i := range videoTable {
245+ if videoTable[i].CompareAndSwap(nil, s) {
246+ s.table = i
247+ break
248+ }
249+ }
250+ if s.table < 0 {
251+ return nil, ErrVideoTableFull
252+ }
253+
254+ cname := append([]byte(name), 0)
255+ props := append([]byte(`media.class=Video/Source node.name="`+name+`"`), 0)
256+ propsPtr := c.capi.PWPropertiesNewString(&props[0])
257+ if propsPtr == nil {
258+ videoTable[s.table].Store(nil)
259+ return nil, ErrVideoStreamCreate
260+ }
261+ s.stream = c.capi.PWStreamNew(c.ptr, &cname[0], propsPtr) // takes ownership of props
262+ if s.stream == nil {
263+ videoTable[s.table].Store(nil)
264+ return nil, ErrVideoStreamCreate
265+ }
266+
267+ s.events = videoEvents{
268+ Version: 2,
269+ StateChanged: videoCB.stateChanged,
270+ ParamChanged: videoCB.paramChanged,
271+ AddBuffer: videoCB.addBuffer,
272+ RemoveBuf: videoCB.removeBuffer,
273+ Process: videoCB.process,
274+ TriggerDone: videoCB.triggerDone,
275+ }
276+ data := uptr(uintptr(s.table + 1))
277+ c.capi.PWStreamAddListener(s.stream, unsafe.Pointer(&s.hook[0]), unsafe.Pointer(&s.events), data)
278+
279+ s.params[0] = unsafe.Pointer(&s.enumPod[0])
280+ ret := c.capi.PWStreamConnect(s.stream, 1 /* PW_DIRECTION_OUTPUT */, spa.IDInvalid,
281+ pwStreamFlagDriver|pwStreamFlagAllocBuffers, unsafe.Pointer(&s.params[0]), 1)
282+ if ret < 0 {
283+ s.closed = true
284+ s.teardown()
285+ return nil, fmt.Errorf("%w: pw_stream_connect returned %d", ErrVideoConnect, ret)
286+ }
287+ return s, nil
288+}
289+
290+// NodeID returns the PipeWire node id, or 0 until the stream is paused or
291+// streaming.
292+func (s *VideoSource) NodeID() uint32 { return s.nodeID }
293+
294+// State returns the last stream state (see VideoHandler.StateChanged).
295+func (s *VideoSource) State() int32 { return s.state }
296+
297+// Dequeue returns a free buffer to draw into, or nil when none is available.
298+// The buffer is borrowed until Queue or Release. Buffers that could not be
299+// given a memfd are skipped (they stay out of the queue).
300+func (s *VideoSource) Dequeue() *VideoBuffer {
301+ if s.stream == nil || !s.negotiated {
302+ return nil
303+ }
304+ for i := 0; i < 2*videoMaxBuffers; i++ {
305+ p := s.capi.PWStreamDequeueBuffer(s.stream)
306+ if p == nil {
307+ return nil
308+ }
309+ idx := int((*videoPWBuffer)(p).UserData) - 1
310+ if uint(idx) >= videoMaxBuffers {
311+ continue // unusable buffer: never handed out
312+ }
313+ sl := &s.slots[idx]
314+ if !sl.live || sl.removed || sl.borrowed || sl.pw != p {
315+ continue
316+ }
317+ sl.borrowed = true
318+ return &sl.buf
319+ }
320+ return nil
321+}
322+
323+// slotOf validates b against the slot table.
324+func (s *VideoSource) slotOf(b *VideoBuffer) *videoSlot {
325+ if b == nil || uint(b.Index) >= videoMaxBuffers {
326+ return nil
327+ }
328+ sl := &s.slots[b.Index]
329+ if &sl.buf != b || !sl.live || !sl.borrowed {
330+ return nil
331+ }
332+ return sl
333+}
334+
335+// Queue hands a filled buffer back to PipeWire with its frame sequence and
336+// presentation time. When corrupted is set the frame is flagged corrupted and
337+// carries no data. Call Trigger after Queue: the buffer is queued before the
338+// graph cycle is triggered. Queue on a buffer PipeWire already removed only
339+// releases it.
340+func (s *VideoSource) Queue(b *VideoBuffer, seq uint64, pts time.Duration, corrupted bool) {
341+ sl := s.slotOf(b)
342+ if sl == nil {
343+ return
344+ }
345+ if sl.removed || s.stream == nil {
346+ s.freeSlot(sl)
347+ return
348+ }
349+ size := uint32(sl.buf.Stride * sl.buf.Height)
350+ if c := sl.chunk; c != nil {
351+ c.Offset, c.Size, c.Stride, c.Flags = 0, size, int32(sl.buf.Stride), 0
352+ if corrupted {
353+ c.Size, c.Flags = 0, spa.ChunkFlagCorrupted
354+ }
355+ }
356+ if h := sl.hdr; h != nil {
357+ h.Flags, h.Offset, h.PTS, h.DTSOffset, h.Seq = 0, 0, int64(pts), 0, seq
358+ if corrupted {
359+ h.Flags = spa.MetaHeaderFlagCorrupted
360+ }
361+ }
362+ sl.borrowed = false
363+ s.capi.PWStreamQueueBuffer(s.stream, sl.pw)
364+}
365+
366+// Release gives a dequeued buffer back without queueing a frame. If PipeWire
367+// removed the buffer in the meantime its memory is unmapped now. b.Data must
368+// not be used afterwards.
369+func (s *VideoSource) Release(b *VideoBuffer) {
370+ sl := s.slotOf(b)
371+ if sl == nil {
372+ return
373+ }
374+ if sl.removed || s.stream == nil {
375+ s.freeSlot(sl)
376+ return
377+ }
378+ sl.borrowed = false
379+ s.capi.PWStreamReturnBuffer(s.stream, sl.pw)
380+}
381+
382+// Trigger starts a graph cycle (pw_stream_trigger_process). Queue the filled
383+// buffer first.
384+func (s *VideoSource) Trigger() {
385+ if s.stream != nil {
386+ s.capi.PWStreamTriggerProcess(s.stream)
387+ }
388+}
389+
390+// Resize renegotiates the stream with a new size. Buffers PipeWire replaces
391+// stay valid while borrowed; hand them back with Queue or Release (ideally
392+// resize when none is borrowed).
393+func (s *VideoSource) Resize(w, h int) error {
394+ if s.stream == nil {
395+ return ErrVideoResize
396+ }
397+ if w <= 0 || h <= 0 || w > 1<<15 || h > 1<<15 {
398+ return ErrVideoConfig
399+ }
400+ if _, err := spa.VideoEnumFormat(s.enumPod[:], w, h, s.cfg.MaxFPS, s.formats[:s.nformats]...); err != nil {
401+ return fmt.Errorf("%w: %v", ErrVideoResize, err)
402+ }
403+ s.cfg.Width, s.cfg.Height = w, h
404+ s.params[0] = unsafe.Pointer(&s.enumPod[0])
405+ if ret := s.capi.PWStreamUpdateParams(s.stream, unsafe.Pointer(&s.params[0]), 1); ret < 0 {
406+ return fmt.Errorf("%w: pw_stream_update_params returned %d", ErrVideoResize, ret)
407+ }
408+ return nil
409+}
410+
411+// Destroy disconnects and destroys the stream. PipeWire removes every buffer
412+// during the disconnect; buffers that are still borrowed keep their mapping
413+// until Release (or Queue). Call Destroy only when no buffer is borrowed,
414+// unless the caller releases them afterwards. No handler callback runs after
415+// Destroy starts. Destroy is idempotent.
416+func (s *VideoSource) Destroy() {
417+ s.closed = true
418+ s.teardown()
419+}
420+
421+func (s *VideoSource) teardown() {
422+ if s.stream != nil {
423+ stream := s.stream
424+ s.capi.PWStreamDisconnect(stream)
425+ s.capi.PWStreamDestroy(stream)
426+ s.stream = nil
427+ }
428+ if s.table >= 0 {
429+ videoTable[s.table].Store(nil)
430+ s.table = -1
431+ }
432+ for i := range s.slots {
433+ sl := &s.slots[i]
434+ if !sl.live {
435+ continue
436+ }
437+ sl.pw, sl.hdr, sl.chunk = nil, nil, nil
438+ if sl.borrowed {
439+ sl.removed = true
440+ } else {
441+ s.freeSlot(sl)
442+ }
443+ }
444+}
445+
446+// freeSlot unmaps the slot's memory and makes the slot reusable.
447+func (s *VideoSource) freeSlot(sl *videoSlot) {
448+ if sl.live {
449+ s.shm.FreeSharedMem(sl.fd, sl.mem)
450+ }
451+ *sl = videoSlot{}
452+}
453+
454+// --- stream event handlers (loop thread) ---
455+
456+func (s *VideoSource) onStateChanged(state int32, errp unsafe.Pointer) {
457+ s.state = state
458+ if state == pwStreamStatePaused || state == pwStreamStateStreaming {
459+ s.nodeID = s.capi.PWStreamGetNodeId(s.stream)
460+ }
461+ if state == pwStreamStateStreaming && !s.warned {
462+ s.warned = true
463+ if !s.capi.PWStreamIsDriving(s.stream) {
464+ slog.Warn("purego-pipewire: video stream is not driving the graph", "node", s.nodeID)
465+ }
466+ }
467+ if s.closed {
468+ return
469+ }
470+ msg := ""
471+ if state < 0 {
472+ msg = cString(errp)
473+ }
474+ s.handler.StateChanged(state, s.nodeID, msg)
475+}
476+
477+func cString(p unsafe.Pointer) string {
478+ if p == nil {
479+ return ""
480+ }
481+ n := 0
482+ for n < 512 && *(*byte)(unsafe.Add(p, n)) != 0 {
483+ n++
484+ }
485+ return string(unsafe.Slice((*byte)(p), n))
486+}
487+
488+func (s *VideoSource) onParamChanged(id uint32, param unsafe.Pointer) {
489+ if id != spa.ParamFormat || s.stream == nil {
490+ return
491+ }
492+ if param == nil {
493+ s.negotiated = false
494+ return
495+ }
496+ size := int(*(*uint32)(param))
497+ if size < 8 || size > 4096 {
498+ return
499+ }
500+ pod := unsafe.Slice((*byte)(param), 8+size)
501+ f, w, h, ok := spa.ParseVideoFormat(pod)
502+ if !ok {
503+ return
504+ }
505+ format := spa.VideoFormat(f)
506+ allowed := false
507+ for _, af := range s.formats[:s.nformats] {
508+ allowed = allowed || af == format
509+ }
510+ if !allowed {
511+ return
512+ }
513+ stride := w * 4
514+ buffers, err := spa.VideoBuffers(s.buffPod[:], stride*h, stride, 2, 8, videoMaxBuffers, 1<<spa.DataMemFd)
515+ if err != nil {
516+ return
517+ }
518+ meta, err := spa.MetaHeader(s.metaPod[:])
519+ if err != nil {
520+ return
521+ }
522+ s.format, s.width, s.height, s.stride, s.negotiated = format, w, h, stride, true
523+ s.params[0] = unsafe.Pointer(&buffers[0])
524+ s.params[1] = unsafe.Pointer(&meta[0])
525+ s.capi.PWStreamUpdateParams(s.stream, unsafe.Pointer(&s.params[0]), 2)
526+ if !s.closed {
527+ s.handler.FormatChanged(format, w, h, stride)
528+ }
529+}
530+
531+func (s *VideoSource) onAddBuffer(p unsafe.Pointer) {
532+ if p == nil {
533+ return
534+ }
535+ pb := (*videoPWBuffer)(p)
536+ pb.UserData = 0 // unusable until a slot is assigned
537+ sb := pb.Buffer
538+ if sb == nil || sb.NDatas == 0 || sb.Datas == nil || !s.negotiated {
539+ return
540+ }
541+ d := (*spaData)(sb.Datas)
542+ if d.Type&(1<<spa.DataMemFd) == 0 {
543+ return // DMA-BUF only: not supported
544+ }
545+ idx := -1
546+ for i := range s.slots {
547+ if !s.slots[i].live {
548+ idx = i
549+ break
550+ }
551+ }
552+ if idx < 0 {
553+ return
554+ }
555+ size := s.stride * s.height
556+ fd, mem, err := s.shm.NewSharedMem("pw-video", size)
557+ if err != nil || len(mem) < size {
558+ if err == nil {
559+ s.shm.FreeSharedMem(fd, mem)
560+ }
561+ return
562+ }
563+ d.Type, d.Flags, d.Fd = spa.DataMemFd, spa.DataFlagReadWrite, int64(fd)
564+ d.MapOffset, d.Maxsize, d.Data = 0, uint32(size), unsafe.Pointer(&mem[0])
565+ if d.Chunk != nil {
566+ d.Chunk.Offset, d.Chunk.Size, d.Chunk.Stride, d.Chunk.Flags = 0, uint32(size), int32(s.stride), 0
567+ }
568+ sl := &s.slots[idx]
569+ *sl = videoSlot{
570+ buf: VideoBuffer{Index: idx, Data: mem, Stride: s.stride, Width: s.width, Height: s.height, Format: s.format},
571+ pw: p,
572+ chunk: d.Chunk,
573+ fd: fd,
574+ mem: mem,
575+ live: true,
576+ }
577+ if sb.Metas != nil {
578+ metas := unsafe.Slice((*spaMeta)(sb.Metas), int(sb.NMetas))
579+ for i := range metas {
580+ if metas[i].Type == spa.MetaTypeHeader && metas[i].Size >= spa.MetaHeaderSize && metas[i].Data != nil {
581+ sl.hdr = (*spaMetaHeader)(metas[i].Data)
582+ break
583+ }
584+ }
585+ }
586+ pb.UserData = uintptr(idx + 1)
587+ if !s.closed {
588+ s.handler.BuffersChanged()
589+ }
590+}
591+
592+func (s *VideoSource) onRemoveBuffer(p unsafe.Pointer) {
593+ if p == nil {
594+ return
595+ }
596+ pb := (*videoPWBuffer)(p)
597+ idx := int(pb.UserData) - 1
598+ if uint(idx) >= videoMaxBuffers {
599+ return
600+ }
601+ sl := &s.slots[idx]
602+ if !sl.live || sl.pw != p {
603+ return
604+ }
605+ pb.UserData = 0
606+ if sl.borrowed {
607+ // The owner may still write into the mapping: keep it until Release.
608+ sl.removed = true
609+ sl.pw, sl.hdr, sl.chunk = nil, nil, nil
610+ } else {
611+ s.freeSlot(sl)
612+ }
613+ if !s.closed {
614+ s.handler.BuffersChanged()
615+ }
616+}
@@ -0,0 +1,616 @@
1+package core
2+
3+import (
4+ "errors"
5+ "fmt"
6+ "log/slog"
7+ "strings"
8+ "sync"
9+ "sync/atomic"
10+ "time"
11+ "unsafe"
12+
13+ "github.com/bnema/purego"
14+
15+ portin "github.com/bnema/purego-pipewire/internal/ports/in"
16+ portout "github.com/bnema/purego-pipewire/internal/ports/out"
17+ "github.com/bnema/purego-pipewire/spa"
18+)
19+
20+// Video source limits. They are fixed so that nothing is allocated after
21+// NewVideoSource except the memfd mappings made in add_buffer.
22+const (
23+ videoMaxBuffers = 16 // Buffers param maximum, size of the buffer slot table
24+ videoMaxSources = 64 // size of the process-wide callback slot table
25+ videoPodSize = 512
26+
27+ pwStreamFlagDriver = 0x8
28+ pwStreamFlagAllocBuffers = 0x100
29+ pwStreamStateStreaming = 3
30+ pwStreamStatePaused = 2
31+
32+ defaultVideoFPS = 60
33+)
34+
35+var (
36+ ErrVideoConfig = errors.New("invalid video source config")
37+ ErrVideoTableFull = errors.New("too many video sources")
38+ ErrVideoStreamCreate = errors.New("failed to create video stream")
39+ ErrVideoConnect = errors.New("failed to connect video stream")
40+ ErrVideoResize = errors.New("failed to resize video stream")
41+)
42+
43+// VideoConfig configures a VideoSource. MaxFPS defaults to 60 and Formats to
44+// BGRx.
45+type VideoConfig struct {
46+ Name string
47+ Width, Height int
48+ MaxFPS int
49+ Formats []spa.VideoFormat
50+}
51+
52+// VideoBuffer is a buffer that was handed out by VideoSource.Dequeue. Data
53+// aliases a memfd mapping owned by the source: it stays valid until the buffer
54+// is given back with Queue or Release, and not afterwards. The structure is
55+// owned by the source; do not copy it, retain it or modify it.
56+type VideoBuffer struct {
57+ Index int
58+ Data []byte
59+ Stride, Width, Height int
60+ Format spa.VideoFormat
61+}
62+
63+// C layouts (amd64/arm64). Offsets are asserted in tests.
64+
65+// videoPWBuffer mirrors struct pw_buffer; UserData carries slot index+1.
66+type videoPWBuffer struct {
67+ Buffer *spaBuffer
68+ UserData uintptr
69+ Size uint64
70+}
71+
72+// spaMeta mirrors struct spa_meta.
73+type spaMeta struct {
74+ Type uint32
75+ Size uint32
76+ Data unsafe.Pointer
77+}
78+
79+// spaMetaHeader mirrors struct spa_meta_header.
80+type spaMetaHeader struct {
81+ Flags uint32
82+ Offset uint32
83+ PTS int64
84+ DTSOffset int64
85+ Seq uint64
86+}
87+
88+// videoEvents mirrors struct pw_stream_events (version 2).
89+type videoEvents struct {
90+ Version uint32
91+ Destroy uintptr
92+ StateChanged uintptr
93+ ControlInfo uintptr
94+ IOChanged uintptr
95+ ParamChanged uintptr
96+ AddBuffer uintptr
97+ RemoveBuf uintptr
98+ Process uintptr
99+ Drained uintptr
100+ Command uintptr
101+ TriggerDone uintptr
102+}
103+
104+type videoSlot struct {
105+ buf VideoBuffer
106+ pw unsafe.Pointer // struct pw_buffer; nil once removed
107+ hdr *spaMetaHeader // nil if the buffer has no header meta
108+ chunk *spaChunk
109+ fd int
110+ mem []byte
111+ live bool // slot holds a mapped buffer
112+ removed bool // PipeWire removed the buffer while it was borrowed
113+ borrowed bool
114+}
115+
116+// VideoSource is a PipeWire Video/Source node that drives the graph and
117+// exposes memfd-backed buffers. Every method, and every handler callback, runs
118+// on the loop thread: the goroutine (locked to its OS thread) that calls
119+// Loop.Iterate.
120+//
121+// Frames are produced with Dequeue, then writing Data, then Queue, then
122+// Trigger. The buffer must be queued before Trigger, because the process
123+// callback does nothing: PipeWire picks up queued buffers when triggered.
124+type VideoSource struct {
125+ capi portout.VideoStreamAPI
126+ shm portout.SharedMemAPI
127+ handler portin.VideoHandler
128+
129+ stream unsafe.Pointer
130+ table int // index in videoTable
131+ events videoEvents
132+ hook [8]uint64 // struct spa_hook, 48 bytes
133+ params [2]unsafe.Pointer
134+ enumPod [videoPodSize]byte
135+ buffPod [videoPodSize]byte
136+ metaPod [128]byte
137+ cfg VideoConfig
138+ formats [4]spa.VideoFormat
139+ nformats int
140+
141+ state int32
142+ nodeID uint32
143+ format spa.VideoFormat
144+ width int
145+ height int
146+ stride int
147+ negotiated bool
148+ closed bool
149+ warned bool
150+
151+ slots [videoMaxBuffers]videoSlot
152+}
153+
154+var (
155+ videoTable [videoMaxSources]atomic.Pointer[VideoSource]
156+
157+ videoCBOnce sync.Once
158+ videoCB struct {
159+ stateChanged, paramChanged, addBuffer, removeBuffer, process, triggerDone uintptr
160+ }
161+)
162+
163+// uptr turns a raw callback argument into a pointer without a
164+// uintptr-to-unsafe.Pointer conversion; the value is C memory or a small
165+// integer, never Go memory.
166+func uptr(v uintptr) unsafe.Pointer { return *(*unsafe.Pointer)(unsafe.Pointer(&v)) }
167+
168+func videoLookup(a *purego.CallbackArgs) *VideoSource {
169+ idx := int(a.Int(0)) - 1
170+ if uint(idx) >= videoMaxSources {
171+ return nil
172+ }
173+ return videoTable[idx].Load()
174+}
175+
176+func registerVideoCallbacks() {
177+ videoCBOnce.Do(func() {
178+ videoCB.stateChanged = purego.NewCallbackInts(func(a *purego.CallbackArgs) uintptr {
179+ if s := videoLookup(a); s != nil {
180+ s.onStateChanged(int32(a.Int(2)), uptr(a.Int(3)))
181+ }
182+ return 0
183+ })
184+ videoCB.paramChanged = purego.NewCallbackInts(func(a *purego.CallbackArgs) uintptr {
185+ if s := videoLookup(a); s != nil {
186+ s.onParamChanged(uint32(a.Int(1)), uptr(a.Int(2)))
187+ }
188+ return 0
189+ })
190+ videoCB.addBuffer = purego.NewCallbackInts(func(a *purego.CallbackArgs) uintptr {
191+ if s := videoLookup(a); s != nil {
192+ s.onAddBuffer(uptr(a.Int(1)))
193+ }
194+ return 0
195+ })
196+ videoCB.removeBuffer = purego.NewCallbackInts(func(a *purego.CallbackArgs) uintptr {
197+ if s := videoLookup(a); s != nil {
198+ s.onRemoveBuffer(uptr(a.Int(1)))
199+ }
200+ return 0
201+ })
202+ // process and trigger_done intentionally do nothing: buffers are
203+ // queued by the owner before Trigger.
204+ videoCB.process = purego.NewCallbackInts(func(*purego.CallbackArgs) uintptr { return 0 })
205+ videoCB.triggerDone = purego.NewCallbackInts(func(*purego.CallbackArgs) uintptr { return 0 })
206+ })
207+}
208+
209+// NewVideoSource creates and connects a Video/Source stream on the core. The
210+// stream drives the graph (DRIVER) and allocates its own memfd buffers
211+// (ALLOC_BUFFERS). Call it, and every other method, on the loop thread.
212+func (c *Core) NewVideoSource(cfg VideoConfig, h portin.VideoHandler) (*VideoSource, error) {
213+ if c.ptr == nil || c.capi == nil {
214+ return nil, ErrVideoStreamCreate
215+ }
216+ if h == nil || cfg.Width <= 0 || cfg.Height <= 0 || cfg.Width > 1<<15 || cfg.Height > 1<<15 {
217+ return nil, ErrVideoConfig
218+ }
219+ if cfg.MaxFPS <= 0 {
220+ cfg.MaxFPS = defaultVideoFPS
221+ }
222+ s := &VideoSource{capi: c.capi, shm: c.shm, handler: h, cfg: cfg, table: -1}
223+ if len(cfg.Formats) == 0 {
224+ s.formats[0], s.nformats = spa.VideoFormatBGRx, 1
225+ } else {
226+ if len(cfg.Formats) > len(s.formats) {
227+ return nil, ErrVideoConfig
228+ }
229+ s.nformats = copy(s.formats[:], cfg.Formats)
230+ }
231+ s.cfg.Formats = nil // the slot-owned array is the source of truth
232+ name := cfg.Name
233+ if name == "" {
234+ name = "purego-pipewire"
235+ }
236+ if strings.ContainsAny(name, "\"\\") || strings.ContainsFunc(name, func(r rune) bool { return r < 0x20 || r == 0x7f }) {
237+ return nil, fmt.Errorf("%w: invalid name %q", ErrVideoConfig, name)
238+ }
239+ if _, err := spa.VideoEnumFormat(s.enumPod[:], cfg.Width, cfg.Height, cfg.MaxFPS, s.formats[:s.nformats]...); err != nil {
240+ return nil, fmt.Errorf("%w: %v", ErrVideoConfig, err)
241+ }
242+
243+ registerVideoCallbacks()
244+ for i := range videoTable {
245+ if videoTable[i].CompareAndSwap(nil, s) {
246+ s.table = i
247+ break
248+ }
249+ }
250+ if s.table < 0 {
251+ return nil, ErrVideoTableFull
252+ }
253+
254+ cname := append([]byte(name), 0)
255+ props := append([]byte(`media.class=Video/Source node.name="`+name+`"`), 0)
256+ propsPtr := c.capi.PWPropertiesNewString(&props[0])
257+ if propsPtr == nil {
258+ videoTable[s.table].Store(nil)
259+ return nil, ErrVideoStreamCreate
260+ }
261+ s.stream = c.capi.PWStreamNew(c.ptr, &cname[0], propsPtr) // takes ownership of props
262+ if s.stream == nil {
263+ videoTable[s.table].Store(nil)
264+ return nil, ErrVideoStreamCreate
265+ }
266+
267+ s.events = videoEvents{
268+ Version: 2,
269+ StateChanged: videoCB.stateChanged,
270+ ParamChanged: videoCB.paramChanged,
271+ AddBuffer: videoCB.addBuffer,
272+ RemoveBuf: videoCB.removeBuffer,
273+ Process: videoCB.process,
274+ TriggerDone: videoCB.triggerDone,
275+ }
276+ data := uptr(uintptr(s.table + 1))
277+ c.capi.PWStreamAddListener(s.stream, unsafe.Pointer(&s.hook[0]), unsafe.Pointer(&s.events), data)
278+
279+ s.params[0] = unsafe.Pointer(&s.enumPod[0])
280+ ret := c.capi.PWStreamConnect(s.stream, 1 /* PW_DIRECTION_OUTPUT */, spa.IDInvalid,
281+ pwStreamFlagDriver|pwStreamFlagAllocBuffers, unsafe.Pointer(&s.params[0]), 1)
282+ if ret < 0 {
283+ s.closed = true
284+ s.teardown()
285+ return nil, fmt.Errorf("%w: pw_stream_connect returned %d", ErrVideoConnect, ret)
286+ }
287+ return s, nil
288+}
289+
290+// NodeID returns the PipeWire node id, or 0 until the stream is paused or
291+// streaming.
292+func (s *VideoSource) NodeID() uint32 { return s.nodeID }
293+
294+// State returns the last stream state (see VideoHandler.StateChanged).
295+func (s *VideoSource) State() int32 { return s.state }
296+
297+// Dequeue returns a free buffer to draw into, or nil when none is available.
298+// The buffer is borrowed until Queue or Release. Buffers that could not be
299+// given a memfd are skipped (they stay out of the queue).
300+func (s *VideoSource) Dequeue() *VideoBuffer {
301+ if s.stream == nil || !s.negotiated {
302+ return nil
303+ }
304+ for i := 0; i < 2*videoMaxBuffers; i++ {
305+ p := s.capi.PWStreamDequeueBuffer(s.stream)
306+ if p == nil {
307+ return nil
308+ }
309+ idx := int((*videoPWBuffer)(p).UserData) - 1
310+ if uint(idx) >= videoMaxBuffers {
311+ continue // unusable buffer: never handed out
312+ }
313+ sl := &s.slots[idx]
314+ if !sl.live || sl.removed || sl.borrowed || sl.pw != p {
315+ continue
316+ }
317+ sl.borrowed = true
318+ return &sl.buf
319+ }
320+ return nil
321+}
322+
323+// slotOf validates b against the slot table.
324+func (s *VideoSource) slotOf(b *VideoBuffer) *videoSlot {
325+ if b == nil || uint(b.Index) >= videoMaxBuffers {
326+ return nil
327+ }
328+ sl := &s.slots[b.Index]
329+ if &sl.buf != b || !sl.live || !sl.borrowed {
330+ return nil
331+ }
332+ return sl
333+}
334+
335+// Queue hands a filled buffer back to PipeWire with its frame sequence and
336+// presentation time. When corrupted is set the frame is flagged corrupted and
337+// carries no data. Call Trigger after Queue: the buffer is queued before the
338+// graph cycle is triggered. Queue on a buffer PipeWire already removed only
339+// releases it.
340+func (s *VideoSource) Queue(b *VideoBuffer, seq uint64, pts time.Duration, corrupted bool) {
341+ sl := s.slotOf(b)
342+ if sl == nil {
343+ return
344+ }
345+ if sl.removed || s.stream == nil {
346+ s.freeSlot(sl)
347+ return
348+ }
349+ size := uint32(sl.buf.Stride * sl.buf.Height)
350+ if c := sl.chunk; c != nil {
351+ c.Offset, c.Size, c.Stride, c.Flags = 0, size, int32(sl.buf.Stride), 0
352+ if corrupted {
353+ c.Size, c.Flags = 0, spa.ChunkFlagCorrupted
354+ }
355+ }
356+ if h := sl.hdr; h != nil {
357+ h.Flags, h.Offset, h.PTS, h.DTSOffset, h.Seq = 0, 0, int64(pts), 0, seq
358+ if corrupted {
359+ h.Flags = spa.MetaHeaderFlagCorrupted
360+ }
361+ }
362+ sl.borrowed = false
363+ s.capi.PWStreamQueueBuffer(s.stream, sl.pw)
364+}
365+
366+// Release gives a dequeued buffer back without queueing a frame. If PipeWire
367+// removed the buffer in the meantime its memory is unmapped now. b.Data must
368+// not be used afterwards.
369+func (s *VideoSource) Release(b *VideoBuffer) {
370+ sl := s.slotOf(b)
371+ if sl == nil {
372+ return
373+ }
374+ if sl.removed || s.stream == nil {
375+ s.freeSlot(sl)
376+ return
377+ }
378+ sl.borrowed = false
379+ s.capi.PWStreamReturnBuffer(s.stream, sl.pw)
380+}
381+
382+// Trigger starts a graph cycle (pw_stream_trigger_process). Queue the filled
383+// buffer first.
384+func (s *VideoSource) Trigger() {
385+ if s.stream != nil {
386+ s.capi.PWStreamTriggerProcess(s.stream)
387+ }
388+}
389+
390+// Resize renegotiates the stream with a new size. Buffers PipeWire replaces
391+// stay valid while borrowed; hand them back with Queue or Release (ideally
392+// resize when none is borrowed).
393+func (s *VideoSource) Resize(w, h int) error {
394+ if s.stream == nil {
395+ return ErrVideoResize
396+ }
397+ if w <= 0 || h <= 0 || w > 1<<15 || h > 1<<15 {
398+ return ErrVideoConfig
399+ }
400+ if _, err := spa.VideoEnumFormat(s.enumPod[:], w, h, s.cfg.MaxFPS, s.formats[:s.nformats]...); err != nil {
401+ return fmt.Errorf("%w: %v", ErrVideoResize, err)
402+ }
403+ s.cfg.Width, s.cfg.Height = w, h
404+ s.params[0] = unsafe.Pointer(&s.enumPod[0])
405+ if ret := s.capi.PWStreamUpdateParams(s.stream, unsafe.Pointer(&s.params[0]), 1); ret < 0 {
406+ return fmt.Errorf("%w: pw_stream_update_params returned %d", ErrVideoResize, ret)
407+ }
408+ return nil
409+}
410+
411+// Destroy disconnects and destroys the stream. PipeWire removes every buffer
412+// during the disconnect; buffers that are still borrowed keep their mapping
413+// until Release (or Queue). Call Destroy only when no buffer is borrowed,
414+// unless the caller releases them afterwards. No handler callback runs after
415+// Destroy starts. Destroy is idempotent.
416+func (s *VideoSource) Destroy() {
417+ s.closed = true
418+ s.teardown()
419+}
420+
421+func (s *VideoSource) teardown() {
422+ if s.stream != nil {
423+ stream := s.stream
424+ s.capi.PWStreamDisconnect(stream)
425+ s.capi.PWStreamDestroy(stream)
426+ s.stream = nil
427+ }
428+ if s.table >= 0 {
429+ videoTable[s.table].Store(nil)
430+ s.table = -1
431+ }
432+ for i := range s.slots {
433+ sl := &s.slots[i]
434+ if !sl.live {
435+ continue
436+ }
437+ sl.pw, sl.hdr, sl.chunk = nil, nil, nil
438+ if sl.borrowed {
439+ sl.removed = true
440+ } else {
441+ s.freeSlot(sl)
442+ }
443+ }
444+}
445+
446+// freeSlot unmaps the slot's memory and makes the slot reusable.
447+func (s *VideoSource) freeSlot(sl *videoSlot) {
448+ if sl.live {
449+ s.shm.FreeSharedMem(sl.fd, sl.mem)
450+ }
451+ *sl = videoSlot{}
452+}
453+
454+// --- stream event handlers (loop thread) ---
455+
456+func (s *VideoSource) onStateChanged(state int32, errp unsafe.Pointer) {
457+ s.state = state
458+ if state == pwStreamStatePaused || state == pwStreamStateStreaming {
459+ s.nodeID = s.capi.PWStreamGetNodeId(s.stream)
460+ }
461+ if state == pwStreamStateStreaming && !s.warned {
462+ s.warned = true
463+ if !s.capi.PWStreamIsDriving(s.stream) {
464+ slog.Warn("purego-pipewire: video stream is not driving the graph", "node", s.nodeID)
465+ }
466+ }
467+ if s.closed {
468+ return
469+ }
470+ msg := ""
471+ if state < 0 {
472+ msg = cString(errp)
473+ }
474+ s.handler.StateChanged(state, s.nodeID, msg)
475+}
476+
477+func cString(p unsafe.Pointer) string {
478+ if p == nil {
479+ return ""
480+ }
481+ n := 0
482+ for n < 512 && *(*byte)(unsafe.Add(p, n)) != 0 {
483+ n++
484+ }
485+ return string(unsafe.Slice((*byte)(p), n))
486+}
487+
488+func (s *VideoSource) onParamChanged(id uint32, param unsafe.Pointer) {
489+ if id != spa.ParamFormat || s.stream == nil {
490+ return
491+ }
492+ if param == nil {
493+ s.negotiated = false
494+ return
495+ }
496+ size := int(*(*uint32)(param))
497+ if size < 8 || size > 4096 {
498+ return
499+ }
500+ pod := unsafe.Slice((*byte)(param), 8+size)
501+ f, w, h, ok := spa.ParseVideoFormat(pod)
502+ if !ok {
503+ return
504+ }
505+ format := spa.VideoFormat(f)
506+ allowed := false
507+ for _, af := range s.formats[:s.nformats] {
508+ allowed = allowed || af == format
509+ }
510+ if !allowed {
511+ return
512+ }
513+ stride := w * 4
514+ buffers, err := spa.VideoBuffers(s.buffPod[:], stride*h, stride, 2, 8, videoMaxBuffers, 1<<spa.DataMemFd)
515+ if err != nil {
516+ return
517+ }
518+ meta, err := spa.MetaHeader(s.metaPod[:])
519+ if err != nil {
520+ return
521+ }
522+ s.format, s.width, s.height, s.stride, s.negotiated = format, w, h, stride, true
523+ s.params[0] = unsafe.Pointer(&buffers[0])
524+ s.params[1] = unsafe.Pointer(&meta[0])
525+ s.capi.PWStreamUpdateParams(s.stream, unsafe.Pointer(&s.params[0]), 2)
526+ if !s.closed {
527+ s.handler.FormatChanged(format, w, h, stride)
528+ }
529+}
530+
531+func (s *VideoSource) onAddBuffer(p unsafe.Pointer) {
532+ if p == nil {
533+ return
534+ }
535+ pb := (*videoPWBuffer)(p)
536+ pb.UserData = 0 // unusable until a slot is assigned
537+ sb := pb.Buffer
538+ if sb == nil || sb.NDatas == 0 || sb.Datas == nil || !s.negotiated {
539+ return
540+ }
541+ d := (*spaData)(sb.Datas)
542+ if d.Type&(1<<spa.DataMemFd) == 0 {
543+ return // DMA-BUF only: not supported
544+ }
545+ idx := -1
546+ for i := range s.slots {
547+ if !s.slots[i].live {
548+ idx = i
549+ break
550+ }
551+ }
552+ if idx < 0 {
553+ return
554+ }
555+ size := s.stride * s.height
556+ fd, mem, err := s.shm.NewSharedMem("pw-video", size)
557+ if err != nil || len(mem) < size {
558+ if err == nil {
559+ s.shm.FreeSharedMem(fd, mem)
560+ }
561+ return
562+ }
563+ d.Type, d.Flags, d.Fd = spa.DataMemFd, spa.DataFlagReadWrite, int64(fd)
564+ d.MapOffset, d.Maxsize, d.Data = 0, uint32(size), unsafe.Pointer(&mem[0])
565+ if d.Chunk != nil {
566+ d.Chunk.Offset, d.Chunk.Size, d.Chunk.Stride, d.Chunk.Flags = 0, uint32(size), int32(s.stride), 0
567+ }
568+ sl := &s.slots[idx]
569+ *sl = videoSlot{
570+ buf: VideoBuffer{Index: idx, Data: mem, Stride: s.stride, Width: s.width, Height: s.height, Format: s.format},
571+ pw: p,
572+ chunk: d.Chunk,
573+ fd: fd,
574+ mem: mem,
575+ live: true,
576+ }
577+ if sb.Metas != nil {
578+ metas := unsafe.Slice((*spaMeta)(sb.Metas), int(sb.NMetas))
579+ for i := range metas {
580+ if metas[i].Type == spa.MetaTypeHeader && metas[i].Size >= spa.MetaHeaderSize && metas[i].Data != nil {
581+ sl.hdr = (*spaMetaHeader)(metas[i].Data)
582+ break
583+ }
584+ }
585+ }
586+ pb.UserData = uintptr(idx + 1)
587+ if !s.closed {
588+ s.handler.BuffersChanged()
589+ }
590+}
591+
592+func (s *VideoSource) onRemoveBuffer(p unsafe.Pointer) {
593+ if p == nil {
594+ return
595+ }
596+ pb := (*videoPWBuffer)(p)
597+ idx := int(pb.UserData) - 1
598+ if uint(idx) >= videoMaxBuffers {
599+ return
600+ }
601+ sl := &s.slots[idx]
602+ if !sl.live || sl.pw != p {
603+ return
604+ }
605+ pb.UserData = 0
606+ if sl.borrowed {
607+ // The owner may still write into the mapping: keep it until Release.
608+ sl.removed = true
609+ sl.pw, sl.hdr, sl.chunk = nil, nil, nil
610+ } else {
611+ s.freeSlot(sl)
612+ }
613+ if !s.closed {
614+ s.handler.BuffersChanged()
615+ }
616+}
A internal/ports/out/mocks/mock_VideoStreamAPI.go +1411 -0
@@ -0,0 +1,1411 @@
1+// Code generated by mockery; DO NOT EDIT.
2+// github.com/vektra/mockery
3+// template: testify
4+
5+package mocks
6+
7+import (
8+ "unsafe"
9+
10+ mock "github.com/stretchr/testify/mock"
11+)
12+
13+// NewMockVideoStreamAPI creates a new instance of MockVideoStreamAPI. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
14+// The first argument is typically a *testing.T value.
15+func NewMockVideoStreamAPI(t interface {
16+ mock.TestingT
17+ Cleanup(func())
18+}) *MockVideoStreamAPI {
19+ if helper, ok := t.(interface{ Helper() }); ok {
20+ helper.Helper()
21+ }
22+
23+ mock := &MockVideoStreamAPI{}
24+ mock.Mock.Test(t)
25+
26+ t.Cleanup(func() {
27+ if helper, ok := t.(interface{ Helper() }); ok {
28+ helper.Helper()
29+ }
30+ mock.AssertExpectations(t)
31+ })
32+
33+ return mock
34+}
35+
36+// MockVideoStreamAPI is an autogenerated mock type for the VideoStreamAPI type
37+type MockVideoStreamAPI struct {
38+ mock.Mock
39+}
40+
41+type MockVideoStreamAPI_Expecter struct {
42+ mock *mock.Mock
43+}
44+
45+func (_m *MockVideoStreamAPI) EXPECT() *MockVideoStreamAPI_Expecter {
46+ return &MockVideoStreamAPI_Expecter{mock: &_m.Mock}
47+}
48+
49+// PWContextConnect provides a mock function for the type MockVideoStreamAPI
50+func (_mock *MockVideoStreamAPI) PWContextConnect(context unsafe.Pointer, props unsafe.Pointer, user_data_size uintptr) unsafe.Pointer {
51+ ret := _mock.Called(context, props, user_data_size)
52+
53+ if len(ret) == 0 {
54+ panic("no return value specified for PWContextConnect")
55+ }
56+
57+ var r0 unsafe.Pointer
58+ if returnFunc, ok := ret.Get(0).(func(unsafe.Pointer, unsafe.Pointer, uintptr) unsafe.Pointer); ok {
59+ r0 = returnFunc(context, props, user_data_size)
60+ } else {
61+ r0 = ret.Get(0).(unsafe.Pointer)
62+ }
63+ return r0
64+}
65+
66+// MockVideoStreamAPI_PWContextConnect_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'PWContextConnect'
67+type MockVideoStreamAPI_PWContextConnect_Call struct {
68+ *mock.Call
69+}
70+
71+// PWContextConnect is a helper method to define mock.On call
72+// - context unsafe.Pointer
73+// - props unsafe.Pointer
74+// - user_data_size uintptr
75+func (_e *MockVideoStreamAPI_Expecter) PWContextConnect(context any, props any, user_data_size any) *MockVideoStreamAPI_PWContextConnect_Call {
76+ return &MockVideoStreamAPI_PWContextConnect_Call{Call: _e.mock.On("PWContextConnect", context, props, user_data_size)}
77+}
78+
79+func (_c *MockVideoStreamAPI_PWContextConnect_Call) Run(run func(context unsafe.Pointer, props unsafe.Pointer, user_data_size uintptr)) *MockVideoStreamAPI_PWContextConnect_Call {
80+ _c.Call.Run(func(args mock.Arguments) {
81+ var arg0 unsafe.Pointer
82+ if args[0] != nil {
83+ arg0 = args[0].(unsafe.Pointer)
84+ }
85+ var arg1 unsafe.Pointer
86+ if args[1] != nil {
87+ arg1 = args[1].(unsafe.Pointer)
88+ }
89+ var arg2 uintptr
90+ if args[2] != nil {
91+ arg2 = args[2].(uintptr)
92+ }
93+ run(
94+ arg0,
95+ arg1,
96+ arg2,
97+ )
98+ })
99+ return _c
100+}
101+
102+func (_c *MockVideoStreamAPI_PWContextConnect_Call) Return(v unsafe.Pointer) *MockVideoStreamAPI_PWContextConnect_Call {
103+ _c.Call.Return(v)
104+ return _c
105+}
106+
107+func (_c *MockVideoStreamAPI_PWContextConnect_Call) RunAndReturn(run func(context unsafe.Pointer, props unsafe.Pointer, user_data_size uintptr) unsafe.Pointer) *MockVideoStreamAPI_PWContextConnect_Call {
108+ _c.Call.Return(run)
109+ return _c
110+}
111+
112+// PWContextDestroy provides a mock function for the type MockVideoStreamAPI
113+func (_mock *MockVideoStreamAPI) PWContextDestroy(context unsafe.Pointer) {
114+ _mock.Called(context)
115+ return
116+}
117+
118+// MockVideoStreamAPI_PWContextDestroy_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'PWContextDestroy'
119+type MockVideoStreamAPI_PWContextDestroy_Call struct {
120+ *mock.Call
121+}
122+
123+// PWContextDestroy is a helper method to define mock.On call
124+// - context unsafe.Pointer
125+func (_e *MockVideoStreamAPI_Expecter) PWContextDestroy(context any) *MockVideoStreamAPI_PWContextDestroy_Call {
126+ return &MockVideoStreamAPI_PWContextDestroy_Call{Call: _e.mock.On("PWContextDestroy", context)}
127+}
128+
129+func (_c *MockVideoStreamAPI_PWContextDestroy_Call) Run(run func(context unsafe.Pointer)) *MockVideoStreamAPI_PWContextDestroy_Call {
130+ _c.Call.Run(func(args mock.Arguments) {
131+ var arg0 unsafe.Pointer
132+ if args[0] != nil {
133+ arg0 = args[0].(unsafe.Pointer)
134+ }
135+ run(
136+ arg0,
137+ )
138+ })
139+ return _c
140+}
141+
142+func (_c *MockVideoStreamAPI_PWContextDestroy_Call) Return() *MockVideoStreamAPI_PWContextDestroy_Call {
143+ _c.Call.Return()
144+ return _c
145+}
146+
147+func (_c *MockVideoStreamAPI_PWContextDestroy_Call) RunAndReturn(run func(context unsafe.Pointer)) *MockVideoStreamAPI_PWContextDestroy_Call {
148+ _c.Run(run)
149+ return _c
150+}
151+
152+// PWContextNew provides a mock function for the type MockVideoStreamAPI
153+func (_mock *MockVideoStreamAPI) PWContextNew(loop unsafe.Pointer, props unsafe.Pointer, user_data_size uintptr) unsafe.Pointer {
154+ ret := _mock.Called(loop, props, user_data_size)
155+
156+ if len(ret) == 0 {
157+ panic("no return value specified for PWContextNew")
158+ }
159+
160+ var r0 unsafe.Pointer
161+ if returnFunc, ok := ret.Get(0).(func(unsafe.Pointer, unsafe.Pointer, uintptr) unsafe.Pointer); ok {
162+ r0 = returnFunc(loop, props, user_data_size)
163+ } else {
164+ r0 = ret.Get(0).(unsafe.Pointer)
165+ }
166+ return r0
167+}
168+
169+// MockVideoStreamAPI_PWContextNew_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'PWContextNew'
170+type MockVideoStreamAPI_PWContextNew_Call struct {
171+ *mock.Call
172+}
173+
174+// PWContextNew is a helper method to define mock.On call
175+// - loop unsafe.Pointer
176+// - props unsafe.Pointer
177+// - user_data_size uintptr
178+func (_e *MockVideoStreamAPI_Expecter) PWContextNew(loop any, props any, user_data_size any) *MockVideoStreamAPI_PWContextNew_Call {
179+ return &MockVideoStreamAPI_PWContextNew_Call{Call: _e.mock.On("PWContextNew", loop, props, user_data_size)}
180+}
181+
182+func (_c *MockVideoStreamAPI_PWContextNew_Call) Run(run func(loop unsafe.Pointer, props unsafe.Pointer, user_data_size uintptr)) *MockVideoStreamAPI_PWContextNew_Call {
183+ _c.Call.Run(func(args mock.Arguments) {
184+ var arg0 unsafe.Pointer
185+ if args[0] != nil {
186+ arg0 = args[0].(unsafe.Pointer)
187+ }
188+ var arg1 unsafe.Pointer
189+ if args[1] != nil {
190+ arg1 = args[1].(unsafe.Pointer)
191+ }
192+ var arg2 uintptr
193+ if args[2] != nil {
194+ arg2 = args[2].(uintptr)
195+ }
196+ run(
197+ arg0,
198+ arg1,
199+ arg2,
200+ )
201+ })
202+ return _c
203+}
204+
205+func (_c *MockVideoStreamAPI_PWContextNew_Call) Return(v unsafe.Pointer) *MockVideoStreamAPI_PWContextNew_Call {
206+ _c.Call.Return(v)
207+ return _c
208+}
209+
210+func (_c *MockVideoStreamAPI_PWContextNew_Call) RunAndReturn(run func(loop unsafe.Pointer, props unsafe.Pointer, user_data_size uintptr) unsafe.Pointer) *MockVideoStreamAPI_PWContextNew_Call {
211+ _c.Call.Return(run)
212+ return _c
213+}
214+
215+// PWCoreDisconnect provides a mock function for the type MockVideoStreamAPI
216+func (_mock *MockVideoStreamAPI) PWCoreDisconnect(core unsafe.Pointer) int32 {
217+ ret := _mock.Called(core)
218+
219+ if len(ret) == 0 {
220+ panic("no return value specified for PWCoreDisconnect")
221+ }
222+
223+ var r0 int32
224+ if returnFunc, ok := ret.Get(0).(func(unsafe.Pointer) int32); ok {
225+ r0 = returnFunc(core)
226+ } else {
227+ r0 = ret.Get(0).(int32)
228+ }
229+ return r0
230+}
231+
232+// MockVideoStreamAPI_PWCoreDisconnect_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'PWCoreDisconnect'
233+type MockVideoStreamAPI_PWCoreDisconnect_Call struct {
234+ *mock.Call
235+}
236+
237+// PWCoreDisconnect is a helper method to define mock.On call
238+// - core unsafe.Pointer
239+func (_e *MockVideoStreamAPI_Expecter) PWCoreDisconnect(core any) *MockVideoStreamAPI_PWCoreDisconnect_Call {
240+ return &MockVideoStreamAPI_PWCoreDisconnect_Call{Call: _e.mock.On("PWCoreDisconnect", core)}
241+}
242+
243+func (_c *MockVideoStreamAPI_PWCoreDisconnect_Call) Run(run func(core unsafe.Pointer)) *MockVideoStreamAPI_PWCoreDisconnect_Call {
244+ _c.Call.Run(func(args mock.Arguments) {
245+ var arg0 unsafe.Pointer
246+ if args[0] != nil {
247+ arg0 = args[0].(unsafe.Pointer)
248+ }
249+ run(
250+ arg0,
251+ )
252+ })
253+ return _c
254+}
255+
256+func (_c *MockVideoStreamAPI_PWCoreDisconnect_Call) Return(n int32) *MockVideoStreamAPI_PWCoreDisconnect_Call {
257+ _c.Call.Return(n)
258+ return _c
259+}
260+
261+func (_c *MockVideoStreamAPI_PWCoreDisconnect_Call) RunAndReturn(run func(core unsafe.Pointer) int32) *MockVideoStreamAPI_PWCoreDisconnect_Call {
262+ _c.Call.Return(run)
263+ return _c
264+}
265+
266+// PWLoopDestroy provides a mock function for the type MockVideoStreamAPI
267+func (_mock *MockVideoStreamAPI) PWLoopDestroy(loop unsafe.Pointer) {
268+ _mock.Called(loop)
269+ return
270+}
271+
272+// MockVideoStreamAPI_PWLoopDestroy_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'PWLoopDestroy'
273+type MockVideoStreamAPI_PWLoopDestroy_Call struct {
274+ *mock.Call
275+}
276+
277+// PWLoopDestroy is a helper method to define mock.On call
278+// - loop unsafe.Pointer
279+func (_e *MockVideoStreamAPI_Expecter) PWLoopDestroy(loop any) *MockVideoStreamAPI_PWLoopDestroy_Call {
280+ return &MockVideoStreamAPI_PWLoopDestroy_Call{Call: _e.mock.On("PWLoopDestroy", loop)}
281+}
282+
283+func (_c *MockVideoStreamAPI_PWLoopDestroy_Call) Run(run func(loop unsafe.Pointer)) *MockVideoStreamAPI_PWLoopDestroy_Call {
284+ _c.Call.Run(func(args mock.Arguments) {
285+ var arg0 unsafe.Pointer
286+ if args[0] != nil {
287+ arg0 = args[0].(unsafe.Pointer)
288+ }
289+ run(
290+ arg0,
291+ )
292+ })
293+ return _c
294+}
295+
296+func (_c *MockVideoStreamAPI_PWLoopDestroy_Call) Return() *MockVideoStreamAPI_PWLoopDestroy_Call {
297+ _c.Call.Return()
298+ return _c
299+}
300+
301+func (_c *MockVideoStreamAPI_PWLoopDestroy_Call) RunAndReturn(run func(loop unsafe.Pointer)) *MockVideoStreamAPI_PWLoopDestroy_Call {
302+ _c.Run(run)
303+ return _c
304+}
305+
306+// PWLoopEnter provides a mock function for the type MockVideoStreamAPI
307+func (_mock *MockVideoStreamAPI) PWLoopEnter(loop unsafe.Pointer) {
308+ _mock.Called(loop)
309+ return
310+}
311+
312+// MockVideoStreamAPI_PWLoopEnter_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'PWLoopEnter'
313+type MockVideoStreamAPI_PWLoopEnter_Call struct {
314+ *mock.Call
315+}
316+
317+// PWLoopEnter is a helper method to define mock.On call
318+// - loop unsafe.Pointer
319+func (_e *MockVideoStreamAPI_Expecter) PWLoopEnter(loop any) *MockVideoStreamAPI_PWLoopEnter_Call {
320+ return &MockVideoStreamAPI_PWLoopEnter_Call{Call: _e.mock.On("PWLoopEnter", loop)}
321+}
322+
323+func (_c *MockVideoStreamAPI_PWLoopEnter_Call) Run(run func(loop unsafe.Pointer)) *MockVideoStreamAPI_PWLoopEnter_Call {
324+ _c.Call.Run(func(args mock.Arguments) {
325+ var arg0 unsafe.Pointer
326+ if args[0] != nil {
327+ arg0 = args[0].(unsafe.Pointer)
328+ }
329+ run(
330+ arg0,
331+ )
332+ })
333+ return _c
334+}
335+
336+func (_c *MockVideoStreamAPI_PWLoopEnter_Call) Return() *MockVideoStreamAPI_PWLoopEnter_Call {
337+ _c.Call.Return()
338+ return _c
339+}
340+
341+func (_c *MockVideoStreamAPI_PWLoopEnter_Call) RunAndReturn(run func(loop unsafe.Pointer)) *MockVideoStreamAPI_PWLoopEnter_Call {
342+ _c.Run(run)
343+ return _c
344+}
345+
346+// PWLoopGetFd provides a mock function for the type MockVideoStreamAPI
347+func (_mock *MockVideoStreamAPI) PWLoopGetFd(loop unsafe.Pointer) int32 {
348+ ret := _mock.Called(loop)
349+
350+ if len(ret) == 0 {
351+ panic("no return value specified for PWLoopGetFd")
352+ }
353+
354+ var r0 int32
355+ if returnFunc, ok := ret.Get(0).(func(unsafe.Pointer) int32); ok {
356+ r0 = returnFunc(loop)
357+ } else {
358+ r0 = ret.Get(0).(int32)
359+ }
360+ return r0
361+}
362+
363+// MockVideoStreamAPI_PWLoopGetFd_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'PWLoopGetFd'
364+type MockVideoStreamAPI_PWLoopGetFd_Call struct {
365+ *mock.Call
366+}
367+
368+// PWLoopGetFd is a helper method to define mock.On call
369+// - loop unsafe.Pointer
370+func (_e *MockVideoStreamAPI_Expecter) PWLoopGetFd(loop any) *MockVideoStreamAPI_PWLoopGetFd_Call {
371+ return &MockVideoStreamAPI_PWLoopGetFd_Call{Call: _e.mock.On("PWLoopGetFd", loop)}
372+}
373+
374+func (_c *MockVideoStreamAPI_PWLoopGetFd_Call) Run(run func(loop unsafe.Pointer)) *MockVideoStreamAPI_PWLoopGetFd_Call {
375+ _c.Call.Run(func(args mock.Arguments) {
376+ var arg0 unsafe.Pointer
377+ if args[0] != nil {
378+ arg0 = args[0].(unsafe.Pointer)
379+ }
380+ run(
381+ arg0,
382+ )
383+ })
384+ return _c
385+}
386+
387+func (_c *MockVideoStreamAPI_PWLoopGetFd_Call) Return(n int32) *MockVideoStreamAPI_PWLoopGetFd_Call {
388+ _c.Call.Return(n)
389+ return _c
390+}
391+
392+func (_c *MockVideoStreamAPI_PWLoopGetFd_Call) RunAndReturn(run func(loop unsafe.Pointer) int32) *MockVideoStreamAPI_PWLoopGetFd_Call {
393+ _c.Call.Return(run)
394+ return _c
395+}
396+
397+// PWLoopIterate provides a mock function for the type MockVideoStreamAPI
398+func (_mock *MockVideoStreamAPI) PWLoopIterate(loop unsafe.Pointer, timeout int32) int32 {
399+ ret := _mock.Called(loop, timeout)
400+
401+ if len(ret) == 0 {
402+ panic("no return value specified for PWLoopIterate")
403+ }
404+
405+ var r0 int32
406+ if returnFunc, ok := ret.Get(0).(func(unsafe.Pointer, int32) int32); ok {
407+ r0 = returnFunc(loop, timeout)
408+ } else {
409+ r0 = ret.Get(0).(int32)
410+ }
411+ return r0
412+}
413+
414+// MockVideoStreamAPI_PWLoopIterate_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'PWLoopIterate'
415+type MockVideoStreamAPI_PWLoopIterate_Call struct {
416+ *mock.Call
417+}
418+
419+// PWLoopIterate is a helper method to define mock.On call
420+// - loop unsafe.Pointer
421+// - timeout int32
422+func (_e *MockVideoStreamAPI_Expecter) PWLoopIterate(loop any, timeout any) *MockVideoStreamAPI_PWLoopIterate_Call {
423+ return &MockVideoStreamAPI_PWLoopIterate_Call{Call: _e.mock.On("PWLoopIterate", loop, timeout)}
424+}
425+
426+func (_c *MockVideoStreamAPI_PWLoopIterate_Call) Run(run func(loop unsafe.Pointer, timeout int32)) *MockVideoStreamAPI_PWLoopIterate_Call {
427+ _c.Call.Run(func(args mock.Arguments) {
428+ var arg0 unsafe.Pointer
429+ if args[0] != nil {
430+ arg0 = args[0].(unsafe.Pointer)
431+ }
432+ var arg1 int32
433+ if args[1] != nil {
434+ arg1 = args[1].(int32)
435+ }
436+ run(
437+ arg0,
438+ arg1,
439+ )
440+ })
441+ return _c
442+}
443+
444+func (_c *MockVideoStreamAPI_PWLoopIterate_Call) Return(n int32) *MockVideoStreamAPI_PWLoopIterate_Call {
445+ _c.Call.Return(n)
446+ return _c
447+}
448+
449+func (_c *MockVideoStreamAPI_PWLoopIterate_Call) RunAndReturn(run func(loop unsafe.Pointer, timeout int32) int32) *MockVideoStreamAPI_PWLoopIterate_Call {
450+ _c.Call.Return(run)
451+ return _c
452+}
453+
454+// PWLoopLeave provides a mock function for the type MockVideoStreamAPI
455+func (_mock *MockVideoStreamAPI) PWLoopLeave(loop unsafe.Pointer) {
456+ _mock.Called(loop)
457+ return
458+}
459+
460+// MockVideoStreamAPI_PWLoopLeave_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'PWLoopLeave'
461+type MockVideoStreamAPI_PWLoopLeave_Call struct {
462+ *mock.Call
463+}
464+
465+// PWLoopLeave is a helper method to define mock.On call
466+// - loop unsafe.Pointer
467+func (_e *MockVideoStreamAPI_Expecter) PWLoopLeave(loop any) *MockVideoStreamAPI_PWLoopLeave_Call {
468+ return &MockVideoStreamAPI_PWLoopLeave_Call{Call: _e.mock.On("PWLoopLeave", loop)}
469+}
470+
471+func (_c *MockVideoStreamAPI_PWLoopLeave_Call) Run(run func(loop unsafe.Pointer)) *MockVideoStreamAPI_PWLoopLeave_Call {
472+ _c.Call.Run(func(args mock.Arguments) {
473+ var arg0 unsafe.Pointer
474+ if args[0] != nil {
475+ arg0 = args[0].(unsafe.Pointer)
476+ }
477+ run(
478+ arg0,
479+ )
480+ })
481+ return _c
482+}
483+
484+func (_c *MockVideoStreamAPI_PWLoopLeave_Call) Return() *MockVideoStreamAPI_PWLoopLeave_Call {
485+ _c.Call.Return()
486+ return _c
487+}
488+
489+func (_c *MockVideoStreamAPI_PWLoopLeave_Call) RunAndReturn(run func(loop unsafe.Pointer)) *MockVideoStreamAPI_PWLoopLeave_Call {
490+ _c.Run(run)
491+ return _c
492+}
493+
494+// PWLoopNew provides a mock function for the type MockVideoStreamAPI
495+func (_mock *MockVideoStreamAPI) PWLoopNew(props unsafe.Pointer) unsafe.Pointer {
496+ ret := _mock.Called(props)
497+
498+ if len(ret) == 0 {
499+ panic("no return value specified for PWLoopNew")
500+ }
501+
502+ var r0 unsafe.Pointer
503+ if returnFunc, ok := ret.Get(0).(func(unsafe.Pointer) unsafe.Pointer); ok {
504+ r0 = returnFunc(props)
505+ } else {
506+ r0 = ret.Get(0).(unsafe.Pointer)
507+ }
508+ return r0
509+}
510+
511+// MockVideoStreamAPI_PWLoopNew_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'PWLoopNew'
512+type MockVideoStreamAPI_PWLoopNew_Call struct {
513+ *mock.Call
514+}
515+
516+// PWLoopNew is a helper method to define mock.On call
517+// - props unsafe.Pointer
518+func (_e *MockVideoStreamAPI_Expecter) PWLoopNew(props any) *MockVideoStreamAPI_PWLoopNew_Call {
519+ return &MockVideoStreamAPI_PWLoopNew_Call{Call: _e.mock.On("PWLoopNew", props)}
520+}
521+
522+func (_c *MockVideoStreamAPI_PWLoopNew_Call) Run(run func(props unsafe.Pointer)) *MockVideoStreamAPI_PWLoopNew_Call {
523+ _c.Call.Run(func(args mock.Arguments) {
524+ var arg0 unsafe.Pointer
525+ if args[0] != nil {
526+ arg0 = args[0].(unsafe.Pointer)
527+ }
528+ run(
529+ arg0,
530+ )
531+ })
532+ return _c
533+}
534+
535+func (_c *MockVideoStreamAPI_PWLoopNew_Call) Return(v unsafe.Pointer) *MockVideoStreamAPI_PWLoopNew_Call {
536+ _c.Call.Return(v)
537+ return _c
538+}
539+
540+func (_c *MockVideoStreamAPI_PWLoopNew_Call) RunAndReturn(run func(props unsafe.Pointer) unsafe.Pointer) *MockVideoStreamAPI_PWLoopNew_Call {
541+ _c.Call.Return(run)
542+ return _c
543+}
544+
545+// PWPropertiesNewString provides a mock function for the type MockVideoStreamAPI
546+func (_mock *MockVideoStreamAPI) PWPropertiesNewString(args *byte) unsafe.Pointer {
547+ ret := _mock.Called(args)
548+
549+ if len(ret) == 0 {
550+ panic("no return value specified for PWPropertiesNewString")
551+ }
552+
553+ var r0 unsafe.Pointer
554+ if returnFunc, ok := ret.Get(0).(func(*byte) unsafe.Pointer); ok {
555+ r0 = returnFunc(args)
556+ } else {
557+ r0 = ret.Get(0).(unsafe.Pointer)
558+ }
559+ return r0
560+}
561+
562+// MockVideoStreamAPI_PWPropertiesNewString_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'PWPropertiesNewString'
563+type MockVideoStreamAPI_PWPropertiesNewString_Call struct {
564+ *mock.Call
565+}
566+
567+// PWPropertiesNewString is a helper method to define mock.On call
568+// - args *byte
569+func (_e *MockVideoStreamAPI_Expecter) PWPropertiesNewString(args any) *MockVideoStreamAPI_PWPropertiesNewString_Call {
570+ return &MockVideoStreamAPI_PWPropertiesNewString_Call{Call: _e.mock.On("PWPropertiesNewString", args)}
571+}
572+
573+func (_c *MockVideoStreamAPI_PWPropertiesNewString_Call) Run(run func(args *byte)) *MockVideoStreamAPI_PWPropertiesNewString_Call {
574+ _c.Call.Run(func(args mock.Arguments) {
575+ var arg0 *byte
576+ if args[0] != nil {
577+ arg0 = args[0].(*byte)
578+ }
579+ run(
580+ arg0,
581+ )
582+ })
583+ return _c
584+}
585+
586+func (_c *MockVideoStreamAPI_PWPropertiesNewString_Call) Return(v unsafe.Pointer) *MockVideoStreamAPI_PWPropertiesNewString_Call {
587+ _c.Call.Return(v)
588+ return _c
589+}
590+
591+func (_c *MockVideoStreamAPI_PWPropertiesNewString_Call) RunAndReturn(run func(args *byte) unsafe.Pointer) *MockVideoStreamAPI_PWPropertiesNewString_Call {
592+ _c.Call.Return(run)
593+ return _c
594+}
595+
596+// PWStreamAddListener provides a mock function for the type MockVideoStreamAPI
597+func (_mock *MockVideoStreamAPI) PWStreamAddListener(stream unsafe.Pointer, listener unsafe.Pointer, events unsafe.Pointer, data unsafe.Pointer) int32 {
598+ ret := _mock.Called(stream, listener, events, data)
599+
600+ if len(ret) == 0 {
601+ panic("no return value specified for PWStreamAddListener")
602+ }
603+
604+ var r0 int32
605+ if returnFunc, ok := ret.Get(0).(func(unsafe.Pointer, unsafe.Pointer, unsafe.Pointer, unsafe.Pointer) int32); ok {
606+ r0 = returnFunc(stream, listener, events, data)
607+ } else {
608+ r0 = ret.Get(0).(int32)
609+ }
610+ return r0
611+}
612+
613+// MockVideoStreamAPI_PWStreamAddListener_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'PWStreamAddListener'
614+type MockVideoStreamAPI_PWStreamAddListener_Call struct {
615+ *mock.Call
616+}
617+
618+// PWStreamAddListener is a helper method to define mock.On call
619+// - stream unsafe.Pointer
620+// - listener unsafe.Pointer
621+// - events unsafe.Pointer
622+// - data unsafe.Pointer
623+func (_e *MockVideoStreamAPI_Expecter) PWStreamAddListener(stream any, listener any, events any, data any) *MockVideoStreamAPI_PWStreamAddListener_Call {
624+ return &MockVideoStreamAPI_PWStreamAddListener_Call{Call: _e.mock.On("PWStreamAddListener", stream, listener, events, data)}
625+}
626+
627+func (_c *MockVideoStreamAPI_PWStreamAddListener_Call) Run(run func(stream unsafe.Pointer, listener unsafe.Pointer, events unsafe.Pointer, data unsafe.Pointer)) *MockVideoStreamAPI_PWStreamAddListener_Call {
628+ _c.Call.Run(func(args mock.Arguments) {
629+ var arg0 unsafe.Pointer
630+ if args[0] != nil {
631+ arg0 = args[0].(unsafe.Pointer)
632+ }
633+ var arg1 unsafe.Pointer
634+ if args[1] != nil {
635+ arg1 = args[1].(unsafe.Pointer)
636+ }
637+ var arg2 unsafe.Pointer
638+ if args[2] != nil {
639+ arg2 = args[2].(unsafe.Pointer)
640+ }
641+ var arg3 unsafe.Pointer
642+ if args[3] != nil {
643+ arg3 = args[3].(unsafe.Pointer)
644+ }
645+ run(
646+ arg0,
647+ arg1,
648+ arg2,
649+ arg3,
650+ )
651+ })
652+ return _c
653+}
654+
655+func (_c *MockVideoStreamAPI_PWStreamAddListener_Call) Return(n int32) *MockVideoStreamAPI_PWStreamAddListener_Call {
656+ _c.Call.Return(n)
657+ return _c
658+}
659+
660+func (_c *MockVideoStreamAPI_PWStreamAddListener_Call) RunAndReturn(run func(stream unsafe.Pointer, listener unsafe.Pointer, events unsafe.Pointer, data unsafe.Pointer) int32) *MockVideoStreamAPI_PWStreamAddListener_Call {
661+ _c.Call.Return(run)
662+ return _c
663+}
664+
665+// PWStreamConnect provides a mock function for the type MockVideoStreamAPI
666+func (_mock *MockVideoStreamAPI) PWStreamConnect(stream unsafe.Pointer, direction int32, id uint32, flags uint32, ports unsafe.Pointer, n_ports uint32) int32 {
667+ ret := _mock.Called(stream, direction, id, flags, ports, n_ports)
668+
669+ if len(ret) == 0 {
670+ panic("no return value specified for PWStreamConnect")
671+ }
672+
673+ var r0 int32
674+ if returnFunc, ok := ret.Get(0).(func(unsafe.Pointer, int32, uint32, uint32, unsafe.Pointer, uint32) int32); ok {
675+ r0 = returnFunc(stream, direction, id, flags, ports, n_ports)
676+ } else {
677+ r0 = ret.Get(0).(int32)
678+ }
679+ return r0
680+}
681+
682+// MockVideoStreamAPI_PWStreamConnect_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'PWStreamConnect'
683+type MockVideoStreamAPI_PWStreamConnect_Call struct {
684+ *mock.Call
685+}
686+
687+// PWStreamConnect is a helper method to define mock.On call
688+// - stream unsafe.Pointer
689+// - direction int32
690+// - id uint32
691+// - flags uint32
692+// - ports unsafe.Pointer
693+// - n_ports uint32
694+func (_e *MockVideoStreamAPI_Expecter) PWStreamConnect(stream any, direction any, id any, flags any, ports any, n_ports any) *MockVideoStreamAPI_PWStreamConnect_Call {
695+ return &MockVideoStreamAPI_PWStreamConnect_Call{Call: _e.mock.On("PWStreamConnect", stream, direction, id, flags, ports, n_ports)}
696+}
697+
698+func (_c *MockVideoStreamAPI_PWStreamConnect_Call) Run(run func(stream unsafe.Pointer, direction int32, id uint32, flags uint32, ports unsafe.Pointer, n_ports uint32)) *MockVideoStreamAPI_PWStreamConnect_Call {
699+ _c.Call.Run(func(args mock.Arguments) {
700+ var arg0 unsafe.Pointer
701+ if args[0] != nil {
702+ arg0 = args[0].(unsafe.Pointer)
703+ }
704+ var arg1 int32
705+ if args[1] != nil {
706+ arg1 = args[1].(int32)
707+ }
708+ var arg2 uint32
709+ if args[2] != nil {
710+ arg2 = args[2].(uint32)
711+ }
712+ var arg3 uint32
713+ if args[3] != nil {
714+ arg3 = args[3].(uint32)
715+ }
716+ var arg4 unsafe.Pointer
717+ if args[4] != nil {
718+ arg4 = args[4].(unsafe.Pointer)
719+ }
720+ var arg5 uint32
721+ if args[5] != nil {
722+ arg5 = args[5].(uint32)
723+ }
724+ run(
725+ arg0,
726+ arg1,
727+ arg2,
728+ arg3,
729+ arg4,
730+ arg5,
731+ )
732+ })
733+ return _c
734+}
735+
736+func (_c *MockVideoStreamAPI_PWStreamConnect_Call) Return(n int32) *MockVideoStreamAPI_PWStreamConnect_Call {
737+ _c.Call.Return(n)
738+ return _c
739+}
740+
741+func (_c *MockVideoStreamAPI_PWStreamConnect_Call) RunAndReturn(run func(stream unsafe.Pointer, direction int32, id uint32, flags uint32, ports unsafe.Pointer, n_ports uint32) int32) *MockVideoStreamAPI_PWStreamConnect_Call {
742+ _c.Call.Return(run)
743+ return _c
744+}
745+
746+// PWStreamDequeueBuffer provides a mock function for the type MockVideoStreamAPI
747+func (_mock *MockVideoStreamAPI) PWStreamDequeueBuffer(stream unsafe.Pointer) unsafe.Pointer {
748+ ret := _mock.Called(stream)
749+
750+ if len(ret) == 0 {
751+ panic("no return value specified for PWStreamDequeueBuffer")
752+ }
753+
754+ var r0 unsafe.Pointer
755+ if returnFunc, ok := ret.Get(0).(func(unsafe.Pointer) unsafe.Pointer); ok {
756+ r0 = returnFunc(stream)
757+ } else {
758+ r0 = ret.Get(0).(unsafe.Pointer)
759+ }
760+ return r0
761+}
762+
763+// MockVideoStreamAPI_PWStreamDequeueBuffer_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'PWStreamDequeueBuffer'
764+type MockVideoStreamAPI_PWStreamDequeueBuffer_Call struct {
765+ *mock.Call
766+}
767+
768+// PWStreamDequeueBuffer is a helper method to define mock.On call
769+// - stream unsafe.Pointer
770+func (_e *MockVideoStreamAPI_Expecter) PWStreamDequeueBuffer(stream any) *MockVideoStreamAPI_PWStreamDequeueBuffer_Call {
771+ return &MockVideoStreamAPI_PWStreamDequeueBuffer_Call{Call: _e.mock.On("PWStreamDequeueBuffer", stream)}
772+}
773+
774+func (_c *MockVideoStreamAPI_PWStreamDequeueBuffer_Call) Run(run func(stream unsafe.Pointer)) *MockVideoStreamAPI_PWStreamDequeueBuffer_Call {
775+ _c.Call.Run(func(args mock.Arguments) {
776+ var arg0 unsafe.Pointer
777+ if args[0] != nil {
778+ arg0 = args[0].(unsafe.Pointer)
779+ }
780+ run(
781+ arg0,
782+ )
783+ })
784+ return _c
785+}
786+
787+func (_c *MockVideoStreamAPI_PWStreamDequeueBuffer_Call) Return(v unsafe.Pointer) *MockVideoStreamAPI_PWStreamDequeueBuffer_Call {
788+ _c.Call.Return(v)
789+ return _c
790+}
791+
792+func (_c *MockVideoStreamAPI_PWStreamDequeueBuffer_Call) RunAndReturn(run func(stream unsafe.Pointer) unsafe.Pointer) *MockVideoStreamAPI_PWStreamDequeueBuffer_Call {
793+ _c.Call.Return(run)
794+ return _c
795+}
796+
797+// PWStreamDestroy provides a mock function for the type MockVideoStreamAPI
798+func (_mock *MockVideoStreamAPI) PWStreamDestroy(stream unsafe.Pointer) {
799+ _mock.Called(stream)
800+ return
801+}
802+
803+// MockVideoStreamAPI_PWStreamDestroy_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'PWStreamDestroy'
804+type MockVideoStreamAPI_PWStreamDestroy_Call struct {
805+ *mock.Call
806+}
807+
808+// PWStreamDestroy is a helper method to define mock.On call
809+// - stream unsafe.Pointer
810+func (_e *MockVideoStreamAPI_Expecter) PWStreamDestroy(stream any) *MockVideoStreamAPI_PWStreamDestroy_Call {
811+ return &MockVideoStreamAPI_PWStreamDestroy_Call{Call: _e.mock.On("PWStreamDestroy", stream)}
812+}
813+
814+func (_c *MockVideoStreamAPI_PWStreamDestroy_Call) Run(run func(stream unsafe.Pointer)) *MockVideoStreamAPI_PWStreamDestroy_Call {
815+ _c.Call.Run(func(args mock.Arguments) {
816+ var arg0 unsafe.Pointer
817+ if args[0] != nil {
818+ arg0 = args[0].(unsafe.Pointer)
819+ }
820+ run(
821+ arg0,
822+ )
823+ })
824+ return _c
825+}
826+
827+func (_c *MockVideoStreamAPI_PWStreamDestroy_Call) Return() *MockVideoStreamAPI_PWStreamDestroy_Call {
828+ _c.Call.Return()
829+ return _c
830+}
831+
832+func (_c *MockVideoStreamAPI_PWStreamDestroy_Call) RunAndReturn(run func(stream unsafe.Pointer)) *MockVideoStreamAPI_PWStreamDestroy_Call {
833+ _c.Run(run)
834+ return _c
835+}
836+
837+// PWStreamDisconnect provides a mock function for the type MockVideoStreamAPI
838+func (_mock *MockVideoStreamAPI) PWStreamDisconnect(stream unsafe.Pointer) int32 {
839+ ret := _mock.Called(stream)
840+
841+ if len(ret) == 0 {
842+ panic("no return value specified for PWStreamDisconnect")
843+ }
844+
845+ var r0 int32
846+ if returnFunc, ok := ret.Get(0).(func(unsafe.Pointer) int32); ok {
847+ r0 = returnFunc(stream)
848+ } else {
849+ r0 = ret.Get(0).(int32)
850+ }
851+ return r0
852+}
853+
854+// MockVideoStreamAPI_PWStreamDisconnect_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'PWStreamDisconnect'
855+type MockVideoStreamAPI_PWStreamDisconnect_Call struct {
856+ *mock.Call
857+}
858+
859+// PWStreamDisconnect is a helper method to define mock.On call
860+// - stream unsafe.Pointer
861+func (_e *MockVideoStreamAPI_Expecter) PWStreamDisconnect(stream any) *MockVideoStreamAPI_PWStreamDisconnect_Call {
862+ return &MockVideoStreamAPI_PWStreamDisconnect_Call{Call: _e.mock.On("PWStreamDisconnect", stream)}
863+}
864+
865+func (_c *MockVideoStreamAPI_PWStreamDisconnect_Call) Run(run func(stream unsafe.Pointer)) *MockVideoStreamAPI_PWStreamDisconnect_Call {
866+ _c.Call.Run(func(args mock.Arguments) {
867+ var arg0 unsafe.Pointer
868+ if args[0] != nil {
869+ arg0 = args[0].(unsafe.Pointer)
870+ }
871+ run(
872+ arg0,
873+ )
874+ })
875+ return _c
876+}
877+
878+func (_c *MockVideoStreamAPI_PWStreamDisconnect_Call) Return(n int32) *MockVideoStreamAPI_PWStreamDisconnect_Call {
879+ _c.Call.Return(n)
880+ return _c
881+}
882+
883+func (_c *MockVideoStreamAPI_PWStreamDisconnect_Call) RunAndReturn(run func(stream unsafe.Pointer) int32) *MockVideoStreamAPI_PWStreamDisconnect_Call {
884+ _c.Call.Return(run)
885+ return _c
886+}
887+
888+// PWStreamGetNodeId provides a mock function for the type MockVideoStreamAPI
889+func (_mock *MockVideoStreamAPI) PWStreamGetNodeId(stream unsafe.Pointer) uint32 {
890+ ret := _mock.Called(stream)
891+
892+ if len(ret) == 0 {
893+ panic("no return value specified for PWStreamGetNodeId")
894+ }
895+
896+ var r0 uint32
897+ if returnFunc, ok := ret.Get(0).(func(unsafe.Pointer) uint32); ok {
898+ r0 = returnFunc(stream)
899+ } else {
900+ r0 = ret.Get(0).(uint32)
901+ }
902+ return r0
903+}
904+
905+// MockVideoStreamAPI_PWStreamGetNodeId_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'PWStreamGetNodeId'
906+type MockVideoStreamAPI_PWStreamGetNodeId_Call struct {
907+ *mock.Call
908+}
909+
910+// PWStreamGetNodeId is a helper method to define mock.On call
911+// - stream unsafe.Pointer
912+func (_e *MockVideoStreamAPI_Expecter) PWStreamGetNodeId(stream any) *MockVideoStreamAPI_PWStreamGetNodeId_Call {
913+ return &MockVideoStreamAPI_PWStreamGetNodeId_Call{Call: _e.mock.On("PWStreamGetNodeId", stream)}
914+}
915+
916+func (_c *MockVideoStreamAPI_PWStreamGetNodeId_Call) Run(run func(stream unsafe.Pointer)) *MockVideoStreamAPI_PWStreamGetNodeId_Call {
917+ _c.Call.Run(func(args mock.Arguments) {
918+ var arg0 unsafe.Pointer
919+ if args[0] != nil {
920+ arg0 = args[0].(unsafe.Pointer)
921+ }
922+ run(
923+ arg0,
924+ )
925+ })
926+ return _c
927+}
928+
929+func (_c *MockVideoStreamAPI_PWStreamGetNodeId_Call) Return(v uint32) *MockVideoStreamAPI_PWStreamGetNodeId_Call {
930+ _c.Call.Return(v)
931+ return _c
932+}
933+
934+func (_c *MockVideoStreamAPI_PWStreamGetNodeId_Call) RunAndReturn(run func(stream unsafe.Pointer) uint32) *MockVideoStreamAPI_PWStreamGetNodeId_Call {
935+ _c.Call.Return(run)
936+ return _c
937+}
938+
939+// PWStreamIsDriving provides a mock function for the type MockVideoStreamAPI
940+func (_mock *MockVideoStreamAPI) PWStreamIsDriving(stream unsafe.Pointer) bool {
941+ ret := _mock.Called(stream)
942+
943+ if len(ret) == 0 {
944+ panic("no return value specified for PWStreamIsDriving")
945+ }
946+
947+ var r0 bool
948+ if returnFunc, ok := ret.Get(0).(func(unsafe.Pointer) bool); ok {
949+ r0 = returnFunc(stream)
950+ } else {
951+ r0 = ret.Get(0).(bool)
952+ }
953+ return r0
954+}
955+
956+// MockVideoStreamAPI_PWStreamIsDriving_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'PWStreamIsDriving'
957+type MockVideoStreamAPI_PWStreamIsDriving_Call struct {
958+ *mock.Call
959+}
960+
961+// PWStreamIsDriving is a helper method to define mock.On call
962+// - stream unsafe.Pointer
963+func (_e *MockVideoStreamAPI_Expecter) PWStreamIsDriving(stream any) *MockVideoStreamAPI_PWStreamIsDriving_Call {
964+ return &MockVideoStreamAPI_PWStreamIsDriving_Call{Call: _e.mock.On("PWStreamIsDriving", stream)}
965+}
966+
967+func (_c *MockVideoStreamAPI_PWStreamIsDriving_Call) Run(run func(stream unsafe.Pointer)) *MockVideoStreamAPI_PWStreamIsDriving_Call {
968+ _c.Call.Run(func(args mock.Arguments) {
969+ var arg0 unsafe.Pointer
970+ if args[0] != nil {
971+ arg0 = args[0].(unsafe.Pointer)
972+ }
973+ run(
974+ arg0,
975+ )
976+ })
977+ return _c
978+}
979+
980+func (_c *MockVideoStreamAPI_PWStreamIsDriving_Call) Return(b bool) *MockVideoStreamAPI_PWStreamIsDriving_Call {
981+ _c.Call.Return(b)
982+ return _c
983+}
984+
985+func (_c *MockVideoStreamAPI_PWStreamIsDriving_Call) RunAndReturn(run func(stream unsafe.Pointer) bool) *MockVideoStreamAPI_PWStreamIsDriving_Call {
986+ _c.Call.Return(run)
987+ return _c
988+}
989+
990+// PWStreamNew provides a mock function for the type MockVideoStreamAPI
991+func (_mock *MockVideoStreamAPI) PWStreamNew(core unsafe.Pointer, name *byte, props unsafe.Pointer) unsafe.Pointer {
992+ ret := _mock.Called(core, name, props)
993+
994+ if len(ret) == 0 {
995+ panic("no return value specified for PWStreamNew")
996+ }
997+
998+ var r0 unsafe.Pointer
999+ if returnFunc, ok := ret.Get(0).(func(unsafe.Pointer, *byte, unsafe.Pointer) unsafe.Pointer); ok {
1000+ r0 = returnFunc(core, name, props)
1001+ } else {
1002+ r0 = ret.Get(0).(unsafe.Pointer)
1003+ }
1004+ return r0
1005+}
1006+
1007+// MockVideoStreamAPI_PWStreamNew_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'PWStreamNew'
1008+type MockVideoStreamAPI_PWStreamNew_Call struct {
1009+ *mock.Call
1010+}
1011+
1012+// PWStreamNew is a helper method to define mock.On call
1013+// - core unsafe.Pointer
1014+// - name *byte
1015+// - props unsafe.Pointer
1016+func (_e *MockVideoStreamAPI_Expecter) PWStreamNew(core any, name any, props any) *MockVideoStreamAPI_PWStreamNew_Call {
1017+ return &MockVideoStreamAPI_PWStreamNew_Call{Call: _e.mock.On("PWStreamNew", core, name, props)}
1018+}
1019+
1020+func (_c *MockVideoStreamAPI_PWStreamNew_Call) Run(run func(core unsafe.Pointer, name *byte, props unsafe.Pointer)) *MockVideoStreamAPI_PWStreamNew_Call {
1021+ _c.Call.Run(func(args mock.Arguments) {
1022+ var arg0 unsafe.Pointer
1023+ if args[0] != nil {
1024+ arg0 = args[0].(unsafe.Pointer)
1025+ }
1026+ var arg1 *byte
1027+ if args[1] != nil {
1028+ arg1 = args[1].(*byte)
1029+ }
1030+ var arg2 unsafe.Pointer
1031+ if args[2] != nil {
1032+ arg2 = args[2].(unsafe.Pointer)
1033+ }
1034+ run(
1035+ arg0,
1036+ arg1,
1037+ arg2,
1038+ )
1039+ })
1040+ return _c
1041+}
1042+
1043+func (_c *MockVideoStreamAPI_PWStreamNew_Call) Return(v unsafe.Pointer) *MockVideoStreamAPI_PWStreamNew_Call {
1044+ _c.Call.Return(v)
1045+ return _c
1046+}
1047+
1048+func (_c *MockVideoStreamAPI_PWStreamNew_Call) RunAndReturn(run func(core unsafe.Pointer, name *byte, props unsafe.Pointer) unsafe.Pointer) *MockVideoStreamAPI_PWStreamNew_Call {
1049+ _c.Call.Return(run)
1050+ return _c
1051+}
1052+
1053+// PWStreamNewSimple provides a mock function for the type MockVideoStreamAPI
1054+func (_mock *MockVideoStreamAPI) PWStreamNewSimple(context unsafe.Pointer, name *byte, props unsafe.Pointer, events unsafe.Pointer, data unsafe.Pointer) unsafe.Pointer {
1055+ ret := _mock.Called(context, name, props, events, data)
1056+
1057+ if len(ret) == 0 {
1058+ panic("no return value specified for PWStreamNewSimple")
1059+ }
1060+
1061+ var r0 unsafe.Pointer
1062+ if returnFunc, ok := ret.Get(0).(func(unsafe.Pointer, *byte, unsafe.Pointer, unsafe.Pointer, unsafe.Pointer) unsafe.Pointer); ok {
1063+ r0 = returnFunc(context, name, props, events, data)
1064+ } else {
1065+ r0 = ret.Get(0).(unsafe.Pointer)
1066+ }
1067+ return r0
1068+}
1069+
1070+// MockVideoStreamAPI_PWStreamNewSimple_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'PWStreamNewSimple'
1071+type MockVideoStreamAPI_PWStreamNewSimple_Call struct {
1072+ *mock.Call
1073+}
1074+
1075+// PWStreamNewSimple is a helper method to define mock.On call
1076+// - context unsafe.Pointer
1077+// - name *byte
1078+// - props unsafe.Pointer
1079+// - events unsafe.Pointer
1080+// - data unsafe.Pointer
1081+func (_e *MockVideoStreamAPI_Expecter) PWStreamNewSimple(context any, name any, props any, events any, data any) *MockVideoStreamAPI_PWStreamNewSimple_Call {
1082+ return &MockVideoStreamAPI_PWStreamNewSimple_Call{Call: _e.mock.On("PWStreamNewSimple", context, name, props, events, data)}
1083+}
1084+
1085+func (_c *MockVideoStreamAPI_PWStreamNewSimple_Call) Run(run func(context unsafe.Pointer, name *byte, props unsafe.Pointer, events unsafe.Pointer, data unsafe.Pointer)) *MockVideoStreamAPI_PWStreamNewSimple_Call {
1086+ _c.Call.Run(func(args mock.Arguments) {
1087+ var arg0 unsafe.Pointer
1088+ if args[0] != nil {
1089+ arg0 = args[0].(unsafe.Pointer)
1090+ }
1091+ var arg1 *byte
1092+ if args[1] != nil {
1093+ arg1 = args[1].(*byte)
1094+ }
1095+ var arg2 unsafe.Pointer
1096+ if args[2] != nil {
1097+ arg2 = args[2].(unsafe.Pointer)
1098+ }
1099+ var arg3 unsafe.Pointer
1100+ if args[3] != nil {
1101+ arg3 = args[3].(unsafe.Pointer)
1102+ }
1103+ var arg4 unsafe.Pointer
1104+ if args[4] != nil {
1105+ arg4 = args[4].(unsafe.Pointer)
1106+ }
1107+ run(
1108+ arg0,
1109+ arg1,
1110+ arg2,
1111+ arg3,
1112+ arg4,
1113+ )
1114+ })
1115+ return _c
1116+}
1117+
1118+func (_c *MockVideoStreamAPI_PWStreamNewSimple_Call) Return(v unsafe.Pointer) *MockVideoStreamAPI_PWStreamNewSimple_Call {
1119+ _c.Call.Return(v)
1120+ return _c
1121+}
1122+
1123+func (_c *MockVideoStreamAPI_PWStreamNewSimple_Call) RunAndReturn(run func(context unsafe.Pointer, name *byte, props unsafe.Pointer, events unsafe.Pointer, data unsafe.Pointer) unsafe.Pointer) *MockVideoStreamAPI_PWStreamNewSimple_Call {
1124+ _c.Call.Return(run)
1125+ return _c
1126+}
1127+
1128+// PWStreamQueueBuffer provides a mock function for the type MockVideoStreamAPI
1129+func (_mock *MockVideoStreamAPI) PWStreamQueueBuffer(stream unsafe.Pointer, buffer unsafe.Pointer) int32 {
1130+ ret := _mock.Called(stream, buffer)
1131+
1132+ if len(ret) == 0 {
1133+ panic("no return value specified for PWStreamQueueBuffer")
1134+ }
1135+
1136+ var r0 int32
1137+ if returnFunc, ok := ret.Get(0).(func(unsafe.Pointer, unsafe.Pointer) int32); ok {
1138+ r0 = returnFunc(stream, buffer)
1139+ } else {
1140+ r0 = ret.Get(0).(int32)
1141+ }
1142+ return r0
1143+}
1144+
1145+// MockVideoStreamAPI_PWStreamQueueBuffer_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'PWStreamQueueBuffer'
1146+type MockVideoStreamAPI_PWStreamQueueBuffer_Call struct {
1147+ *mock.Call
1148+}
1149+
1150+// PWStreamQueueBuffer is a helper method to define mock.On call
1151+// - stream unsafe.Pointer
1152+// - buffer unsafe.Pointer
1153+func (_e *MockVideoStreamAPI_Expecter) PWStreamQueueBuffer(stream any, buffer any) *MockVideoStreamAPI_PWStreamQueueBuffer_Call {
1154+ return &MockVideoStreamAPI_PWStreamQueueBuffer_Call{Call: _e.mock.On("PWStreamQueueBuffer", stream, buffer)}
1155+}
1156+
1157+func (_c *MockVideoStreamAPI_PWStreamQueueBuffer_Call) Run(run func(stream unsafe.Pointer, buffer unsafe.Pointer)) *MockVideoStreamAPI_PWStreamQueueBuffer_Call {
1158+ _c.Call.Run(func(args mock.Arguments) {
1159+ var arg0 unsafe.Pointer
1160+ if args[0] != nil {
1161+ arg0 = args[0].(unsafe.Pointer)
1162+ }
1163+ var arg1 unsafe.Pointer
1164+ if args[1] != nil {
1165+ arg1 = args[1].(unsafe.Pointer)
1166+ }
1167+ run(
1168+ arg0,
1169+ arg1,
1170+ )
1171+ })
1172+ return _c
1173+}
1174+
1175+func (_c *MockVideoStreamAPI_PWStreamQueueBuffer_Call) Return(n int32) *MockVideoStreamAPI_PWStreamQueueBuffer_Call {
1176+ _c.Call.Return(n)
1177+ return _c
1178+}
1179+
1180+func (_c *MockVideoStreamAPI_PWStreamQueueBuffer_Call) RunAndReturn(run func(stream unsafe.Pointer, buffer unsafe.Pointer) int32) *MockVideoStreamAPI_PWStreamQueueBuffer_Call {
1181+ _c.Call.Return(run)
1182+ return _c
1183+}
1184+
1185+// PWStreamReturnBuffer provides a mock function for the type MockVideoStreamAPI
1186+func (_mock *MockVideoStreamAPI) PWStreamReturnBuffer(stream unsafe.Pointer, buffer unsafe.Pointer) int32 {
1187+ ret := _mock.Called(stream, buffer)
1188+
1189+ if len(ret) == 0 {
1190+ panic("no return value specified for PWStreamReturnBuffer")
1191+ }
1192+
1193+ var r0 int32
1194+ if returnFunc, ok := ret.Get(0).(func(unsafe.Pointer, unsafe.Pointer) int32); ok {
1195+ r0 = returnFunc(stream, buffer)
1196+ } else {
1197+ r0 = ret.Get(0).(int32)
1198+ }
1199+ return r0
1200+}
1201+
1202+// MockVideoStreamAPI_PWStreamReturnBuffer_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'PWStreamReturnBuffer'
1203+type MockVideoStreamAPI_PWStreamReturnBuffer_Call struct {
1204+ *mock.Call
1205+}
1206+
1207+// PWStreamReturnBuffer is a helper method to define mock.On call
1208+// - stream unsafe.Pointer
1209+// - buffer unsafe.Pointer
1210+func (_e *MockVideoStreamAPI_Expecter) PWStreamReturnBuffer(stream any, buffer any) *MockVideoStreamAPI_PWStreamReturnBuffer_Call {
1211+ return &MockVideoStreamAPI_PWStreamReturnBuffer_Call{Call: _e.mock.On("PWStreamReturnBuffer", stream, buffer)}
1212+}
1213+
1214+func (_c *MockVideoStreamAPI_PWStreamReturnBuffer_Call) Run(run func(stream unsafe.Pointer, buffer unsafe.Pointer)) *MockVideoStreamAPI_PWStreamReturnBuffer_Call {
1215+ _c.Call.Run(func(args mock.Arguments) {
1216+ var arg0 unsafe.Pointer
1217+ if args[0] != nil {
1218+ arg0 = args[0].(unsafe.Pointer)
1219+ }
1220+ var arg1 unsafe.Pointer
1221+ if args[1] != nil {
1222+ arg1 = args[1].(unsafe.Pointer)
1223+ }
1224+ run(
1225+ arg0,
1226+ arg1,
1227+ )
1228+ })
1229+ return _c
1230+}
1231+
1232+func (_c *MockVideoStreamAPI_PWStreamReturnBuffer_Call) Return(n int32) *MockVideoStreamAPI_PWStreamReturnBuffer_Call {
1233+ _c.Call.Return(n)
1234+ return _c
1235+}
1236+
1237+func (_c *MockVideoStreamAPI_PWStreamReturnBuffer_Call) RunAndReturn(run func(stream unsafe.Pointer, buffer unsafe.Pointer) int32) *MockVideoStreamAPI_PWStreamReturnBuffer_Call {
1238+ _c.Call.Return(run)
1239+ return _c
1240+}
1241+
1242+// PWStreamSetActive provides a mock function for the type MockVideoStreamAPI
1243+func (_mock *MockVideoStreamAPI) PWStreamSetActive(stream unsafe.Pointer, active bool) int32 {
1244+ ret := _mock.Called(stream, active)
1245+
1246+ if len(ret) == 0 {
1247+ panic("no return value specified for PWStreamSetActive")
1248+ }
1249+
1250+ var r0 int32
1251+ if returnFunc, ok := ret.Get(0).(func(unsafe.Pointer, bool) int32); ok {
1252+ r0 = returnFunc(stream, active)
1253+ } else {
1254+ r0 = ret.Get(0).(int32)
1255+ }
1256+ return r0
1257+}
1258+
1259+// MockVideoStreamAPI_PWStreamSetActive_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'PWStreamSetActive'
1260+type MockVideoStreamAPI_PWStreamSetActive_Call struct {
1261+ *mock.Call
1262+}
1263+
1264+// PWStreamSetActive is a helper method to define mock.On call
1265+// - stream unsafe.Pointer
1266+// - active bool
1267+func (_e *MockVideoStreamAPI_Expecter) PWStreamSetActive(stream any, active any) *MockVideoStreamAPI_PWStreamSetActive_Call {
1268+ return &MockVideoStreamAPI_PWStreamSetActive_Call{Call: _e.mock.On("PWStreamSetActive", stream, active)}
1269+}
1270+
1271+func (_c *MockVideoStreamAPI_PWStreamSetActive_Call) Run(run func(stream unsafe.Pointer, active bool)) *MockVideoStreamAPI_PWStreamSetActive_Call {
1272+ _c.Call.Run(func(args mock.Arguments) {
1273+ var arg0 unsafe.Pointer
1274+ if args[0] != nil {
1275+ arg0 = args[0].(unsafe.Pointer)
1276+ }
1277+ var arg1 bool
1278+ if args[1] != nil {
1279+ arg1 = args[1].(bool)
1280+ }
1281+ run(
1282+ arg0,
1283+ arg1,
1284+ )
1285+ })
1286+ return _c
1287+}
1288+
1289+func (_c *MockVideoStreamAPI_PWStreamSetActive_Call) Return(n int32) *MockVideoStreamAPI_PWStreamSetActive_Call {
1290+ _c.Call.Return(n)
1291+ return _c
1292+}
1293+
1294+func (_c *MockVideoStreamAPI_PWStreamSetActive_Call) RunAndReturn(run func(stream unsafe.Pointer, active bool) int32) *MockVideoStreamAPI_PWStreamSetActive_Call {
1295+ _c.Call.Return(run)
1296+ return _c
1297+}
1298+
1299+// PWStreamTriggerProcess provides a mock function for the type MockVideoStreamAPI
1300+func (_mock *MockVideoStreamAPI) PWStreamTriggerProcess(stream unsafe.Pointer) int32 {
1301+ ret := _mock.Called(stream)
1302+
1303+ if len(ret) == 0 {
1304+ panic("no return value specified for PWStreamTriggerProcess")
1305+ }
1306+
1307+ var r0 int32
1308+ if returnFunc, ok := ret.Get(0).(func(unsafe.Pointer) int32); ok {
1309+ r0 = returnFunc(stream)
1310+ } else {
1311+ r0 = ret.Get(0).(int32)
1312+ }
1313+ return r0
1314+}
1315+
1316+// MockVideoStreamAPI_PWStreamTriggerProcess_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'PWStreamTriggerProcess'
1317+type MockVideoStreamAPI_PWStreamTriggerProcess_Call struct {
1318+ *mock.Call
1319+}
1320+
1321+// PWStreamTriggerProcess is a helper method to define mock.On call
1322+// - stream unsafe.Pointer
1323+func (_e *MockVideoStreamAPI_Expecter) PWStreamTriggerProcess(stream any) *MockVideoStreamAPI_PWStreamTriggerProcess_Call {
1324+ return &MockVideoStreamAPI_PWStreamTriggerProcess_Call{Call: _e.mock.On("PWStreamTriggerProcess", stream)}
1325+}
1326+
1327+func (_c *MockVideoStreamAPI_PWStreamTriggerProcess_Call) Run(run func(stream unsafe.Pointer)) *MockVideoStreamAPI_PWStreamTriggerProcess_Call {
1328+ _c.Call.Run(func(args mock.Arguments) {
1329+ var arg0 unsafe.Pointer
1330+ if args[0] != nil {
1331+ arg0 = args[0].(unsafe.Pointer)
1332+ }
1333+ run(
1334+ arg0,
1335+ )
1336+ })
1337+ return _c
1338+}
1339+
1340+func (_c *MockVideoStreamAPI_PWStreamTriggerProcess_Call) Return(n int32) *MockVideoStreamAPI_PWStreamTriggerProcess_Call {
1341+ _c.Call.Return(n)
1342+ return _c
1343+}
1344+
1345+func (_c *MockVideoStreamAPI_PWStreamTriggerProcess_Call) RunAndReturn(run func(stream unsafe.Pointer) int32) *MockVideoStreamAPI_PWStreamTriggerProcess_Call {
1346+ _c.Call.Return(run)
1347+ return _c
1348+}
1349+
1350+// PWStreamUpdateParams provides a mock function for the type MockVideoStreamAPI
1351+func (_mock *MockVideoStreamAPI) PWStreamUpdateParams(stream unsafe.Pointer, params unsafe.Pointer, n_params uint32) int32 {
1352+ ret := _mock.Called(stream, params, n_params)
1353+
1354+ if len(ret) == 0 {
1355+ panic("no return value specified for PWStreamUpdateParams")
1356+ }
1357+
1358+ var r0 int32
1359+ if returnFunc, ok := ret.Get(0).(func(unsafe.Pointer, unsafe.Pointer, uint32) int32); ok {
1360+ r0 = returnFunc(stream, params, n_params)
1361+ } else {
1362+ r0 = ret.Get(0).(int32)
1363+ }
1364+ return r0
1365+}
1366+
1367+// MockVideoStreamAPI_PWStreamUpdateParams_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'PWStreamUpdateParams'
1368+type MockVideoStreamAPI_PWStreamUpdateParams_Call struct {
1369+ *mock.Call
1370+}
1371+
1372+// PWStreamUpdateParams is a helper method to define mock.On call
1373+// - stream unsafe.Pointer
1374+// - params unsafe.Pointer
1375+// - n_params uint32
1376+func (_e *MockVideoStreamAPI_Expecter) PWStreamUpdateParams(stream any, params any, n_params any) *MockVideoStreamAPI_PWStreamUpdateParams_Call {
1377+ return &MockVideoStreamAPI_PWStreamUpdateParams_Call{Call: _e.mock.On("PWStreamUpdateParams", stream, params, n_params)}
1378+}
1379+
1380+func (_c *MockVideoStreamAPI_PWStreamUpdateParams_Call) Run(run func(stream unsafe.Pointer, params unsafe.Pointer, n_params uint32)) *MockVideoStreamAPI_PWStreamUpdateParams_Call {
1381+ _c.Call.Run(func(args mock.Arguments) {
1382+ var arg0 unsafe.Pointer
1383+ if args[0] != nil {
1384+ arg0 = args[0].(unsafe.Pointer)
1385+ }
1386+ var arg1 unsafe.Pointer
1387+ if args[1] != nil {
1388+ arg1 = args[1].(unsafe.Pointer)
1389+ }
1390+ var arg2 uint32
1391+ if args[2] != nil {
1392+ arg2 = args[2].(uint32)
1393+ }
1394+ run(
1395+ arg0,
1396+ arg1,
1397+ arg2,
1398+ )
1399+ })
1400+ return _c
1401+}
1402+
1403+func (_c *MockVideoStreamAPI_PWStreamUpdateParams_Call) Return(n int32) *MockVideoStreamAPI_PWStreamUpdateParams_Call {
1404+ _c.Call.Return(n)
1405+ return _c
1406+}
1407+
1408+func (_c *MockVideoStreamAPI_PWStreamUpdateParams_Call) RunAndReturn(run func(stream unsafe.Pointer, params unsafe.Pointer, n_params uint32) int32) *MockVideoStreamAPI_PWStreamUpdateParams_Call {
1409+ _c.Call.Return(run)
1410+ return _c
1411+}
@@ -0,0 +1,1411 @@
1+// Code generated by mockery; DO NOT EDIT.
2+// github.com/vektra/mockery
3+// template: testify
4+
5+package mocks
6+
7+import (
8+ "unsafe"
9+
10+ mock "github.com/stretchr/testify/mock"
11+)
12+
13+// NewMockVideoStreamAPI creates a new instance of MockVideoStreamAPI. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
14+// The first argument is typically a *testing.T value.
15+func NewMockVideoStreamAPI(t interface {
16+ mock.TestingT
17+ Cleanup(func())
18+}) *MockVideoStreamAPI {
19+ if helper, ok := t.(interface{ Helper() }); ok {
20+ helper.Helper()
21+ }
22+
23+ mock := &MockVideoStreamAPI{}
24+ mock.Mock.Test(t)
25+
26+ t.Cleanup(func() {
27+ if helper, ok := t.(interface{ Helper() }); ok {
28+ helper.Helper()
29+ }
30+ mock.AssertExpectations(t)
31+ })
32+
33+ return mock
34+}
35+
36+// MockVideoStreamAPI is an autogenerated mock type for the VideoStreamAPI type
37+type MockVideoStreamAPI struct {
38+ mock.Mock
39+}
40+
41+type MockVideoStreamAPI_Expecter struct {
42+ mock *mock.Mock
43+}
44+
45+func (_m *MockVideoStreamAPI) EXPECT() *MockVideoStreamAPI_Expecter {
46+ return &MockVideoStreamAPI_Expecter{mock: &_m.Mock}
47+}
48+
49+// PWContextConnect provides a mock function for the type MockVideoStreamAPI
50+func (_mock *MockVideoStreamAPI) PWContextConnect(context unsafe.Pointer, props unsafe.Pointer, user_data_size uintptr) unsafe.Pointer {
51+ ret := _mock.Called(context, props, user_data_size)
52+
53+ if len(ret) == 0 {
54+ panic("no return value specified for PWContextConnect")
55+ }
56+
57+ var r0 unsafe.Pointer
58+ if returnFunc, ok := ret.Get(0).(func(unsafe.Pointer, unsafe.Pointer, uintptr) unsafe.Pointer); ok {
59+ r0 = returnFunc(context, props, user_data_size)
60+ } else {
61+ r0 = ret.Get(0).(unsafe.Pointer)
62+ }
63+ return r0
64+}
65+
66+// MockVideoStreamAPI_PWContextConnect_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'PWContextConnect'
67+type MockVideoStreamAPI_PWContextConnect_Call struct {
68+ *mock.Call
69+}
70+
71+// PWContextConnect is a helper method to define mock.On call
72+// - context unsafe.Pointer
73+// - props unsafe.Pointer
74+// - user_data_size uintptr
75+func (_e *MockVideoStreamAPI_Expecter) PWContextConnect(context any, props any, user_data_size any) *MockVideoStreamAPI_PWContextConnect_Call {
76+ return &MockVideoStreamAPI_PWContextConnect_Call{Call: _e.mock.On("PWContextConnect", context, props, user_data_size)}
77+}
78+
79+func (_c *MockVideoStreamAPI_PWContextConnect_Call) Run(run func(context unsafe.Pointer, props unsafe.Pointer, user_data_size uintptr)) *MockVideoStreamAPI_PWContextConnect_Call {
80+ _c.Call.Run(func(args mock.Arguments) {
81+ var arg0 unsafe.Pointer
82+ if args[0] != nil {
83+ arg0 = args[0].(unsafe.Pointer)
84+ }
85+ var arg1 unsafe.Pointer
86+ if args[1] != nil {
87+ arg1 = args[1].(unsafe.Pointer)
88+ }
89+ var arg2 uintptr
90+ if args[2] != nil {
91+ arg2 = args[2].(uintptr)
92+ }
93+ run(
94+ arg0,
95+ arg1,
96+ arg2,
97+ )
98+ })
99+ return _c
100+}
101+
102+func (_c *MockVideoStreamAPI_PWContextConnect_Call) Return(v unsafe.Pointer) *MockVideoStreamAPI_PWContextConnect_Call {
103+ _c.Call.Return(v)
104+ return _c
105+}
106+
107+func (_c *MockVideoStreamAPI_PWContextConnect_Call) RunAndReturn(run func(context unsafe.Pointer, props unsafe.Pointer, user_data_size uintptr) unsafe.Pointer) *MockVideoStreamAPI_PWContextConnect_Call {
108+ _c.Call.Return(run)
109+ return _c
110+}
111+
112+// PWContextDestroy provides a mock function for the type MockVideoStreamAPI
113+func (_mock *MockVideoStreamAPI) PWContextDestroy(context unsafe.Pointer) {
114+ _mock.Called(context)
115+ return
116+}
117+
118+// MockVideoStreamAPI_PWContextDestroy_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'PWContextDestroy'
119+type MockVideoStreamAPI_PWContextDestroy_Call struct {
120+ *mock.Call
121+}
122+
123+// PWContextDestroy is a helper method to define mock.On call
124+// - context unsafe.Pointer
125+func (_e *MockVideoStreamAPI_Expecter) PWContextDestroy(context any) *MockVideoStreamAPI_PWContextDestroy_Call {
126+ return &MockVideoStreamAPI_PWContextDestroy_Call{Call: _e.mock.On("PWContextDestroy", context)}
127+}
128+
129+func (_c *MockVideoStreamAPI_PWContextDestroy_Call) Run(run func(context unsafe.Pointer)) *MockVideoStreamAPI_PWContextDestroy_Call {
130+ _c.Call.Run(func(args mock.Arguments) {
131+ var arg0 unsafe.Pointer
132+ if args[0] != nil {
133+ arg0 = args[0].(unsafe.Pointer)
134+ }
135+ run(
136+ arg0,
137+ )
138+ })
139+ return _c
140+}
141+
142+func (_c *MockVideoStreamAPI_PWContextDestroy_Call) Return() *MockVideoStreamAPI_PWContextDestroy_Call {
143+ _c.Call.Return()
144+ return _c
145+}
146+
147+func (_c *MockVideoStreamAPI_PWContextDestroy_Call) RunAndReturn(run func(context unsafe.Pointer)) *MockVideoStreamAPI_PWContextDestroy_Call {
148+ _c.Run(run)
149+ return _c
150+}
151+
152+// PWContextNew provides a mock function for the type MockVideoStreamAPI
153+func (_mock *MockVideoStreamAPI) PWContextNew(loop unsafe.Pointer, props unsafe.Pointer, user_data_size uintptr) unsafe.Pointer {
154+ ret := _mock.Called(loop, props, user_data_size)
155+
156+ if len(ret) == 0 {
157+ panic("no return value specified for PWContextNew")
158+ }
159+
160+ var r0 unsafe.Pointer
161+ if returnFunc, ok := ret.Get(0).(func(unsafe.Pointer, unsafe.Pointer, uintptr) unsafe.Pointer); ok {
162+ r0 = returnFunc(loop, props, user_data_size)
163+ } else {
164+ r0 = ret.Get(0).(unsafe.Pointer)
165+ }
166+ return r0
167+}
168+
169+// MockVideoStreamAPI_PWContextNew_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'PWContextNew'
170+type MockVideoStreamAPI_PWContextNew_Call struct {
171+ *mock.Call
172+}
173+
174+// PWContextNew is a helper method to define mock.On call
175+// - loop unsafe.Pointer
176+// - props unsafe.Pointer
177+// - user_data_size uintptr
178+func (_e *MockVideoStreamAPI_Expecter) PWContextNew(loop any, props any, user_data_size any) *MockVideoStreamAPI_PWContextNew_Call {
179+ return &MockVideoStreamAPI_PWContextNew_Call{Call: _e.mock.On("PWContextNew", loop, props, user_data_size)}
180+}
181+
182+func (_c *MockVideoStreamAPI_PWContextNew_Call) Run(run func(loop unsafe.Pointer, props unsafe.Pointer, user_data_size uintptr)) *MockVideoStreamAPI_PWContextNew_Call {
183+ _c.Call.Run(func(args mock.Arguments) {
184+ var arg0 unsafe.Pointer
185+ if args[0] != nil {
186+ arg0 = args[0].(unsafe.Pointer)
187+ }
188+ var arg1 unsafe.Pointer
189+ if args[1] != nil {
190+ arg1 = args[1].(unsafe.Pointer)
191+ }
192+ var arg2 uintptr
193+ if args[2] != nil {
194+ arg2 = args[2].(uintptr)
195+ }
196+ run(
197+ arg0,
198+ arg1,
199+ arg2,
200+ )
201+ })
202+ return _c
203+}
204+
205+func (_c *MockVideoStreamAPI_PWContextNew_Call) Return(v unsafe.Pointer) *MockVideoStreamAPI_PWContextNew_Call {
206+ _c.Call.Return(v)
207+ return _c
208+}
209+
210+func (_c *MockVideoStreamAPI_PWContextNew_Call) RunAndReturn(run func(loop unsafe.Pointer, props unsafe.Pointer, user_data_size uintptr) unsafe.Pointer) *MockVideoStreamAPI_PWContextNew_Call {
211+ _c.Call.Return(run)
212+ return _c
213+}
214+
215+// PWCoreDisconnect provides a mock function for the type MockVideoStreamAPI
216+func (_mock *MockVideoStreamAPI) PWCoreDisconnect(core unsafe.Pointer) int32 {
217+ ret := _mock.Called(core)
218+
219+ if len(ret) == 0 {
220+ panic("no return value specified for PWCoreDisconnect")
221+ }
222+
223+ var r0 int32
224+ if returnFunc, ok := ret.Get(0).(func(unsafe.Pointer) int32); ok {
225+ r0 = returnFunc(core)
226+ } else {
227+ r0 = ret.Get(0).(int32)
228+ }
229+ return r0
230+}
231+
232+// MockVideoStreamAPI_PWCoreDisconnect_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'PWCoreDisconnect'
233+type MockVideoStreamAPI_PWCoreDisconnect_Call struct {
234+ *mock.Call
235+}
236+
237+// PWCoreDisconnect is a helper method to define mock.On call
238+// - core unsafe.Pointer
239+func (_e *MockVideoStreamAPI_Expecter) PWCoreDisconnect(core any) *MockVideoStreamAPI_PWCoreDisconnect_Call {
240+ return &MockVideoStreamAPI_PWCoreDisconnect_Call{Call: _e.mock.On("PWCoreDisconnect", core)}
241+}
242+
243+func (_c *MockVideoStreamAPI_PWCoreDisconnect_Call) Run(run func(core unsafe.Pointer)) *MockVideoStreamAPI_PWCoreDisconnect_Call {
244+ _c.Call.Run(func(args mock.Arguments) {
245+ var arg0 unsafe.Pointer
246+ if args[0] != nil {
247+ arg0 = args[0].(unsafe.Pointer)
248+ }
249+ run(
250+ arg0,
251+ )
252+ })
253+ return _c
254+}
255+
256+func (_c *MockVideoStreamAPI_PWCoreDisconnect_Call) Return(n int32) *MockVideoStreamAPI_PWCoreDisconnect_Call {
257+ _c.Call.Return(n)
258+ return _c
259+}
260+
261+func (_c *MockVideoStreamAPI_PWCoreDisconnect_Call) RunAndReturn(run func(core unsafe.Pointer) int32) *MockVideoStreamAPI_PWCoreDisconnect_Call {
262+ _c.Call.Return(run)
263+ return _c
264+}
265+
266+// PWLoopDestroy provides a mock function for the type MockVideoStreamAPI
267+func (_mock *MockVideoStreamAPI) PWLoopDestroy(loop unsafe.Pointer) {
268+ _mock.Called(loop)
269+ return
270+}
271+
272+// MockVideoStreamAPI_PWLoopDestroy_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'PWLoopDestroy'
273+type MockVideoStreamAPI_PWLoopDestroy_Call struct {
274+ *mock.Call
275+}
276+
277+// PWLoopDestroy is a helper method to define mock.On call
278+// - loop unsafe.Pointer
279+func (_e *MockVideoStreamAPI_Expecter) PWLoopDestroy(loop any) *MockVideoStreamAPI_PWLoopDestroy_Call {
280+ return &MockVideoStreamAPI_PWLoopDestroy_Call{Call: _e.mock.On("PWLoopDestroy", loop)}
281+}
282+
283+func (_c *MockVideoStreamAPI_PWLoopDestroy_Call) Run(run func(loop unsafe.Pointer)) *MockVideoStreamAPI_PWLoopDestroy_Call {
284+ _c.Call.Run(func(args mock.Arguments) {
285+ var arg0 unsafe.Pointer
286+ if args[0] != nil {
287+ arg0 = args[0].(unsafe.Pointer)
288+ }
289+ run(
290+ arg0,
291+ )
292+ })
293+ return _c
294+}
295+
296+func (_c *MockVideoStreamAPI_PWLoopDestroy_Call) Return() *MockVideoStreamAPI_PWLoopDestroy_Call {
297+ _c.Call.Return()
298+ return _c
299+}
300+
301+func (_c *MockVideoStreamAPI_PWLoopDestroy_Call) RunAndReturn(run func(loop unsafe.Pointer)) *MockVideoStreamAPI_PWLoopDestroy_Call {
302+ _c.Run(run)
303+ return _c
304+}
305+
306+// PWLoopEnter provides a mock function for the type MockVideoStreamAPI
307+func (_mock *MockVideoStreamAPI) PWLoopEnter(loop unsafe.Pointer) {
308+ _mock.Called(loop)
309+ return
310+}
311+
312+// MockVideoStreamAPI_PWLoopEnter_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'PWLoopEnter'
313+type MockVideoStreamAPI_PWLoopEnter_Call struct {
314+ *mock.Call
315+}
316+
317+// PWLoopEnter is a helper method to define mock.On call
318+// - loop unsafe.Pointer
319+func (_e *MockVideoStreamAPI_Expecter) PWLoopEnter(loop any) *MockVideoStreamAPI_PWLoopEnter_Call {
320+ return &MockVideoStreamAPI_PWLoopEnter_Call{Call: _e.mock.On("PWLoopEnter", loop)}
321+}
322+
323+func (_c *MockVideoStreamAPI_PWLoopEnter_Call) Run(run func(loop unsafe.Pointer)) *MockVideoStreamAPI_PWLoopEnter_Call {
324+ _c.Call.Run(func(args mock.Arguments) {
325+ var arg0 unsafe.Pointer
326+ if args[0] != nil {
327+ arg0 = args[0].(unsafe.Pointer)
328+ }
329+ run(
330+ arg0,
331+ )
332+ })
333+ return _c
334+}
335+
336+func (_c *MockVideoStreamAPI_PWLoopEnter_Call) Return() *MockVideoStreamAPI_PWLoopEnter_Call {
337+ _c.Call.Return()
338+ return _c
339+}
340+
341+func (_c *MockVideoStreamAPI_PWLoopEnter_Call) RunAndReturn(run func(loop unsafe.Pointer)) *MockVideoStreamAPI_PWLoopEnter_Call {
342+ _c.Run(run)
343+ return _c
344+}
345+
346+// PWLoopGetFd provides a mock function for the type MockVideoStreamAPI
347+func (_mock *MockVideoStreamAPI) PWLoopGetFd(loop unsafe.Pointer) int32 {
348+ ret := _mock.Called(loop)
349+
350+ if len(ret) == 0 {
351+ panic("no return value specified for PWLoopGetFd")
352+ }
353+
354+ var r0 int32
355+ if returnFunc, ok := ret.Get(0).(func(unsafe.Pointer) int32); ok {
356+ r0 = returnFunc(loop)
357+ } else {
358+ r0 = ret.Get(0).(int32)
359+ }
360+ return r0
361+}
362+
363+// MockVideoStreamAPI_PWLoopGetFd_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'PWLoopGetFd'
364+type MockVideoStreamAPI_PWLoopGetFd_Call struct {
365+ *mock.Call
366+}
367+
368+// PWLoopGetFd is a helper method to define mock.On call
369+// - loop unsafe.Pointer
370+func (_e *MockVideoStreamAPI_Expecter) PWLoopGetFd(loop any) *MockVideoStreamAPI_PWLoopGetFd_Call {
371+ return &MockVideoStreamAPI_PWLoopGetFd_Call{Call: _e.mock.On("PWLoopGetFd", loop)}
372+}
373+
374+func (_c *MockVideoStreamAPI_PWLoopGetFd_Call) Run(run func(loop unsafe.Pointer)) *MockVideoStreamAPI_PWLoopGetFd_Call {
375+ _c.Call.Run(func(args mock.Arguments) {
376+ var arg0 unsafe.Pointer
377+ if args[0] != nil {
378+ arg0 = args[0].(unsafe.Pointer)
379+ }
380+ run(
381+ arg0,
382+ )
383+ })
384+ return _c
385+}
386+
387+func (_c *MockVideoStreamAPI_PWLoopGetFd_Call) Return(n int32) *MockVideoStreamAPI_PWLoopGetFd_Call {
388+ _c.Call.Return(n)
389+ return _c
390+}
391+
392+func (_c *MockVideoStreamAPI_PWLoopGetFd_Call) RunAndReturn(run func(loop unsafe.Pointer) int32) *MockVideoStreamAPI_PWLoopGetFd_Call {
393+ _c.Call.Return(run)
394+ return _c
395+}
396+
397+// PWLoopIterate provides a mock function for the type MockVideoStreamAPI
398+func (_mock *MockVideoStreamAPI) PWLoopIterate(loop unsafe.Pointer, timeout int32) int32 {
399+ ret := _mock.Called(loop, timeout)
400+
401+ if len(ret) == 0 {
402+ panic("no return value specified for PWLoopIterate")
403+ }
404+
405+ var r0 int32
406+ if returnFunc, ok := ret.Get(0).(func(unsafe.Pointer, int32) int32); ok {
407+ r0 = returnFunc(loop, timeout)
408+ } else {
409+ r0 = ret.Get(0).(int32)
410+ }
411+ return r0
412+}
413+
414+// MockVideoStreamAPI_PWLoopIterate_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'PWLoopIterate'
415+type MockVideoStreamAPI_PWLoopIterate_Call struct {
416+ *mock.Call
417+}
418+
419+// PWLoopIterate is a helper method to define mock.On call
420+// - loop unsafe.Pointer
421+// - timeout int32
422+func (_e *MockVideoStreamAPI_Expecter) PWLoopIterate(loop any, timeout any) *MockVideoStreamAPI_PWLoopIterate_Call {
423+ return &MockVideoStreamAPI_PWLoopIterate_Call{Call: _e.mock.On("PWLoopIterate", loop, timeout)}
424+}
425+
426+func (_c *MockVideoStreamAPI_PWLoopIterate_Call) Run(run func(loop unsafe.Pointer, timeout int32)) *MockVideoStreamAPI_PWLoopIterate_Call {
427+ _c.Call.Run(func(args mock.Arguments) {
428+ var arg0 unsafe.Pointer
429+ if args[0] != nil {
430+ arg0 = args[0].(unsafe.Pointer)
431+ }
432+ var arg1 int32
433+ if args[1] != nil {
434+ arg1 = args[1].(int32)
435+ }
436+ run(
437+ arg0,
438+ arg1,
439+ )
440+ })
441+ return _c
442+}
443+
444+func (_c *MockVideoStreamAPI_PWLoopIterate_Call) Return(n int32) *MockVideoStreamAPI_PWLoopIterate_Call {
445+ _c.Call.Return(n)
446+ return _c
447+}
448+
449+func (_c *MockVideoStreamAPI_PWLoopIterate_Call) RunAndReturn(run func(loop unsafe.Pointer, timeout int32) int32) *MockVideoStreamAPI_PWLoopIterate_Call {
450+ _c.Call.Return(run)
451+ return _c
452+}
453+
454+// PWLoopLeave provides a mock function for the type MockVideoStreamAPI
455+func (_mock *MockVideoStreamAPI) PWLoopLeave(loop unsafe.Pointer) {
456+ _mock.Called(loop)
457+ return
458+}
459+
460+// MockVideoStreamAPI_PWLoopLeave_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'PWLoopLeave'
461+type MockVideoStreamAPI_PWLoopLeave_Call struct {
462+ *mock.Call
463+}
464+
465+// PWLoopLeave is a helper method to define mock.On call
466+// - loop unsafe.Pointer
467+func (_e *MockVideoStreamAPI_Expecter) PWLoopLeave(loop any) *MockVideoStreamAPI_PWLoopLeave_Call {
468+ return &MockVideoStreamAPI_PWLoopLeave_Call{Call: _e.mock.On("PWLoopLeave", loop)}
469+}
470+
471+func (_c *MockVideoStreamAPI_PWLoopLeave_Call) Run(run func(loop unsafe.Pointer)) *MockVideoStreamAPI_PWLoopLeave_Call {
472+ _c.Call.Run(func(args mock.Arguments) {
473+ var arg0 unsafe.Pointer
474+ if args[0] != nil {
475+ arg0 = args[0].(unsafe.Pointer)
476+ }
477+ run(
478+ arg0,
479+ )
480+ })
481+ return _c
482+}
483+
484+func (_c *MockVideoStreamAPI_PWLoopLeave_Call) Return() *MockVideoStreamAPI_PWLoopLeave_Call {
485+ _c.Call.Return()
486+ return _c
487+}
488+
489+func (_c *MockVideoStreamAPI_PWLoopLeave_Call) RunAndReturn(run func(loop unsafe.Pointer)) *MockVideoStreamAPI_PWLoopLeave_Call {
490+ _c.Run(run)
491+ return _c
492+}
493+
494+// PWLoopNew provides a mock function for the type MockVideoStreamAPI
495+func (_mock *MockVideoStreamAPI) PWLoopNew(props unsafe.Pointer) unsafe.Pointer {
496+ ret := _mock.Called(props)
497+
498+ if len(ret) == 0 {
499+ panic("no return value specified for PWLoopNew")
500+ }
501+
502+ var r0 unsafe.Pointer
503+ if returnFunc, ok := ret.Get(0).(func(unsafe.Pointer) unsafe.Pointer); ok {
504+ r0 = returnFunc(props)
505+ } else {
506+ r0 = ret.Get(0).(unsafe.Pointer)
507+ }
508+ return r0
509+}
510+
511+// MockVideoStreamAPI_PWLoopNew_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'PWLoopNew'
512+type MockVideoStreamAPI_PWLoopNew_Call struct {
513+ *mock.Call
514+}
515+
516+// PWLoopNew is a helper method to define mock.On call
517+// - props unsafe.Pointer
518+func (_e *MockVideoStreamAPI_Expecter) PWLoopNew(props any) *MockVideoStreamAPI_PWLoopNew_Call {
519+ return &MockVideoStreamAPI_PWLoopNew_Call{Call: _e.mock.On("PWLoopNew", props)}
520+}
521+
522+func (_c *MockVideoStreamAPI_PWLoopNew_Call) Run(run func(props unsafe.Pointer)) *MockVideoStreamAPI_PWLoopNew_Call {
523+ _c.Call.Run(func(args mock.Arguments) {
524+ var arg0 unsafe.Pointer
525+ if args[0] != nil {
526+ arg0 = args[0].(unsafe.Pointer)
527+ }
528+ run(
529+ arg0,
530+ )
531+ })
532+ return _c
533+}
534+
535+func (_c *MockVideoStreamAPI_PWLoopNew_Call) Return(v unsafe.Pointer) *MockVideoStreamAPI_PWLoopNew_Call {
536+ _c.Call.Return(v)
537+ return _c
538+}
539+
540+func (_c *MockVideoStreamAPI_PWLoopNew_Call) RunAndReturn(run func(props unsafe.Pointer) unsafe.Pointer) *MockVideoStreamAPI_PWLoopNew_Call {
541+ _c.Call.Return(run)
542+ return _c
543+}
544+
545+// PWPropertiesNewString provides a mock function for the type MockVideoStreamAPI
546+func (_mock *MockVideoStreamAPI) PWPropertiesNewString(args *byte) unsafe.Pointer {
547+ ret := _mock.Called(args)
548+
549+ if len(ret) == 0 {
550+ panic("no return value specified for PWPropertiesNewString")
551+ }
552+
553+ var r0 unsafe.Pointer
554+ if returnFunc, ok := ret.Get(0).(func(*byte) unsafe.Pointer); ok {
555+ r0 = returnFunc(args)
556+ } else {
557+ r0 = ret.Get(0).(unsafe.Pointer)
558+ }
559+ return r0
560+}
561+
562+// MockVideoStreamAPI_PWPropertiesNewString_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'PWPropertiesNewString'
563+type MockVideoStreamAPI_PWPropertiesNewString_Call struct {
564+ *mock.Call
565+}
566+
567+// PWPropertiesNewString is a helper method to define mock.On call
568+// - args *byte
569+func (_e *MockVideoStreamAPI_Expecter) PWPropertiesNewString(args any) *MockVideoStreamAPI_PWPropertiesNewString_Call {
570+ return &MockVideoStreamAPI_PWPropertiesNewString_Call{Call: _e.mock.On("PWPropertiesNewString", args)}
571+}
572+
573+func (_c *MockVideoStreamAPI_PWPropertiesNewString_Call) Run(run func(args *byte)) *MockVideoStreamAPI_PWPropertiesNewString_Call {
574+ _c.Call.Run(func(args mock.Arguments) {
575+ var arg0 *byte
576+ if args[0] != nil {
577+ arg0 = args[0].(*byte)
578+ }
579+ run(
580+ arg0,
581+ )
582+ })
583+ return _c
584+}
585+
586+func (_c *MockVideoStreamAPI_PWPropertiesNewString_Call) Return(v unsafe.Pointer) *MockVideoStreamAPI_PWPropertiesNewString_Call {
587+ _c.Call.Return(v)
588+ return _c
589+}
590+
591+func (_c *MockVideoStreamAPI_PWPropertiesNewString_Call) RunAndReturn(run func(args *byte) unsafe.Pointer) *MockVideoStreamAPI_PWPropertiesNewString_Call {
592+ _c.Call.Return(run)
593+ return _c
594+}
595+
596+// PWStreamAddListener provides a mock function for the type MockVideoStreamAPI
597+func (_mock *MockVideoStreamAPI) PWStreamAddListener(stream unsafe.Pointer, listener unsafe.Pointer, events unsafe.Pointer, data unsafe.Pointer) int32 {
598+ ret := _mock.Called(stream, listener, events, data)
599+
600+ if len(ret) == 0 {
601+ panic("no return value specified for PWStreamAddListener")
602+ }
603+
604+ var r0 int32
605+ if returnFunc, ok := ret.Get(0).(func(unsafe.Pointer, unsafe.Pointer, unsafe.Pointer, unsafe.Pointer) int32); ok {
606+ r0 = returnFunc(stream, listener, events, data)
607+ } else {
608+ r0 = ret.Get(0).(int32)
609+ }
610+ return r0
611+}
612+
613+// MockVideoStreamAPI_PWStreamAddListener_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'PWStreamAddListener'
614+type MockVideoStreamAPI_PWStreamAddListener_Call struct {
615+ *mock.Call
616+}
617+
618+// PWStreamAddListener is a helper method to define mock.On call
619+// - stream unsafe.Pointer
620+// - listener unsafe.Pointer
621+// - events unsafe.Pointer
622+// - data unsafe.Pointer
623+func (_e *MockVideoStreamAPI_Expecter) PWStreamAddListener(stream any, listener any, events any, data any) *MockVideoStreamAPI_PWStreamAddListener_Call {
624+ return &MockVideoStreamAPI_PWStreamAddListener_Call{Call: _e.mock.On("PWStreamAddListener", stream, listener, events, data)}
625+}
626+
627+func (_c *MockVideoStreamAPI_PWStreamAddListener_Call) Run(run func(stream unsafe.Pointer, listener unsafe.Pointer, events unsafe.Pointer, data unsafe.Pointer)) *MockVideoStreamAPI_PWStreamAddListener_Call {
628+ _c.Call.Run(func(args mock.Arguments) {
629+ var arg0 unsafe.Pointer
630+ if args[0] != nil {
631+ arg0 = args[0].(unsafe.Pointer)
632+ }
633+ var arg1 unsafe.Pointer
634+ if args[1] != nil {
635+ arg1 = args[1].(unsafe.Pointer)
636+ }
637+ var arg2 unsafe.Pointer
638+ if args[2] != nil {
639+ arg2 = args[2].(unsafe.Pointer)
640+ }
641+ var arg3 unsafe.Pointer
642+ if args[3] != nil {
643+ arg3 = args[3].(unsafe.Pointer)
644+ }
645+ run(
646+ arg0,
647+ arg1,
648+ arg2,
649+ arg3,
650+ )
651+ })
652+ return _c
653+}
654+
655+func (_c *MockVideoStreamAPI_PWStreamAddListener_Call) Return(n int32) *MockVideoStreamAPI_PWStreamAddListener_Call {
656+ _c.Call.Return(n)
657+ return _c
658+}
659+
660+func (_c *MockVideoStreamAPI_PWStreamAddListener_Call) RunAndReturn(run func(stream unsafe.Pointer, listener unsafe.Pointer, events unsafe.Pointer, data unsafe.Pointer) int32) *MockVideoStreamAPI_PWStreamAddListener_Call {
661+ _c.Call.Return(run)
662+ return _c
663+}
664+
665+// PWStreamConnect provides a mock function for the type MockVideoStreamAPI
666+func (_mock *MockVideoStreamAPI) PWStreamConnect(stream unsafe.Pointer, direction int32, id uint32, flags uint32, ports unsafe.Pointer, n_ports uint32) int32 {
667+ ret := _mock.Called(stream, direction, id, flags, ports, n_ports)
668+
669+ if len(ret) == 0 {
670+ panic("no return value specified for PWStreamConnect")
671+ }
672+
673+ var r0 int32
674+ if returnFunc, ok := ret.Get(0).(func(unsafe.Pointer, int32, uint32, uint32, unsafe.Pointer, uint32) int32); ok {
675+ r0 = returnFunc(stream, direction, id, flags, ports, n_ports)
676+ } else {
677+ r0 = ret.Get(0).(int32)
678+ }
679+ return r0
680+}
681+
682+// MockVideoStreamAPI_PWStreamConnect_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'PWStreamConnect'
683+type MockVideoStreamAPI_PWStreamConnect_Call struct {
684+ *mock.Call
685+}
686+
687+// PWStreamConnect is a helper method to define mock.On call
688+// - stream unsafe.Pointer
689+// - direction int32
690+// - id uint32
691+// - flags uint32
692+// - ports unsafe.Pointer
693+// - n_ports uint32
694+func (_e *MockVideoStreamAPI_Expecter) PWStreamConnect(stream any, direction any, id any, flags any, ports any, n_ports any) *MockVideoStreamAPI_PWStreamConnect_Call {
695+ return &MockVideoStreamAPI_PWStreamConnect_Call{Call: _e.mock.On("PWStreamConnect", stream, direction, id, flags, ports, n_ports)}
696+}
697+
698+func (_c *MockVideoStreamAPI_PWStreamConnect_Call) Run(run func(stream unsafe.Pointer, direction int32, id uint32, flags uint32, ports unsafe.Pointer, n_ports uint32)) *MockVideoStreamAPI_PWStreamConnect_Call {
699+ _c.Call.Run(func(args mock.Arguments) {
700+ var arg0 unsafe.Pointer
701+ if args[0] != nil {
702+ arg0 = args[0].(unsafe.Pointer)
703+ }
704+ var arg1 int32
705+ if args[1] != nil {
706+ arg1 = args[1].(int32)
707+ }
708+ var arg2 uint32
709+ if args[2] != nil {
710+ arg2 = args[2].(uint32)
711+ }
712+ var arg3 uint32
713+ if args[3] != nil {
714+ arg3 = args[3].(uint32)
715+ }
716+ var arg4 unsafe.Pointer
717+ if args[4] != nil {
718+ arg4 = args[4].(unsafe.Pointer)
719+ }
720+ var arg5 uint32
721+ if args[5] != nil {
722+ arg5 = args[5].(uint32)
723+ }
724+ run(
725+ arg0,
726+ arg1,
727+ arg2,
728+ arg3,
729+ arg4,
730+ arg5,
731+ )
732+ })
733+ return _c
734+}
735+
736+func (_c *MockVideoStreamAPI_PWStreamConnect_Call) Return(n int32) *MockVideoStreamAPI_PWStreamConnect_Call {
737+ _c.Call.Return(n)
738+ return _c
739+}
740+
741+func (_c *MockVideoStreamAPI_PWStreamConnect_Call) RunAndReturn(run func(stream unsafe.Pointer, direction int32, id uint32, flags uint32, ports unsafe.Pointer, n_ports uint32) int32) *MockVideoStreamAPI_PWStreamConnect_Call {
742+ _c.Call.Return(run)
743+ return _c
744+}
745+
746+// PWStreamDequeueBuffer provides a mock function for the type MockVideoStreamAPI
747+func (_mock *MockVideoStreamAPI) PWStreamDequeueBuffer(stream unsafe.Pointer) unsafe.Pointer {
748+ ret := _mock.Called(stream)
749+
750+ if len(ret) == 0 {
751+ panic("no return value specified for PWStreamDequeueBuffer")
752+ }
753+
754+ var r0 unsafe.Pointer
755+ if returnFunc, ok := ret.Get(0).(func(unsafe.Pointer) unsafe.Pointer); ok {
756+ r0 = returnFunc(stream)
757+ } else {
758+ r0 = ret.Get(0).(unsafe.Pointer)
759+ }
760+ return r0
761+}
762+
763+// MockVideoStreamAPI_PWStreamDequeueBuffer_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'PWStreamDequeueBuffer'
764+type MockVideoStreamAPI_PWStreamDequeueBuffer_Call struct {
765+ *mock.Call
766+}
767+
768+// PWStreamDequeueBuffer is a helper method to define mock.On call
769+// - stream unsafe.Pointer
770+func (_e *MockVideoStreamAPI_Expecter) PWStreamDequeueBuffer(stream any) *MockVideoStreamAPI_PWStreamDequeueBuffer_Call {
771+ return &MockVideoStreamAPI_PWStreamDequeueBuffer_Call{Call: _e.mock.On("PWStreamDequeueBuffer", stream)}
772+}
773+
774+func (_c *MockVideoStreamAPI_PWStreamDequeueBuffer_Call) Run(run func(stream unsafe.Pointer)) *MockVideoStreamAPI_PWStreamDequeueBuffer_Call {
775+ _c.Call.Run(func(args mock.Arguments) {
776+ var arg0 unsafe.Pointer
777+ if args[0] != nil {
778+ arg0 = args[0].(unsafe.Pointer)
779+ }
780+ run(
781+ arg0,
782+ )
783+ })
784+ return _c
785+}
786+
787+func (_c *MockVideoStreamAPI_PWStreamDequeueBuffer_Call) Return(v unsafe.Pointer) *MockVideoStreamAPI_PWStreamDequeueBuffer_Call {
788+ _c.Call.Return(v)
789+ return _c
790+}
791+
792+func (_c *MockVideoStreamAPI_PWStreamDequeueBuffer_Call) RunAndReturn(run func(stream unsafe.Pointer) unsafe.Pointer) *MockVideoStreamAPI_PWStreamDequeueBuffer_Call {
793+ _c.Call.Return(run)
794+ return _c
795+}
796+
797+// PWStreamDestroy provides a mock function for the type MockVideoStreamAPI
798+func (_mock *MockVideoStreamAPI) PWStreamDestroy(stream unsafe.Pointer) {
799+ _mock.Called(stream)
800+ return
801+}
802+
803+// MockVideoStreamAPI_PWStreamDestroy_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'PWStreamDestroy'
804+type MockVideoStreamAPI_PWStreamDestroy_Call struct {
805+ *mock.Call
806+}
807+
808+// PWStreamDestroy is a helper method to define mock.On call
809+// - stream unsafe.Pointer
810+func (_e *MockVideoStreamAPI_Expecter) PWStreamDestroy(stream any) *MockVideoStreamAPI_PWStreamDestroy_Call {
811+ return &MockVideoStreamAPI_PWStreamDestroy_Call{Call: _e.mock.On("PWStreamDestroy", stream)}
812+}
813+
814+func (_c *MockVideoStreamAPI_PWStreamDestroy_Call) Run(run func(stream unsafe.Pointer)) *MockVideoStreamAPI_PWStreamDestroy_Call {
815+ _c.Call.Run(func(args mock.Arguments) {
816+ var arg0 unsafe.Pointer
817+ if args[0] != nil {
818+ arg0 = args[0].(unsafe.Pointer)
819+ }
820+ run(
821+ arg0,
822+ )
823+ })
824+ return _c
825+}
826+
827+func (_c *MockVideoStreamAPI_PWStreamDestroy_Call) Return() *MockVideoStreamAPI_PWStreamDestroy_Call {
828+ _c.Call.Return()
829+ return _c
830+}
831+
832+func (_c *MockVideoStreamAPI_PWStreamDestroy_Call) RunAndReturn(run func(stream unsafe.Pointer)) *MockVideoStreamAPI_PWStreamDestroy_Call {
833+ _c.Run(run)
834+ return _c
835+}
836+
837+// PWStreamDisconnect provides a mock function for the type MockVideoStreamAPI
838+func (_mock *MockVideoStreamAPI) PWStreamDisconnect(stream unsafe.Pointer) int32 {
839+ ret := _mock.Called(stream)
840+
841+ if len(ret) == 0 {
842+ panic("no return value specified for PWStreamDisconnect")
843+ }
844+
845+ var r0 int32
846+ if returnFunc, ok := ret.Get(0).(func(unsafe.Pointer) int32); ok {
847+ r0 = returnFunc(stream)
848+ } else {
849+ r0 = ret.Get(0).(int32)
850+ }
851+ return r0
852+}
853+
854+// MockVideoStreamAPI_PWStreamDisconnect_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'PWStreamDisconnect'
855+type MockVideoStreamAPI_PWStreamDisconnect_Call struct {
856+ *mock.Call
857+}
858+
859+// PWStreamDisconnect is a helper method to define mock.On call
860+// - stream unsafe.Pointer
861+func (_e *MockVideoStreamAPI_Expecter) PWStreamDisconnect(stream any) *MockVideoStreamAPI_PWStreamDisconnect_Call {
862+ return &MockVideoStreamAPI_PWStreamDisconnect_Call{Call: _e.mock.On("PWStreamDisconnect", stream)}
863+}
864+
865+func (_c *MockVideoStreamAPI_PWStreamDisconnect_Call) Run(run func(stream unsafe.Pointer)) *MockVideoStreamAPI_PWStreamDisconnect_Call {
866+ _c.Call.Run(func(args mock.Arguments) {
867+ var arg0 unsafe.Pointer
868+ if args[0] != nil {
869+ arg0 = args[0].(unsafe.Pointer)
870+ }
871+ run(
872+ arg0,
873+ )
874+ })
875+ return _c
876+}
877+
878+func (_c *MockVideoStreamAPI_PWStreamDisconnect_Call) Return(n int32) *MockVideoStreamAPI_PWStreamDisconnect_Call {
879+ _c.Call.Return(n)
880+ return _c
881+}
882+
883+func (_c *MockVideoStreamAPI_PWStreamDisconnect_Call) RunAndReturn(run func(stream unsafe.Pointer) int32) *MockVideoStreamAPI_PWStreamDisconnect_Call {
884+ _c.Call.Return(run)
885+ return _c
886+}
887+
888+// PWStreamGetNodeId provides a mock function for the type MockVideoStreamAPI
889+func (_mock *MockVideoStreamAPI) PWStreamGetNodeId(stream unsafe.Pointer) uint32 {
890+ ret := _mock.Called(stream)
891+
892+ if len(ret) == 0 {
893+ panic("no return value specified for PWStreamGetNodeId")
894+ }
895+
896+ var r0 uint32
897+ if returnFunc, ok := ret.Get(0).(func(unsafe.Pointer) uint32); ok {
898+ r0 = returnFunc(stream)
899+ } else {
900+ r0 = ret.Get(0).(uint32)
901+ }
902+ return r0
903+}
904+
905+// MockVideoStreamAPI_PWStreamGetNodeId_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'PWStreamGetNodeId'
906+type MockVideoStreamAPI_PWStreamGetNodeId_Call struct {
907+ *mock.Call
908+}
909+
910+// PWStreamGetNodeId is a helper method to define mock.On call
911+// - stream unsafe.Pointer
912+func (_e *MockVideoStreamAPI_Expecter) PWStreamGetNodeId(stream any) *MockVideoStreamAPI_PWStreamGetNodeId_Call {
913+ return &MockVideoStreamAPI_PWStreamGetNodeId_Call{Call: _e.mock.On("PWStreamGetNodeId", stream)}
914+}
915+
916+func (_c *MockVideoStreamAPI_PWStreamGetNodeId_Call) Run(run func(stream unsafe.Pointer)) *MockVideoStreamAPI_PWStreamGetNodeId_Call {
917+ _c.Call.Run(func(args mock.Arguments) {
918+ var arg0 unsafe.Pointer
919+ if args[0] != nil {
920+ arg0 = args[0].(unsafe.Pointer)
921+ }
922+ run(
923+ arg0,
924+ )
925+ })
926+ return _c
927+}
928+
929+func (_c *MockVideoStreamAPI_PWStreamGetNodeId_Call) Return(v uint32) *MockVideoStreamAPI_PWStreamGetNodeId_Call {
930+ _c.Call.Return(v)
931+ return _c
932+}
933+
934+func (_c *MockVideoStreamAPI_PWStreamGetNodeId_Call) RunAndReturn(run func(stream unsafe.Pointer) uint32) *MockVideoStreamAPI_PWStreamGetNodeId_Call {
935+ _c.Call.Return(run)
936+ return _c
937+}
938+
939+// PWStreamIsDriving provides a mock function for the type MockVideoStreamAPI
940+func (_mock *MockVideoStreamAPI) PWStreamIsDriving(stream unsafe.Pointer) bool {
941+ ret := _mock.Called(stream)
942+
943+ if len(ret) == 0 {
944+ panic("no return value specified for PWStreamIsDriving")
945+ }
946+
947+ var r0 bool
948+ if returnFunc, ok := ret.Get(0).(func(unsafe.Pointer) bool); ok {
949+ r0 = returnFunc(stream)
950+ } else {
951+ r0 = ret.Get(0).(bool)
952+ }
953+ return r0
954+}
955+
956+// MockVideoStreamAPI_PWStreamIsDriving_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'PWStreamIsDriving'
957+type MockVideoStreamAPI_PWStreamIsDriving_Call struct {
958+ *mock.Call
959+}
960+
961+// PWStreamIsDriving is a helper method to define mock.On call
962+// - stream unsafe.Pointer
963+func (_e *MockVideoStreamAPI_Expecter) PWStreamIsDriving(stream any) *MockVideoStreamAPI_PWStreamIsDriving_Call {
964+ return &MockVideoStreamAPI_PWStreamIsDriving_Call{Call: _e.mock.On("PWStreamIsDriving", stream)}
965+}
966+
967+func (_c *MockVideoStreamAPI_PWStreamIsDriving_Call) Run(run func(stream unsafe.Pointer)) *MockVideoStreamAPI_PWStreamIsDriving_Call {
968+ _c.Call.Run(func(args mock.Arguments) {
969+ var arg0 unsafe.Pointer
970+ if args[0] != nil {
971+ arg0 = args[0].(unsafe.Pointer)
972+ }
973+ run(
974+ arg0,
975+ )
976+ })
977+ return _c
978+}
979+
980+func (_c *MockVideoStreamAPI_PWStreamIsDriving_Call) Return(b bool) *MockVideoStreamAPI_PWStreamIsDriving_Call {
981+ _c.Call.Return(b)
982+ return _c
983+}
984+
985+func (_c *MockVideoStreamAPI_PWStreamIsDriving_Call) RunAndReturn(run func(stream unsafe.Pointer) bool) *MockVideoStreamAPI_PWStreamIsDriving_Call {
986+ _c.Call.Return(run)
987+ return _c
988+}
989+
990+// PWStreamNew provides a mock function for the type MockVideoStreamAPI
991+func (_mock *MockVideoStreamAPI) PWStreamNew(core unsafe.Pointer, name *byte, props unsafe.Pointer) unsafe.Pointer {
992+ ret := _mock.Called(core, name, props)
993+
994+ if len(ret) == 0 {
995+ panic("no return value specified for PWStreamNew")
996+ }
997+
998+ var r0 unsafe.Pointer
999+ if returnFunc, ok := ret.Get(0).(func(unsafe.Pointer, *byte, unsafe.Pointer) unsafe.Pointer); ok {
1000+ r0 = returnFunc(core, name, props)
1001+ } else {
1002+ r0 = ret.Get(0).(unsafe.Pointer)
1003+ }
1004+ return r0
1005+}
1006+
1007+// MockVideoStreamAPI_PWStreamNew_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'PWStreamNew'
1008+type MockVideoStreamAPI_PWStreamNew_Call struct {
1009+ *mock.Call
1010+}
1011+
1012+// PWStreamNew is a helper method to define mock.On call
1013+// - core unsafe.Pointer
1014+// - name *byte
1015+// - props unsafe.Pointer
1016+func (_e *MockVideoStreamAPI_Expecter) PWStreamNew(core any, name any, props any) *MockVideoStreamAPI_PWStreamNew_Call {
1017+ return &MockVideoStreamAPI_PWStreamNew_Call{Call: _e.mock.On("PWStreamNew", core, name, props)}
1018+}
1019+
1020+func (_c *MockVideoStreamAPI_PWStreamNew_Call) Run(run func(core unsafe.Pointer, name *byte, props unsafe.Pointer)) *MockVideoStreamAPI_PWStreamNew_Call {
1021+ _c.Call.Run(func(args mock.Arguments) {
1022+ var arg0 unsafe.Pointer
1023+ if args[0] != nil {
1024+ arg0 = args[0].(unsafe.Pointer)
1025+ }
1026+ var arg1 *byte
1027+ if args[1] != nil {
1028+ arg1 = args[1].(*byte)
1029+ }
1030+ var arg2 unsafe.Pointer
1031+ if args[2] != nil {
1032+ arg2 = args[2].(unsafe.Pointer)
1033+ }
1034+ run(
1035+ arg0,
1036+ arg1,
1037+ arg2,
1038+ )
1039+ })
1040+ return _c
1041+}
1042+
1043+func (_c *MockVideoStreamAPI_PWStreamNew_Call) Return(v unsafe.Pointer) *MockVideoStreamAPI_PWStreamNew_Call {
1044+ _c.Call.Return(v)
1045+ return _c
1046+}
1047+
1048+func (_c *MockVideoStreamAPI_PWStreamNew_Call) RunAndReturn(run func(core unsafe.Pointer, name *byte, props unsafe.Pointer) unsafe.Pointer) *MockVideoStreamAPI_PWStreamNew_Call {
1049+ _c.Call.Return(run)
1050+ return _c
1051+}
1052+
1053+// PWStreamNewSimple provides a mock function for the type MockVideoStreamAPI
1054+func (_mock *MockVideoStreamAPI) PWStreamNewSimple(context unsafe.Pointer, name *byte, props unsafe.Pointer, events unsafe.Pointer, data unsafe.Pointer) unsafe.Pointer {
1055+ ret := _mock.Called(context, name, props, events, data)
1056+
1057+ if len(ret) == 0 {
1058+ panic("no return value specified for PWStreamNewSimple")
1059+ }
1060+
1061+ var r0 unsafe.Pointer
1062+ if returnFunc, ok := ret.Get(0).(func(unsafe.Pointer, *byte, unsafe.Pointer, unsafe.Pointer, unsafe.Pointer) unsafe.Pointer); ok {
1063+ r0 = returnFunc(context, name, props, events, data)
1064+ } else {
1065+ r0 = ret.Get(0).(unsafe.Pointer)
1066+ }
1067+ return r0
1068+}
1069+
1070+// MockVideoStreamAPI_PWStreamNewSimple_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'PWStreamNewSimple'
1071+type MockVideoStreamAPI_PWStreamNewSimple_Call struct {
1072+ *mock.Call
1073+}
1074+
1075+// PWStreamNewSimple is a helper method to define mock.On call
1076+// - context unsafe.Pointer
1077+// - name *byte
1078+// - props unsafe.Pointer
1079+// - events unsafe.Pointer
1080+// - data unsafe.Pointer
1081+func (_e *MockVideoStreamAPI_Expecter) PWStreamNewSimple(context any, name any, props any, events any, data any) *MockVideoStreamAPI_PWStreamNewSimple_Call {
1082+ return &MockVideoStreamAPI_PWStreamNewSimple_Call{Call: _e.mock.On("PWStreamNewSimple", context, name, props, events, data)}
1083+}
1084+
1085+func (_c *MockVideoStreamAPI_PWStreamNewSimple_Call) Run(run func(context unsafe.Pointer, name *byte, props unsafe.Pointer, events unsafe.Pointer, data unsafe.Pointer)) *MockVideoStreamAPI_PWStreamNewSimple_Call {
1086+ _c.Call.Run(func(args mock.Arguments) {
1087+ var arg0 unsafe.Pointer
1088+ if args[0] != nil {
1089+ arg0 = args[0].(unsafe.Pointer)
1090+ }
1091+ var arg1 *byte
1092+ if args[1] != nil {
1093+ arg1 = args[1].(*byte)
1094+ }
1095+ var arg2 unsafe.Pointer
1096+ if args[2] != nil {
1097+ arg2 = args[2].(unsafe.Pointer)
1098+ }
1099+ var arg3 unsafe.Pointer
1100+ if args[3] != nil {
1101+ arg3 = args[3].(unsafe.Pointer)
1102+ }
1103+ var arg4 unsafe.Pointer
1104+ if args[4] != nil {
1105+ arg4 = args[4].(unsafe.Pointer)
1106+ }
1107+ run(
1108+ arg0,
1109+ arg1,
1110+ arg2,
1111+ arg3,
1112+ arg4,
1113+ )
1114+ })
1115+ return _c
1116+}
1117+
1118+func (_c *MockVideoStreamAPI_PWStreamNewSimple_Call) Return(v unsafe.Pointer) *MockVideoStreamAPI_PWStreamNewSimple_Call {
1119+ _c.Call.Return(v)
1120+ return _c
1121+}
1122+
1123+func (_c *MockVideoStreamAPI_PWStreamNewSimple_Call) RunAndReturn(run func(context unsafe.Pointer, name *byte, props unsafe.Pointer, events unsafe.Pointer, data unsafe.Pointer) unsafe.Pointer) *MockVideoStreamAPI_PWStreamNewSimple_Call {
1124+ _c.Call.Return(run)
1125+ return _c
1126+}
1127+
1128+// PWStreamQueueBuffer provides a mock function for the type MockVideoStreamAPI
1129+func (_mock *MockVideoStreamAPI) PWStreamQueueBuffer(stream unsafe.Pointer, buffer unsafe.Pointer) int32 {
1130+ ret := _mock.Called(stream, buffer)
1131+
1132+ if len(ret) == 0 {
1133+ panic("no return value specified for PWStreamQueueBuffer")
1134+ }
1135+
1136+ var r0 int32
1137+ if returnFunc, ok := ret.Get(0).(func(unsafe.Pointer, unsafe.Pointer) int32); ok {
1138+ r0 = returnFunc(stream, buffer)
1139+ } else {
1140+ r0 = ret.Get(0).(int32)
1141+ }
1142+ return r0
1143+}
1144+
1145+// MockVideoStreamAPI_PWStreamQueueBuffer_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'PWStreamQueueBuffer'
1146+type MockVideoStreamAPI_PWStreamQueueBuffer_Call struct {
1147+ *mock.Call
1148+}
1149+
1150+// PWStreamQueueBuffer is a helper method to define mock.On call
1151+// - stream unsafe.Pointer
1152+// - buffer unsafe.Pointer
1153+func (_e *MockVideoStreamAPI_Expecter) PWStreamQueueBuffer(stream any, buffer any) *MockVideoStreamAPI_PWStreamQueueBuffer_Call {
1154+ return &MockVideoStreamAPI_PWStreamQueueBuffer_Call{Call: _e.mock.On("PWStreamQueueBuffer", stream, buffer)}
1155+}
1156+
1157+func (_c *MockVideoStreamAPI_PWStreamQueueBuffer_Call) Run(run func(stream unsafe.Pointer, buffer unsafe.Pointer)) *MockVideoStreamAPI_PWStreamQueueBuffer_Call {
1158+ _c.Call.Run(func(args mock.Arguments) {
1159+ var arg0 unsafe.Pointer
1160+ if args[0] != nil {
1161+ arg0 = args[0].(unsafe.Pointer)
1162+ }
1163+ var arg1 unsafe.Pointer
1164+ if args[1] != nil {
1165+ arg1 = args[1].(unsafe.Pointer)
1166+ }
1167+ run(
1168+ arg0,
1169+ arg1,
1170+ )
1171+ })
1172+ return _c
1173+}
1174+
1175+func (_c *MockVideoStreamAPI_PWStreamQueueBuffer_Call) Return(n int32) *MockVideoStreamAPI_PWStreamQueueBuffer_Call {
1176+ _c.Call.Return(n)
1177+ return _c
1178+}
1179+
1180+func (_c *MockVideoStreamAPI_PWStreamQueueBuffer_Call) RunAndReturn(run func(stream unsafe.Pointer, buffer unsafe.Pointer) int32) *MockVideoStreamAPI_PWStreamQueueBuffer_Call {
1181+ _c.Call.Return(run)
1182+ return _c
1183+}
1184+
1185+// PWStreamReturnBuffer provides a mock function for the type MockVideoStreamAPI
1186+func (_mock *MockVideoStreamAPI) PWStreamReturnBuffer(stream unsafe.Pointer, buffer unsafe.Pointer) int32 {
1187+ ret := _mock.Called(stream, buffer)
1188+
1189+ if len(ret) == 0 {
1190+ panic("no return value specified for PWStreamReturnBuffer")
1191+ }
1192+
1193+ var r0 int32
1194+ if returnFunc, ok := ret.Get(0).(func(unsafe.Pointer, unsafe.Pointer) int32); ok {
1195+ r0 = returnFunc(stream, buffer)
1196+ } else {
1197+ r0 = ret.Get(0).(int32)
1198+ }
1199+ return r0
1200+}
1201+
1202+// MockVideoStreamAPI_PWStreamReturnBuffer_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'PWStreamReturnBuffer'
1203+type MockVideoStreamAPI_PWStreamReturnBuffer_Call struct {
1204+ *mock.Call
1205+}
1206+
1207+// PWStreamReturnBuffer is a helper method to define mock.On call
1208+// - stream unsafe.Pointer
1209+// - buffer unsafe.Pointer
1210+func (_e *MockVideoStreamAPI_Expecter) PWStreamReturnBuffer(stream any, buffer any) *MockVideoStreamAPI_PWStreamReturnBuffer_Call {
1211+ return &MockVideoStreamAPI_PWStreamReturnBuffer_Call{Call: _e.mock.On("PWStreamReturnBuffer", stream, buffer)}
1212+}
1213+
1214+func (_c *MockVideoStreamAPI_PWStreamReturnBuffer_Call) Run(run func(stream unsafe.Pointer, buffer unsafe.Pointer)) *MockVideoStreamAPI_PWStreamReturnBuffer_Call {
1215+ _c.Call.Run(func(args mock.Arguments) {
1216+ var arg0 unsafe.Pointer
1217+ if args[0] != nil {
1218+ arg0 = args[0].(unsafe.Pointer)
1219+ }
1220+ var arg1 unsafe.Pointer
1221+ if args[1] != nil {
1222+ arg1 = args[1].(unsafe.Pointer)
1223+ }
1224+ run(
1225+ arg0,
1226+ arg1,
1227+ )
1228+ })
1229+ return _c
1230+}
1231+
1232+func (_c *MockVideoStreamAPI_PWStreamReturnBuffer_Call) Return(n int32) *MockVideoStreamAPI_PWStreamReturnBuffer_Call {
1233+ _c.Call.Return(n)
1234+ return _c
1235+}
1236+
1237+func (_c *MockVideoStreamAPI_PWStreamReturnBuffer_Call) RunAndReturn(run func(stream unsafe.Pointer, buffer unsafe.Pointer) int32) *MockVideoStreamAPI_PWStreamReturnBuffer_Call {
1238+ _c.Call.Return(run)
1239+ return _c
1240+}
1241+
1242+// PWStreamSetActive provides a mock function for the type MockVideoStreamAPI
1243+func (_mock *MockVideoStreamAPI) PWStreamSetActive(stream unsafe.Pointer, active bool) int32 {
1244+ ret := _mock.Called(stream, active)
1245+
1246+ if len(ret) == 0 {
1247+ panic("no return value specified for PWStreamSetActive")
1248+ }
1249+
1250+ var r0 int32
1251+ if returnFunc, ok := ret.Get(0).(func(unsafe.Pointer, bool) int32); ok {
1252+ r0 = returnFunc(stream, active)
1253+ } else {
1254+ r0 = ret.Get(0).(int32)
1255+ }
1256+ return r0
1257+}
1258+
1259+// MockVideoStreamAPI_PWStreamSetActive_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'PWStreamSetActive'
1260+type MockVideoStreamAPI_PWStreamSetActive_Call struct {
1261+ *mock.Call
1262+}
1263+
1264+// PWStreamSetActive is a helper method to define mock.On call
1265+// - stream unsafe.Pointer
1266+// - active bool
1267+func (_e *MockVideoStreamAPI_Expecter) PWStreamSetActive(stream any, active any) *MockVideoStreamAPI_PWStreamSetActive_Call {
1268+ return &MockVideoStreamAPI_PWStreamSetActive_Call{Call: _e.mock.On("PWStreamSetActive", stream, active)}
1269+}
1270+
1271+func (_c *MockVideoStreamAPI_PWStreamSetActive_Call) Run(run func(stream unsafe.Pointer, active bool)) *MockVideoStreamAPI_PWStreamSetActive_Call {
1272+ _c.Call.Run(func(args mock.Arguments) {
1273+ var arg0 unsafe.Pointer
1274+ if args[0] != nil {
1275+ arg0 = args[0].(unsafe.Pointer)
1276+ }
1277+ var arg1 bool
1278+ if args[1] != nil {
1279+ arg1 = args[1].(bool)
1280+ }
1281+ run(
1282+ arg0,
1283+ arg1,
1284+ )
1285+ })
1286+ return _c
1287+}
1288+
1289+func (_c *MockVideoStreamAPI_PWStreamSetActive_Call) Return(n int32) *MockVideoStreamAPI_PWStreamSetActive_Call {
1290+ _c.Call.Return(n)
1291+ return _c
1292+}
1293+
1294+func (_c *MockVideoStreamAPI_PWStreamSetActive_Call) RunAndReturn(run func(stream unsafe.Pointer, active bool) int32) *MockVideoStreamAPI_PWStreamSetActive_Call {
1295+ _c.Call.Return(run)
1296+ return _c
1297+}
1298+
1299+// PWStreamTriggerProcess provides a mock function for the type MockVideoStreamAPI
1300+func (_mock *MockVideoStreamAPI) PWStreamTriggerProcess(stream unsafe.Pointer) int32 {
1301+ ret := _mock.Called(stream)
1302+
1303+ if len(ret) == 0 {
1304+ panic("no return value specified for PWStreamTriggerProcess")
1305+ }
1306+
1307+ var r0 int32
1308+ if returnFunc, ok := ret.Get(0).(func(unsafe.Pointer) int32); ok {
1309+ r0 = returnFunc(stream)
1310+ } else {
1311+ r0 = ret.Get(0).(int32)
1312+ }
1313+ return r0
1314+}
1315+
1316+// MockVideoStreamAPI_PWStreamTriggerProcess_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'PWStreamTriggerProcess'
1317+type MockVideoStreamAPI_PWStreamTriggerProcess_Call struct {
1318+ *mock.Call
1319+}
1320+
1321+// PWStreamTriggerProcess is a helper method to define mock.On call
1322+// - stream unsafe.Pointer
1323+func (_e *MockVideoStreamAPI_Expecter) PWStreamTriggerProcess(stream any) *MockVideoStreamAPI_PWStreamTriggerProcess_Call {
1324+ return &MockVideoStreamAPI_PWStreamTriggerProcess_Call{Call: _e.mock.On("PWStreamTriggerProcess", stream)}
1325+}
1326+
1327+func (_c *MockVideoStreamAPI_PWStreamTriggerProcess_Call) Run(run func(stream unsafe.Pointer)) *MockVideoStreamAPI_PWStreamTriggerProcess_Call {
1328+ _c.Call.Run(func(args mock.Arguments) {
1329+ var arg0 unsafe.Pointer
1330+ if args[0] != nil {
1331+ arg0 = args[0].(unsafe.Pointer)
1332+ }
1333+ run(
1334+ arg0,
1335+ )
1336+ })
1337+ return _c
1338+}
1339+
1340+func (_c *MockVideoStreamAPI_PWStreamTriggerProcess_Call) Return(n int32) *MockVideoStreamAPI_PWStreamTriggerProcess_Call {
1341+ _c.Call.Return(n)
1342+ return _c
1343+}
1344+
1345+func (_c *MockVideoStreamAPI_PWStreamTriggerProcess_Call) RunAndReturn(run func(stream unsafe.Pointer) int32) *MockVideoStreamAPI_PWStreamTriggerProcess_Call {
1346+ _c.Call.Return(run)
1347+ return _c
1348+}
1349+
1350+// PWStreamUpdateParams provides a mock function for the type MockVideoStreamAPI
1351+func (_mock *MockVideoStreamAPI) PWStreamUpdateParams(stream unsafe.Pointer, params unsafe.Pointer, n_params uint32) int32 {
1352+ ret := _mock.Called(stream, params, n_params)
1353+
1354+ if len(ret) == 0 {
1355+ panic("no return value specified for PWStreamUpdateParams")
1356+ }
1357+
1358+ var r0 int32
1359+ if returnFunc, ok := ret.Get(0).(func(unsafe.Pointer, unsafe.Pointer, uint32) int32); ok {
1360+ r0 = returnFunc(stream, params, n_params)
1361+ } else {
1362+ r0 = ret.Get(0).(int32)
1363+ }
1364+ return r0
1365+}
1366+
1367+// MockVideoStreamAPI_PWStreamUpdateParams_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'PWStreamUpdateParams'
1368+type MockVideoStreamAPI_PWStreamUpdateParams_Call struct {
1369+ *mock.Call
1370+}
1371+
1372+// PWStreamUpdateParams is a helper method to define mock.On call
1373+// - stream unsafe.Pointer
1374+// - params unsafe.Pointer
1375+// - n_params uint32
1376+func (_e *MockVideoStreamAPI_Expecter) PWStreamUpdateParams(stream any, params any, n_params any) *MockVideoStreamAPI_PWStreamUpdateParams_Call {
1377+ return &MockVideoStreamAPI_PWStreamUpdateParams_Call{Call: _e.mock.On("PWStreamUpdateParams", stream, params, n_params)}
1378+}
1379+
1380+func (_c *MockVideoStreamAPI_PWStreamUpdateParams_Call) Run(run func(stream unsafe.Pointer, params unsafe.Pointer, n_params uint32)) *MockVideoStreamAPI_PWStreamUpdateParams_Call {
1381+ _c.Call.Run(func(args mock.Arguments) {
1382+ var arg0 unsafe.Pointer
1383+ if args[0] != nil {
1384+ arg0 = args[0].(unsafe.Pointer)
1385+ }
1386+ var arg1 unsafe.Pointer
1387+ if args[1] != nil {
1388+ arg1 = args[1].(unsafe.Pointer)
1389+ }
1390+ var arg2 uint32
1391+ if args[2] != nil {
1392+ arg2 = args[2].(uint32)
1393+ }
1394+ run(
1395+ arg0,
1396+ arg1,
1397+ arg2,
1398+ )
1399+ })
1400+ return _c
1401+}
1402+
1403+func (_c *MockVideoStreamAPI_PWStreamUpdateParams_Call) Return(n int32) *MockVideoStreamAPI_PWStreamUpdateParams_Call {
1404+ _c.Call.Return(n)
1405+ return _c
1406+}
1407+
1408+func (_c *MockVideoStreamAPI_PWStreamUpdateParams_Call) RunAndReturn(run func(stream unsafe.Pointer, params unsafe.Pointer, n_params uint32) int32) *MockVideoStreamAPI_PWStreamUpdateParams_Call {
1409+ _c.Call.Return(run)
1410+ return _c
1411+}
A internal/ports/out/videostream.go +9 -0
@@ -0,0 +1,9 @@
1+package out
2+
3+// VideoStreamAPI is the set of C entry points needed by the video source: the
4+// generated VideoAPI group plus the stream calls shared with playback. CAPI
5+// satisfies it.
6+type VideoStreamAPI interface {
7+ VideoAPI
8+ StreamPlaybackAPI
9+}
@@ -0,0 +1,9 @@
1+package out
2+
3+// VideoStreamAPI is the set of C entry points needed by the video source: the
4+// generated VideoAPI group plus the stream calls shared with playback. CAPI
5+// satisfies it.
6+type VideoStreamAPI interface {
7+ VideoAPI
8+ StreamPlaybackAPI
9+}
M pipewire/context.go +2 -1
@@ -1,7 +1,8 @@
11 package pipewire
22
33 // Context is the public interface for PipeWire context operations.
4-// Contexts manage resources and connections to the PipeWire server.
4+// Contexts manage resources and connections to the PipeWire server. Create
5+// one with Runtime.NewContext on a Loop; destroy it before the Loop.
56 type Context interface {
67 Destroy()
78 Connect() (Core, error)
@@ -1,7 +1,8 @@
1 package pipewire1 package pipewire
2 2
3 // Context is the public interface for PipeWire context operations.3 // Context is the public interface for PipeWire context operations.
4-// Contexts manage resources and connections to the PipeWire server.4+// Contexts manage resources and connections to the PipeWire server. Create
5+// one with Runtime.NewContext on a Loop; destroy it before the Loop.
5 type Context interface {6 type Context interface {
6 Destroy()7 Destroy()
7 Connect() (Core, error)8 Connect() (Core, error)
M pipewire/core.go +4 -0
@@ -7,7 +7,11 @@ import (
77 // Core is the public interface for PipeWire core connection operations.
88 // A Core represents a connection to the PipeWire server.
99 type Core interface {
10+ // Disconnect disconnects from the server. Destroy streams first.
1011 Disconnect()
1112 Registry() (Registry, error)
1213 NewStream(name string, props unsafe.Pointer) (Stream, error)
14+ // NewVideoSource creates a Video/Source node fed by the caller. Call it
15+ // on the loop thread. See VideoSource.
16+ NewVideoSource(cfg VideoConfig, h VideoHandler) (*VideoSource, error)
1317 }
@@ -7,7 +7,11 @@ import (
7 // Core is the public interface for PipeWire core connection operations.7 // Core is the public interface for PipeWire core connection operations.
8 // A Core represents a connection to the PipeWire server.8 // A Core represents a connection to the PipeWire server.
9 type Core interface {9 type Core interface {
10+ // Disconnect disconnects from the server. Destroy streams first.
10 Disconnect()11 Disconnect()
11 Registry() (Registry, error)12 Registry() (Registry, error)
12 NewStream(name string, props unsafe.Pointer) (Stream, error)13 NewStream(name string, props unsafe.Pointer) (Stream, error)
14+ // NewVideoSource creates a Video/Source node fed by the caller. Call it
15+ // on the loop thread. See VideoSource.
16+ NewVideoSource(cfg VideoConfig, h VideoHandler) (*VideoSource, error)
13 }17 }
M pipewire/interfaces.go +5 -0
@@ -5,6 +5,11 @@ type Runtime interface {
55 Init() error
66 Deinit()
77 NewMainLoop() (MainLoop, error)
8+ // NewLoop creates a loop the caller iterates itself. See Loop for the
9+ // threading rules.
10+ NewLoop() (Loop, error)
11+ // NewContext creates a context that runs on loop.
12+ NewContext(loop Loop) (Context, error)
813 }
914
1015 // MainLoop is the public interface for PipeWire main loop operations.
@@ -5,6 +5,11 @@ type Runtime interface {
5 Init() error5 Init() error
6 Deinit()6 Deinit()
7 NewMainLoop() (MainLoop, error)7 NewMainLoop() (MainLoop, error)
8+ // NewLoop creates a loop the caller iterates itself. See Loop for the
9+ // threading rules.
10+ NewLoop() (Loop, error)
11+ // NewContext creates a context that runs on loop.
12+ NewContext(loop Loop) (Context, error)
8 }13 }
9 14
10 // MainLoop is the public interface for PipeWire main loop operations.15 // MainLoop is the public interface for PipeWire main loop operations.
A pipewire/loop.go +19 -0
@@ -0,0 +1,19 @@
1+package pipewire
2+
3+// Loop is a PipeWire loop that the caller iterates itself, typically from a
4+// poll loop that waits on Fd. Create it with Runtime.NewLoop.
5+//
6+// A Loop and everything created on it (Context, Core, VideoSource) must only
7+// be used from one goroutine that stays on one OS thread: call
8+// runtime.LockOSThread before creating the loop and keep it until Destroy.
9+type Loop interface {
10+ // Fd returns a pollable file descriptor that becomes readable when
11+ // Iterate has work to do.
12+ Fd() int
13+ // Iterate dispatches pending events without blocking. Stream callbacks
14+ // (VideoHandler methods) run inside it. A transient failure such as
15+ // EINTR is ignored; the next Iterate retries.
16+ Iterate()
17+ // Destroy destroys the loop. Destroy contexts created on it first.
18+ Destroy()
19+}
@@ -0,0 +1,19 @@
1+package pipewire
2+
3+// Loop is a PipeWire loop that the caller iterates itself, typically from a
4+// poll loop that waits on Fd. Create it with Runtime.NewLoop.
5+//
6+// A Loop and everything created on it (Context, Core, VideoSource) must only
7+// be used from one goroutine that stays on one OS thread: call
8+// runtime.LockOSThread before creating the loop and keep it until Destroy.
9+type Loop interface {
10+ // Fd returns a pollable file descriptor that becomes readable when
11+ // Iterate has work to do.
12+ Fd() int
13+ // Iterate dispatches pending events without blocking. Stream callbacks
14+ // (VideoHandler methods) run inside it. A transient failure such as
15+ // EINTR is ignored; the next Iterate retries.
16+ Iterate()
17+ // Destroy destroys the loop. Destroy contexts created on it first.
18+ Destroy()
19+}
M pipewire/mocks/mock_Runtime.go +117 -0
@@ -122,6 +122,123 @@ func (_c *MockRuntime_Init_Call) RunAndReturn(run func() error) *MockRuntime_Ini
122122 return _c
123123 }
124124
125+// NewContext provides a mock function for the type MockRuntime
126+func (_mock *MockRuntime) NewContext(loop pipewire.Loop) (pipewire.Context, error) {
127+ ret := _mock.Called(loop)
128+
129+ if len(ret) == 0 {
130+ panic("no return value specified for NewContext")
131+ }
132+
133+ var r0 pipewire.Context
134+ var r1 error
135+ if returnFunc, ok := ret.Get(0).(func(pipewire.Loop) (pipewire.Context, error)); ok {
136+ return returnFunc(loop)
137+ }
138+ if returnFunc, ok := ret.Get(0).(func(pipewire.Loop) pipewire.Context); ok {
139+ r0 = returnFunc(loop)
140+ } else {
141+ if ret.Get(0) != nil {
142+ r0 = ret.Get(0).(pipewire.Context)
143+ }
144+ }
145+ if returnFunc, ok := ret.Get(1).(func(pipewire.Loop) error); ok {
146+ r1 = returnFunc(loop)
147+ } else {
148+ r1 = ret.Error(1)
149+ }
150+ return r0, r1
151+}
152+
153+// MockRuntime_NewContext_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'NewContext'
154+type MockRuntime_NewContext_Call struct {
155+ *mock.Call
156+}
157+
158+// NewContext is a helper method to define mock.On call
159+// - loop pipewire.Loop
160+func (_e *MockRuntime_Expecter) NewContext(loop any) *MockRuntime_NewContext_Call {
161+ return &MockRuntime_NewContext_Call{Call: _e.mock.On("NewContext", loop)}
162+}
163+
164+func (_c *MockRuntime_NewContext_Call) Run(run func(loop pipewire.Loop)) *MockRuntime_NewContext_Call {
165+ _c.Call.Run(func(args mock.Arguments) {
166+ var arg0 pipewire.Loop
167+ if args[0] != nil {
168+ arg0 = args[0].(pipewire.Loop)
169+ }
170+ run(
171+ arg0,
172+ )
173+ })
174+ return _c
175+}
176+
177+func (_c *MockRuntime_NewContext_Call) Return(context pipewire.Context, err error) *MockRuntime_NewContext_Call {
178+ _c.Call.Return(context, err)
179+ return _c
180+}
181+
182+func (_c *MockRuntime_NewContext_Call) RunAndReturn(run func(loop pipewire.Loop) (pipewire.Context, error)) *MockRuntime_NewContext_Call {
183+ _c.Call.Return(run)
184+ return _c
185+}
186+
187+// NewLoop provides a mock function for the type MockRuntime
188+func (_mock *MockRuntime) NewLoop() (pipewire.Loop, error) {
189+ ret := _mock.Called()
190+
191+ if len(ret) == 0 {
192+ panic("no return value specified for NewLoop")
193+ }
194+
195+ var r0 pipewire.Loop
196+ var r1 error
197+ if returnFunc, ok := ret.Get(0).(func() (pipewire.Loop, error)); ok {
198+ return returnFunc()
199+ }
200+ if returnFunc, ok := ret.Get(0).(func() pipewire.Loop); ok {
201+ r0 = returnFunc()
202+ } else {
203+ if ret.Get(0) != nil {
204+ r0 = ret.Get(0).(pipewire.Loop)
205+ }
206+ }
207+ if returnFunc, ok := ret.Get(1).(func() error); ok {
208+ r1 = returnFunc()
209+ } else {
210+ r1 = ret.Error(1)
211+ }
212+ return r0, r1
213+}
214+
215+// MockRuntime_NewLoop_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'NewLoop'
216+type MockRuntime_NewLoop_Call struct {
217+ *mock.Call
218+}
219+
220+// NewLoop is a helper method to define mock.On call
221+func (_e *MockRuntime_Expecter) NewLoop() *MockRuntime_NewLoop_Call {
222+ return &MockRuntime_NewLoop_Call{Call: _e.mock.On("NewLoop")}
223+}
224+
225+func (_c *MockRuntime_NewLoop_Call) Run(run func()) *MockRuntime_NewLoop_Call {
226+ _c.Call.Run(func(args mock.Arguments) {
227+ run()
228+ })
229+ return _c
230+}
231+
232+func (_c *MockRuntime_NewLoop_Call) Return(loop pipewire.Loop, err error) *MockRuntime_NewLoop_Call {
233+ _c.Call.Return(loop, err)
234+ return _c
235+}
236+
237+func (_c *MockRuntime_NewLoop_Call) RunAndReturn(run func() (pipewire.Loop, error)) *MockRuntime_NewLoop_Call {
238+ _c.Call.Return(run)
239+ return _c
240+}
241+
125242 // NewMainLoop provides a mock function for the type MockRuntime
126243 func (_mock *MockRuntime) NewMainLoop() (pipewire.MainLoop, error) {
127244 ret := _mock.Called()
@@ -122,6 +122,123 @@ func (_c *MockRuntime_Init_Call) RunAndReturn(run func() error) *MockRuntime_Ini
122 return _c122 return _c
123 }123 }
124 124
125+// NewContext provides a mock function for the type MockRuntime
126+func (_mock *MockRuntime) NewContext(loop pipewire.Loop) (pipewire.Context, error) {
127+ ret := _mock.Called(loop)
128+
129+ if len(ret) == 0 {
130+ panic("no return value specified for NewContext")
131+ }
132+
133+ var r0 pipewire.Context
134+ var r1 error
135+ if returnFunc, ok := ret.Get(0).(func(pipewire.Loop) (pipewire.Context, error)); ok {
136+ return returnFunc(loop)
137+ }
138+ if returnFunc, ok := ret.Get(0).(func(pipewire.Loop) pipewire.Context); ok {
139+ r0 = returnFunc(loop)
140+ } else {
141+ if ret.Get(0) != nil {
142+ r0 = ret.Get(0).(pipewire.Context)
143+ }
144+ }
145+ if returnFunc, ok := ret.Get(1).(func(pipewire.Loop) error); ok {
146+ r1 = returnFunc(loop)
147+ } else {
148+ r1 = ret.Error(1)
149+ }
150+ return r0, r1
151+}
152+
153+// MockRuntime_NewContext_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'NewContext'
154+type MockRuntime_NewContext_Call struct {
155+ *mock.Call
156+}
157+
158+// NewContext is a helper method to define mock.On call
159+// - loop pipewire.Loop
160+func (_e *MockRuntime_Expecter) NewContext(loop any) *MockRuntime_NewContext_Call {
161+ return &MockRuntime_NewContext_Call{Call: _e.mock.On("NewContext", loop)}
162+}
163+
164+func (_c *MockRuntime_NewContext_Call) Run(run func(loop pipewire.Loop)) *MockRuntime_NewContext_Call {
165+ _c.Call.Run(func(args mock.Arguments) {
166+ var arg0 pipewire.Loop
167+ if args[0] != nil {
168+ arg0 = args[0].(pipewire.Loop)
169+ }
170+ run(
171+ arg0,
172+ )
173+ })
174+ return _c
175+}
176+
177+func (_c *MockRuntime_NewContext_Call) Return(context pipewire.Context, err error) *MockRuntime_NewContext_Call {
178+ _c.Call.Return(context, err)
179+ return _c
180+}
181+
182+func (_c *MockRuntime_NewContext_Call) RunAndReturn(run func(loop pipewire.Loop) (pipewire.Context, error)) *MockRuntime_NewContext_Call {
183+ _c.Call.Return(run)
184+ return _c
185+}
186+
187+// NewLoop provides a mock function for the type MockRuntime
188+func (_mock *MockRuntime) NewLoop() (pipewire.Loop, error) {
189+ ret := _mock.Called()
190+
191+ if len(ret) == 0 {
192+ panic("no return value specified for NewLoop")
193+ }
194+
195+ var r0 pipewire.Loop
196+ var r1 error
197+ if returnFunc, ok := ret.Get(0).(func() (pipewire.Loop, error)); ok {
198+ return returnFunc()
199+ }
200+ if returnFunc, ok := ret.Get(0).(func() pipewire.Loop); ok {
201+ r0 = returnFunc()
202+ } else {
203+ if ret.Get(0) != nil {
204+ r0 = ret.Get(0).(pipewire.Loop)
205+ }
206+ }
207+ if returnFunc, ok := ret.Get(1).(func() error); ok {
208+ r1 = returnFunc()
209+ } else {
210+ r1 = ret.Error(1)
211+ }
212+ return r0, r1
213+}
214+
215+// MockRuntime_NewLoop_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'NewLoop'
216+type MockRuntime_NewLoop_Call struct {
217+ *mock.Call
218+}
219+
220+// NewLoop is a helper method to define mock.On call
221+func (_e *MockRuntime_Expecter) NewLoop() *MockRuntime_NewLoop_Call {
222+ return &MockRuntime_NewLoop_Call{Call: _e.mock.On("NewLoop")}
223+}
224+
225+func (_c *MockRuntime_NewLoop_Call) Run(run func()) *MockRuntime_NewLoop_Call {
226+ _c.Call.Run(func(args mock.Arguments) {
227+ run()
228+ })
229+ return _c
230+}
231+
232+func (_c *MockRuntime_NewLoop_Call) Return(loop pipewire.Loop, err error) *MockRuntime_NewLoop_Call {
233+ _c.Call.Return(loop, err)
234+ return _c
235+}
236+
237+func (_c *MockRuntime_NewLoop_Call) RunAndReturn(run func() (pipewire.Loop, error)) *MockRuntime_NewLoop_Call {
238+ _c.Call.Return(run)
239+ return _c
240+}
241+
125 // NewMainLoop provides a mock function for the type MockRuntime242 // NewMainLoop provides a mock function for the type MockRuntime
126 func (_mock *MockRuntime) NewMainLoop() (pipewire.MainLoop, error) {243 func (_mock *MockRuntime) NewMainLoop() (pipewire.MainLoop, error) {
127 ret := _mock.Called()244 ret := _mock.Called()
M pipewire/runtime.go +66 -0
@@ -2,6 +2,7 @@ package pipewire
22
33 import (
44 "errors"
5+ "unsafe"
56
67 "github.com/bnema/purego-pipewire/internal/capi"
78 "github.com/bnema/purego-pipewire/internal/core"
@@ -28,6 +29,71 @@ func (rw runtimeWrapper) NewMainLoop() (MainLoop, error) {
2829 return mainLoopWrapper{inner: ml}, nil
2930 }
3031
32+func (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+
40+func (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.
53+type contextWrapper struct {
54+ inner *core.Context
55+}
56+
57+func (cw contextWrapper) Destroy() { cw.inner.Destroy() }
58+
59+func (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.
68+type coreWrapper struct {
69+ inner *core.Core
70+}
71+
72+func (cw coreWrapper) Disconnect() { cw.inner.Disconnect() }
73+
74+func (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+
82+func (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+
90+func (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+
3197 // mainLoopWrapper wraps the internal core.MainLoop to implement the public MainLoop interface.
3298 type mainLoopWrapper struct {
3399 inner *core.MainLoop
@@ -2,6 +2,7 @@ package pipewire
2 2
3 import (3 import (
4 "errors"4 "errors"
5+ "unsafe"
5 6
6 "github.com/bnema/purego-pipewire/internal/capi"7 "github.com/bnema/purego-pipewire/internal/capi"
7 "github.com/bnema/purego-pipewire/internal/core"8 "github.com/bnema/purego-pipewire/internal/core"
@@ -28,6 +29,71 @@ func (rw runtimeWrapper) NewMainLoop() (MainLoop, error) {
28 return mainLoopWrapper{inner: ml}, nil29 return mainLoopWrapper{inner: ml}, nil
29 }30 }
30 31
32+func (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+
40+func (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.
53+type contextWrapper struct {
54+ inner *core.Context
55+}
56+
57+func (cw contextWrapper) Destroy() { cw.inner.Destroy() }
58+
59+func (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.
68+type coreWrapper struct {
69+ inner *core.Core
70+}
71+
72+func (cw coreWrapper) Disconnect() { cw.inner.Disconnect() }
73+
74+func (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+
82+func (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+
90+func (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+
31 // mainLoopWrapper wraps the internal core.MainLoop to implement the public MainLoop interface.97 // mainLoopWrapper wraps the internal core.MainLoop to implement the public MainLoop interface.
32 type mainLoopWrapper struct {98 type mainLoopWrapper struct {
33 inner *core.MainLoop99 inner *core.MainLoop
A pipewire/video.go +69 -0
@@ -0,0 +1,69 @@
1+package pipewire
2+
3+import (
4+ "github.com/bnema/purego-pipewire/internal/core"
5+ "github.com/bnema/purego-pipewire/spa"
6+)
7+
8+// VideoFormat is a SPA raw video format (BGRx=8, BGRA=12).
9+type VideoFormat = spa.VideoFormat
10+
11+// Supported video formats. They map to wl_shm XRGB8888 (BGRx) and ARGB8888
12+// (BGRA).
13+const (
14+ VideoFormatBGRx = spa.VideoFormatBGRx
15+ VideoFormatBGRA = spa.VideoFormatBGRA
16+)
17+
18+// pw_stream_state values reported to VideoHandler.StateChanged.
19+const (
20+ StreamStateError int32 = -1
21+ StreamStateUnconnected int32 = 0
22+ StreamStateConnecting int32 = 1
23+ StreamStatePaused int32 = 2
24+ StreamStateStreaming int32 = 3
25+)
26+
27+// VideoConfig configures a VideoSource: the node name, the initial size, the
28+// maximum frame rate (60 when zero) and the accepted formats (BGRx when
29+// empty; at most 4, the first is preferred).
30+type VideoConfig = core.VideoConfig
31+
32+// VideoHandler receives VideoSource events. Every method runs on the loop
33+// thread, inside Loop.Iterate (or, for the first events, inside the call that
34+// triggered them). Implementations must not block and must not allocate.
35+type VideoHandler interface {
36+ // StateChanged reports a stream state change; see the StreamState
37+ // constants. nodeID is the PipeWire node id once known (0 before). err
38+ // carries the message when state is StreamStateError.
39+ StateChanged(state int32, nodeID uint32, err string)
40+ // FormatChanged reports the negotiated format and its row stride.
41+ FormatChanged(f VideoFormat, w, h, stride int)
42+ // BuffersChanged is called after a buffer was added or removed;
43+ // Dequeue may now return a buffer.
44+ BuffersChanged()
45+}
46+
47+// VideoBuffer is a buffer handed out by VideoSource.Dequeue. Data aliases a
48+// mapped memfd owned by the source; it is valid until the buffer is given back
49+// with Queue or Release. The value is owned by the source: do not copy it or
50+// keep it after giving it back.
51+type VideoBuffer = core.VideoBuffer
52+
53+// VideoSource is a PipeWire Video/Source node that drives the graph and
54+// exposes shared-memory (memfd) buffers. All methods run on the loop thread.
55+//
56+// Produce a frame with Dequeue, write Data, Queue, then Trigger — in that
57+// order: the buffer must be queued before Trigger. A steady-state cycle
58+// performs no heap allocation.
59+//
60+// b := src.Dequeue() // nil: no buffer is free
61+// // ... fill b.Data (b.Stride bytes per row) ...
62+// src.Queue(b, seq, pts, false)
63+// src.Trigger()
64+//
65+// Buffers PipeWire removes (renegotiation, Resize, Destroy, consumer
66+// disconnect) stay mapped while borrowed and are unmapped when given back with
67+// Queue or Release. Resize and Destroy are best called when no buffer is
68+// borrowed. DMA-BUF is not supported.
69+type VideoSource = core.VideoSource
@@ -0,0 +1,69 @@
1+package pipewire
2+
3+import (
4+ "github.com/bnema/purego-pipewire/internal/core"
5+ "github.com/bnema/purego-pipewire/spa"
6+)
7+
8+// VideoFormat is a SPA raw video format (BGRx=8, BGRA=12).
9+type VideoFormat = spa.VideoFormat
10+
11+// Supported video formats. They map to wl_shm XRGB8888 (BGRx) and ARGB8888
12+// (BGRA).
13+const (
14+ VideoFormatBGRx = spa.VideoFormatBGRx
15+ VideoFormatBGRA = spa.VideoFormatBGRA
16+)
17+
18+// pw_stream_state values reported to VideoHandler.StateChanged.
19+const (
20+ StreamStateError int32 = -1
21+ StreamStateUnconnected int32 = 0
22+ StreamStateConnecting int32 = 1
23+ StreamStatePaused int32 = 2
24+ StreamStateStreaming int32 = 3
25+)
26+
27+// VideoConfig configures a VideoSource: the node name, the initial size, the
28+// maximum frame rate (60 when zero) and the accepted formats (BGRx when
29+// empty; at most 4, the first is preferred).
30+type VideoConfig = core.VideoConfig
31+
32+// VideoHandler receives VideoSource events. Every method runs on the loop
33+// thread, inside Loop.Iterate (or, for the first events, inside the call that
34+// triggered them). Implementations must not block and must not allocate.
35+type VideoHandler interface {
36+ // StateChanged reports a stream state change; see the StreamState
37+ // constants. nodeID is the PipeWire node id once known (0 before). err
38+ // carries the message when state is StreamStateError.
39+ StateChanged(state int32, nodeID uint32, err string)
40+ // FormatChanged reports the negotiated format and its row stride.
41+ FormatChanged(f VideoFormat, w, h, stride int)
42+ // BuffersChanged is called after a buffer was added or removed;
43+ // Dequeue may now return a buffer.
44+ BuffersChanged()
45+}
46+
47+// VideoBuffer is a buffer handed out by VideoSource.Dequeue. Data aliases a
48+// mapped memfd owned by the source; it is valid until the buffer is given back
49+// with Queue or Release. The value is owned by the source: do not copy it or
50+// keep it after giving it back.
51+type VideoBuffer = core.VideoBuffer
52+
53+// VideoSource is a PipeWire Video/Source node that drives the graph and
54+// exposes shared-memory (memfd) buffers. All methods run on the loop thread.
55+//
56+// Produce a frame with Dequeue, write Data, Queue, then Trigger — in that
57+// order: the buffer must be queued before Trigger. A steady-state cycle
58+// performs no heap allocation.
59+//
60+// b := src.Dequeue() // nil: no buffer is free
61+// // ... fill b.Data (b.Stride bytes per row) ...
62+// src.Queue(b, seq, pts, false)
63+// src.Trigger()
64+//
65+// Buffers PipeWire removes (renegotiation, Resize, Destroy, consumer
66+// disconnect) stay mapped while borrowed and are unmapped when given back with
67+// Queue or Release. Resize and Destroy are best called when no buffer is
68+// borrowed. DMA-BUF is not supported.
69+type VideoSource = core.VideoSource

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 1

Tags 8

↑↓ moveenter openesc close