Skip to content

Commit d7905fb

Browse files
authored
Merge pull request tinyzimmer#26 from go-gst/device-monitor
Device monitor
2 parents b549813 + 074f909 commit d7905fb

File tree

7 files changed

+310
-0
lines changed

7 files changed

+310
-0
lines changed

examples/device_monitor/main.go

+75
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
// This example uses gstreamer's device monitor api.
2+
//
3+
// https://gstreamer.freedesktop.org/documentation/gstreamer/gstdevicemonitor.html
4+
package main
5+
6+
import (
7+
"fmt"
8+
9+
"github.com/go-gst/go-glib/glib"
10+
"github.com/go-gst/go-gst/examples"
11+
"github.com/go-gst/go-gst/gst"
12+
)
13+
14+
func runPipeline(loop *glib.MainLoop) error {
15+
16+
gst.Init(nil)
17+
fmt.Println("Running device monitor")
18+
// if len(os.Args) < 2 {
19+
// fmt.Printf("USAGE: %s <uri>\n", os.Args[0])
20+
// os.Exit(1)
21+
// }
22+
23+
// uri := os.Args[1]
24+
fmt.Println("Creating device monitor")
25+
26+
monitor := gst.NewDeviceMonitor()
27+
fmt.Println("Created device monitor", monitor)
28+
29+
// if err != nil {
30+
// fmt.Println("ERROR:", err)
31+
// os.Exit(2)
32+
// }
33+
caps := gst.NewCapsFromString("video/x-raw")
34+
35+
monitor.AddFilter("Video/Source", caps)
36+
37+
fmt.Println("Getting device monitor bus")
38+
bus := monitor.GetBus()
39+
fmt.Println("Got device monitor bus", bus)
40+
41+
bus.AddWatch(func(msg *gst.Message) bool {
42+
switch msg.Type() {
43+
case gst.MessageDeviceAdded:
44+
message := msg.ParseDeviceAdded().GetDisplayName()
45+
fmt.Println("Added: ", message)
46+
case gst.MessageDeviceRemoved:
47+
message := msg.ParseDeviceRemoved().GetDisplayName()
48+
fmt.Println("Removed: ", message)
49+
default:
50+
// All messages implement a Stringer. However, this is
51+
// typically an expensive thing to do and should be avoided.
52+
fmt.Println("Type: ", msg.Type())
53+
fmt.Println("Message: ", msg)
54+
}
55+
return true
56+
})
57+
58+
fmt.Println("Starting device monitor")
59+
monitor.Start()
60+
fmt.Println("Started device monitor")
61+
devices := monitor.GetDevices()
62+
for i, v := range devices {
63+
fmt.Printf("Device: %d %s\n", i, v.GetDisplayName())
64+
}
65+
66+
loop.Run()
67+
68+
return nil
69+
}
70+
71+
func main() {
72+
examples.RunLoop(func(loop *glib.MainLoop) error {
73+
return runPipeline(loop)
74+
})
75+
}

examples/device_provider/main.go

+78
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
// This example uses gstreamer's device provider api.
2+
//
3+
// https://gstreamer.freedesktop.org/documentation/gstreamer/gstdeviceprovider.html
4+
package main
5+
6+
import (
7+
"fmt"
8+
"os"
9+
10+
"github.com/go-gst/go-glib/glib"
11+
"github.com/go-gst/go-gst/examples"
12+
"github.com/go-gst/go-gst/gst"
13+
)
14+
15+
func runPipeline(loop *glib.MainLoop) error {
16+
17+
gst.Init(nil)
18+
fmt.Println("Running device provider")
19+
// if len(os.Args) < 2 {
20+
// fmt.Printf("USAGE: %s <uri>\n", os.Args[0])
21+
// os.Exit(1)
22+
// }
23+
24+
// uri := os.Args[1]
25+
fmt.Println("Creating device monitor")
26+
27+
// provider := gst.FindDeviceProviderByName("foo")
28+
// fmt.Println("Created device provider", provider)
29+
30+
provider := gst.FindDeviceProviderByName("avfdeviceprovider")
31+
fmt.Println("Created device provider", provider)
32+
33+
if provider == nil {
34+
fmt.Println("No provider found")
35+
os.Exit(2)
36+
}
37+
38+
fmt.Println("Getting device provider bus")
39+
bus := provider.GetBus()
40+
fmt.Println("Got device provider bus", bus)
41+
42+
bus.AddWatch(func(msg *gst.Message) bool {
43+
switch msg.Type() {
44+
case gst.MessageDeviceAdded:
45+
message := msg.ParseDeviceAdded().GetDisplayName()
46+
fmt.Println("Added: ", message)
47+
case gst.MessageDeviceRemoved:
48+
message := msg.ParseDeviceRemoved().GetDisplayName()
49+
fmt.Println("Removed: ", message)
50+
default:
51+
// All messages implement a Stringer. However, this is
52+
// typically an expensive thing to do and should be avoided.
53+
fmt.Println("Type: ", msg.Type())
54+
fmt.Println("Message: ", msg)
55+
}
56+
return true
57+
})
58+
59+
fmt.Println("Starting device monitor")
60+
provider.Start()
61+
fmt.Println("Started device monitor")
62+
63+
fmt.Println("listing devices from provider")
64+
devices := provider.GetDevices()
65+
for i, v := range devices {
66+
fmt.Printf("Device: %d %s\n", i, v.GetDisplayName())
67+
}
68+
69+
loop.Run()
70+
71+
return nil
72+
}
73+
74+
func main() {
75+
examples.RunLoop(func(loop *glib.MainLoop) error {
76+
return runPipeline(loop)
77+
})
78+
}

gst/gst.go.c

+1
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ GstChildProxy * toGstChildProxy (void *p) { re
1515
GstClock * toGstClock (void *p) { return (GST_CLOCK(p)); }
1616
GstContext * toGstContext (void *p) { return (GST_CONTEXT_CAST(p)); }
1717
GstDevice * toGstDevice (void *p) { return (GST_DEVICE_CAST(p)); }
18+
GstDeviceProvider * toGstDeviceProvider (void *p) { return (GST_DEVICE_PROVIDER_CAST(p)); }
1819
GstElementFactory * toGstElementFactory (void *p) { return (GST_ELEMENT_FACTORY(p)); }
1920
GstElementClass * toGstElementClass (void *p) { return (GST_ELEMENT_CLASS(p)); }
2021
GstElement * toGstElement (void *p) { return (GST_ELEMENT(p)); }

gst/gst.go.h

+1
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ extern GstChildProxy * toGstChildProxy (void *
3131
extern GstClock * toGstClock (void *p);
3232
extern GstContext * toGstContext (void *p);
3333
extern GstDevice * toGstDevice (void *p);
34+
extern GstDeviceProvider * toGstDeviceProvider (void *p);
3435
extern GstElementFactory * toGstElementFactory (void *p);
3536
extern GstElementClass * toGstElementClass (void *p);
3637
extern GstElement * toGstElement (void *p);

gst/gst_device_monitor.go

+82
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
package gst
2+
3+
// #include "gst.go.h"
4+
import "C"
5+
6+
import (
7+
"unsafe"
8+
9+
"github.com/go-gst/go-glib/glib"
10+
)
11+
12+
// DeviceMonitor is a Go representation of a GstDeviceMonitor.
13+
type DeviceMonitor struct {
14+
ptr *C.GstDeviceMonitor
15+
bus *Bus
16+
}
17+
18+
func NewDeviceMonitor() *DeviceMonitor {
19+
monitor := C.gst_device_monitor_new()
20+
if monitor == nil {
21+
return nil
22+
}
23+
return &DeviceMonitor{ptr: monitor}
24+
}
25+
26+
func (d *DeviceMonitor) AddFilter(classes string, caps *Caps) uint {
27+
var cClasses *C.gchar
28+
if classes != "" {
29+
cClasses = C.CString(classes)
30+
defer C.free(unsafe.Pointer(cClasses))
31+
}
32+
33+
filterId := C.gst_device_monitor_add_filter(d.ptr, cClasses, caps.Instance())
34+
return uint(filterId)
35+
}
36+
37+
func (d *DeviceMonitor) RemoveFilter(filterId uint) bool {
38+
return gobool(C.gst_device_monitor_remove_filter(d.ptr, C.guint(filterId)))
39+
}
40+
41+
// GetBus returns the message bus for this pipeline.
42+
func (d *DeviceMonitor) GetBus() *Bus {
43+
if d.bus == nil {
44+
cBus := C.gst_device_monitor_get_bus(d.ptr)
45+
d.bus = FromGstBusUnsafeFull(unsafe.Pointer(cBus))
46+
}
47+
return d.bus
48+
}
49+
50+
func (d *DeviceMonitor) Start() bool {
51+
return gobool(C.gst_device_monitor_start(d.ptr))
52+
//should return if we were able to add the filter
53+
}
54+
55+
func (d *DeviceMonitor) Stop() {
56+
C.gst_device_monitor_stop(d.ptr)
57+
//should return if we were able to add the filter
58+
}
59+
60+
func (d *DeviceMonitor) GetDevices() []*Device {
61+
glist := C.gst_device_monitor_get_devices(d.ptr)
62+
if glist == nil {
63+
return nil
64+
}
65+
goList := glib.WrapList(uintptr(unsafe.Pointer(glist)))
66+
out := make([]*Device, 0)
67+
goList.Foreach(func(item interface{}) {
68+
pt := item.(unsafe.Pointer)
69+
out = append(out, FromGstDeviceUnsafeFull(pt))
70+
})
71+
return out
72+
}
73+
74+
func (d *DeviceMonitor) SetShowAllDevices(show bool) {
75+
C.gst_device_monitor_set_show_all_devices(d.ptr, gboolean(show))
76+
}
77+
78+
func (d *DeviceMonitor) GetShowAllDevices() bool {
79+
return gobool(C.gst_device_monitor_get_show_all_devices(d.ptr))
80+
}
81+
82+
//gst_device_monitor_get_providers

gst/gst_device_provider.go

+55
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
package gst
2+
3+
// #include "gst.go.h"
4+
import "C"
5+
6+
import (
7+
"unsafe"
8+
9+
"github.com/go-gst/go-glib/glib"
10+
)
11+
12+
// DeviceProvider is a Go representation of a GstDeviceProvider.
13+
type DeviceProvider struct{ *Object }
14+
15+
// FromGstDeviceProviderUnsafeNone wraps the given device with a ref and finalizer.
16+
func FromGstDeviceProviderUnsafeNone(deviceProvider unsafe.Pointer) *DeviceProvider {
17+
return &DeviceProvider{wrapObject(glib.TransferNone(deviceProvider))}
18+
}
19+
20+
// FromGstDeviceProviderUnsafeFull wraps the given device with a finalizer.
21+
func FromGstDeviceProviderUnsafeFull(deviceProvider unsafe.Pointer) *DeviceProvider {
22+
return &DeviceProvider{wrapObject(glib.TransferFull(deviceProvider))}
23+
}
24+
25+
// Instance returns the underlying GstDevice object.
26+
func (d *DeviceProvider) Instance() *C.GstDeviceProvider { return C.toGstDeviceProvider(d.Unsafe()) }
27+
28+
func (d *DeviceProvider) GetDevices() []*Device {
29+
glist := C.gst_device_provider_get_devices((*C.GstDeviceProvider)(d.Instance()))
30+
if glist == nil {
31+
return nil
32+
}
33+
goList := glib.WrapList(uintptr(unsafe.Pointer(glist)))
34+
out := make([]*Device, 0)
35+
goList.Foreach(func(item interface{}) {
36+
pt := item.(unsafe.Pointer)
37+
out = append(out, FromGstDeviceUnsafeFull(pt))
38+
})
39+
return out
40+
}
41+
42+
// GetBus returns the message bus for this pipeline.
43+
func (d *DeviceProvider) GetBus() *Bus {
44+
cBus := C.gst_device_provider_get_bus((*C.GstDeviceProvider)(d.Instance()))
45+
bus := FromGstBusUnsafeFull(unsafe.Pointer(cBus))
46+
return bus
47+
}
48+
49+
func (d *DeviceProvider) Start() bool {
50+
return gobool(C.gst_device_provider_start((*C.GstDeviceProvider)(d.Instance())))
51+
}
52+
53+
func (d *DeviceProvider) Stop() {
54+
C.gst_device_provider_stop((*C.GstDeviceProvider)(d.Instance()))
55+
}

gst/gst_device_provider_factory.go

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package gst
2+
3+
// #include "gst.go.h"
4+
import "C"
5+
6+
import (
7+
"unsafe"
8+
)
9+
10+
func FindDeviceProviderByName(factoryName string) *DeviceProvider {
11+
cFactoryName := C.CString(factoryName)
12+
defer C.free(unsafe.Pointer(cFactoryName))
13+
provider := C.gst_device_provider_factory_get_by_name((*C.gchar)(unsafe.Pointer(cFactoryName)))
14+
if provider == nil {
15+
return nil
16+
}
17+
return FromGstDeviceProviderUnsafeFull(unsafe.Pointer(provider))
18+
}

0 commit comments

Comments
 (0)